]>
Commit | Line | Data |
---|---|---|
e78d8e51 | 1 | /* Definitions for code generation pass of GNU compiler. |
7e5487a2 | 2 | Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
20f06221 | 3 | Free Software Foundation, Inc. |
e78d8e51 | 4 | |
40803cd5 | 5 | This file is part of GCC. |
e78d8e51 | 6 | |
40803cd5 | 7 | GCC is free software; you can redistribute it and/or modify |
e78d8e51 | 8 | it under the terms of the GNU General Public License as published by |
9dcd6f09 | 9 | the Free Software Foundation; either version 3, or (at your option) |
e78d8e51 ZW |
10 | any later version. |
11 | ||
40803cd5 | 12 | GCC is distributed in the hope that it will be useful, |
e78d8e51 ZW |
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 | |
9dcd6f09 NC |
18 | along with GCC; see the file COPYING3. If not see |
19 | <http://www.gnu.org/licenses/>. */ | |
e78d8e51 ZW |
20 | |
21 | #ifndef GCC_OPTABS_H | |
22 | #define GCC_OPTABS_H | |
23 | ||
24 | #include "insn-codes.h" | |
25 | ||
26 | /* Optabs are tables saying how to generate insn bodies | |
27 | for various machine modes and numbers of operands. | |
28 | Each optab applies to one operation. | |
98b44b0e | 29 | |
e78d8e51 ZW |
30 | For example, add_optab applies to addition. |
31 | ||
32 | The insn_code slot is the enum insn_code that says how to | |
33 | generate an insn for this operation on a particular machine mode. | |
34 | It is CODE_FOR_nothing if there is no such insn on the target machine. | |
35 | ||
36 | The `lib_call' slot is the name of the library function that | |
37 | can be used to perform the operation. | |
38 | ||
f90b7a5a | 39 | A few optabs, such as move_optab, are used by special code. */ |
e78d8e51 | 40 | |
8a33f100 | 41 | struct optab_handlers |
85363ca0 ZW |
42 | { |
43 | enum insn_code insn_code; | |
85363ca0 ZW |
44 | }; |
45 | ||
7e5487a2 | 46 | struct optab_d |
e78d8e51 ZW |
47 | { |
48 | enum rtx_code code; | |
8a33f100 JH |
49 | const char *libcall_basename; |
50 | char libcall_suffix; | |
7e5487a2 ILT |
51 | void (*libcall_gen)(struct optab_d *, const char *name, char suffix, |
52 | enum machine_mode); | |
85363ca0 | 53 | struct optab_handlers handlers[NUM_MACHINE_MODES]; |
e2500fed | 54 | }; |
7e5487a2 | 55 | typedef struct optab_d * optab; |
e78d8e51 | 56 | |
85363ca0 ZW |
57 | /* A convert_optab is for some sort of conversion operation between |
58 | modes. The first array index is the destination mode, the second | |
59 | is the source mode. */ | |
7e5487a2 | 60 | struct convert_optab_d |
85363ca0 ZW |
61 | { |
62 | enum rtx_code code; | |
8a33f100 | 63 | const char *libcall_basename; |
7e5487a2 | 64 | void (*libcall_gen)(struct convert_optab_d *, const char *name, |
8a33f100 JH |
65 | enum machine_mode, |
66 | enum machine_mode); | |
85363ca0 ZW |
67 | struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES]; |
68 | }; | |
7e5487a2 | 69 | typedef struct convert_optab_d *convert_optab; |
85363ca0 | 70 | |
e78d8e51 ZW |
71 | /* Given an enum insn_code, access the function to construct |
72 | the body of that kind of insn. */ | |
85363ca0 | 73 | #define GEN_FCN(CODE) (insn_data[CODE].genfun) |
e78d8e51 ZW |
74 | |
75 | /* Enumeration of valid indexes into optab_table. */ | |
76 | enum optab_index | |
77 | { | |
0f996086 CF |
78 | /* Fixed-point operators with signed/unsigned saturation */ |
79 | OTI_ssadd, | |
80 | OTI_usadd, | |
81 | OTI_sssub, | |
82 | OTI_ussub, | |
83 | OTI_ssmul, | |
84 | OTI_usmul, | |
85 | OTI_ssdiv, | |
86 | OTI_usdiv, | |
87 | OTI_ssneg, | |
88 | OTI_usneg, | |
89 | OTI_ssashl, | |
90 | OTI_usashl, | |
91 | ||
e78d8e51 ZW |
92 | OTI_add, |
93 | OTI_addv, | |
94 | OTI_sub, | |
95 | OTI_subv, | |
96 | ||
97 | /* Signed and fp multiply */ | |
98 | OTI_smul, | |
99 | OTI_smulv, | |
100 | /* Signed multiply, return high word */ | |
101 | OTI_smul_highpart, | |
102 | OTI_umul_highpart, | |
103 | /* Signed multiply with result one machine mode wider than args */ | |
104 | OTI_smul_widen, | |
105 | OTI_umul_widen, | |
8b44057d BS |
106 | /* Widening multiply of one unsigned and one signed operand. */ |
107 | OTI_usmul_widen, | |
7f9844ca RS |
108 | /* Signed multiply and add with the result and addend one machine mode |
109 | wider than the multiplicand and multiplier. */ | |
110 | OTI_smadd_widen, | |
c80b4100 | 111 | /* Unsigned multiply and add with the result and addend one machine mode |
7f9844ca RS |
112 | wider than the multiplicand and multiplier. */ |
113 | OTI_umadd_widen, | |
0f996086 CF |
114 | /* Signed multiply and add with the result and addend one machine mode |
115 | wider than the multiplicand and multiplier. | |
116 | All involved operations are saturating. */ | |
117 | OTI_ssmadd_widen, | |
fa10beec | 118 | /* Unsigned multiply and add with the result and addend one machine mode |
0f996086 CF |
119 | wider than the multiplicand and multiplier. |
120 | All involved operations are saturating. */ | |
121 | OTI_usmadd_widen, | |
14661f36 CF |
122 | /* Signed multiply and subtract the result and minuend one machine mode |
123 | wider than the multiplicand and multiplier. */ | |
124 | OTI_smsub_widen, | |
c80b4100 | 125 | /* Unsigned multiply and subtract the result and minuend one machine mode |
14661f36 CF |
126 | wider than the multiplicand and multiplier. */ |
127 | OTI_umsub_widen, | |
0f996086 CF |
128 | /* Signed multiply and subtract the result and minuend one machine mode |
129 | wider than the multiplicand and multiplier. | |
130 | All involved operations are saturating. */ | |
131 | OTI_ssmsub_widen, | |
fa10beec | 132 | /* Unsigned multiply and subtract the result and minuend one machine mode |
0f996086 CF |
133 | wider than the multiplicand and multiplier. |
134 | All involved operations are saturating. */ | |
135 | OTI_usmsub_widen, | |
e78d8e51 ZW |
136 | |
137 | /* Signed divide */ | |
138 | OTI_sdiv, | |
139 | OTI_sdivv, | |
140 | /* Signed divide-and-remainder in one */ | |
141 | OTI_sdivmod, | |
142 | OTI_udiv, | |
143 | OTI_udivmod, | |
144 | /* Signed remainder */ | |
145 | OTI_smod, | |
146 | OTI_umod, | |
5ae27cfa UB |
147 | /* Floating point remainder functions */ |
148 | OTI_fmod, | |
17b98269 | 149 | OTI_remainder, |
e78d8e51 ZW |
150 | /* Convert float to integer in float fmt */ |
151 | OTI_ftrunc, | |
152 | ||
153 | /* Logical and */ | |
154 | OTI_and, | |
155 | /* Logical or */ | |
156 | OTI_ior, | |
157 | /* Logical xor */ | |
158 | OTI_xor, | |
159 | ||
160 | /* Arithmetic shift left */ | |
161 | OTI_ashl, | |
162 | /* Logical shift right */ | |
0c20a65f | 163 | OTI_lshr, |
e78d8e51 ZW |
164 | /* Arithmetic shift right */ |
165 | OTI_ashr, | |
166 | /* Rotate left */ | |
167 | OTI_rotl, | |
168 | /* Rotate right */ | |
169 | OTI_rotr, | |
71d46ca5 MM |
170 | |
171 | /* Arithmetic shift left of vector by vector */ | |
172 | OTI_vashl, | |
173 | /* Logical shift right of vector by vector */ | |
174 | OTI_vlshr, | |
175 | /* Arithmetic shift right of vector by vector */ | |
176 | OTI_vashr, | |
177 | /* Rotate left of vector by vector */ | |
178 | OTI_vrotl, | |
179 | /* Rotate right of vector by vector */ | |
180 | OTI_vrotr, | |
181 | ||
e78d8e51 ZW |
182 | /* Signed and floating-point minimum value */ |
183 | OTI_smin, | |
184 | /* Signed and floating-point maximum value */ | |
185 | OTI_smax, | |
186 | /* Unsigned minimum value */ | |
187 | OTI_umin, | |
188 | /* Unsigned maximum value */ | |
189 | OTI_umax, | |
b5e01d4b RS |
190 | /* Power */ |
191 | OTI_pow, | |
192 | /* Arc tangent of y/x */ | |
193 | OTI_atan2, | |
e78d8e51 ZW |
194 | |
195 | /* Move instruction. */ | |
196 | OTI_mov, | |
197 | /* Move, preserving high part of register. */ | |
198 | OTI_movstrict, | |
1e0598e2 RH |
199 | /* Move, with a misaligned memory. */ |
200 | OTI_movmisalign, | |
79f5e442 ZD |
201 | /* Nontemporal store. */ |
202 | OTI_storent, | |
e78d8e51 ZW |
203 | |
204 | /* Unary operations */ | |
205 | /* Negation */ | |
206 | OTI_neg, | |
207 | OTI_negv, | |
208 | /* Abs value */ | |
209 | OTI_abs, | |
210 | OTI_absv, | |
167fa32c EC |
211 | /* Byteswap */ |
212 | OTI_bswap, | |
e78d8e51 ZW |
213 | /* Bitwise not */ |
214 | OTI_one_cmpl, | |
2928cd7a | 215 | /* Bit scanning and counting */ |
e78d8e51 | 216 | OTI_ffs, |
2928cd7a RH |
217 | OTI_clz, |
218 | OTI_ctz, | |
219 | OTI_popcount, | |
220 | OTI_parity, | |
e78d8e51 ZW |
221 | /* Square root */ |
222 | OTI_sqrt, | |
6c7cf1f0 UB |
223 | /* Sine-Cosine */ |
224 | OTI_sincos, | |
e78d8e51 ZW |
225 | /* Sine */ |
226 | OTI_sin, | |
c56122d8 UB |
227 | /* Inverse sine */ |
228 | OTI_asin, | |
e78d8e51 ZW |
229 | /* Cosine */ |
230 | OTI_cos, | |
c56122d8 UB |
231 | /* Inverse cosine */ |
232 | OTI_acos, | |
e7b489c8 RS |
233 | /* Exponential */ |
234 | OTI_exp, | |
a251102e UB |
235 | /* Base-10 Exponential */ |
236 | OTI_exp10, | |
237 | /* Base-2 Exponential */ | |
238 | OTI_exp2, | |
7a8e07c7 UB |
239 | /* Exponential - 1*/ |
240 | OTI_expm1, | |
c94a75af UB |
241 | /* Load exponent of a floating point number */ |
242 | OTI_ldexp, | |
0c0d910d KG |
243 | /* Multiply floating-point number by integral power of radix */ |
244 | OTI_scalb, | |
dc6707b8 UB |
245 | /* Mantissa of a floating-point number */ |
246 | OTI_significand, | |
88b28a31 UB |
247 | /* Radix-independent exponent */ |
248 | OTI_logb, | |
249 | OTI_ilogb, | |
e7b489c8 RS |
250 | /* Natural Logarithm */ |
251 | OTI_log, | |
3b8e0c91 UB |
252 | /* Base-10 Logarithm */ |
253 | OTI_log10, | |
254 | /* Base-2 Logarithm */ | |
255 | OTI_log2, | |
c2fcfa4f UB |
256 | /* logarithm of 1 plus argument */ |
257 | OTI_log1p, | |
4977bab6 ZW |
258 | /* Rounding functions */ |
259 | OTI_floor, | |
260 | OTI_ceil, | |
edeacc14 | 261 | OTI_btrunc, |
4977bab6 ZW |
262 | OTI_round, |
263 | OTI_nearbyint, | |
edeacc14 | 264 | OTI_rint, |
82d397c7 RS |
265 | /* Tangent */ |
266 | OTI_tan, | |
267 | /* Inverse tangent */ | |
268 | OTI_atan, | |
046625fa RH |
269 | /* Copy sign */ |
270 | OTI_copysign, | |
d0c9d431 UB |
271 | /* Signbit */ |
272 | OTI_signbit, | |
9ed4207f UB |
273 | /* Test for infinite value */ |
274 | OTI_isinf, | |
275 | ||
f90b7a5a | 276 | /* Compare insn; two operands. Used only for libcalls. */ |
e78d8e51 | 277 | OTI_cmp, |
e78d8e51 | 278 | OTI_ucmp, |
e78d8e51 | 279 | |
c9034561 ZW |
280 | /* Floating point comparison optabs - used primarily for libfuncs */ |
281 | OTI_eq, | |
282 | OTI_ne, | |
283 | OTI_gt, | |
284 | OTI_ge, | |
285 | OTI_lt, | |
286 | OTI_le, | |
287 | OTI_unord, | |
288 | ||
e78d8e51 ZW |
289 | /* String length */ |
290 | OTI_strlen, | |
291 | ||
f90b7a5a | 292 | /* Combined compare & jump/move/store flags/trap operations. */ |
e78d8e51 ZW |
293 | OTI_cbranch, |
294 | OTI_cmov, | |
295 | OTI_cstore, | |
f90b7a5a | 296 | OTI_ctrap, |
0c20a65f | 297 | |
e78d8e51 ZW |
298 | /* Push instruction. */ |
299 | OTI_push, | |
300 | ||
068f5dea JH |
301 | /* Conditional add instruction. */ |
302 | OTI_addcc, | |
303 | ||
61d3cdbb DN |
304 | /* Reduction operations on a vector operand. */ |
305 | OTI_reduc_smax, | |
306 | OTI_reduc_umax, | |
307 | OTI_reduc_smin, | |
308 | OTI_reduc_umin, | |
a6b46ba2 DN |
309 | OTI_reduc_splus, |
310 | OTI_reduc_uplus, | |
61d3cdbb | 311 | |
20f06221 DN |
312 | /* Summation, with result machine mode one or more wider than args. */ |
313 | OTI_ssum_widen, | |
314 | OTI_usum_widen, | |
315 | ||
316 | /* Dot product, with result machine mode one or more wider than args. */ | |
317 | OTI_sdot_prod, | |
318 | OTI_udot_prod, | |
319 | ||
997404de JH |
320 | /* Set specified field of vector operand. */ |
321 | OTI_vec_set, | |
322 | /* Extract specified field of vector operand. */ | |
323 | OTI_vec_extract, | |
98b44b0e IR |
324 | /* Extract even/odd fields of vector operands. */ |
325 | OTI_vec_extract_even, | |
326 | OTI_vec_extract_odd, | |
327 | /* Interleave fields of vector operands. */ | |
328 | OTI_vec_interleave_high, | |
329 | OTI_vec_interleave_low, | |
997404de JH |
330 | /* Initialize vector operand. */ |
331 | OTI_vec_init, | |
a6b46ba2 DN |
332 | /* Whole vector shift. The shift amount is in bits. */ |
333 | OTI_vec_shl, | |
334 | OTI_vec_shr, | |
7ccf35ed DN |
335 | /* Extract specified elements from vectors, for vector load. */ |
336 | OTI_vec_realign_load, | |
b8698a0f | 337 | /* Widening multiplication. |
89d67cca DN |
338 | The high/low part of the resulting vector of products is returned. */ |
339 | OTI_vec_widen_umult_hi, | |
340 | OTI_vec_widen_umult_lo, | |
341 | OTI_vec_widen_smult_hi, | |
342 | OTI_vec_widen_smult_lo, | |
8115817b UB |
343 | /* Extract and widen the high/low part of a vector of signed or |
344 | floating point elements. */ | |
89d67cca DN |
345 | OTI_vec_unpacks_hi, |
346 | OTI_vec_unpacks_lo, | |
8115817b UB |
347 | /* Extract and widen the high/low part of a vector of unsigned |
348 | elements. */ | |
89d67cca DN |
349 | OTI_vec_unpacku_hi, |
350 | OTI_vec_unpacku_lo, | |
d9987fb4 UB |
351 | |
352 | /* Extract, convert to floating point and widen the high/low part of | |
353 | a vector of signed or unsigned integer elements. */ | |
354 | OTI_vec_unpacks_float_hi, | |
355 | OTI_vec_unpacks_float_lo, | |
356 | OTI_vec_unpacku_float_hi, | |
357 | OTI_vec_unpacku_float_lo, | |
358 | ||
89d67cca | 359 | /* Narrow (demote) and merge the elements of two vectors. */ |
8115817b | 360 | OTI_vec_pack_trunc, |
89d67cca DN |
361 | OTI_vec_pack_usat, |
362 | OTI_vec_pack_ssat, | |
997404de | 363 | |
d9987fb4 UB |
364 | /* Convert to signed/unsigned integer, narrow and merge elements |
365 | of two vectors of floating point elements. */ | |
366 | OTI_vec_pack_sfix_trunc, | |
367 | OTI_vec_pack_ufix_trunc, | |
368 | ||
17684d46 RG |
369 | /* Perform a raise to the power of integer. */ |
370 | OTI_powi, | |
371 | ||
e78d8e51 ZW |
372 | OTI_MAX |
373 | }; | |
374 | ||
7e5487a2 | 375 | extern struct optab_d optab_table[OTI_MAX]; |
33727b5e JJ |
376 | |
377 | #define ssadd_optab (&optab_table[OTI_ssadd]) | |
378 | #define usadd_optab (&optab_table[OTI_usadd]) | |
379 | #define sssub_optab (&optab_table[OTI_sssub]) | |
380 | #define ussub_optab (&optab_table[OTI_ussub]) | |
381 | #define ssmul_optab (&optab_table[OTI_ssmul]) | |
382 | #define usmul_optab (&optab_table[OTI_usmul]) | |
383 | #define ssdiv_optab (&optab_table[OTI_ssdiv]) | |
384 | #define usdiv_optab (&optab_table[OTI_usdiv]) | |
385 | #define ssneg_optab (&optab_table[OTI_ssneg]) | |
386 | #define usneg_optab (&optab_table[OTI_usneg]) | |
387 | #define ssashl_optab (&optab_table[OTI_ssashl]) | |
388 | #define usashl_optab (&optab_table[OTI_usashl]) | |
389 | ||
390 | #define add_optab (&optab_table[OTI_add]) | |
391 | #define sub_optab (&optab_table[OTI_sub]) | |
392 | #define smul_optab (&optab_table[OTI_smul]) | |
393 | #define addv_optab (&optab_table[OTI_addv]) | |
394 | #define subv_optab (&optab_table[OTI_subv]) | |
395 | #define smul_highpart_optab (&optab_table[OTI_smul_highpart]) | |
396 | #define umul_highpart_optab (&optab_table[OTI_umul_highpart]) | |
397 | #define smul_widen_optab (&optab_table[OTI_smul_widen]) | |
398 | #define umul_widen_optab (&optab_table[OTI_umul_widen]) | |
399 | #define usmul_widen_optab (&optab_table[OTI_usmul_widen]) | |
400 | #define smadd_widen_optab (&optab_table[OTI_smadd_widen]) | |
401 | #define umadd_widen_optab (&optab_table[OTI_umadd_widen]) | |
402 | #define ssmadd_widen_optab (&optab_table[OTI_ssmadd_widen]) | |
403 | #define usmadd_widen_optab (&optab_table[OTI_usmadd_widen]) | |
404 | #define smsub_widen_optab (&optab_table[OTI_smsub_widen]) | |
405 | #define umsub_widen_optab (&optab_table[OTI_umsub_widen]) | |
406 | #define ssmsub_widen_optab (&optab_table[OTI_ssmsub_widen]) | |
407 | #define usmsub_widen_optab (&optab_table[OTI_usmsub_widen]) | |
408 | #define sdiv_optab (&optab_table[OTI_sdiv]) | |
409 | #define smulv_optab (&optab_table[OTI_smulv]) | |
410 | #define sdivv_optab (&optab_table[OTI_sdivv]) | |
411 | #define sdivmod_optab (&optab_table[OTI_sdivmod]) | |
412 | #define udiv_optab (&optab_table[OTI_udiv]) | |
413 | #define udivmod_optab (&optab_table[OTI_udivmod]) | |
414 | #define smod_optab (&optab_table[OTI_smod]) | |
415 | #define umod_optab (&optab_table[OTI_umod]) | |
416 | #define fmod_optab (&optab_table[OTI_fmod]) | |
417 | #define remainder_optab (&optab_table[OTI_remainder]) | |
418 | #define ftrunc_optab (&optab_table[OTI_ftrunc]) | |
419 | #define and_optab (&optab_table[OTI_and]) | |
420 | #define ior_optab (&optab_table[OTI_ior]) | |
421 | #define xor_optab (&optab_table[OTI_xor]) | |
422 | #define ashl_optab (&optab_table[OTI_ashl]) | |
423 | #define lshr_optab (&optab_table[OTI_lshr]) | |
424 | #define ashr_optab (&optab_table[OTI_ashr]) | |
425 | #define rotl_optab (&optab_table[OTI_rotl]) | |
426 | #define rotr_optab (&optab_table[OTI_rotr]) | |
71d46ca5 MM |
427 | #define vashl_optab (&optab_table[OTI_vashl]) |
428 | #define vlshr_optab (&optab_table[OTI_vlshr]) | |
429 | #define vashr_optab (&optab_table[OTI_vashr]) | |
430 | #define vrotl_optab (&optab_table[OTI_vrotl]) | |
431 | #define vrotr_optab (&optab_table[OTI_vrotr]) | |
33727b5e JJ |
432 | #define smin_optab (&optab_table[OTI_smin]) |
433 | #define smax_optab (&optab_table[OTI_smax]) | |
434 | #define umin_optab (&optab_table[OTI_umin]) | |
435 | #define umax_optab (&optab_table[OTI_umax]) | |
436 | #define pow_optab (&optab_table[OTI_pow]) | |
437 | #define atan2_optab (&optab_table[OTI_atan2]) | |
438 | ||
439 | #define mov_optab (&optab_table[OTI_mov]) | |
440 | #define movstrict_optab (&optab_table[OTI_movstrict]) | |
441 | #define movmisalign_optab (&optab_table[OTI_movmisalign]) | |
442 | #define storent_optab (&optab_table[OTI_storent]) | |
443 | ||
444 | #define neg_optab (&optab_table[OTI_neg]) | |
445 | #define negv_optab (&optab_table[OTI_negv]) | |
446 | #define abs_optab (&optab_table[OTI_abs]) | |
447 | #define absv_optab (&optab_table[OTI_absv]) | |
448 | #define one_cmpl_optab (&optab_table[OTI_one_cmpl]) | |
449 | #define bswap_optab (&optab_table[OTI_bswap]) | |
450 | #define ffs_optab (&optab_table[OTI_ffs]) | |
451 | #define clz_optab (&optab_table[OTI_clz]) | |
452 | #define ctz_optab (&optab_table[OTI_ctz]) | |
453 | #define popcount_optab (&optab_table[OTI_popcount]) | |
454 | #define parity_optab (&optab_table[OTI_parity]) | |
455 | #define sqrt_optab (&optab_table[OTI_sqrt]) | |
456 | #define sincos_optab (&optab_table[OTI_sincos]) | |
457 | #define sin_optab (&optab_table[OTI_sin]) | |
458 | #define asin_optab (&optab_table[OTI_asin]) | |
459 | #define cos_optab (&optab_table[OTI_cos]) | |
460 | #define acos_optab (&optab_table[OTI_acos]) | |
461 | #define exp_optab (&optab_table[OTI_exp]) | |
462 | #define exp10_optab (&optab_table[OTI_exp10]) | |
463 | #define exp2_optab (&optab_table[OTI_exp2]) | |
464 | #define expm1_optab (&optab_table[OTI_expm1]) | |
465 | #define ldexp_optab (&optab_table[OTI_ldexp]) | |
466 | #define scalb_optab (&optab_table[OTI_scalb]) | |
dc6707b8 | 467 | #define significand_optab (&optab_table[OTI_significand]) |
33727b5e JJ |
468 | #define logb_optab (&optab_table[OTI_logb]) |
469 | #define ilogb_optab (&optab_table[OTI_ilogb]) | |
470 | #define log_optab (&optab_table[OTI_log]) | |
471 | #define log10_optab (&optab_table[OTI_log10]) | |
472 | #define log2_optab (&optab_table[OTI_log2]) | |
473 | #define log1p_optab (&optab_table[OTI_log1p]) | |
474 | #define floor_optab (&optab_table[OTI_floor]) | |
475 | #define ceil_optab (&optab_table[OTI_ceil]) | |
476 | #define btrunc_optab (&optab_table[OTI_btrunc]) | |
477 | #define round_optab (&optab_table[OTI_round]) | |
478 | #define nearbyint_optab (&optab_table[OTI_nearbyint]) | |
479 | #define rint_optab (&optab_table[OTI_rint]) | |
480 | #define tan_optab (&optab_table[OTI_tan]) | |
481 | #define atan_optab (&optab_table[OTI_atan]) | |
482 | #define copysign_optab (&optab_table[OTI_copysign]) | |
483 | #define signbit_optab (&optab_table[OTI_signbit]) | |
484 | #define isinf_optab (&optab_table[OTI_isinf]) | |
485 | ||
486 | #define cmp_optab (&optab_table[OTI_cmp]) | |
487 | #define ucmp_optab (&optab_table[OTI_ucmp]) | |
33727b5e JJ |
488 | |
489 | #define eq_optab (&optab_table[OTI_eq]) | |
490 | #define ne_optab (&optab_table[OTI_ne]) | |
491 | #define gt_optab (&optab_table[OTI_gt]) | |
492 | #define ge_optab (&optab_table[OTI_ge]) | |
493 | #define lt_optab (&optab_table[OTI_lt]) | |
494 | #define le_optab (&optab_table[OTI_le]) | |
495 | #define unord_optab (&optab_table[OTI_unord]) | |
496 | ||
497 | #define strlen_optab (&optab_table[OTI_strlen]) | |
498 | ||
499 | #define cbranch_optab (&optab_table[OTI_cbranch]) | |
500 | #define cmov_optab (&optab_table[OTI_cmov]) | |
501 | #define cstore_optab (&optab_table[OTI_cstore]) | |
f90b7a5a PB |
502 | #define ctrap_optab (&optab_table[OTI_ctrap]) |
503 | ||
33727b5e JJ |
504 | #define push_optab (&optab_table[OTI_push]) |
505 | #define addcc_optab (&optab_table[OTI_addcc]) | |
506 | ||
507 | #define reduc_smax_optab (&optab_table[OTI_reduc_smax]) | |
508 | #define reduc_umax_optab (&optab_table[OTI_reduc_umax]) | |
509 | #define reduc_smin_optab (&optab_table[OTI_reduc_smin]) | |
510 | #define reduc_umin_optab (&optab_table[OTI_reduc_umin]) | |
511 | #define reduc_splus_optab (&optab_table[OTI_reduc_splus]) | |
512 | #define reduc_uplus_optab (&optab_table[OTI_reduc_uplus]) | |
513 | ||
514 | #define ssum_widen_optab (&optab_table[OTI_ssum_widen]) | |
515 | #define usum_widen_optab (&optab_table[OTI_usum_widen]) | |
516 | #define sdot_prod_optab (&optab_table[OTI_sdot_prod]) | |
517 | #define udot_prod_optab (&optab_table[OTI_udot_prod]) | |
518 | ||
519 | #define vec_set_optab (&optab_table[OTI_vec_set]) | |
520 | #define vec_extract_optab (&optab_table[OTI_vec_extract]) | |
521 | #define vec_extract_even_optab (&optab_table[OTI_vec_extract_even]) | |
522 | #define vec_extract_odd_optab (&optab_table[OTI_vec_extract_odd]) | |
523 | #define vec_interleave_high_optab (&optab_table[OTI_vec_interleave_high]) | |
524 | #define vec_interleave_low_optab (&optab_table[OTI_vec_interleave_low]) | |
525 | #define vec_init_optab (&optab_table[OTI_vec_init]) | |
526 | #define vec_shl_optab (&optab_table[OTI_vec_shl]) | |
527 | #define vec_shr_optab (&optab_table[OTI_vec_shr]) | |
528 | #define vec_realign_load_optab (&optab_table[OTI_vec_realign_load]) | |
529 | #define vec_widen_umult_hi_optab (&optab_table[OTI_vec_widen_umult_hi]) | |
530 | #define vec_widen_umult_lo_optab (&optab_table[OTI_vec_widen_umult_lo]) | |
531 | #define vec_widen_smult_hi_optab (&optab_table[OTI_vec_widen_smult_hi]) | |
532 | #define vec_widen_smult_lo_optab (&optab_table[OTI_vec_widen_smult_lo]) | |
533 | #define vec_unpacks_hi_optab (&optab_table[OTI_vec_unpacks_hi]) | |
534 | #define vec_unpacks_lo_optab (&optab_table[OTI_vec_unpacks_lo]) | |
535 | #define vec_unpacku_hi_optab (&optab_table[OTI_vec_unpacku_hi]) | |
536 | #define vec_unpacku_lo_optab (&optab_table[OTI_vec_unpacku_lo]) | |
537 | #define vec_unpacks_float_hi_optab (&optab_table[OTI_vec_unpacks_float_hi]) | |
538 | #define vec_unpacks_float_lo_optab (&optab_table[OTI_vec_unpacks_float_lo]) | |
539 | #define vec_unpacku_float_hi_optab (&optab_table[OTI_vec_unpacku_float_hi]) | |
540 | #define vec_unpacku_float_lo_optab (&optab_table[OTI_vec_unpacku_float_lo]) | |
541 | #define vec_pack_trunc_optab (&optab_table[OTI_vec_pack_trunc]) | |
542 | #define vec_pack_ssat_optab (&optab_table[OTI_vec_pack_ssat]) | |
543 | #define vec_pack_usat_optab (&optab_table[OTI_vec_pack_usat]) | |
544 | #define vec_pack_sfix_trunc_optab (&optab_table[OTI_vec_pack_sfix_trunc]) | |
545 | #define vec_pack_ufix_trunc_optab (&optab_table[OTI_vec_pack_ufix_trunc]) | |
546 | ||
547 | #define powi_optab (&optab_table[OTI_powi]) | |
17684d46 | 548 | |
85363ca0 ZW |
549 | /* Conversion optabs have their own table and indexes. */ |
550 | enum convert_optab_index | |
551 | { | |
c414ac1d EC |
552 | COI_sext, |
553 | COI_zext, | |
554 | COI_trunc, | |
85363ca0 | 555 | |
c414ac1d EC |
556 | COI_sfix, |
557 | COI_ufix, | |
85363ca0 | 558 | |
c414ac1d EC |
559 | COI_sfixtrunc, |
560 | COI_ufixtrunc, | |
85363ca0 | 561 | |
c414ac1d EC |
562 | COI_sfloat, |
563 | COI_ufloat, | |
85363ca0 | 564 | |
bb7f0423 | 565 | COI_lrint, |
4d81bf84 | 566 | COI_lround, |
c3a4177f RG |
567 | COI_lfloor, |
568 | COI_lceil, | |
bb7f0423 | 569 | |
0f996086 CF |
570 | COI_fract, |
571 | COI_fractuns, | |
572 | COI_satfract, | |
573 | COI_satfractuns, | |
574 | ||
c414ac1d | 575 | COI_MAX |
85363ca0 ZW |
576 | }; |
577 | ||
7e5487a2 | 578 | extern struct convert_optab_d convert_optab_table[COI_MAX]; |
33727b5e JJ |
579 | |
580 | #define sext_optab (&convert_optab_table[COI_sext]) | |
581 | #define zext_optab (&convert_optab_table[COI_zext]) | |
582 | #define trunc_optab (&convert_optab_table[COI_trunc]) | |
583 | #define sfix_optab (&convert_optab_table[COI_sfix]) | |
584 | #define ufix_optab (&convert_optab_table[COI_ufix]) | |
585 | #define sfixtrunc_optab (&convert_optab_table[COI_sfixtrunc]) | |
586 | #define ufixtrunc_optab (&convert_optab_table[COI_ufixtrunc]) | |
587 | #define sfloat_optab (&convert_optab_table[COI_sfloat]) | |
588 | #define ufloat_optab (&convert_optab_table[COI_ufloat]) | |
589 | #define lrint_optab (&convert_optab_table[COI_lrint]) | |
590 | #define lround_optab (&convert_optab_table[COI_lround]) | |
591 | #define lfloor_optab (&convert_optab_table[COI_lfloor]) | |
592 | #define lceil_optab (&convert_optab_table[COI_lceil]) | |
593 | #define fract_optab (&convert_optab_table[COI_fract]) | |
594 | #define fractuns_optab (&convert_optab_table[COI_fractuns]) | |
595 | #define satfract_optab (&convert_optab_table[COI_satfract]) | |
596 | #define satfractuns_optab (&convert_optab_table[COI_satfractuns]) | |
e78d8e51 ZW |
597 | |
598 | /* These arrays record the insn_code of insns that may be needed to | |
599 | perform input and output reloads of special objects. They provide a | |
600 | place to pass a scratch register. */ | |
601 | extern enum insn_code reload_in_optab[NUM_MACHINE_MODES]; | |
602 | extern enum insn_code reload_out_optab[NUM_MACHINE_MODES]; | |
603 | ||
604 | /* Contains the optab used for each rtx code. */ | |
8a33f100 | 605 | extern optab code_to_optab[NUM_RTX_CODE + 1]; |
e78d8e51 | 606 | |
e78d8e51 | 607 | \f |
0c20a65f | 608 | typedef rtx (*rtxfun) (rtx); |
e78d8e51 | 609 | |
e78d8e51 ZW |
610 | #ifdef HAVE_conditional_move |
611 | /* Indexed by the machine mode, gives the insn code to make a conditional | |
612 | move insn. */ | |
613 | ||
614 | extern enum insn_code movcc_gen_code[NUM_MACHINE_MODES]; | |
615 | #endif | |
616 | ||
7ce67fbe DP |
617 | /* Indexed by the machine mode, gives the insn code for vector conditional |
618 | operation. */ | |
619 | ||
620 | extern enum insn_code vcond_gen_code[NUM_MACHINE_MODES]; | |
621 | extern enum insn_code vcondu_gen_code[NUM_MACHINE_MODES]; | |
622 | ||
e78d8e51 | 623 | /* This array records the insn_code of insns to perform block moves. */ |
70128ad9 | 624 | extern enum insn_code movmem_optab[NUM_MACHINE_MODES]; |
e78d8e51 | 625 | |
57e84f18 AS |
626 | /* This array records the insn_code of insns to perform block sets. */ |
627 | extern enum insn_code setmem_optab[NUM_MACHINE_MODES]; | |
118355a0 ZW |
628 | |
629 | /* These arrays record the insn_code of two different kinds of insns | |
630 | to perform block compares. */ | |
631 | extern enum insn_code cmpstr_optab[NUM_MACHINE_MODES]; | |
40c1d5f8 | 632 | extern enum insn_code cmpstrn_optab[NUM_MACHINE_MODES]; |
118355a0 | 633 | extern enum insn_code cmpmem_optab[NUM_MACHINE_MODES]; |
e78d8e51 | 634 | |
48ae6c13 RH |
635 | /* Synchronization primitives. This first set is atomic operation for |
636 | which we don't care about the resulting value. */ | |
637 | extern enum insn_code sync_add_optab[NUM_MACHINE_MODES]; | |
638 | extern enum insn_code sync_sub_optab[NUM_MACHINE_MODES]; | |
639 | extern enum insn_code sync_ior_optab[NUM_MACHINE_MODES]; | |
640 | extern enum insn_code sync_and_optab[NUM_MACHINE_MODES]; | |
641 | extern enum insn_code sync_xor_optab[NUM_MACHINE_MODES]; | |
642 | extern enum insn_code sync_nand_optab[NUM_MACHINE_MODES]; | |
643 | ||
644 | /* This second set is atomic operations in which we return the value | |
645 | that existed in memory before the operation. */ | |
646 | extern enum insn_code sync_old_add_optab[NUM_MACHINE_MODES]; | |
647 | extern enum insn_code sync_old_sub_optab[NUM_MACHINE_MODES]; | |
648 | extern enum insn_code sync_old_ior_optab[NUM_MACHINE_MODES]; | |
649 | extern enum insn_code sync_old_and_optab[NUM_MACHINE_MODES]; | |
650 | extern enum insn_code sync_old_xor_optab[NUM_MACHINE_MODES]; | |
651 | extern enum insn_code sync_old_nand_optab[NUM_MACHINE_MODES]; | |
652 | ||
653 | /* This third set is atomic operations in which we return the value | |
654 | that resulted after performing the operation. */ | |
655 | extern enum insn_code sync_new_add_optab[NUM_MACHINE_MODES]; | |
656 | extern enum insn_code sync_new_sub_optab[NUM_MACHINE_MODES]; | |
657 | extern enum insn_code sync_new_ior_optab[NUM_MACHINE_MODES]; | |
658 | extern enum insn_code sync_new_and_optab[NUM_MACHINE_MODES]; | |
659 | extern enum insn_code sync_new_xor_optab[NUM_MACHINE_MODES]; | |
660 | extern enum insn_code sync_new_nand_optab[NUM_MACHINE_MODES]; | |
661 | ||
662 | /* Atomic compare and swap. */ | |
663 | extern enum insn_code sync_compare_and_swap[NUM_MACHINE_MODES]; | |
48ae6c13 RH |
664 | |
665 | /* Atomic exchange with acquire semantics. */ | |
666 | extern enum insn_code sync_lock_test_and_set[NUM_MACHINE_MODES]; | |
667 | ||
668 | /* Atomic clear with release semantics. */ | |
669 | extern enum insn_code sync_lock_release[NUM_MACHINE_MODES]; | |
670 | ||
e78d8e51 ZW |
671 | /* Define functions given in optabs.c. */ |
672 | ||
8e7aa1f9 | 673 | extern rtx expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op, |
20f06221 DN |
674 | rtx target, int unsignedp); |
675 | ||
c414ac1d EC |
676 | extern rtx expand_ternary_op (enum machine_mode mode, optab ternary_optab, |
677 | rtx op0, rtx op1, rtx op2, rtx target, | |
7ccf35ed DN |
678 | int unsignedp); |
679 | ||
e78d8e51 | 680 | /* Expand a binary operation given optab and rtx operands. */ |
0c20a65f AJ |
681 | extern rtx expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int, |
682 | enum optab_methods); | |
e78d8e51 | 683 | |
bef5d8b6 RS |
684 | extern bool force_expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int, |
685 | enum optab_methods); | |
686 | ||
e78d8e51 | 687 | /* Expand a binary operation with both signed and unsigned forms. */ |
0c20a65f AJ |
688 | extern rtx sign_expand_binop (enum machine_mode, optab, optab, rtx, rtx, |
689 | rtx, int, enum optab_methods); | |
e78d8e51 | 690 | |
6c7cf1f0 UB |
691 | /* Generate code to perform an operation on one operand with two results. */ |
692 | extern int expand_twoval_unop (optab, rtx, rtx, rtx, int); | |
693 | ||
e78d8e51 | 694 | /* Generate code to perform an operation on two operands with two results. */ |
0c20a65f | 695 | extern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int); |
e78d8e51 | 696 | |
b3f8d95d MM |
697 | /* Generate code to perform an operation on two operands with two |
698 | results, using a library function. */ | |
5906d013 | 699 | extern bool expand_twoval_binop_libfunc (optab, rtx, rtx, rtx, rtx, |
b3f8d95d MM |
700 | enum rtx_code); |
701 | ||
e78d8e51 | 702 | /* Expand a unary arithmetic operation given optab rtx operand. */ |
0c20a65f | 703 | extern rtx expand_unop (enum machine_mode, optab, rtx, rtx, int); |
e78d8e51 ZW |
704 | |
705 | /* Expand the absolute value operation. */ | |
0c20a65f AJ |
706 | extern rtx expand_abs_nojump (enum machine_mode, rtx, rtx, int); |
707 | extern rtx expand_abs (enum machine_mode, rtx, rtx, int, int); | |
e78d8e51 | 708 | |
65026047 ER |
709 | /* Expand the one's complement absolute value operation. */ |
710 | extern rtx expand_one_cmpl_abs_nojump (enum machine_mode, rtx, rtx); | |
711 | ||
046625fa RH |
712 | /* Expand the copysign operation. */ |
713 | extern rtx expand_copysign (rtx, rtx, rtx); | |
714 | ||
e78d8e51 ZW |
715 | /* Generate an instruction with a given INSN_CODE with an output and |
716 | an input. */ | |
0c20a65f | 717 | extern void emit_unop_insn (int, rtx, rtx, enum rtx_code); |
18bd082d | 718 | extern bool maybe_emit_unop_insn (int, rtx, rtx, enum rtx_code); |
e78d8e51 | 719 | |
71d46ca5 MM |
720 | /* An extra flag to control optab_for_tree_code's behavior. This is needed to |
721 | distinguish between machines with a vector shift that takes a scalar for the | |
722 | shift amount vs. machines that take a vector for the shift amount. */ | |
723 | enum optab_subtype | |
724 | { | |
725 | optab_default, | |
726 | optab_scalar, | |
727 | optab_vector | |
728 | }; | |
729 | ||
730 | /* Return the optab used for computing the given operation on the type given by | |
731 | the second argument. The third argument distinguishes between the types of | |
732 | vector shifts and rotates */ | |
733 | extern optab optab_for_tree_code (enum tree_code, const_tree, enum optab_subtype); | |
734 | ||
e78d8e51 ZW |
735 | /* The various uses that a comparison can have; used by can_compare_p: |
736 | jumps, conditional moves, store flag operations. */ | |
737 | enum can_compare_purpose | |
738 | { | |
739 | ccp_jump, | |
740 | ccp_cmov, | |
741 | ccp_store_flag | |
742 | }; | |
743 | ||
744 | /* Nonzero if a compare of mode MODE can be done straightforwardly | |
745 | (without splitting it into pieces). */ | |
0c20a65f AJ |
746 | extern int can_compare_p (enum rtx_code, enum machine_mode, |
747 | enum can_compare_purpose); | |
e78d8e51 | 748 | |
e78d8e51 | 749 | /* Return the INSN_CODE to use for an extend operation. */ |
0c20a65f | 750 | extern enum insn_code can_extend_p (enum machine_mode, enum machine_mode, int); |
e78d8e51 ZW |
751 | |
752 | /* Generate the body of an insn to extend Y (with mode MFROM) | |
753 | into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */ | |
0c20a65f AJ |
754 | extern rtx gen_extend_insn (rtx, rtx, enum machine_mode, |
755 | enum machine_mode, int); | |
e78d8e51 | 756 | |
c15c90bb ZW |
757 | /* Call this to reset the function entry for one optab. */ |
758 | extern void set_optab_libfunc (optab, enum machine_mode, const char *); | |
85363ca0 ZW |
759 | extern void set_conv_libfunc (convert_optab, enum machine_mode, |
760 | enum machine_mode, const char *); | |
c15c90bb | 761 | |
0f996086 CF |
762 | /* Generate code for a FIXED_CONVERT_EXPR. */ |
763 | extern void expand_fixed_convert (rtx, rtx, int, int); | |
764 | ||
e78d8e51 | 765 | /* Generate code for a FLOAT_EXPR. */ |
0c20a65f | 766 | extern void expand_float (rtx, rtx, int); |
e78d8e51 ZW |
767 | |
768 | /* Generate code for a FIX_EXPR. */ | |
0c20a65f | 769 | extern void expand_fix (rtx, rtx, int); |
e78d8e51 | 770 | |
bb7f0423 RG |
771 | /* Generate code for float to integral conversion. */ |
772 | extern bool expand_sfix_optab (rtx, rtx, convert_optab); | |
773 | ||
6dbd43ba | 774 | /* Return tree if target supports vector operations for COND_EXPR. */ |
7ce67fbe DP |
775 | bool expand_vec_cond_expr_p (tree, enum machine_mode); |
776 | ||
777 | /* Generate code for VEC_COND_EXPR. */ | |
8e7aa1f9 | 778 | extern rtx expand_vec_cond_expr (tree, tree, tree, tree, rtx); |
a6b46ba2 | 779 | /* Generate code for VEC_LSHIFT_EXPR and VEC_RSHIFT_EXPR. */ |
8e7aa1f9 | 780 | extern rtx expand_vec_shift_expr (sepops, rtx); |
a6b46ba2 | 781 | |
166cdb08 JH |
782 | #define optab_handler(optab,mode) (&(optab)->handlers[(int) (mode)]) |
783 | #define convert_optab_handler(optab,mode,mode2) \ | |
784 | (&(optab)->handlers[(int) (mode)][(int) (mode2)]) | |
785 | ||
8a33f100 JH |
786 | extern rtx optab_libfunc (optab optab, enum machine_mode mode); |
787 | extern rtx convert_optab_libfunc (convert_optab optab, enum machine_mode mode1, | |
788 | enum machine_mode mode2); | |
e78d8e51 | 789 | #endif /* GCC_OPTABS_H */ |