optabs-query.h revision 1.4
1/* IR-agnostic target query functions relating to optabs 2 Copyright (C) 2001-2018 Free Software Foundation, Inc. 3 4This file is part of GCC. 5 6GCC is free software; you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation; either version 3, or (at your option) 9any later version. 10 11GCC is distributed in the hope that it will be useful, 12but WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14GNU General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with GCC; see the file COPYING3. If not see 18<http://www.gnu.org/licenses/>. */ 19 20#ifndef GCC_OPTABS_QUERY_H 21#define GCC_OPTABS_QUERY_H 22 23#include "insn-opinit.h" 24#include "target.h" 25 26/* Return true if OP is a conversion optab. */ 27 28inline bool 29convert_optab_p (optab op) 30{ 31 return op > unknown_optab && op <= LAST_CONV_OPTAB; 32} 33 34/* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing 35 if the target does not have such an insn. */ 36 37inline enum insn_code 38optab_handler (optab op, machine_mode mode) 39{ 40 unsigned scode = (op << 16) | mode; 41 gcc_assert (op > LAST_CONV_OPTAB); 42 return raw_optab_handler (scode); 43} 44 45/* Return the insn used to perform conversion OP from mode FROM_MODE 46 to mode TO_MODE; return CODE_FOR_nothing if the target does not have 47 such an insn. */ 48 49inline enum insn_code 50convert_optab_handler (convert_optab op, machine_mode to_mode, 51 machine_mode from_mode) 52{ 53 unsigned scode = (op << 16) | (from_mode << 8) | to_mode; 54 gcc_assert (convert_optab_p (op)); 55 return raw_optab_handler (scode); 56} 57 58enum insn_code convert_optab_handler (convert_optab, machine_mode, 59 machine_mode, optimization_type); 60 61/* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing 62 if the target does not have such an insn. */ 63 64inline enum insn_code 65direct_optab_handler (direct_optab op, machine_mode mode) 66{ 67 return optab_handler (op, mode); 68} 69 70enum insn_code direct_optab_handler (convert_optab, machine_mode, 71 optimization_type); 72 73/* Return true if UNOPTAB is for a trapping-on-overflow operation. */ 74 75inline bool 76trapv_unoptab_p (optab unoptab) 77{ 78 return (unoptab == negv_optab 79 || unoptab == absv_optab); 80} 81 82/* Return true if BINOPTAB is for a trapping-on-overflow operation. */ 83 84inline bool 85trapv_binoptab_p (optab binoptab) 86{ 87 return (binoptab == addv_optab 88 || binoptab == subv_optab 89 || binoptab == smulv_optab); 90} 91 92/* Return insn code for a comparison operator with VMODE 93 resultin MASK_MODE, unsigned if UNS is true. */ 94 95static inline enum insn_code 96get_vec_cmp_icode (machine_mode vmode, machine_mode mask_mode, bool uns) 97{ 98 optab tab = uns ? vec_cmpu_optab : vec_cmp_optab; 99 return convert_optab_handler (tab, vmode, mask_mode); 100} 101 102/* Return insn code for a comparison operator with VMODE 103 resultin MASK_MODE (only for EQ/NE). */ 104 105static inline enum insn_code 106get_vec_cmp_eq_icode (machine_mode vmode, machine_mode mask_mode) 107{ 108 return convert_optab_handler (vec_cmpeq_optab, vmode, mask_mode); 109} 110 111/* Return insn code for a conditional operator with a comparison in 112 mode CMODE, unsigned if UNS is true, resulting in a value of mode VMODE. */ 113 114inline enum insn_code 115get_vcond_icode (machine_mode vmode, machine_mode cmode, bool uns) 116{ 117 enum insn_code icode = CODE_FOR_nothing; 118 if (uns) 119 icode = convert_optab_handler (vcondu_optab, vmode, cmode); 120 else 121 icode = convert_optab_handler (vcond_optab, vmode, cmode); 122 return icode; 123} 124 125/* Return insn code for a conditional operator with a mask mode 126 MMODE resulting in a value of mode VMODE. */ 127 128static inline enum insn_code 129get_vcond_mask_icode (machine_mode vmode, machine_mode mmode) 130{ 131 return convert_optab_handler (vcond_mask_optab, vmode, mmode); 132} 133 134/* Return insn code for a conditional operator with a comparison in 135 mode CMODE (only EQ/NE), resulting in a value of mode VMODE. */ 136 137static inline enum insn_code 138get_vcond_eq_icode (machine_mode vmode, machine_mode cmode) 139{ 140 return convert_optab_handler (vcondeq_optab, vmode, cmode); 141} 142 143/* Enumerates the possible extraction_insn operations. */ 144enum extraction_pattern { EP_insv, EP_extv, EP_extzv }; 145 146/* Describes an instruction that inserts or extracts a bitfield. */ 147struct extraction_insn 148{ 149 /* The code of the instruction. */ 150 enum insn_code icode; 151 152 /* The mode that the structure operand should have. This is byte_mode 153 when using the legacy insv, extv and extzv patterns to access memory. 154 If no mode is given, the structure is a BLKmode memory. */ 155 opt_scalar_int_mode struct_mode; 156 157 /* The mode of the field to be inserted or extracted, and by extension 158 the mode of the insertion or extraction itself. */ 159 scalar_int_mode field_mode; 160 161 /* The mode of the field's bit position. This is only important 162 when the position is variable rather than constant. */ 163 scalar_int_mode pos_mode; 164}; 165 166bool get_best_reg_extraction_insn (extraction_insn *, 167 enum extraction_pattern, 168 unsigned HOST_WIDE_INT, machine_mode); 169bool get_best_mem_extraction_insn (extraction_insn *, 170 enum extraction_pattern, 171 HOST_WIDE_INT, HOST_WIDE_INT, machine_mode); 172 173enum insn_code can_extend_p (machine_mode, machine_mode, int); 174enum insn_code can_float_p (machine_mode, machine_mode, int); 175enum insn_code can_fix_p (machine_mode, machine_mode, int, bool *); 176bool can_conditionally_move_p (machine_mode mode); 177opt_machine_mode qimode_for_vec_perm (machine_mode); 178bool selector_fits_mode_p (machine_mode, const vec_perm_indices &); 179bool can_vec_perm_var_p (machine_mode); 180bool can_vec_perm_const_p (machine_mode, const vec_perm_indices &, 181 bool = true); 182/* Find a widening optab even if it doesn't widen as much as we want. */ 183#define find_widening_optab_handler(A, B, C) \ 184 find_widening_optab_handler_and_mode (A, B, C, NULL) 185enum insn_code find_widening_optab_handler_and_mode (optab, machine_mode, 186 machine_mode, 187 machine_mode *); 188int can_mult_highpart_p (machine_mode, bool); 189bool can_vec_mask_load_store_p (machine_mode, machine_mode, bool); 190bool can_compare_and_swap_p (machine_mode, bool); 191bool can_atomic_exchange_p (machine_mode, bool); 192bool can_atomic_load_p (machine_mode); 193bool lshift_cheap_p (bool); 194bool supports_vec_gather_load_p (); 195bool supports_vec_scatter_store_p (); 196 197/* Version of find_widening_optab_handler_and_mode that operates on 198 specific mode types. */ 199 200template<typename T> 201inline enum insn_code 202find_widening_optab_handler_and_mode (optab op, const T &to_mode, 203 const T &from_mode, T *found_mode) 204{ 205 machine_mode tmp; 206 enum insn_code icode = find_widening_optab_handler_and_mode 207 (op, machine_mode (to_mode), machine_mode (from_mode), &tmp); 208 if (icode != CODE_FOR_nothing && found_mode) 209 *found_mode = as_a <T> (tmp); 210 return icode; 211} 212 213#endif 214