Line data Source code
1 : /* IR-agnostic target query functions relating to optabs
2 : Copyright (C) 2001-2026 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 34199742 : convert_optab_p (optab op)
30 : {
31 32845280 : 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 256471054 : optab_handler (optab op, machine_mode mode)
39 : {
40 256471054 : unsigned scode = (op << 20) | mode;
41 106957092 : gcc_assert (op > LAST_CONV_OPTAB);
42 256471054 : 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 20159478 : convert_optab_handler (convert_optab op, machine_mode to_mode,
51 : machine_mode from_mode)
52 : {
53 20159478 : unsigned scode = (op << 20) | (from_mode << 10) | to_mode;
54 19726363 : gcc_assert (convert_optab_p (op));
55 19883775 : 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 14839655 : direct_optab_handler (direct_optab op, machine_mode mode)
66 : {
67 18727611 : 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 38464 : trapv_unoptab_p (optab unoptab)
77 : {
78 38464 : return (unoptab == negv_optab
79 38464 : || unoptab == absv_optab);
80 : }
81 :
82 : /* Return true if BINOPTAB is for a trapping-on-overflow operation. */
83 :
84 : inline bool
85 68713 : trapv_binoptab_p (optab binoptab)
86 : {
87 68713 : 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 :
95 : inline enum insn_code
96 1339461 : get_vec_cmp_icode (machine_mode vmode, machine_mode mask_mode, bool uns)
97 : {
98 1339461 : optab tab = uns ? vec_cmpu_optab : vec_cmp_optab;
99 1339461 : 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 180399 : get_vec_cmp_eq_icode (machine_mode vmode, machine_mode mask_mode)
107 : {
108 180399 : 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 104098 : get_vcond_mask_icode (machine_mode vmode, machine_mode mmode)
116 : {
117 104098 : 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 1928638 : 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 236365 : 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 236365 : (op, machine_mode (to_mode), machine_mode (from_mode), &tmp);
191 236365 : if (icode != CODE_FOR_nothing && found_mode)
192 10127 : *found_mode = as_a <T> (tmp);
193 236365 : return icode;
194 : }
195 :
196 : #endif
|