Branch data Line data Source code
1 : : /* IR-agnostic target query functions relating to optabs
2 : : Copyright (C) 2001-2024 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify
7 : : it under the terms of the GNU General Public License as published by
8 : : the Free Software Foundation; either version 3, or (at your option)
9 : : any later version.
10 : :
11 : : GCC is distributed in the hope that it will be useful,
12 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : : GNU General Public License for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along 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 : :
28 : : inline bool
29 : 27603540 : convert_optab_p (optab op)
30 : : {
31 : 26440787 : 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 : :
37 : : inline enum insn_code
38 : 245232390 : optab_handler (optab op, machine_mode mode)
39 : : {
40 : 245232390 : unsigned scode = (op << 20) | mode;
41 : 94558709 : gcc_assert (op > LAST_CONV_OPTAB);
42 : 245232390 : 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 : :
49 : : inline enum insn_code
50 : 14278558 : convert_optab_handler (convert_optab op, machine_mode to_mode,
51 : : machine_mode from_mode)
52 : : {
53 : 14278558 : unsigned scode = (op << 20) | (from_mode << 10) | to_mode;
54 : 13929020 : gcc_assert (convert_optab_p (op));
55 : 14074877 : return raw_optab_handler (scode);
56 : : }
57 : :
58 : : enum 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 : :
64 : : inline enum insn_code
65 : 13658999 : direct_optab_handler (direct_optab op, machine_mode mode)
66 : : {
67 : 18357151 : return optab_handler (op, mode);
68 : : }
69 : :
70 : : enum 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 : :
75 : : inline bool
76 : 36243 : trapv_unoptab_p (optab unoptab)
77 : : {
78 : 36243 : return (unoptab == negv_optab
79 : 36243 : || unoptab == absv_optab);
80 : : }
81 : :
82 : : /* Return true if BINOPTAB is for a trapping-on-overflow operation. */
83 : :
84 : : inline bool
85 : 66186 : trapv_binoptab_p (optab binoptab)
86 : : {
87 : 66186 : return (binoptab == addv_optab
88 : 66186 : || binoptab == subv_optab
89 : 66186 : || 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 : :
95 : : inline enum insn_code
96 : 1152511 : get_vec_cmp_icode (machine_mode vmode, machine_mode mask_mode, bool uns)
97 : : {
98 : 1152511 : optab tab = uns ? vec_cmpu_optab : vec_cmp_optab;
99 : 1152511 : 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 : :
105 : : inline enum insn_code
106 : 158739 : get_vec_cmp_eq_icode (machine_mode vmode, machine_mode mask_mode)
107 : : {
108 : 158739 : return convert_optab_handler (vec_cmpeq_optab, vmode, mask_mode);
109 : : }
110 : :
111 : : /* Return insn code for a conditional operator with a mask mode
112 : : MMODE resulting in a value of mode VMODE. */
113 : :
114 : : inline enum insn_code
115 : 51198 : get_vcond_mask_icode (machine_mode vmode, machine_mode mmode)
116 : : {
117 : 51198 : return convert_optab_handler (vcond_mask_optab, vmode, mmode);
118 : : }
119 : :
120 : : /* Enumerates the possible extraction_insn operations. */
121 : : enum extraction_pattern { EP_insv, EP_extv, EP_extzv };
122 : :
123 : : /* Describes an instruction that inserts or extracts a bitfield. */
124 : 1817852 : class extraction_insn
125 : : {
126 : : public:
127 : : /* The code of the instruction. */
128 : : enum insn_code icode;
129 : :
130 : : /* The mode that the structure operand should have. This is byte_mode
131 : : when using the legacy insv, extv and extzv patterns to access memory.
132 : : If no mode is given, the structure is a BLKmode memory. */
133 : : opt_scalar_int_mode struct_mode;
134 : :
135 : : /* The mode of the field to be inserted or extracted, and by extension
136 : : the mode of the insertion or extraction itself. */
137 : : scalar_int_mode field_mode;
138 : :
139 : : /* The mode of the field's bit position. This is only important
140 : : when the position is variable rather than constant. */
141 : : scalar_int_mode pos_mode;
142 : : };
143 : :
144 : : bool get_best_reg_extraction_insn (extraction_insn *,
145 : : enum extraction_pattern,
146 : : unsigned HOST_WIDE_INT, machine_mode);
147 : : bool get_best_mem_extraction_insn (extraction_insn *,
148 : : enum extraction_pattern,
149 : : HOST_WIDE_INT, HOST_WIDE_INT, machine_mode);
150 : :
151 : : enum insn_code can_extend_p (machine_mode, machine_mode, int);
152 : : enum insn_code can_float_p (machine_mode, machine_mode, int);
153 : : enum insn_code can_fix_p (machine_mode, machine_mode, int, bool *);
154 : : bool can_conditionally_move_p (machine_mode mode);
155 : : opt_machine_mode qimode_for_vec_perm (machine_mode);
156 : : bool selector_fits_mode_p (machine_mode, const vec_perm_indices &);
157 : : bool can_vec_perm_var_p (machine_mode);
158 : : bool can_vec_perm_const_p (machine_mode, machine_mode,
159 : : const vec_perm_indices &, bool = true);
160 : : /* Find a widening optab even if it doesn't widen as much as we want. */
161 : : #define find_widening_optab_handler(A, B, C) \
162 : : find_widening_optab_handler_and_mode (A, B, C, NULL)
163 : : enum insn_code find_widening_optab_handler_and_mode (optab, machine_mode,
164 : : machine_mode,
165 : : machine_mode *);
166 : : int can_mult_highpart_p (machine_mode, bool);
167 : : bool can_compare_and_swap_p (machine_mode, bool);
168 : : bool can_atomic_exchange_p (machine_mode, bool);
169 : : bool can_atomic_load_p (machine_mode);
170 : : bool lshift_cheap_p (bool);
171 : : bool supports_vec_gather_load_p (machine_mode = E_VOIDmode,
172 : : vec<int> * = nullptr);
173 : : bool supports_vec_scatter_store_p (machine_mode = E_VOIDmode);
174 : : opt_machine_mode get_absneg_bit_mode (optab, machine_mode,
175 : : scalar_float_mode, int *);
176 : : bool can_vec_extract (machine_mode, machine_mode);
177 : : bool can_open_code_p (optab, machine_mode);
178 : : bool can_implement_p (optab, machine_mode);
179 : :
180 : : /* Version of find_widening_optab_handler_and_mode that operates on
181 : : specific mode types. */
182 : :
183 : : template<typename T>
184 : : inline enum insn_code
185 : 225015 : find_widening_optab_handler_and_mode (optab op, const T &to_mode,
186 : : const T &from_mode, T *found_mode)
187 : : {
188 : : machine_mode tmp;
189 : : enum insn_code icode = find_widening_optab_handler_and_mode
190 : 225015 : (op, machine_mode (to_mode), machine_mode (from_mode), &tmp);
191 : 225015 : if (icode != CODE_FOR_nothing && found_mode)
192 : 10209 : *found_mode = as_a <T> (tmp);
193 : 225015 : return icode;
194 : : }
195 : :
196 : : #endif
|