]>
Commit | Line | Data |
---|---|---|
d8fc4d0b | 1 | /* Definitions for code generation pass of GNU compiler. |
3072d30e | 2 | Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 |
4a61a337 | 3 | Free Software Foundation, Inc. |
d8fc4d0b | 4 | |
049df704 | 5 | This file is part of GCC. |
d8fc4d0b | 6 | |
049df704 | 7 | GCC is free software; you can redistribute it and/or modify |
d8fc4d0b | 8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 2, or (at your option) | |
10 | any later version. | |
11 | ||
049df704 | 12 | GCC is distributed in the hope that it will be useful, |
d8fc4d0b | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
049df704 | 18 | along with GCC; see the file COPYING. If not, write to |
67ce556b | 19 | the Free Software Foundation, 51 Franklin Street, Fifth Floor, |
20 | Boston, MA 02110-1301, USA. */ | |
d8fc4d0b | 21 | |
22 | #ifndef GCC_OPTABS_H | |
23 | #define GCC_OPTABS_H | |
24 | ||
25 | #include "insn-codes.h" | |
26 | ||
27 | /* Optabs are tables saying how to generate insn bodies | |
28 | for various machine modes and numbers of operands. | |
29 | Each optab applies to one operation. | |
6b8dbb53 | 30 | |
d8fc4d0b | 31 | For example, add_optab applies to addition. |
32 | ||
33 | The insn_code slot is the enum insn_code that says how to | |
34 | generate an insn for this operation on a particular machine mode. | |
35 | It is CODE_FOR_nothing if there is no such insn on the target machine. | |
36 | ||
37 | The `lib_call' slot is the name of the library function that | |
38 | can be used to perform the operation. | |
39 | ||
40 | A few optabs, such as move_optab and cmp_optab, are used | |
41 | by special code. */ | |
42 | ||
a7cc195f | 43 | struct optab_handlers GTY(()) |
44 | { | |
45 | enum insn_code insn_code; | |
46 | rtx libfunc; | |
47 | }; | |
48 | ||
1f3233d1 | 49 | struct optab GTY(()) |
d8fc4d0b | 50 | { |
51 | enum rtx_code code; | |
a7cc195f | 52 | struct optab_handlers handlers[NUM_MACHINE_MODES]; |
1f3233d1 | 53 | }; |
54 | typedef struct optab * optab; | |
d8fc4d0b | 55 | |
a7cc195f | 56 | /* A convert_optab is for some sort of conversion operation between |
57 | modes. The first array index is the destination mode, the second | |
58 | is the source mode. */ | |
59 | struct convert_optab GTY(()) | |
60 | { | |
61 | enum rtx_code code; | |
62 | struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES]; | |
63 | }; | |
64 | typedef struct convert_optab *convert_optab; | |
65 | ||
d8fc4d0b | 66 | /* Given an enum insn_code, access the function to construct |
67 | the body of that kind of insn. */ | |
a7cc195f | 68 | #define GEN_FCN(CODE) (insn_data[CODE].genfun) |
d8fc4d0b | 69 | |
70 | /* Enumeration of valid indexes into optab_table. */ | |
71 | enum optab_index | |
72 | { | |
73 | OTI_add, | |
74 | OTI_addv, | |
75 | OTI_sub, | |
76 | OTI_subv, | |
77 | ||
78 | /* Signed and fp multiply */ | |
79 | OTI_smul, | |
80 | OTI_smulv, | |
81 | /* Signed multiply, return high word */ | |
82 | OTI_smul_highpart, | |
83 | OTI_umul_highpart, | |
84 | /* Signed multiply with result one machine mode wider than args */ | |
85 | OTI_smul_widen, | |
86 | OTI_umul_widen, | |
8f0c8a8b | 87 | /* Widening multiply of one unsigned and one signed operand. */ |
88 | OTI_usmul_widen, | |
7e564f73 | 89 | /* Signed multiply and add with the result and addend one machine mode |
90 | wider than the multiplicand and multiplier. */ | |
91 | OTI_smadd_widen, | |
310d2511 | 92 | /* Unsigned multiply and add with the result and addend one machine mode |
7e564f73 | 93 | wider than the multiplicand and multiplier. */ |
94 | OTI_umadd_widen, | |
43fda261 | 95 | /* Signed multiply and subtract the result and minuend one machine mode |
96 | wider than the multiplicand and multiplier. */ | |
97 | OTI_smsub_widen, | |
310d2511 | 98 | /* Unsigned multiply and subtract the result and minuend one machine mode |
43fda261 | 99 | wider than the multiplicand and multiplier. */ |
100 | OTI_umsub_widen, | |
d8fc4d0b | 101 | |
102 | /* Signed divide */ | |
103 | OTI_sdiv, | |
104 | OTI_sdivv, | |
105 | /* Signed divide-and-remainder in one */ | |
106 | OTI_sdivmod, | |
107 | OTI_udiv, | |
108 | OTI_udivmod, | |
109 | /* Signed remainder */ | |
110 | OTI_smod, | |
111 | OTI_umod, | |
80ed5c06 | 112 | /* Floating point remainder functions */ |
113 | OTI_fmod, | |
ef722005 | 114 | OTI_remainder, |
d8fc4d0b | 115 | /* Convert float to integer in float fmt */ |
116 | OTI_ftrunc, | |
117 | ||
118 | /* Logical and */ | |
119 | OTI_and, | |
120 | /* Logical or */ | |
121 | OTI_ior, | |
122 | /* Logical xor */ | |
123 | OTI_xor, | |
124 | ||
125 | /* Arithmetic shift left */ | |
126 | OTI_ashl, | |
127 | /* Logical shift right */ | |
3ad4992f | 128 | OTI_lshr, |
d8fc4d0b | 129 | /* Arithmetic shift right */ |
130 | OTI_ashr, | |
131 | /* Rotate left */ | |
132 | OTI_rotl, | |
133 | /* Rotate right */ | |
134 | OTI_rotr, | |
135 | /* Signed and floating-point minimum value */ | |
136 | OTI_smin, | |
137 | /* Signed and floating-point maximum value */ | |
138 | OTI_smax, | |
139 | /* Unsigned minimum value */ | |
140 | OTI_umin, | |
141 | /* Unsigned maximum value */ | |
142 | OTI_umax, | |
0fd605a5 | 143 | /* Power */ |
144 | OTI_pow, | |
145 | /* Arc tangent of y/x */ | |
146 | OTI_atan2, | |
d8fc4d0b | 147 | |
148 | /* Move instruction. */ | |
149 | OTI_mov, | |
150 | /* Move, preserving high part of register. */ | |
151 | OTI_movstrict, | |
f1a494f4 | 152 | /* Move, with a misaligned memory. */ |
153 | OTI_movmisalign, | |
5b5037b3 | 154 | /* Nontemporal store. */ |
155 | OTI_storent, | |
d8fc4d0b | 156 | |
157 | /* Unary operations */ | |
158 | /* Negation */ | |
159 | OTI_neg, | |
160 | OTI_negv, | |
161 | /* Abs value */ | |
162 | OTI_abs, | |
163 | OTI_absv, | |
42791117 | 164 | /* Byteswap */ |
165 | OTI_bswap, | |
d8fc4d0b | 166 | /* Bitwise not */ |
167 | OTI_one_cmpl, | |
6a08d0ab | 168 | /* Bit scanning and counting */ |
d8fc4d0b | 169 | OTI_ffs, |
6a08d0ab | 170 | OTI_clz, |
171 | OTI_ctz, | |
172 | OTI_popcount, | |
173 | OTI_parity, | |
d8fc4d0b | 174 | /* Square root */ |
175 | OTI_sqrt, | |
6b43bae4 | 176 | /* Sine-Cosine */ |
177 | OTI_sincos, | |
d8fc4d0b | 178 | /* Sine */ |
179 | OTI_sin, | |
8de2f465 | 180 | /* Inverse sine */ |
181 | OTI_asin, | |
d8fc4d0b | 182 | /* Cosine */ |
183 | OTI_cos, | |
8de2f465 | 184 | /* Inverse cosine */ |
185 | OTI_acos, | |
42721db0 | 186 | /* Exponential */ |
187 | OTI_exp, | |
750ef9f5 | 188 | /* Base-10 Exponential */ |
189 | OTI_exp10, | |
190 | /* Base-2 Exponential */ | |
191 | OTI_exp2, | |
a6b4eed2 | 192 | /* Exponential - 1*/ |
193 | OTI_expm1, | |
4737caf2 | 194 | /* Load exponent of a floating point number */ |
195 | OTI_ldexp, | |
73a954a1 | 196 | /* Multiply floating-point number by integral power of radix */ |
197 | OTI_scalb, | |
4efbc641 | 198 | /* Radix-independent exponent */ |
199 | OTI_logb, | |
200 | OTI_ilogb, | |
42721db0 | 201 | /* Natural Logarithm */ |
202 | OTI_log, | |
d3cd9bde | 203 | /* Base-10 Logarithm */ |
204 | OTI_log10, | |
205 | /* Base-2 Logarithm */ | |
206 | OTI_log2, | |
f474cd93 | 207 | /* logarithm of 1 plus argument */ |
208 | OTI_log1p, | |
805e22b2 | 209 | /* Rounding functions */ |
210 | OTI_floor, | |
211 | OTI_ceil, | |
aef94a0f | 212 | OTI_btrunc, |
805e22b2 | 213 | OTI_round, |
214 | OTI_nearbyint, | |
aef94a0f | 215 | OTI_rint, |
528ee710 | 216 | /* Tangent */ |
217 | OTI_tan, | |
218 | /* Inverse tangent */ | |
219 | OTI_atan, | |
270436f3 | 220 | /* Copy sign */ |
221 | OTI_copysign, | |
d8fc4d0b | 222 | |
69b779ea | 223 | /* Test for infinite value */ |
224 | OTI_isinf, | |
225 | ||
d8fc4d0b | 226 | /* Compare insn; two operands. */ |
227 | OTI_cmp, | |
228 | /* Used only for libcalls for unsigned comparisons. */ | |
229 | OTI_ucmp, | |
230 | /* tst insn; compare one operand against 0 */ | |
231 | OTI_tst, | |
232 | ||
c88a6ebd | 233 | /* Floating point comparison optabs - used primarily for libfuncs */ |
234 | OTI_eq, | |
235 | OTI_ne, | |
236 | OTI_gt, | |
237 | OTI_ge, | |
238 | OTI_lt, | |
239 | OTI_le, | |
240 | OTI_unord, | |
241 | ||
d8fc4d0b | 242 | /* String length */ |
243 | OTI_strlen, | |
244 | ||
245 | /* Combined compare & jump/store flags/move operations. */ | |
246 | OTI_cbranch, | |
247 | OTI_cmov, | |
248 | OTI_cstore, | |
3ad4992f | 249 | |
d8fc4d0b | 250 | /* Push instruction. */ |
251 | OTI_push, | |
252 | ||
d3da2ad8 | 253 | /* Conditional add instruction. */ |
254 | OTI_addcc, | |
255 | ||
ea8f3370 | 256 | /* Reduction operations on a vector operand. */ |
257 | OTI_reduc_smax, | |
258 | OTI_reduc_umax, | |
259 | OTI_reduc_smin, | |
260 | OTI_reduc_umin, | |
925c62d4 | 261 | OTI_reduc_splus, |
262 | OTI_reduc_uplus, | |
ea8f3370 | 263 | |
4a61a337 | 264 | /* Summation, with result machine mode one or more wider than args. */ |
265 | OTI_ssum_widen, | |
266 | OTI_usum_widen, | |
267 | ||
268 | /* Dot product, with result machine mode one or more wider than args. */ | |
269 | OTI_sdot_prod, | |
270 | OTI_udot_prod, | |
271 | ||
b8d2bcdd | 272 | /* Set specified field of vector operand. */ |
273 | OTI_vec_set, | |
274 | /* Extract specified field of vector operand. */ | |
275 | OTI_vec_extract, | |
6b8dbb53 | 276 | /* Extract even/odd fields of vector operands. */ |
277 | OTI_vec_extract_even, | |
278 | OTI_vec_extract_odd, | |
279 | /* Interleave fields of vector operands. */ | |
280 | OTI_vec_interleave_high, | |
281 | OTI_vec_interleave_low, | |
b8d2bcdd | 282 | /* Initialize vector operand. */ |
283 | OTI_vec_init, | |
925c62d4 | 284 | /* Whole vector shift. The shift amount is in bits. */ |
285 | OTI_vec_shl, | |
286 | OTI_vec_shr, | |
b056d812 | 287 | /* Extract specified elements from vectors, for vector load. */ |
288 | OTI_vec_realign_load, | |
c6c91d61 | 289 | /* Widening multiplication. |
290 | The high/low part of the resulting vector of products is returned. */ | |
291 | OTI_vec_widen_umult_hi, | |
292 | OTI_vec_widen_umult_lo, | |
293 | OTI_vec_widen_smult_hi, | |
294 | OTI_vec_widen_smult_lo, | |
bb8107e7 | 295 | /* Extract and widen the high/low part of a vector of signed or |
296 | floating point elements. */ | |
c6c91d61 | 297 | OTI_vec_unpacks_hi, |
298 | OTI_vec_unpacks_lo, | |
bb8107e7 | 299 | /* Extract and widen the high/low part of a vector of unsigned |
300 | elements. */ | |
c6c91d61 | 301 | OTI_vec_unpacku_hi, |
302 | OTI_vec_unpacku_lo, | |
8aa4e142 | 303 | |
304 | /* Extract, convert to floating point and widen the high/low part of | |
305 | a vector of signed or unsigned integer elements. */ | |
306 | OTI_vec_unpacks_float_hi, | |
307 | OTI_vec_unpacks_float_lo, | |
308 | OTI_vec_unpacku_float_hi, | |
309 | OTI_vec_unpacku_float_lo, | |
310 | ||
c6c91d61 | 311 | /* Narrow (demote) and merge the elements of two vectors. */ |
bb8107e7 | 312 | OTI_vec_pack_trunc, |
c6c91d61 | 313 | OTI_vec_pack_usat, |
314 | OTI_vec_pack_ssat, | |
b8d2bcdd | 315 | |
8aa4e142 | 316 | /* Convert to signed/unsigned integer, narrow and merge elements |
317 | of two vectors of floating point elements. */ | |
318 | OTI_vec_pack_sfix_trunc, | |
319 | OTI_vec_pack_ufix_trunc, | |
320 | ||
757c219d | 321 | /* Perform a raise to the power of integer. */ |
322 | OTI_powi, | |
323 | ||
d8fc4d0b | 324 | OTI_MAX |
325 | }; | |
326 | ||
1f3233d1 | 327 | extern GTY(()) optab optab_table[OTI_MAX]; |
d8fc4d0b | 328 | |
329 | #define add_optab (optab_table[OTI_add]) | |
330 | #define sub_optab (optab_table[OTI_sub]) | |
331 | #define smul_optab (optab_table[OTI_smul]) | |
332 | #define addv_optab (optab_table[OTI_addv]) | |
333 | #define subv_optab (optab_table[OTI_subv]) | |
334 | #define smul_highpart_optab (optab_table[OTI_smul_highpart]) | |
335 | #define umul_highpart_optab (optab_table[OTI_umul_highpart]) | |
336 | #define smul_widen_optab (optab_table[OTI_smul_widen]) | |
337 | #define umul_widen_optab (optab_table[OTI_umul_widen]) | |
8f0c8a8b | 338 | #define usmul_widen_optab (optab_table[OTI_usmul_widen]) |
7e564f73 | 339 | #define smadd_widen_optab (optab_table[OTI_smadd_widen]) |
340 | #define umadd_widen_optab (optab_table[OTI_umadd_widen]) | |
43fda261 | 341 | #define smsub_widen_optab (optab_table[OTI_smsub_widen]) |
342 | #define umsub_widen_optab (optab_table[OTI_umsub_widen]) | |
d8fc4d0b | 343 | #define sdiv_optab (optab_table[OTI_sdiv]) |
344 | #define smulv_optab (optab_table[OTI_smulv]) | |
345 | #define sdivv_optab (optab_table[OTI_sdivv]) | |
346 | #define sdivmod_optab (optab_table[OTI_sdivmod]) | |
347 | #define udiv_optab (optab_table[OTI_udiv]) | |
348 | #define udivmod_optab (optab_table[OTI_udivmod]) | |
349 | #define smod_optab (optab_table[OTI_smod]) | |
350 | #define umod_optab (optab_table[OTI_umod]) | |
80ed5c06 | 351 | #define fmod_optab (optab_table[OTI_fmod]) |
ef722005 | 352 | #define remainder_optab (optab_table[OTI_remainder]) |
d8fc4d0b | 353 | #define ftrunc_optab (optab_table[OTI_ftrunc]) |
354 | #define and_optab (optab_table[OTI_and]) | |
355 | #define ior_optab (optab_table[OTI_ior]) | |
356 | #define xor_optab (optab_table[OTI_xor]) | |
357 | #define ashl_optab (optab_table[OTI_ashl]) | |
358 | #define lshr_optab (optab_table[OTI_lshr]) | |
359 | #define ashr_optab (optab_table[OTI_ashr]) | |
360 | #define rotl_optab (optab_table[OTI_rotl]) | |
361 | #define rotr_optab (optab_table[OTI_rotr]) | |
362 | #define smin_optab (optab_table[OTI_smin]) | |
363 | #define smax_optab (optab_table[OTI_smax]) | |
364 | #define umin_optab (optab_table[OTI_umin]) | |
365 | #define umax_optab (optab_table[OTI_umax]) | |
0fd605a5 | 366 | #define pow_optab (optab_table[OTI_pow]) |
367 | #define atan2_optab (optab_table[OTI_atan2]) | |
d8fc4d0b | 368 | |
369 | #define mov_optab (optab_table[OTI_mov]) | |
370 | #define movstrict_optab (optab_table[OTI_movstrict]) | |
f1a494f4 | 371 | #define movmisalign_optab (optab_table[OTI_movmisalign]) |
5b5037b3 | 372 | #define storent_optab (optab_table[OTI_storent]) |
d8fc4d0b | 373 | |
374 | #define neg_optab (optab_table[OTI_neg]) | |
375 | #define negv_optab (optab_table[OTI_negv]) | |
376 | #define abs_optab (optab_table[OTI_abs]) | |
377 | #define absv_optab (optab_table[OTI_absv]) | |
378 | #define one_cmpl_optab (optab_table[OTI_one_cmpl]) | |
42791117 | 379 | #define bswap_optab (optab_table[OTI_bswap]) |
d8fc4d0b | 380 | #define ffs_optab (optab_table[OTI_ffs]) |
6a08d0ab | 381 | #define clz_optab (optab_table[OTI_clz]) |
382 | #define ctz_optab (optab_table[OTI_ctz]) | |
383 | #define popcount_optab (optab_table[OTI_popcount]) | |
384 | #define parity_optab (optab_table[OTI_parity]) | |
d8fc4d0b | 385 | #define sqrt_optab (optab_table[OTI_sqrt]) |
6b43bae4 | 386 | #define sincos_optab (optab_table[OTI_sincos]) |
d8fc4d0b | 387 | #define sin_optab (optab_table[OTI_sin]) |
8de2f465 | 388 | #define asin_optab (optab_table[OTI_asin]) |
d8fc4d0b | 389 | #define cos_optab (optab_table[OTI_cos]) |
8de2f465 | 390 | #define acos_optab (optab_table[OTI_acos]) |
42721db0 | 391 | #define exp_optab (optab_table[OTI_exp]) |
750ef9f5 | 392 | #define exp10_optab (optab_table[OTI_exp10]) |
393 | #define exp2_optab (optab_table[OTI_exp2]) | |
a6b4eed2 | 394 | #define expm1_optab (optab_table[OTI_expm1]) |
4737caf2 | 395 | #define ldexp_optab (optab_table[OTI_ldexp]) |
73a954a1 | 396 | #define scalb_optab (optab_table[OTI_scalb]) |
4efbc641 | 397 | #define logb_optab (optab_table[OTI_logb]) |
398 | #define ilogb_optab (optab_table[OTI_ilogb]) | |
42721db0 | 399 | #define log_optab (optab_table[OTI_log]) |
d3cd9bde | 400 | #define log10_optab (optab_table[OTI_log10]) |
401 | #define log2_optab (optab_table[OTI_log2]) | |
f474cd93 | 402 | #define log1p_optab (optab_table[OTI_log1p]) |
805e22b2 | 403 | #define floor_optab (optab_table[OTI_floor]) |
404 | #define ceil_optab (optab_table[OTI_ceil]) | |
aef94a0f | 405 | #define btrunc_optab (optab_table[OTI_btrunc]) |
805e22b2 | 406 | #define round_optab (optab_table[OTI_round]) |
407 | #define nearbyint_optab (optab_table[OTI_nearbyint]) | |
aef94a0f | 408 | #define rint_optab (optab_table[OTI_rint]) |
528ee710 | 409 | #define tan_optab (optab_table[OTI_tan]) |
410 | #define atan_optab (optab_table[OTI_atan]) | |
270436f3 | 411 | #define copysign_optab (optab_table[OTI_copysign]) |
d8fc4d0b | 412 | |
69b779ea | 413 | #define isinf_optab (optab_table[OTI_isinf]) |
414 | ||
d8fc4d0b | 415 | #define cmp_optab (optab_table[OTI_cmp]) |
416 | #define ucmp_optab (optab_table[OTI_ucmp]) | |
417 | #define tst_optab (optab_table[OTI_tst]) | |
418 | ||
c88a6ebd | 419 | #define eq_optab (optab_table[OTI_eq]) |
420 | #define ne_optab (optab_table[OTI_ne]) | |
421 | #define gt_optab (optab_table[OTI_gt]) | |
422 | #define ge_optab (optab_table[OTI_ge]) | |
423 | #define lt_optab (optab_table[OTI_lt]) | |
424 | #define le_optab (optab_table[OTI_le]) | |
425 | #define unord_optab (optab_table[OTI_unord]) | |
426 | ||
d8fc4d0b | 427 | #define strlen_optab (optab_table[OTI_strlen]) |
428 | ||
429 | #define cbranch_optab (optab_table[OTI_cbranch]) | |
430 | #define cmov_optab (optab_table[OTI_cmov]) | |
431 | #define cstore_optab (optab_table[OTI_cstore]) | |
432 | #define push_optab (optab_table[OTI_push]) | |
d3da2ad8 | 433 | #define addcc_optab (optab_table[OTI_addcc]) |
d8fc4d0b | 434 | |
ea8f3370 | 435 | #define reduc_smax_optab (optab_table[OTI_reduc_smax]) |
436 | #define reduc_umax_optab (optab_table[OTI_reduc_umax]) | |
437 | #define reduc_smin_optab (optab_table[OTI_reduc_smin]) | |
438 | #define reduc_umin_optab (optab_table[OTI_reduc_umin]) | |
925c62d4 | 439 | #define reduc_splus_optab (optab_table[OTI_reduc_splus]) |
440 | #define reduc_uplus_optab (optab_table[OTI_reduc_uplus]) | |
bb8107e7 | 441 | |
4a61a337 | 442 | #define ssum_widen_optab (optab_table[OTI_ssum_widen]) |
443 | #define usum_widen_optab (optab_table[OTI_usum_widen]) | |
444 | #define sdot_prod_optab (optab_table[OTI_sdot_prod]) | |
445 | #define udot_prod_optab (optab_table[OTI_udot_prod]) | |
ea8f3370 | 446 | |
b8d2bcdd | 447 | #define vec_set_optab (optab_table[OTI_vec_set]) |
448 | #define vec_extract_optab (optab_table[OTI_vec_extract]) | |
6b8dbb53 | 449 | #define vec_extract_even_optab (optab_table[OTI_vec_extract_even]) |
450 | #define vec_extract_odd_optab (optab_table[OTI_vec_extract_odd]) | |
451 | #define vec_interleave_high_optab (optab_table[OTI_vec_interleave_high]) | |
452 | #define vec_interleave_low_optab (optab_table[OTI_vec_interleave_low]) | |
b8d2bcdd | 453 | #define vec_init_optab (optab_table[OTI_vec_init]) |
925c62d4 | 454 | #define vec_shl_optab (optab_table[OTI_vec_shl]) |
455 | #define vec_shr_optab (optab_table[OTI_vec_shr]) | |
b056d812 | 456 | #define vec_realign_load_optab (optab_table[OTI_vec_realign_load]) |
c6c91d61 | 457 | #define vec_widen_umult_hi_optab (optab_table[OTI_vec_widen_umult_hi]) |
458 | #define vec_widen_umult_lo_optab (optab_table[OTI_vec_widen_umult_lo]) | |
459 | #define vec_widen_smult_hi_optab (optab_table[OTI_vec_widen_smult_hi]) | |
460 | #define vec_widen_smult_lo_optab (optab_table[OTI_vec_widen_smult_lo]) | |
461 | #define vec_unpacks_hi_optab (optab_table[OTI_vec_unpacks_hi]) | |
c6c91d61 | 462 | #define vec_unpacks_lo_optab (optab_table[OTI_vec_unpacks_lo]) |
bb8107e7 | 463 | #define vec_unpacku_hi_optab (optab_table[OTI_vec_unpacku_hi]) |
c6c91d61 | 464 | #define vec_unpacku_lo_optab (optab_table[OTI_vec_unpacku_lo]) |
8aa4e142 | 465 | #define vec_unpacks_float_hi_optab (optab_table[OTI_vec_unpacks_float_hi]) |
466 | #define vec_unpacks_float_lo_optab (optab_table[OTI_vec_unpacks_float_lo]) | |
467 | #define vec_unpacku_float_hi_optab (optab_table[OTI_vec_unpacku_float_hi]) | |
468 | #define vec_unpacku_float_lo_optab (optab_table[OTI_vec_unpacku_float_lo]) | |
bb8107e7 | 469 | #define vec_pack_trunc_optab (optab_table[OTI_vec_pack_trunc]) |
c6c91d61 | 470 | #define vec_pack_ssat_optab (optab_table[OTI_vec_pack_ssat]) |
471 | #define vec_pack_usat_optab (optab_table[OTI_vec_pack_usat]) | |
8aa4e142 | 472 | #define vec_pack_sfix_trunc_optab (optab_table[OTI_vec_pack_sfix_trunc]) |
473 | #define vec_pack_ufix_trunc_optab (optab_table[OTI_vec_pack_ufix_trunc]) | |
bb8107e7 | 474 | |
757c219d | 475 | #define powi_optab (optab_table[OTI_powi]) |
476 | ||
a7cc195f | 477 | /* Conversion optabs have their own table and indexes. */ |
478 | enum convert_optab_index | |
479 | { | |
26364c07 | 480 | COI_sext, |
481 | COI_zext, | |
482 | COI_trunc, | |
a7cc195f | 483 | |
26364c07 | 484 | COI_sfix, |
485 | COI_ufix, | |
a7cc195f | 486 | |
26364c07 | 487 | COI_sfixtrunc, |
488 | COI_ufixtrunc, | |
a7cc195f | 489 | |
26364c07 | 490 | COI_sfloat, |
491 | COI_ufloat, | |
a7cc195f | 492 | |
5f51ee59 | 493 | COI_lrint, |
ef2f1a10 | 494 | COI_lround, |
9c42dd28 | 495 | COI_lfloor, |
496 | COI_lceil, | |
5f51ee59 | 497 | |
26364c07 | 498 | COI_MAX |
a7cc195f | 499 | }; |
500 | ||
26364c07 | 501 | extern GTY(()) convert_optab convert_optab_table[COI_MAX]; |
d8fc4d0b | 502 | |
26364c07 | 503 | #define sext_optab (convert_optab_table[COI_sext]) |
504 | #define zext_optab (convert_optab_table[COI_zext]) | |
505 | #define trunc_optab (convert_optab_table[COI_trunc]) | |
506 | #define sfix_optab (convert_optab_table[COI_sfix]) | |
507 | #define ufix_optab (convert_optab_table[COI_ufix]) | |
508 | #define sfixtrunc_optab (convert_optab_table[COI_sfixtrunc]) | |
509 | #define ufixtrunc_optab (convert_optab_table[COI_ufixtrunc]) | |
510 | #define sfloat_optab (convert_optab_table[COI_sfloat]) | |
511 | #define ufloat_optab (convert_optab_table[COI_ufloat]) | |
5f51ee59 | 512 | #define lrint_optab (convert_optab_table[COI_lrint]) |
ef2f1a10 | 513 | #define lround_optab (convert_optab_table[COI_lround]) |
9c42dd28 | 514 | #define lfloor_optab (convert_optab_table[COI_lfloor]) |
515 | #define lceil_optab (convert_optab_table[COI_lceil]) | |
d8fc4d0b | 516 | |
517 | /* These arrays record the insn_code of insns that may be needed to | |
518 | perform input and output reloads of special objects. They provide a | |
519 | place to pass a scratch register. */ | |
520 | extern enum insn_code reload_in_optab[NUM_MACHINE_MODES]; | |
521 | extern enum insn_code reload_out_optab[NUM_MACHINE_MODES]; | |
522 | ||
523 | /* Contains the optab used for each rtx code. */ | |
573aba85 | 524 | extern GTY(()) optab code_to_optab[NUM_RTX_CODE + 1]; |
d8fc4d0b | 525 | |
d8fc4d0b | 526 | \f |
3ad4992f | 527 | typedef rtx (*rtxfun) (rtx); |
d8fc4d0b | 528 | |
0c6d8c36 | 529 | /* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...) |
d8fc4d0b | 530 | gives the gen_function to make a branch to test that condition. */ |
531 | ||
532 | extern rtxfun bcc_gen_fctn[NUM_RTX_CODE]; | |
533 | ||
0c6d8c36 | 534 | /* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...) |
d8fc4d0b | 535 | gives the insn code to make a store-condition insn |
536 | to test that condition. */ | |
537 | ||
538 | extern enum insn_code setcc_gen_code[NUM_RTX_CODE]; | |
539 | ||
540 | #ifdef HAVE_conditional_move | |
541 | /* Indexed by the machine mode, gives the insn code to make a conditional | |
542 | move insn. */ | |
543 | ||
544 | extern enum insn_code movcc_gen_code[NUM_MACHINE_MODES]; | |
545 | #endif | |
546 | ||
6b7acc28 | 547 | /* Indexed by the machine mode, gives the insn code for vector conditional |
548 | operation. */ | |
549 | ||
550 | extern enum insn_code vcond_gen_code[NUM_MACHINE_MODES]; | |
551 | extern enum insn_code vcondu_gen_code[NUM_MACHINE_MODES]; | |
552 | ||
d8fc4d0b | 553 | /* This array records the insn_code of insns to perform block moves. */ |
008c057d | 554 | extern enum insn_code movmem_optab[NUM_MACHINE_MODES]; |
d8fc4d0b | 555 | |
7a3e5564 | 556 | /* This array records the insn_code of insns to perform block sets. */ |
557 | extern enum insn_code setmem_optab[NUM_MACHINE_MODES]; | |
0fbe5a3e | 558 | |
559 | /* These arrays record the insn_code of two different kinds of insns | |
560 | to perform block compares. */ | |
561 | extern enum insn_code cmpstr_optab[NUM_MACHINE_MODES]; | |
6ac5504b | 562 | extern enum insn_code cmpstrn_optab[NUM_MACHINE_MODES]; |
0fbe5a3e | 563 | extern enum insn_code cmpmem_optab[NUM_MACHINE_MODES]; |
d8fc4d0b | 564 | |
b6a5fc45 | 565 | /* Synchronization primitives. This first set is atomic operation for |
566 | which we don't care about the resulting value. */ | |
567 | extern enum insn_code sync_add_optab[NUM_MACHINE_MODES]; | |
568 | extern enum insn_code sync_sub_optab[NUM_MACHINE_MODES]; | |
569 | extern enum insn_code sync_ior_optab[NUM_MACHINE_MODES]; | |
570 | extern enum insn_code sync_and_optab[NUM_MACHINE_MODES]; | |
571 | extern enum insn_code sync_xor_optab[NUM_MACHINE_MODES]; | |
572 | extern enum insn_code sync_nand_optab[NUM_MACHINE_MODES]; | |
573 | ||
574 | /* This second set is atomic operations in which we return the value | |
575 | that existed in memory before the operation. */ | |
576 | extern enum insn_code sync_old_add_optab[NUM_MACHINE_MODES]; | |
577 | extern enum insn_code sync_old_sub_optab[NUM_MACHINE_MODES]; | |
578 | extern enum insn_code sync_old_ior_optab[NUM_MACHINE_MODES]; | |
579 | extern enum insn_code sync_old_and_optab[NUM_MACHINE_MODES]; | |
580 | extern enum insn_code sync_old_xor_optab[NUM_MACHINE_MODES]; | |
581 | extern enum insn_code sync_old_nand_optab[NUM_MACHINE_MODES]; | |
582 | ||
583 | /* This third set is atomic operations in which we return the value | |
584 | that resulted after performing the operation. */ | |
585 | extern enum insn_code sync_new_add_optab[NUM_MACHINE_MODES]; | |
586 | extern enum insn_code sync_new_sub_optab[NUM_MACHINE_MODES]; | |
587 | extern enum insn_code sync_new_ior_optab[NUM_MACHINE_MODES]; | |
588 | extern enum insn_code sync_new_and_optab[NUM_MACHINE_MODES]; | |
589 | extern enum insn_code sync_new_xor_optab[NUM_MACHINE_MODES]; | |
590 | extern enum insn_code sync_new_nand_optab[NUM_MACHINE_MODES]; | |
591 | ||
592 | /* Atomic compare and swap. */ | |
593 | extern enum insn_code sync_compare_and_swap[NUM_MACHINE_MODES]; | |
594 | extern enum insn_code sync_compare_and_swap_cc[NUM_MACHINE_MODES]; | |
595 | ||
596 | /* Atomic exchange with acquire semantics. */ | |
597 | extern enum insn_code sync_lock_test_and_set[NUM_MACHINE_MODES]; | |
598 | ||
599 | /* Atomic clear with release semantics. */ | |
600 | extern enum insn_code sync_lock_release[NUM_MACHINE_MODES]; | |
601 | ||
d8fc4d0b | 602 | /* Define functions given in optabs.c. */ |
603 | ||
4a61a337 | 604 | extern rtx expand_widen_pattern_expr (tree exp, rtx op0, rtx op1, rtx wide_op, |
605 | rtx target, int unsignedp); | |
606 | ||
26364c07 | 607 | extern rtx expand_ternary_op (enum machine_mode mode, optab ternary_optab, |
608 | rtx op0, rtx op1, rtx op2, rtx target, | |
b056d812 | 609 | int unsignedp); |
610 | ||
d8fc4d0b | 611 | /* Expand a binary operation given optab and rtx operands. */ |
3ad4992f | 612 | extern rtx expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int, |
613 | enum optab_methods); | |
d8fc4d0b | 614 | |
05d18e8b | 615 | extern bool force_expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int, |
616 | enum optab_methods); | |
617 | ||
d8fc4d0b | 618 | /* Expand a binary operation with both signed and unsigned forms. */ |
3ad4992f | 619 | extern rtx sign_expand_binop (enum machine_mode, optab, optab, rtx, rtx, |
620 | rtx, int, enum optab_methods); | |
d8fc4d0b | 621 | |
6b43bae4 | 622 | /* Generate code to perform an operation on one operand with two results. */ |
623 | extern int expand_twoval_unop (optab, rtx, rtx, rtx, int); | |
624 | ||
d8fc4d0b | 625 | /* Generate code to perform an operation on two operands with two results. */ |
3ad4992f | 626 | extern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int); |
d8fc4d0b | 627 | |
30e9913f | 628 | /* Generate code to perform an operation on two operands with two |
629 | results, using a library function. */ | |
7d3f6cc7 | 630 | extern bool expand_twoval_binop_libfunc (optab, rtx, rtx, rtx, rtx, |
30e9913f | 631 | enum rtx_code); |
632 | ||
d8fc4d0b | 633 | /* Expand a unary arithmetic operation given optab rtx operand. */ |
3ad4992f | 634 | extern rtx expand_unop (enum machine_mode, optab, rtx, rtx, int); |
d8fc4d0b | 635 | |
636 | /* Expand the absolute value operation. */ | |
3ad4992f | 637 | extern rtx expand_abs_nojump (enum machine_mode, rtx, rtx, int); |
638 | extern rtx expand_abs (enum machine_mode, rtx, rtx, int, int); | |
d8fc4d0b | 639 | |
270436f3 | 640 | /* Expand the copysign operation. */ |
641 | extern rtx expand_copysign (rtx, rtx, rtx); | |
642 | ||
d8fc4d0b | 643 | /* Generate an instruction with a given INSN_CODE with an output and |
644 | an input. */ | |
3ad4992f | 645 | extern void emit_unop_insn (int, rtx, rtx, enum rtx_code); |
d8fc4d0b | 646 | |
3072d30e | 647 | /* Excapsulate the block in REG_LIBCALL, and REG_RETVAL reg notes and add |
648 | REG_LIBCALL_ID notes to all insns in block. */ | |
649 | extern void maybe_encapsulate_block (rtx, rtx, rtx); | |
650 | ||
d8fc4d0b | 651 | /* Emit code to perform a series of operations on a multi-word quantity, one |
652 | word at a time. */ | |
3ad4992f | 653 | extern rtx emit_no_conflict_block (rtx, rtx, rtx, rtx, rtx); |
d8fc4d0b | 654 | |
d8fc4d0b | 655 | /* Emit one rtl insn to compare two rtx's. */ |
3ad4992f | 656 | extern void emit_cmp_insn (rtx, rtx, enum rtx_code, rtx, enum machine_mode, |
657 | int); | |
d8fc4d0b | 658 | |
659 | /* The various uses that a comparison can have; used by can_compare_p: | |
660 | jumps, conditional moves, store flag operations. */ | |
661 | enum can_compare_purpose | |
662 | { | |
663 | ccp_jump, | |
664 | ccp_cmov, | |
665 | ccp_store_flag | |
666 | }; | |
667 | ||
83e2a11b | 668 | /* Return the optab used for computing the given operation on the type |
669 | given by the second argument. */ | |
670 | extern optab optab_for_tree_code (enum tree_code, tree); | |
671 | ||
d8fc4d0b | 672 | /* Nonzero if a compare of mode MODE can be done straightforwardly |
673 | (without splitting it into pieces). */ | |
3ad4992f | 674 | extern int can_compare_p (enum rtx_code, enum machine_mode, |
675 | enum can_compare_purpose); | |
d8fc4d0b | 676 | |
d8fc4d0b | 677 | /* Return the INSN_CODE to use for an extend operation. */ |
3ad4992f | 678 | extern enum insn_code can_extend_p (enum machine_mode, enum machine_mode, int); |
d8fc4d0b | 679 | |
680 | /* Generate the body of an insn to extend Y (with mode MFROM) | |
681 | into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */ | |
3ad4992f | 682 | extern rtx gen_extend_insn (rtx, rtx, enum machine_mode, |
683 | enum machine_mode, int); | |
d8fc4d0b | 684 | |
f2f543a3 | 685 | /* Call this to reset the function entry for one optab. */ |
686 | extern void set_optab_libfunc (optab, enum machine_mode, const char *); | |
a7cc195f | 687 | extern void set_conv_libfunc (convert_optab, enum machine_mode, |
688 | enum machine_mode, const char *); | |
f2f543a3 | 689 | |
d8fc4d0b | 690 | /* Generate code for a FLOAT_EXPR. */ |
3ad4992f | 691 | extern void expand_float (rtx, rtx, int); |
d8fc4d0b | 692 | |
693 | /* Generate code for a FIX_EXPR. */ | |
3ad4992f | 694 | extern void expand_fix (rtx, rtx, int); |
d8fc4d0b | 695 | |
5f51ee59 | 696 | /* Generate code for float to integral conversion. */ |
697 | extern bool expand_sfix_optab (rtx, rtx, convert_optab); | |
698 | ||
c1e065f3 | 699 | /* Return tree if target supports vector operations for COND_EXPR. */ |
6b7acc28 | 700 | bool expand_vec_cond_expr_p (tree, enum machine_mode); |
701 | ||
702 | /* Generate code for VEC_COND_EXPR. */ | |
703 | extern rtx expand_vec_cond_expr (tree, rtx); | |
704 | ||
925c62d4 | 705 | /* Generate code for VEC_LSHIFT_EXPR and VEC_RSHIFT_EXPR. */ |
706 | extern rtx expand_vec_shift_expr (tree, rtx); | |
707 | ||
d8fc4d0b | 708 | #endif /* GCC_OPTABS_H */ |