1*e4b17023SJohn Marino /* Definitions for code generation pass of GNU compiler.
2*e4b17023SJohn Marino Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3*e4b17023SJohn Marino Free Software Foundation, Inc.
4*e4b17023SJohn Marino
5*e4b17023SJohn Marino This file is part of GCC.
6*e4b17023SJohn Marino
7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
8*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
9*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
10*e4b17023SJohn Marino any later version.
11*e4b17023SJohn Marino
12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
13*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*e4b17023SJohn Marino GNU General Public License for more details.
16*e4b17023SJohn Marino
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
20*e4b17023SJohn Marino
21*e4b17023SJohn Marino #ifndef GCC_OPTABS_H
22*e4b17023SJohn Marino #define GCC_OPTABS_H
23*e4b17023SJohn Marino
24*e4b17023SJohn Marino #include "insn-codes.h"
25*e4b17023SJohn Marino
26*e4b17023SJohn Marino /* Optabs are tables saying how to generate insn bodies
27*e4b17023SJohn Marino for various machine modes and numbers of operands.
28*e4b17023SJohn Marino Each optab applies to one operation.
29*e4b17023SJohn Marino
30*e4b17023SJohn Marino For example, add_optab applies to addition.
31*e4b17023SJohn Marino
32*e4b17023SJohn Marino The `lib_call' slot is the name of the library function that
33*e4b17023SJohn Marino can be used to perform the operation.
34*e4b17023SJohn Marino
35*e4b17023SJohn Marino A few optabs, such as move_optab, are used by special code. */
36*e4b17023SJohn Marino
37*e4b17023SJohn Marino struct optab_handlers
38*e4b17023SJohn Marino {
39*e4b17023SJohn Marino /* I - CODE_FOR_nothing, where I is either the insn code of the
40*e4b17023SJohn Marino associated insn generator or CODE_FOR_nothing if there is no such
41*e4b17023SJohn Marino insn on the target machine. */
42*e4b17023SJohn Marino int insn_code;
43*e4b17023SJohn Marino };
44*e4b17023SJohn Marino
45*e4b17023SJohn Marino struct widening_optab_handlers
46*e4b17023SJohn Marino {
47*e4b17023SJohn Marino struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
48*e4b17023SJohn Marino };
49*e4b17023SJohn Marino
50*e4b17023SJohn Marino struct optab_d
51*e4b17023SJohn Marino {
52*e4b17023SJohn Marino enum rtx_code code;
53*e4b17023SJohn Marino char libcall_suffix;
54*e4b17023SJohn Marino const char *libcall_basename;
55*e4b17023SJohn Marino void (*libcall_gen)(struct optab_d *, const char *name, char suffix,
56*e4b17023SJohn Marino enum machine_mode);
57*e4b17023SJohn Marino struct optab_handlers handlers[NUM_MACHINE_MODES];
58*e4b17023SJohn Marino struct widening_optab_handlers *widening;
59*e4b17023SJohn Marino };
60*e4b17023SJohn Marino typedef struct optab_d * optab;
61*e4b17023SJohn Marino
62*e4b17023SJohn Marino /* A convert_optab is for some sort of conversion operation between
63*e4b17023SJohn Marino modes. The first array index is the destination mode, the second
64*e4b17023SJohn Marino is the source mode. */
65*e4b17023SJohn Marino struct convert_optab_d
66*e4b17023SJohn Marino {
67*e4b17023SJohn Marino enum rtx_code code;
68*e4b17023SJohn Marino const char *libcall_basename;
69*e4b17023SJohn Marino void (*libcall_gen)(struct convert_optab_d *, const char *name,
70*e4b17023SJohn Marino enum machine_mode,
71*e4b17023SJohn Marino enum machine_mode);
72*e4b17023SJohn Marino struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
73*e4b17023SJohn Marino };
74*e4b17023SJohn Marino typedef struct convert_optab_d *convert_optab;
75*e4b17023SJohn Marino
76*e4b17023SJohn Marino /* Given an enum insn_code, access the function to construct
77*e4b17023SJohn Marino the body of that kind of insn. */
78*e4b17023SJohn Marino #define GEN_FCN(CODE) (insn_data[CODE].genfun)
79*e4b17023SJohn Marino
80*e4b17023SJohn Marino /* Enumeration of valid indexes into optab_table. */
81*e4b17023SJohn Marino enum optab_index
82*e4b17023SJohn Marino {
83*e4b17023SJohn Marino /* Fixed-point operators with signed/unsigned saturation */
84*e4b17023SJohn Marino OTI_ssadd,
85*e4b17023SJohn Marino OTI_usadd,
86*e4b17023SJohn Marino OTI_sssub,
87*e4b17023SJohn Marino OTI_ussub,
88*e4b17023SJohn Marino OTI_ssmul,
89*e4b17023SJohn Marino OTI_usmul,
90*e4b17023SJohn Marino OTI_ssdiv,
91*e4b17023SJohn Marino OTI_usdiv,
92*e4b17023SJohn Marino OTI_ssneg,
93*e4b17023SJohn Marino OTI_usneg,
94*e4b17023SJohn Marino OTI_ssashl,
95*e4b17023SJohn Marino OTI_usashl,
96*e4b17023SJohn Marino
97*e4b17023SJohn Marino OTI_add,
98*e4b17023SJohn Marino OTI_addv,
99*e4b17023SJohn Marino OTI_sub,
100*e4b17023SJohn Marino OTI_subv,
101*e4b17023SJohn Marino
102*e4b17023SJohn Marino /* Signed and fp multiply */
103*e4b17023SJohn Marino OTI_smul,
104*e4b17023SJohn Marino OTI_smulv,
105*e4b17023SJohn Marino /* Signed multiply, return high word */
106*e4b17023SJohn Marino OTI_smul_highpart,
107*e4b17023SJohn Marino OTI_umul_highpart,
108*e4b17023SJohn Marino /* Signed multiply with result one machine mode wider than args */
109*e4b17023SJohn Marino OTI_smul_widen,
110*e4b17023SJohn Marino OTI_umul_widen,
111*e4b17023SJohn Marino /* Widening multiply of one unsigned and one signed operand. */
112*e4b17023SJohn Marino OTI_usmul_widen,
113*e4b17023SJohn Marino /* Signed multiply and add with the result and addend one machine mode
114*e4b17023SJohn Marino wider than the multiplicand and multiplier. */
115*e4b17023SJohn Marino OTI_smadd_widen,
116*e4b17023SJohn Marino /* Unsigned multiply and add with the result and addend one machine mode
117*e4b17023SJohn Marino wider than the multiplicand and multiplier. */
118*e4b17023SJohn Marino OTI_umadd_widen,
119*e4b17023SJohn Marino /* Signed multiply and add with the result and addend one machine mode
120*e4b17023SJohn Marino wider than the multiplicand and multiplier.
121*e4b17023SJohn Marino All involved operations are saturating. */
122*e4b17023SJohn Marino OTI_ssmadd_widen,
123*e4b17023SJohn Marino /* Unsigned multiply and add with the result and addend one machine mode
124*e4b17023SJohn Marino wider than the multiplicand and multiplier.
125*e4b17023SJohn Marino All involved operations are saturating. */
126*e4b17023SJohn Marino OTI_usmadd_widen,
127*e4b17023SJohn Marino /* Signed multiply and subtract the result and minuend one machine mode
128*e4b17023SJohn Marino wider than the multiplicand and multiplier. */
129*e4b17023SJohn Marino OTI_smsub_widen,
130*e4b17023SJohn Marino /* Unsigned multiply and subtract the result and minuend one machine mode
131*e4b17023SJohn Marino wider than the multiplicand and multiplier. */
132*e4b17023SJohn Marino OTI_umsub_widen,
133*e4b17023SJohn Marino /* Signed multiply and subtract the result and minuend one machine mode
134*e4b17023SJohn Marino wider than the multiplicand and multiplier.
135*e4b17023SJohn Marino All involved operations are saturating. */
136*e4b17023SJohn Marino OTI_ssmsub_widen,
137*e4b17023SJohn Marino /* Unsigned multiply and subtract the result and minuend one machine mode
138*e4b17023SJohn Marino wider than the multiplicand and multiplier.
139*e4b17023SJohn Marino All involved operations are saturating. */
140*e4b17023SJohn Marino OTI_usmsub_widen,
141*e4b17023SJohn Marino
142*e4b17023SJohn Marino /* Signed divide */
143*e4b17023SJohn Marino OTI_sdiv,
144*e4b17023SJohn Marino OTI_sdivv,
145*e4b17023SJohn Marino /* Signed divide-and-remainder in one */
146*e4b17023SJohn Marino OTI_sdivmod,
147*e4b17023SJohn Marino OTI_udiv,
148*e4b17023SJohn Marino OTI_udivmod,
149*e4b17023SJohn Marino /* Signed remainder */
150*e4b17023SJohn Marino OTI_smod,
151*e4b17023SJohn Marino OTI_umod,
152*e4b17023SJohn Marino /* Floating point remainder functions */
153*e4b17023SJohn Marino OTI_fmod,
154*e4b17023SJohn Marino OTI_remainder,
155*e4b17023SJohn Marino /* Convert float to integer in float fmt */
156*e4b17023SJohn Marino OTI_ftrunc,
157*e4b17023SJohn Marino
158*e4b17023SJohn Marino /* Logical and */
159*e4b17023SJohn Marino OTI_and,
160*e4b17023SJohn Marino /* Logical or */
161*e4b17023SJohn Marino OTI_ior,
162*e4b17023SJohn Marino /* Logical xor */
163*e4b17023SJohn Marino OTI_xor,
164*e4b17023SJohn Marino
165*e4b17023SJohn Marino /* Arithmetic shift left */
166*e4b17023SJohn Marino OTI_ashl,
167*e4b17023SJohn Marino /* Logical shift right */
168*e4b17023SJohn Marino OTI_lshr,
169*e4b17023SJohn Marino /* Arithmetic shift right */
170*e4b17023SJohn Marino OTI_ashr,
171*e4b17023SJohn Marino /* Rotate left */
172*e4b17023SJohn Marino OTI_rotl,
173*e4b17023SJohn Marino /* Rotate right */
174*e4b17023SJohn Marino OTI_rotr,
175*e4b17023SJohn Marino
176*e4b17023SJohn Marino /* Arithmetic shift left of vector by vector */
177*e4b17023SJohn Marino OTI_vashl,
178*e4b17023SJohn Marino /* Logical shift right of vector by vector */
179*e4b17023SJohn Marino OTI_vlshr,
180*e4b17023SJohn Marino /* Arithmetic shift right of vector by vector */
181*e4b17023SJohn Marino OTI_vashr,
182*e4b17023SJohn Marino /* Rotate left of vector by vector */
183*e4b17023SJohn Marino OTI_vrotl,
184*e4b17023SJohn Marino /* Rotate right of vector by vector */
185*e4b17023SJohn Marino OTI_vrotr,
186*e4b17023SJohn Marino
187*e4b17023SJohn Marino /* Signed and floating-point minimum value */
188*e4b17023SJohn Marino OTI_smin,
189*e4b17023SJohn Marino /* Signed and floating-point maximum value */
190*e4b17023SJohn Marino OTI_smax,
191*e4b17023SJohn Marino /* Unsigned minimum value */
192*e4b17023SJohn Marino OTI_umin,
193*e4b17023SJohn Marino /* Unsigned maximum value */
194*e4b17023SJohn Marino OTI_umax,
195*e4b17023SJohn Marino /* Power */
196*e4b17023SJohn Marino OTI_pow,
197*e4b17023SJohn Marino /* Arc tangent of y/x */
198*e4b17023SJohn Marino OTI_atan2,
199*e4b17023SJohn Marino /* Floating multiply/add */
200*e4b17023SJohn Marino OTI_fma,
201*e4b17023SJohn Marino OTI_fms,
202*e4b17023SJohn Marino OTI_fnma,
203*e4b17023SJohn Marino OTI_fnms,
204*e4b17023SJohn Marino
205*e4b17023SJohn Marino /* Move instruction. */
206*e4b17023SJohn Marino OTI_mov,
207*e4b17023SJohn Marino /* Move, preserving high part of register. */
208*e4b17023SJohn Marino OTI_movstrict,
209*e4b17023SJohn Marino /* Move, with a misaligned memory. */
210*e4b17023SJohn Marino OTI_movmisalign,
211*e4b17023SJohn Marino /* Nontemporal store. */
212*e4b17023SJohn Marino OTI_storent,
213*e4b17023SJohn Marino
214*e4b17023SJohn Marino /* Unary operations */
215*e4b17023SJohn Marino /* Negation */
216*e4b17023SJohn Marino OTI_neg,
217*e4b17023SJohn Marino OTI_negv,
218*e4b17023SJohn Marino /* Abs value */
219*e4b17023SJohn Marino OTI_abs,
220*e4b17023SJohn Marino OTI_absv,
221*e4b17023SJohn Marino /* Byteswap */
222*e4b17023SJohn Marino OTI_bswap,
223*e4b17023SJohn Marino /* Bitwise not */
224*e4b17023SJohn Marino OTI_one_cmpl,
225*e4b17023SJohn Marino /* Bit scanning and counting */
226*e4b17023SJohn Marino OTI_ffs,
227*e4b17023SJohn Marino OTI_clz,
228*e4b17023SJohn Marino OTI_ctz,
229*e4b17023SJohn Marino OTI_clrsb,
230*e4b17023SJohn Marino OTI_popcount,
231*e4b17023SJohn Marino OTI_parity,
232*e4b17023SJohn Marino /* Square root */
233*e4b17023SJohn Marino OTI_sqrt,
234*e4b17023SJohn Marino /* Sine-Cosine */
235*e4b17023SJohn Marino OTI_sincos,
236*e4b17023SJohn Marino /* Sine */
237*e4b17023SJohn Marino OTI_sin,
238*e4b17023SJohn Marino /* Inverse sine */
239*e4b17023SJohn Marino OTI_asin,
240*e4b17023SJohn Marino /* Cosine */
241*e4b17023SJohn Marino OTI_cos,
242*e4b17023SJohn Marino /* Inverse cosine */
243*e4b17023SJohn Marino OTI_acos,
244*e4b17023SJohn Marino /* Exponential */
245*e4b17023SJohn Marino OTI_exp,
246*e4b17023SJohn Marino /* Base-10 Exponential */
247*e4b17023SJohn Marino OTI_exp10,
248*e4b17023SJohn Marino /* Base-2 Exponential */
249*e4b17023SJohn Marino OTI_exp2,
250*e4b17023SJohn Marino /* Exponential - 1*/
251*e4b17023SJohn Marino OTI_expm1,
252*e4b17023SJohn Marino /* Load exponent of a floating point number */
253*e4b17023SJohn Marino OTI_ldexp,
254*e4b17023SJohn Marino /* Multiply floating-point number by integral power of radix */
255*e4b17023SJohn Marino OTI_scalb,
256*e4b17023SJohn Marino /* Mantissa of a floating-point number */
257*e4b17023SJohn Marino OTI_significand,
258*e4b17023SJohn Marino /* Radix-independent exponent */
259*e4b17023SJohn Marino OTI_logb,
260*e4b17023SJohn Marino OTI_ilogb,
261*e4b17023SJohn Marino /* Natural Logarithm */
262*e4b17023SJohn Marino OTI_log,
263*e4b17023SJohn Marino /* Base-10 Logarithm */
264*e4b17023SJohn Marino OTI_log10,
265*e4b17023SJohn Marino /* Base-2 Logarithm */
266*e4b17023SJohn Marino OTI_log2,
267*e4b17023SJohn Marino /* logarithm of 1 plus argument */
268*e4b17023SJohn Marino OTI_log1p,
269*e4b17023SJohn Marino /* Rounding functions */
270*e4b17023SJohn Marino OTI_floor,
271*e4b17023SJohn Marino OTI_ceil,
272*e4b17023SJohn Marino OTI_btrunc,
273*e4b17023SJohn Marino OTI_round,
274*e4b17023SJohn Marino OTI_nearbyint,
275*e4b17023SJohn Marino OTI_rint,
276*e4b17023SJohn Marino /* Tangent */
277*e4b17023SJohn Marino OTI_tan,
278*e4b17023SJohn Marino /* Inverse tangent */
279*e4b17023SJohn Marino OTI_atan,
280*e4b17023SJohn Marino /* Copy sign */
281*e4b17023SJohn Marino OTI_copysign,
282*e4b17023SJohn Marino /* Signbit */
283*e4b17023SJohn Marino OTI_signbit,
284*e4b17023SJohn Marino /* Test for infinite value */
285*e4b17023SJohn Marino OTI_isinf,
286*e4b17023SJohn Marino
287*e4b17023SJohn Marino /* Compare insn; two operands. Used only for libcalls. */
288*e4b17023SJohn Marino OTI_cmp,
289*e4b17023SJohn Marino OTI_ucmp,
290*e4b17023SJohn Marino
291*e4b17023SJohn Marino /* Floating point comparison optabs - used primarily for libfuncs */
292*e4b17023SJohn Marino OTI_eq,
293*e4b17023SJohn Marino OTI_ne,
294*e4b17023SJohn Marino OTI_gt,
295*e4b17023SJohn Marino OTI_ge,
296*e4b17023SJohn Marino OTI_lt,
297*e4b17023SJohn Marino OTI_le,
298*e4b17023SJohn Marino OTI_unord,
299*e4b17023SJohn Marino
300*e4b17023SJohn Marino /* String length */
301*e4b17023SJohn Marino OTI_strlen,
302*e4b17023SJohn Marino
303*e4b17023SJohn Marino /* Combined compare & jump/move/store flags/trap operations. */
304*e4b17023SJohn Marino OTI_cbranch,
305*e4b17023SJohn Marino OTI_cmov,
306*e4b17023SJohn Marino OTI_cstore,
307*e4b17023SJohn Marino OTI_ctrap,
308*e4b17023SJohn Marino
309*e4b17023SJohn Marino /* Push instruction. */
310*e4b17023SJohn Marino OTI_push,
311*e4b17023SJohn Marino
312*e4b17023SJohn Marino /* Conditional add instruction. */
313*e4b17023SJohn Marino OTI_addcc,
314*e4b17023SJohn Marino
315*e4b17023SJohn Marino /* Reduction operations on a vector operand. */
316*e4b17023SJohn Marino OTI_reduc_smax,
317*e4b17023SJohn Marino OTI_reduc_umax,
318*e4b17023SJohn Marino OTI_reduc_smin,
319*e4b17023SJohn Marino OTI_reduc_umin,
320*e4b17023SJohn Marino OTI_reduc_splus,
321*e4b17023SJohn Marino OTI_reduc_uplus,
322*e4b17023SJohn Marino
323*e4b17023SJohn Marino /* Summation, with result machine mode one or more wider than args. */
324*e4b17023SJohn Marino OTI_ssum_widen,
325*e4b17023SJohn Marino OTI_usum_widen,
326*e4b17023SJohn Marino
327*e4b17023SJohn Marino /* Dot product, with result machine mode one or more wider than args. */
328*e4b17023SJohn Marino OTI_sdot_prod,
329*e4b17023SJohn Marino OTI_udot_prod,
330*e4b17023SJohn Marino
331*e4b17023SJohn Marino /* Set specified field of vector operand. */
332*e4b17023SJohn Marino OTI_vec_set,
333*e4b17023SJohn Marino /* Extract specified field of vector operand. */
334*e4b17023SJohn Marino OTI_vec_extract,
335*e4b17023SJohn Marino /* Initialize vector operand. */
336*e4b17023SJohn Marino OTI_vec_init,
337*e4b17023SJohn Marino /* Whole vector shift. The shift amount is in bits. */
338*e4b17023SJohn Marino OTI_vec_shl,
339*e4b17023SJohn Marino OTI_vec_shr,
340*e4b17023SJohn Marino /* Extract specified elements from vectors, for vector load. */
341*e4b17023SJohn Marino OTI_vec_realign_load,
342*e4b17023SJohn Marino /* Widening multiplication.
343*e4b17023SJohn Marino The high/low part of the resulting vector of products is returned. */
344*e4b17023SJohn Marino OTI_vec_widen_umult_hi,
345*e4b17023SJohn Marino OTI_vec_widen_umult_lo,
346*e4b17023SJohn Marino OTI_vec_widen_smult_hi,
347*e4b17023SJohn Marino OTI_vec_widen_smult_lo,
348*e4b17023SJohn Marino /* Widening shift left.
349*e4b17023SJohn Marino The high/low part of the resulting vector is returned. */
350*e4b17023SJohn Marino OTI_vec_widen_ushiftl_hi,
351*e4b17023SJohn Marino OTI_vec_widen_ushiftl_lo,
352*e4b17023SJohn Marino OTI_vec_widen_sshiftl_hi,
353*e4b17023SJohn Marino OTI_vec_widen_sshiftl_lo,
354*e4b17023SJohn Marino /* Extract and widen the high/low part of a vector of signed or
355*e4b17023SJohn Marino floating point elements. */
356*e4b17023SJohn Marino OTI_vec_unpacks_hi,
357*e4b17023SJohn Marino OTI_vec_unpacks_lo,
358*e4b17023SJohn Marino /* Extract and widen the high/low part of a vector of unsigned
359*e4b17023SJohn Marino elements. */
360*e4b17023SJohn Marino OTI_vec_unpacku_hi,
361*e4b17023SJohn Marino OTI_vec_unpacku_lo,
362*e4b17023SJohn Marino
363*e4b17023SJohn Marino /* Extract, convert to floating point and widen the high/low part of
364*e4b17023SJohn Marino a vector of signed or unsigned integer elements. */
365*e4b17023SJohn Marino OTI_vec_unpacks_float_hi,
366*e4b17023SJohn Marino OTI_vec_unpacks_float_lo,
367*e4b17023SJohn Marino OTI_vec_unpacku_float_hi,
368*e4b17023SJohn Marino OTI_vec_unpacku_float_lo,
369*e4b17023SJohn Marino
370*e4b17023SJohn Marino /* Narrow (demote) and merge the elements of two vectors. */
371*e4b17023SJohn Marino OTI_vec_pack_trunc,
372*e4b17023SJohn Marino OTI_vec_pack_usat,
373*e4b17023SJohn Marino OTI_vec_pack_ssat,
374*e4b17023SJohn Marino
375*e4b17023SJohn Marino /* Convert to signed/unsigned integer, narrow and merge elements
376*e4b17023SJohn Marino of two vectors of floating point elements. */
377*e4b17023SJohn Marino OTI_vec_pack_sfix_trunc,
378*e4b17023SJohn Marino OTI_vec_pack_ufix_trunc,
379*e4b17023SJohn Marino
380*e4b17023SJohn Marino /* Perform a raise to the power of integer. */
381*e4b17023SJohn Marino OTI_powi,
382*e4b17023SJohn Marino
383*e4b17023SJohn Marino /* Atomic compare and swap. */
384*e4b17023SJohn Marino OTI_sync_compare_and_swap,
385*e4b17023SJohn Marino
386*e4b17023SJohn Marino /* Atomic exchange with acquire semantics. */
387*e4b17023SJohn Marino OTI_sync_lock_test_and_set,
388*e4b17023SJohn Marino
389*e4b17023SJohn Marino /* This second set is atomic operations in which we return the value
390*e4b17023SJohn Marino that existed in memory before the operation. */
391*e4b17023SJohn Marino OTI_sync_old_add,
392*e4b17023SJohn Marino OTI_sync_old_sub,
393*e4b17023SJohn Marino OTI_sync_old_ior,
394*e4b17023SJohn Marino OTI_sync_old_and,
395*e4b17023SJohn Marino OTI_sync_old_xor,
396*e4b17023SJohn Marino OTI_sync_old_nand,
397*e4b17023SJohn Marino
398*e4b17023SJohn Marino /* This third set is atomic operations in which we return the value
399*e4b17023SJohn Marino that resulted after performing the operation. */
400*e4b17023SJohn Marino OTI_sync_new_add,
401*e4b17023SJohn Marino OTI_sync_new_sub,
402*e4b17023SJohn Marino OTI_sync_new_ior,
403*e4b17023SJohn Marino OTI_sync_new_and,
404*e4b17023SJohn Marino OTI_sync_new_xor,
405*e4b17023SJohn Marino OTI_sync_new_nand,
406*e4b17023SJohn Marino
407*e4b17023SJohn Marino OTI_MAX
408*e4b17023SJohn Marino };
409*e4b17023SJohn Marino
410*e4b17023SJohn Marino #define ssadd_optab (&optab_table[OTI_ssadd])
411*e4b17023SJohn Marino #define usadd_optab (&optab_table[OTI_usadd])
412*e4b17023SJohn Marino #define sssub_optab (&optab_table[OTI_sssub])
413*e4b17023SJohn Marino #define ussub_optab (&optab_table[OTI_ussub])
414*e4b17023SJohn Marino #define ssmul_optab (&optab_table[OTI_ssmul])
415*e4b17023SJohn Marino #define usmul_optab (&optab_table[OTI_usmul])
416*e4b17023SJohn Marino #define ssdiv_optab (&optab_table[OTI_ssdiv])
417*e4b17023SJohn Marino #define usdiv_optab (&optab_table[OTI_usdiv])
418*e4b17023SJohn Marino #define ssneg_optab (&optab_table[OTI_ssneg])
419*e4b17023SJohn Marino #define usneg_optab (&optab_table[OTI_usneg])
420*e4b17023SJohn Marino #define ssashl_optab (&optab_table[OTI_ssashl])
421*e4b17023SJohn Marino #define usashl_optab (&optab_table[OTI_usashl])
422*e4b17023SJohn Marino
423*e4b17023SJohn Marino #define add_optab (&optab_table[OTI_add])
424*e4b17023SJohn Marino #define sub_optab (&optab_table[OTI_sub])
425*e4b17023SJohn Marino #define smul_optab (&optab_table[OTI_smul])
426*e4b17023SJohn Marino #define addv_optab (&optab_table[OTI_addv])
427*e4b17023SJohn Marino #define subv_optab (&optab_table[OTI_subv])
428*e4b17023SJohn Marino #define smul_highpart_optab (&optab_table[OTI_smul_highpart])
429*e4b17023SJohn Marino #define umul_highpart_optab (&optab_table[OTI_umul_highpart])
430*e4b17023SJohn Marino #define smul_widen_optab (&optab_table[OTI_smul_widen])
431*e4b17023SJohn Marino #define umul_widen_optab (&optab_table[OTI_umul_widen])
432*e4b17023SJohn Marino #define usmul_widen_optab (&optab_table[OTI_usmul_widen])
433*e4b17023SJohn Marino #define smadd_widen_optab (&optab_table[OTI_smadd_widen])
434*e4b17023SJohn Marino #define umadd_widen_optab (&optab_table[OTI_umadd_widen])
435*e4b17023SJohn Marino #define ssmadd_widen_optab (&optab_table[OTI_ssmadd_widen])
436*e4b17023SJohn Marino #define usmadd_widen_optab (&optab_table[OTI_usmadd_widen])
437*e4b17023SJohn Marino #define smsub_widen_optab (&optab_table[OTI_smsub_widen])
438*e4b17023SJohn Marino #define umsub_widen_optab (&optab_table[OTI_umsub_widen])
439*e4b17023SJohn Marino #define ssmsub_widen_optab (&optab_table[OTI_ssmsub_widen])
440*e4b17023SJohn Marino #define usmsub_widen_optab (&optab_table[OTI_usmsub_widen])
441*e4b17023SJohn Marino #define sdiv_optab (&optab_table[OTI_sdiv])
442*e4b17023SJohn Marino #define smulv_optab (&optab_table[OTI_smulv])
443*e4b17023SJohn Marino #define sdivv_optab (&optab_table[OTI_sdivv])
444*e4b17023SJohn Marino #define sdivmod_optab (&optab_table[OTI_sdivmod])
445*e4b17023SJohn Marino #define udiv_optab (&optab_table[OTI_udiv])
446*e4b17023SJohn Marino #define udivmod_optab (&optab_table[OTI_udivmod])
447*e4b17023SJohn Marino #define smod_optab (&optab_table[OTI_smod])
448*e4b17023SJohn Marino #define umod_optab (&optab_table[OTI_umod])
449*e4b17023SJohn Marino #define fmod_optab (&optab_table[OTI_fmod])
450*e4b17023SJohn Marino #define remainder_optab (&optab_table[OTI_remainder])
451*e4b17023SJohn Marino #define ftrunc_optab (&optab_table[OTI_ftrunc])
452*e4b17023SJohn Marino #define and_optab (&optab_table[OTI_and])
453*e4b17023SJohn Marino #define ior_optab (&optab_table[OTI_ior])
454*e4b17023SJohn Marino #define xor_optab (&optab_table[OTI_xor])
455*e4b17023SJohn Marino #define ashl_optab (&optab_table[OTI_ashl])
456*e4b17023SJohn Marino #define lshr_optab (&optab_table[OTI_lshr])
457*e4b17023SJohn Marino #define ashr_optab (&optab_table[OTI_ashr])
458*e4b17023SJohn Marino #define rotl_optab (&optab_table[OTI_rotl])
459*e4b17023SJohn Marino #define rotr_optab (&optab_table[OTI_rotr])
460*e4b17023SJohn Marino #define vashl_optab (&optab_table[OTI_vashl])
461*e4b17023SJohn Marino #define vlshr_optab (&optab_table[OTI_vlshr])
462*e4b17023SJohn Marino #define vashr_optab (&optab_table[OTI_vashr])
463*e4b17023SJohn Marino #define vrotl_optab (&optab_table[OTI_vrotl])
464*e4b17023SJohn Marino #define vrotr_optab (&optab_table[OTI_vrotr])
465*e4b17023SJohn Marino #define smin_optab (&optab_table[OTI_smin])
466*e4b17023SJohn Marino #define smax_optab (&optab_table[OTI_smax])
467*e4b17023SJohn Marino #define umin_optab (&optab_table[OTI_umin])
468*e4b17023SJohn Marino #define umax_optab (&optab_table[OTI_umax])
469*e4b17023SJohn Marino #define pow_optab (&optab_table[OTI_pow])
470*e4b17023SJohn Marino #define atan2_optab (&optab_table[OTI_atan2])
471*e4b17023SJohn Marino #define fma_optab (&optab_table[OTI_fma])
472*e4b17023SJohn Marino #define fms_optab (&optab_table[OTI_fms])
473*e4b17023SJohn Marino #define fnma_optab (&optab_table[OTI_fnma])
474*e4b17023SJohn Marino #define fnms_optab (&optab_table[OTI_fnms])
475*e4b17023SJohn Marino
476*e4b17023SJohn Marino #define mov_optab (&optab_table[OTI_mov])
477*e4b17023SJohn Marino #define movstrict_optab (&optab_table[OTI_movstrict])
478*e4b17023SJohn Marino #define movmisalign_optab (&optab_table[OTI_movmisalign])
479*e4b17023SJohn Marino #define storent_optab (&optab_table[OTI_storent])
480*e4b17023SJohn Marino
481*e4b17023SJohn Marino #define neg_optab (&optab_table[OTI_neg])
482*e4b17023SJohn Marino #define negv_optab (&optab_table[OTI_negv])
483*e4b17023SJohn Marino #define abs_optab (&optab_table[OTI_abs])
484*e4b17023SJohn Marino #define absv_optab (&optab_table[OTI_absv])
485*e4b17023SJohn Marino #define one_cmpl_optab (&optab_table[OTI_one_cmpl])
486*e4b17023SJohn Marino #define bswap_optab (&optab_table[OTI_bswap])
487*e4b17023SJohn Marino #define ffs_optab (&optab_table[OTI_ffs])
488*e4b17023SJohn Marino #define clz_optab (&optab_table[OTI_clz])
489*e4b17023SJohn Marino #define ctz_optab (&optab_table[OTI_ctz])
490*e4b17023SJohn Marino #define clrsb_optab (&optab_table[OTI_clrsb])
491*e4b17023SJohn Marino #define popcount_optab (&optab_table[OTI_popcount])
492*e4b17023SJohn Marino #define parity_optab (&optab_table[OTI_parity])
493*e4b17023SJohn Marino #define sqrt_optab (&optab_table[OTI_sqrt])
494*e4b17023SJohn Marino #define sincos_optab (&optab_table[OTI_sincos])
495*e4b17023SJohn Marino #define sin_optab (&optab_table[OTI_sin])
496*e4b17023SJohn Marino #define asin_optab (&optab_table[OTI_asin])
497*e4b17023SJohn Marino #define cos_optab (&optab_table[OTI_cos])
498*e4b17023SJohn Marino #define acos_optab (&optab_table[OTI_acos])
499*e4b17023SJohn Marino #define exp_optab (&optab_table[OTI_exp])
500*e4b17023SJohn Marino #define exp10_optab (&optab_table[OTI_exp10])
501*e4b17023SJohn Marino #define exp2_optab (&optab_table[OTI_exp2])
502*e4b17023SJohn Marino #define expm1_optab (&optab_table[OTI_expm1])
503*e4b17023SJohn Marino #define ldexp_optab (&optab_table[OTI_ldexp])
504*e4b17023SJohn Marino #define scalb_optab (&optab_table[OTI_scalb])
505*e4b17023SJohn Marino #define significand_optab (&optab_table[OTI_significand])
506*e4b17023SJohn Marino #define logb_optab (&optab_table[OTI_logb])
507*e4b17023SJohn Marino #define ilogb_optab (&optab_table[OTI_ilogb])
508*e4b17023SJohn Marino #define log_optab (&optab_table[OTI_log])
509*e4b17023SJohn Marino #define log10_optab (&optab_table[OTI_log10])
510*e4b17023SJohn Marino #define log2_optab (&optab_table[OTI_log2])
511*e4b17023SJohn Marino #define log1p_optab (&optab_table[OTI_log1p])
512*e4b17023SJohn Marino #define floor_optab (&optab_table[OTI_floor])
513*e4b17023SJohn Marino #define ceil_optab (&optab_table[OTI_ceil])
514*e4b17023SJohn Marino #define btrunc_optab (&optab_table[OTI_btrunc])
515*e4b17023SJohn Marino #define round_optab (&optab_table[OTI_round])
516*e4b17023SJohn Marino #define nearbyint_optab (&optab_table[OTI_nearbyint])
517*e4b17023SJohn Marino #define rint_optab (&optab_table[OTI_rint])
518*e4b17023SJohn Marino #define tan_optab (&optab_table[OTI_tan])
519*e4b17023SJohn Marino #define atan_optab (&optab_table[OTI_atan])
520*e4b17023SJohn Marino #define copysign_optab (&optab_table[OTI_copysign])
521*e4b17023SJohn Marino #define signbit_optab (&optab_table[OTI_signbit])
522*e4b17023SJohn Marino #define isinf_optab (&optab_table[OTI_isinf])
523*e4b17023SJohn Marino
524*e4b17023SJohn Marino #define cmp_optab (&optab_table[OTI_cmp])
525*e4b17023SJohn Marino #define ucmp_optab (&optab_table[OTI_ucmp])
526*e4b17023SJohn Marino
527*e4b17023SJohn Marino #define eq_optab (&optab_table[OTI_eq])
528*e4b17023SJohn Marino #define ne_optab (&optab_table[OTI_ne])
529*e4b17023SJohn Marino #define gt_optab (&optab_table[OTI_gt])
530*e4b17023SJohn Marino #define ge_optab (&optab_table[OTI_ge])
531*e4b17023SJohn Marino #define lt_optab (&optab_table[OTI_lt])
532*e4b17023SJohn Marino #define le_optab (&optab_table[OTI_le])
533*e4b17023SJohn Marino #define unord_optab (&optab_table[OTI_unord])
534*e4b17023SJohn Marino
535*e4b17023SJohn Marino #define strlen_optab (&optab_table[OTI_strlen])
536*e4b17023SJohn Marino
537*e4b17023SJohn Marino #define cbranch_optab (&optab_table[OTI_cbranch])
538*e4b17023SJohn Marino #define cmov_optab (&optab_table[OTI_cmov])
539*e4b17023SJohn Marino #define cstore_optab (&optab_table[OTI_cstore])
540*e4b17023SJohn Marino #define ctrap_optab (&optab_table[OTI_ctrap])
541*e4b17023SJohn Marino
542*e4b17023SJohn Marino #define push_optab (&optab_table[OTI_push])
543*e4b17023SJohn Marino #define addcc_optab (&optab_table[OTI_addcc])
544*e4b17023SJohn Marino
545*e4b17023SJohn Marino #define reduc_smax_optab (&optab_table[OTI_reduc_smax])
546*e4b17023SJohn Marino #define reduc_umax_optab (&optab_table[OTI_reduc_umax])
547*e4b17023SJohn Marino #define reduc_smin_optab (&optab_table[OTI_reduc_smin])
548*e4b17023SJohn Marino #define reduc_umin_optab (&optab_table[OTI_reduc_umin])
549*e4b17023SJohn Marino #define reduc_splus_optab (&optab_table[OTI_reduc_splus])
550*e4b17023SJohn Marino #define reduc_uplus_optab (&optab_table[OTI_reduc_uplus])
551*e4b17023SJohn Marino
552*e4b17023SJohn Marino #define ssum_widen_optab (&optab_table[OTI_ssum_widen])
553*e4b17023SJohn Marino #define usum_widen_optab (&optab_table[OTI_usum_widen])
554*e4b17023SJohn Marino #define sdot_prod_optab (&optab_table[OTI_sdot_prod])
555*e4b17023SJohn Marino #define udot_prod_optab (&optab_table[OTI_udot_prod])
556*e4b17023SJohn Marino
557*e4b17023SJohn Marino #define vec_set_optab (&optab_table[OTI_vec_set])
558*e4b17023SJohn Marino #define vec_extract_optab (&optab_table[OTI_vec_extract])
559*e4b17023SJohn Marino #define vec_init_optab (&optab_table[OTI_vec_init])
560*e4b17023SJohn Marino #define vec_shl_optab (&optab_table[OTI_vec_shl])
561*e4b17023SJohn Marino #define vec_shr_optab (&optab_table[OTI_vec_shr])
562*e4b17023SJohn Marino #define vec_realign_load_optab (&optab_table[OTI_vec_realign_load])
563*e4b17023SJohn Marino #define vec_widen_umult_hi_optab (&optab_table[OTI_vec_widen_umult_hi])
564*e4b17023SJohn Marino #define vec_widen_umult_lo_optab (&optab_table[OTI_vec_widen_umult_lo])
565*e4b17023SJohn Marino #define vec_widen_smult_hi_optab (&optab_table[OTI_vec_widen_smult_hi])
566*e4b17023SJohn Marino #define vec_widen_smult_lo_optab (&optab_table[OTI_vec_widen_smult_lo])
567*e4b17023SJohn Marino #define vec_widen_ushiftl_hi_optab (&optab_table[OTI_vec_widen_ushiftl_hi])
568*e4b17023SJohn Marino #define vec_widen_ushiftl_lo_optab (&optab_table[OTI_vec_widen_ushiftl_lo])
569*e4b17023SJohn Marino #define vec_widen_sshiftl_hi_optab (&optab_table[OTI_vec_widen_sshiftl_hi])
570*e4b17023SJohn Marino #define vec_widen_sshiftl_lo_optab (&optab_table[OTI_vec_widen_sshiftl_lo])
571*e4b17023SJohn Marino #define vec_unpacks_hi_optab (&optab_table[OTI_vec_unpacks_hi])
572*e4b17023SJohn Marino #define vec_unpacks_lo_optab (&optab_table[OTI_vec_unpacks_lo])
573*e4b17023SJohn Marino #define vec_unpacku_hi_optab (&optab_table[OTI_vec_unpacku_hi])
574*e4b17023SJohn Marino #define vec_unpacku_lo_optab (&optab_table[OTI_vec_unpacku_lo])
575*e4b17023SJohn Marino #define vec_unpacks_float_hi_optab (&optab_table[OTI_vec_unpacks_float_hi])
576*e4b17023SJohn Marino #define vec_unpacks_float_lo_optab (&optab_table[OTI_vec_unpacks_float_lo])
577*e4b17023SJohn Marino #define vec_unpacku_float_hi_optab (&optab_table[OTI_vec_unpacku_float_hi])
578*e4b17023SJohn Marino #define vec_unpacku_float_lo_optab (&optab_table[OTI_vec_unpacku_float_lo])
579*e4b17023SJohn Marino #define vec_pack_trunc_optab (&optab_table[OTI_vec_pack_trunc])
580*e4b17023SJohn Marino #define vec_pack_ssat_optab (&optab_table[OTI_vec_pack_ssat])
581*e4b17023SJohn Marino #define vec_pack_usat_optab (&optab_table[OTI_vec_pack_usat])
582*e4b17023SJohn Marino #define vec_pack_sfix_trunc_optab (&optab_table[OTI_vec_pack_sfix_trunc])
583*e4b17023SJohn Marino #define vec_pack_ufix_trunc_optab (&optab_table[OTI_vec_pack_ufix_trunc])
584*e4b17023SJohn Marino
585*e4b17023SJohn Marino #define powi_optab (&optab_table[OTI_powi])
586*e4b17023SJohn Marino
587*e4b17023SJohn Marino #define sync_compare_and_swap_optab \
588*e4b17023SJohn Marino (&optab_table[(int) OTI_sync_compare_and_swap])
589*e4b17023SJohn Marino #define sync_lock_test_and_set_optab \
590*e4b17023SJohn Marino (&optab_table[(int) OTI_sync_lock_test_and_set])
591*e4b17023SJohn Marino #define sync_old_add_optab (&optab_table[(int) OTI_sync_old_add])
592*e4b17023SJohn Marino #define sync_old_sub_optab (&optab_table[(int) OTI_sync_old_sub])
593*e4b17023SJohn Marino #define sync_old_ior_optab (&optab_table[(int) OTI_sync_old_ior])
594*e4b17023SJohn Marino #define sync_old_and_optab (&optab_table[(int) OTI_sync_old_and])
595*e4b17023SJohn Marino #define sync_old_xor_optab (&optab_table[(int) OTI_sync_old_xor])
596*e4b17023SJohn Marino #define sync_old_nand_optab (&optab_table[(int) OTI_sync_old_nand])
597*e4b17023SJohn Marino #define sync_new_add_optab (&optab_table[(int) OTI_sync_new_add])
598*e4b17023SJohn Marino #define sync_new_sub_optab (&optab_table[(int) OTI_sync_new_sub])
599*e4b17023SJohn Marino #define sync_new_ior_optab (&optab_table[(int) OTI_sync_new_ior])
600*e4b17023SJohn Marino #define sync_new_and_optab (&optab_table[(int) OTI_sync_new_and])
601*e4b17023SJohn Marino #define sync_new_xor_optab (&optab_table[(int) OTI_sync_new_xor])
602*e4b17023SJohn Marino #define sync_new_nand_optab (&optab_table[(int) OTI_sync_new_nand])
603*e4b17023SJohn Marino
604*e4b17023SJohn Marino /* Conversion optabs have their own table and indexes. */
605*e4b17023SJohn Marino enum convert_optab_index
606*e4b17023SJohn Marino {
607*e4b17023SJohn Marino COI_sext,
608*e4b17023SJohn Marino COI_zext,
609*e4b17023SJohn Marino COI_trunc,
610*e4b17023SJohn Marino
611*e4b17023SJohn Marino COI_sfix,
612*e4b17023SJohn Marino COI_ufix,
613*e4b17023SJohn Marino
614*e4b17023SJohn Marino COI_sfixtrunc,
615*e4b17023SJohn Marino COI_ufixtrunc,
616*e4b17023SJohn Marino
617*e4b17023SJohn Marino COI_sfloat,
618*e4b17023SJohn Marino COI_ufloat,
619*e4b17023SJohn Marino
620*e4b17023SJohn Marino COI_lrint,
621*e4b17023SJohn Marino COI_lround,
622*e4b17023SJohn Marino COI_lfloor,
623*e4b17023SJohn Marino COI_lceil,
624*e4b17023SJohn Marino
625*e4b17023SJohn Marino COI_fract,
626*e4b17023SJohn Marino COI_fractuns,
627*e4b17023SJohn Marino COI_satfract,
628*e4b17023SJohn Marino COI_satfractuns,
629*e4b17023SJohn Marino
630*e4b17023SJohn Marino COI_vec_load_lanes,
631*e4b17023SJohn Marino COI_vec_store_lanes,
632*e4b17023SJohn Marino
633*e4b17023SJohn Marino /* Vector conditional operations. */
634*e4b17023SJohn Marino COI_vcond,
635*e4b17023SJohn Marino COI_vcondu,
636*e4b17023SJohn Marino
637*e4b17023SJohn Marino COI_MAX
638*e4b17023SJohn Marino };
639*e4b17023SJohn Marino
640*e4b17023SJohn Marino #define sext_optab (&convert_optab_table[COI_sext])
641*e4b17023SJohn Marino #define zext_optab (&convert_optab_table[COI_zext])
642*e4b17023SJohn Marino #define trunc_optab (&convert_optab_table[COI_trunc])
643*e4b17023SJohn Marino #define sfix_optab (&convert_optab_table[COI_sfix])
644*e4b17023SJohn Marino #define ufix_optab (&convert_optab_table[COI_ufix])
645*e4b17023SJohn Marino #define sfixtrunc_optab (&convert_optab_table[COI_sfixtrunc])
646*e4b17023SJohn Marino #define ufixtrunc_optab (&convert_optab_table[COI_ufixtrunc])
647*e4b17023SJohn Marino #define sfloat_optab (&convert_optab_table[COI_sfloat])
648*e4b17023SJohn Marino #define ufloat_optab (&convert_optab_table[COI_ufloat])
649*e4b17023SJohn Marino #define lrint_optab (&convert_optab_table[COI_lrint])
650*e4b17023SJohn Marino #define lround_optab (&convert_optab_table[COI_lround])
651*e4b17023SJohn Marino #define lfloor_optab (&convert_optab_table[COI_lfloor])
652*e4b17023SJohn Marino #define lceil_optab (&convert_optab_table[COI_lceil])
653*e4b17023SJohn Marino #define fract_optab (&convert_optab_table[COI_fract])
654*e4b17023SJohn Marino #define fractuns_optab (&convert_optab_table[COI_fractuns])
655*e4b17023SJohn Marino #define satfract_optab (&convert_optab_table[COI_satfract])
656*e4b17023SJohn Marino #define satfractuns_optab (&convert_optab_table[COI_satfractuns])
657*e4b17023SJohn Marino #define vec_load_lanes_optab (&convert_optab_table[COI_vec_load_lanes])
658*e4b17023SJohn Marino #define vec_store_lanes_optab (&convert_optab_table[COI_vec_store_lanes])
659*e4b17023SJohn Marino #define vcond_optab (&convert_optab_table[(int) COI_vcond])
660*e4b17023SJohn Marino #define vcondu_optab (&convert_optab_table[(int) COI_vcondu])
661*e4b17023SJohn Marino
662*e4b17023SJohn Marino /* Contains the optab used for each rtx code. */
663*e4b17023SJohn Marino extern optab code_to_optab[NUM_RTX_CODE + 1];
664*e4b17023SJohn Marino
665*e4b17023SJohn Marino
666*e4b17023SJohn Marino typedef rtx (*rtxfun) (rtx);
667*e4b17023SJohn Marino
668*e4b17023SJohn Marino /* Enumerates operations that have a named .md pattern associated
669*e4b17023SJohn Marino with them, but which are not implemented as library functions. */
670*e4b17023SJohn Marino enum direct_optab_index
671*e4b17023SJohn Marino {
672*e4b17023SJohn Marino #ifdef HAVE_conditional_move
673*e4b17023SJohn Marino /* Conditional move operations. */
674*e4b17023SJohn Marino DOI_movcc,
675*e4b17023SJohn Marino #endif
676*e4b17023SJohn Marino
677*e4b17023SJohn Marino /* Operations that use a scratch register to perform input and output
678*e4b17023SJohn Marino reloads of special objects. */
679*e4b17023SJohn Marino DOI_reload_in,
680*e4b17023SJohn Marino DOI_reload_out,
681*e4b17023SJohn Marino
682*e4b17023SJohn Marino /* Block move operation. */
683*e4b17023SJohn Marino DOI_movmem,
684*e4b17023SJohn Marino
685*e4b17023SJohn Marino /* Block set operation. */
686*e4b17023SJohn Marino DOI_setmem,
687*e4b17023SJohn Marino
688*e4b17023SJohn Marino /* Various types of block compare operation. */
689*e4b17023SJohn Marino DOI_cmpstr,
690*e4b17023SJohn Marino DOI_cmpstrn,
691*e4b17023SJohn Marino DOI_cmpmem,
692*e4b17023SJohn Marino
693*e4b17023SJohn Marino /* Atomic clear with release semantics. */
694*e4b17023SJohn Marino DOI_sync_lock_release,
695*e4b17023SJohn Marino
696*e4b17023SJohn Marino /* Atomic operation with no resulting value. */
697*e4b17023SJohn Marino DOI_sync_add,
698*e4b17023SJohn Marino DOI_sync_sub,
699*e4b17023SJohn Marino DOI_sync_ior,
700*e4b17023SJohn Marino DOI_sync_and,
701*e4b17023SJohn Marino DOI_sync_xor,
702*e4b17023SJohn Marino DOI_sync_nand,
703*e4b17023SJohn Marino
704*e4b17023SJohn Marino /* Atomic operations with memory model parameters. */
705*e4b17023SJohn Marino DOI_atomic_exchange,
706*e4b17023SJohn Marino DOI_atomic_compare_and_swap,
707*e4b17023SJohn Marino DOI_atomic_load,
708*e4b17023SJohn Marino DOI_atomic_store,
709*e4b17023SJohn Marino DOI_atomic_add_fetch,
710*e4b17023SJohn Marino DOI_atomic_sub_fetch,
711*e4b17023SJohn Marino DOI_atomic_and_fetch,
712*e4b17023SJohn Marino DOI_atomic_nand_fetch,
713*e4b17023SJohn Marino DOI_atomic_xor_fetch,
714*e4b17023SJohn Marino DOI_atomic_or_fetch,
715*e4b17023SJohn Marino DOI_atomic_fetch_add,
716*e4b17023SJohn Marino DOI_atomic_fetch_sub,
717*e4b17023SJohn Marino DOI_atomic_fetch_and,
718*e4b17023SJohn Marino DOI_atomic_fetch_nand,
719*e4b17023SJohn Marino DOI_atomic_fetch_xor,
720*e4b17023SJohn Marino DOI_atomic_fetch_or,
721*e4b17023SJohn Marino DOI_atomic_add,
722*e4b17023SJohn Marino DOI_atomic_sub,
723*e4b17023SJohn Marino DOI_atomic_and,
724*e4b17023SJohn Marino DOI_atomic_nand,
725*e4b17023SJohn Marino DOI_atomic_xor,
726*e4b17023SJohn Marino DOI_atomic_or,
727*e4b17023SJohn Marino DOI_atomic_always_lock_free,
728*e4b17023SJohn Marino DOI_atomic_is_lock_free,
729*e4b17023SJohn Marino DOI_atomic_thread_fence,
730*e4b17023SJohn Marino DOI_atomic_signal_fence,
731*e4b17023SJohn Marino
732*e4b17023SJohn Marino /* Vector permutation. */
733*e4b17023SJohn Marino DOI_vec_perm,
734*e4b17023SJohn Marino DOI_vec_perm_const,
735*e4b17023SJohn Marino
736*e4b17023SJohn Marino DOI_MAX
737*e4b17023SJohn Marino };
738*e4b17023SJohn Marino
739*e4b17023SJohn Marino /* A structure that says which insn should be used to perform an operation
740*e4b17023SJohn Marino in a particular mode. */
741*e4b17023SJohn Marino struct direct_optab_d
742*e4b17023SJohn Marino {
743*e4b17023SJohn Marino struct optab_handlers handlers[NUM_MACHINE_MODES];
744*e4b17023SJohn Marino };
745*e4b17023SJohn Marino typedef struct direct_optab_d *direct_optab;
746*e4b17023SJohn Marino
747*e4b17023SJohn Marino #ifdef HAVE_conditional_move
748*e4b17023SJohn Marino #define movcc_optab (&direct_optab_table[(int) DOI_movcc])
749*e4b17023SJohn Marino #endif
750*e4b17023SJohn Marino #define reload_in_optab (&direct_optab_table[(int) DOI_reload_in])
751*e4b17023SJohn Marino #define reload_out_optab (&direct_optab_table[(int) DOI_reload_out])
752*e4b17023SJohn Marino #define movmem_optab (&direct_optab_table[(int) DOI_movmem])
753*e4b17023SJohn Marino #define setmem_optab (&direct_optab_table[(int) DOI_setmem])
754*e4b17023SJohn Marino #define cmpstr_optab (&direct_optab_table[(int) DOI_cmpstr])
755*e4b17023SJohn Marino #define cmpstrn_optab (&direct_optab_table[(int) DOI_cmpstrn])
756*e4b17023SJohn Marino #define cmpmem_optab (&direct_optab_table[(int) DOI_cmpmem])
757*e4b17023SJohn Marino #define sync_lock_release_optab \
758*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_sync_lock_release])
759*e4b17023SJohn Marino #define sync_add_optab (&direct_optab_table[(int) DOI_sync_add])
760*e4b17023SJohn Marino #define sync_sub_optab (&direct_optab_table[(int) DOI_sync_sub])
761*e4b17023SJohn Marino #define sync_ior_optab (&direct_optab_table[(int) DOI_sync_ior])
762*e4b17023SJohn Marino #define sync_and_optab (&direct_optab_table[(int) DOI_sync_and])
763*e4b17023SJohn Marino #define sync_xor_optab (&direct_optab_table[(int) DOI_sync_xor])
764*e4b17023SJohn Marino #define sync_nand_optab (&direct_optab_table[(int) DOI_sync_nand])
765*e4b17023SJohn Marino
766*e4b17023SJohn Marino #define atomic_exchange_optab \
767*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_exchange])
768*e4b17023SJohn Marino #define atomic_compare_and_swap_optab \
769*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_compare_and_swap])
770*e4b17023SJohn Marino #define atomic_load_optab \
771*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_load])
772*e4b17023SJohn Marino #define atomic_store_optab \
773*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_store])
774*e4b17023SJohn Marino #define atomic_add_fetch_optab \
775*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_add_fetch])
776*e4b17023SJohn Marino #define atomic_sub_fetch_optab \
777*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_sub_fetch])
778*e4b17023SJohn Marino #define atomic_and_fetch_optab \
779*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_and_fetch])
780*e4b17023SJohn Marino #define atomic_nand_fetch_optab \
781*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_nand_fetch])
782*e4b17023SJohn Marino #define atomic_xor_fetch_optab \
783*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_xor_fetch])
784*e4b17023SJohn Marino #define atomic_or_fetch_optab \
785*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_or_fetch])
786*e4b17023SJohn Marino #define atomic_fetch_add_optab \
787*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_fetch_add])
788*e4b17023SJohn Marino #define atomic_fetch_sub_optab \
789*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_fetch_sub])
790*e4b17023SJohn Marino #define atomic_fetch_and_optab \
791*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_fetch_and])
792*e4b17023SJohn Marino #define atomic_fetch_nand_optab \
793*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_fetch_nand])
794*e4b17023SJohn Marino #define atomic_fetch_xor_optab \
795*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_fetch_xor])
796*e4b17023SJohn Marino #define atomic_fetch_or_optab \
797*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_fetch_or])
798*e4b17023SJohn Marino #define atomic_add_optab \
799*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_add])
800*e4b17023SJohn Marino #define atomic_sub_optab \
801*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_sub])
802*e4b17023SJohn Marino #define atomic_and_optab \
803*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_and])
804*e4b17023SJohn Marino #define atomic_nand_optab \
805*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_nand])
806*e4b17023SJohn Marino #define atomic_xor_optab \
807*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_xor])
808*e4b17023SJohn Marino #define atomic_or_optab \
809*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_or])
810*e4b17023SJohn Marino #define atomic_always_lock_free_optab \
811*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_always_lock_free])
812*e4b17023SJohn Marino #define atomic_is_lock_free_optab \
813*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_is_lock_free])
814*e4b17023SJohn Marino #define atomic_thread_fence_optab \
815*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_thread_fence])
816*e4b17023SJohn Marino #define atomic_signal_fence_optab \
817*e4b17023SJohn Marino (&direct_optab_table[(int) DOI_atomic_signal_fence])
818*e4b17023SJohn Marino
819*e4b17023SJohn Marino #define vec_perm_optab (&direct_optab_table[DOI_vec_perm])
820*e4b17023SJohn Marino #define vec_perm_const_optab (&direct_optab_table[(int) DOI_vec_perm_const])
821*e4b17023SJohn Marino
822*e4b17023SJohn Marino /* Target-dependent globals. */
823*e4b17023SJohn Marino struct target_optabs {
824*e4b17023SJohn Marino /* Tables of patterns that may have an associated libcall. */
825*e4b17023SJohn Marino struct optab_d x_optab_table[(int) OTI_MAX];
826*e4b17023SJohn Marino
827*e4b17023SJohn Marino /* Tables of patterns for converting one mode to another. */
828*e4b17023SJohn Marino struct convert_optab_d x_convert_optab_table[(int) COI_MAX];
829*e4b17023SJohn Marino
830*e4b17023SJohn Marino /* Tables of patterns for direct optabs (i.e. those which cannot be
831*e4b17023SJohn Marino implemented using a libcall). */
832*e4b17023SJohn Marino struct direct_optab_d x_direct_optab_table[(int) DOI_MAX];
833*e4b17023SJohn Marino };
834*e4b17023SJohn Marino
835*e4b17023SJohn Marino extern struct target_optabs default_target_optabs;
836*e4b17023SJohn Marino #if SWITCHABLE_TARGET
837*e4b17023SJohn Marino extern struct target_optabs *this_target_optabs;
838*e4b17023SJohn Marino #else
839*e4b17023SJohn Marino #define this_target_optabs (&default_target_optabs)
840*e4b17023SJohn Marino #endif
841*e4b17023SJohn Marino
842*e4b17023SJohn Marino #define optab_table \
843*e4b17023SJohn Marino (this_target_optabs->x_optab_table)
844*e4b17023SJohn Marino #define convert_optab_table \
845*e4b17023SJohn Marino (this_target_optabs->x_convert_optab_table)
846*e4b17023SJohn Marino #define direct_optab_table \
847*e4b17023SJohn Marino (this_target_optabs->x_direct_optab_table)
848*e4b17023SJohn Marino
849*e4b17023SJohn Marino /* Define functions given in optabs.c. */
850*e4b17023SJohn Marino
851*e4b17023SJohn Marino extern rtx expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
852*e4b17023SJohn Marino rtx target, int unsignedp);
853*e4b17023SJohn Marino
854*e4b17023SJohn Marino extern rtx expand_ternary_op (enum machine_mode mode, optab ternary_optab,
855*e4b17023SJohn Marino rtx op0, rtx op1, rtx op2, rtx target,
856*e4b17023SJohn Marino int unsignedp);
857*e4b17023SJohn Marino
858*e4b17023SJohn Marino /* Expand a binary operation given optab and rtx operands. */
859*e4b17023SJohn Marino extern rtx expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int,
860*e4b17023SJohn Marino enum optab_methods);
861*e4b17023SJohn Marino
862*e4b17023SJohn Marino extern rtx simplify_expand_binop (enum machine_mode mode, optab binoptab,
863*e4b17023SJohn Marino rtx op0, rtx op1, rtx target, int unsignedp,
864*e4b17023SJohn Marino enum optab_methods methods);
865*e4b17023SJohn Marino
866*e4b17023SJohn Marino extern bool force_expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int,
867*e4b17023SJohn Marino enum optab_methods);
868*e4b17023SJohn Marino
869*e4b17023SJohn Marino /* Expand a binary operation with both signed and unsigned forms. */
870*e4b17023SJohn Marino extern rtx sign_expand_binop (enum machine_mode, optab, optab, rtx, rtx,
871*e4b17023SJohn Marino rtx, int, enum optab_methods);
872*e4b17023SJohn Marino
873*e4b17023SJohn Marino /* Generate code to perform an operation on one operand with two results. */
874*e4b17023SJohn Marino extern int expand_twoval_unop (optab, rtx, rtx, rtx, int);
875*e4b17023SJohn Marino
876*e4b17023SJohn Marino /* Generate code to perform an operation on two operands with two results. */
877*e4b17023SJohn Marino extern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int);
878*e4b17023SJohn Marino
879*e4b17023SJohn Marino /* Generate code to perform an operation on two operands with two
880*e4b17023SJohn Marino results, using a library function. */
881*e4b17023SJohn Marino extern bool expand_twoval_binop_libfunc (optab, rtx, rtx, rtx, rtx,
882*e4b17023SJohn Marino enum rtx_code);
883*e4b17023SJohn Marino
884*e4b17023SJohn Marino /* Expand a unary arithmetic operation given optab rtx operand. */
885*e4b17023SJohn Marino extern rtx expand_unop (enum machine_mode, optab, rtx, rtx, int);
886*e4b17023SJohn Marino
887*e4b17023SJohn Marino /* Expand the absolute value operation. */
888*e4b17023SJohn Marino extern rtx expand_abs_nojump (enum machine_mode, rtx, rtx, int);
889*e4b17023SJohn Marino extern rtx expand_abs (enum machine_mode, rtx, rtx, int, int);
890*e4b17023SJohn Marino
891*e4b17023SJohn Marino /* Expand the one's complement absolute value operation. */
892*e4b17023SJohn Marino extern rtx expand_one_cmpl_abs_nojump (enum machine_mode, rtx, rtx);
893*e4b17023SJohn Marino
894*e4b17023SJohn Marino /* Expand the copysign operation. */
895*e4b17023SJohn Marino extern rtx expand_copysign (rtx, rtx, rtx);
896*e4b17023SJohn Marino
897*e4b17023SJohn Marino /* Generate an instruction with a given INSN_CODE with an output and
898*e4b17023SJohn Marino an input. */
899*e4b17023SJohn Marino extern void emit_unop_insn (enum insn_code, rtx, rtx, enum rtx_code);
900*e4b17023SJohn Marino extern bool maybe_emit_unop_insn (enum insn_code, rtx, rtx, enum rtx_code);
901*e4b17023SJohn Marino
902*e4b17023SJohn Marino /* Find a widening optab even if it doesn't widen as much as we want. */
903*e4b17023SJohn Marino #define find_widening_optab_handler(A,B,C,D) \
904*e4b17023SJohn Marino find_widening_optab_handler_and_mode (A, B, C, D, NULL)
905*e4b17023SJohn Marino extern enum insn_code find_widening_optab_handler_and_mode (optab,
906*e4b17023SJohn Marino enum machine_mode,
907*e4b17023SJohn Marino enum machine_mode,
908*e4b17023SJohn Marino int,
909*e4b17023SJohn Marino enum machine_mode *);
910*e4b17023SJohn Marino
911*e4b17023SJohn Marino /* An extra flag to control optab_for_tree_code's behavior. This is needed to
912*e4b17023SJohn Marino distinguish between machines with a vector shift that takes a scalar for the
913*e4b17023SJohn Marino shift amount vs. machines that take a vector for the shift amount. */
914*e4b17023SJohn Marino enum optab_subtype
915*e4b17023SJohn Marino {
916*e4b17023SJohn Marino optab_default,
917*e4b17023SJohn Marino optab_scalar,
918*e4b17023SJohn Marino optab_vector
919*e4b17023SJohn Marino };
920*e4b17023SJohn Marino
921*e4b17023SJohn Marino /* Return the optab used for computing the given operation on the type given by
922*e4b17023SJohn Marino the second argument. The third argument distinguishes between the types of
923*e4b17023SJohn Marino vector shifts and rotates */
924*e4b17023SJohn Marino extern optab optab_for_tree_code (enum tree_code, const_tree, enum optab_subtype);
925*e4b17023SJohn Marino
926*e4b17023SJohn Marino /* The various uses that a comparison can have; used by can_compare_p:
927*e4b17023SJohn Marino jumps, conditional moves, store flag operations. */
928*e4b17023SJohn Marino enum can_compare_purpose
929*e4b17023SJohn Marino {
930*e4b17023SJohn Marino ccp_jump,
931*e4b17023SJohn Marino ccp_cmov,
932*e4b17023SJohn Marino ccp_store_flag
933*e4b17023SJohn Marino };
934*e4b17023SJohn Marino
935*e4b17023SJohn Marino /* Nonzero if a compare of mode MODE can be done straightforwardly
936*e4b17023SJohn Marino (without splitting it into pieces). */
937*e4b17023SJohn Marino extern int can_compare_p (enum rtx_code, enum machine_mode,
938*e4b17023SJohn Marino enum can_compare_purpose);
939*e4b17023SJohn Marino
940*e4b17023SJohn Marino /* Return the INSN_CODE to use for an extend operation. */
941*e4b17023SJohn Marino extern enum insn_code can_extend_p (enum machine_mode, enum machine_mode, int);
942*e4b17023SJohn Marino
943*e4b17023SJohn Marino /* Generate the body of an insn to extend Y (with mode MFROM)
944*e4b17023SJohn Marino into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
945*e4b17023SJohn Marino extern rtx gen_extend_insn (rtx, rtx, enum machine_mode,
946*e4b17023SJohn Marino enum machine_mode, int);
947*e4b17023SJohn Marino
948*e4b17023SJohn Marino /* Call this to reset the function entry for one optab. */
949*e4b17023SJohn Marino extern void set_optab_libfunc (optab, enum machine_mode, const char *);
950*e4b17023SJohn Marino extern void set_conv_libfunc (convert_optab, enum machine_mode,
951*e4b17023SJohn Marino enum machine_mode, const char *);
952*e4b17023SJohn Marino
953*e4b17023SJohn Marino /* Call this to install all of the __sync libcalls up to size MAX. */
954*e4b17023SJohn Marino extern void init_sync_libfuncs (int max);
955*e4b17023SJohn Marino
956*e4b17023SJohn Marino /* Generate code for a FIXED_CONVERT_EXPR. */
957*e4b17023SJohn Marino extern void expand_fixed_convert (rtx, rtx, int, int);
958*e4b17023SJohn Marino
959*e4b17023SJohn Marino /* Generate code for a FLOAT_EXPR. */
960*e4b17023SJohn Marino extern void expand_float (rtx, rtx, int);
961*e4b17023SJohn Marino
962*e4b17023SJohn Marino /* Return the insn_code for a FLOAT_EXPR. */
963*e4b17023SJohn Marino enum insn_code can_float_p (enum machine_mode, enum machine_mode, int);
964*e4b17023SJohn Marino
965*e4b17023SJohn Marino /* Return true if there is an inline compare and swap pattern. */
966*e4b17023SJohn Marino extern bool can_compare_and_swap_p (enum machine_mode, bool);
967*e4b17023SJohn Marino
968*e4b17023SJohn Marino /* Return true if there is an inline atomic exchange pattern. */
969*e4b17023SJohn Marino extern bool can_atomic_exchange_p (enum machine_mode, bool);
970*e4b17023SJohn Marino
971*e4b17023SJohn Marino /* Generate code for a compare and swap. */
972*e4b17023SJohn Marino extern bool expand_atomic_compare_and_swap (rtx *, rtx *, rtx, rtx, rtx, bool,
973*e4b17023SJohn Marino enum memmodel, enum memmodel);
974*e4b17023SJohn Marino
975*e4b17023SJohn Marino /* Generate memory barriers. */
976*e4b17023SJohn Marino extern void expand_mem_thread_fence (enum memmodel);
977*e4b17023SJohn Marino extern void expand_mem_signal_fence (enum memmodel);
978*e4b17023SJohn Marino
979*e4b17023SJohn Marino /* Check whether an operation represented by the code CODE is a
980*e4b17023SJohn Marino convert operation that is supported by the target platform in
981*e4b17023SJohn Marino vector form */
982*e4b17023SJohn Marino bool supportable_convert_operation (enum tree_code, tree, tree, tree *,
983*e4b17023SJohn Marino enum tree_code *);
984*e4b17023SJohn Marino
985*e4b17023SJohn Marino /* Generate code for a FIX_EXPR. */
986*e4b17023SJohn Marino extern void expand_fix (rtx, rtx, int);
987*e4b17023SJohn Marino
988*e4b17023SJohn Marino /* Generate code for float to integral conversion. */
989*e4b17023SJohn Marino extern bool expand_sfix_optab (rtx, rtx, convert_optab);
990*e4b17023SJohn Marino
991*e4b17023SJohn Marino /* Generate code for a widening multiply. */
992*e4b17023SJohn Marino extern rtx expand_widening_mult (enum machine_mode, rtx, rtx, rtx, int, optab);
993*e4b17023SJohn Marino
994*e4b17023SJohn Marino /* Return tree if target supports vector operations for COND_EXPR. */
995*e4b17023SJohn Marino bool expand_vec_cond_expr_p (tree, tree);
996*e4b17023SJohn Marino
997*e4b17023SJohn Marino /* Generate code for VEC_COND_EXPR. */
998*e4b17023SJohn Marino extern rtx expand_vec_cond_expr (tree, tree, tree, tree, rtx);
999*e4b17023SJohn Marino /* Generate code for VEC_LSHIFT_EXPR and VEC_RSHIFT_EXPR. */
1000*e4b17023SJohn Marino extern rtx expand_vec_shift_expr (sepops, rtx);
1001*e4b17023SJohn Marino
1002*e4b17023SJohn Marino /* Return tree if target supports vector operations for VEC_PERM_EXPR. */
1003*e4b17023SJohn Marino extern bool can_vec_perm_p (enum machine_mode, bool, const unsigned char *);
1004*e4b17023SJohn Marino
1005*e4b17023SJohn Marino /* Generate code for VEC_PERM_EXPR. */
1006*e4b17023SJohn Marino extern rtx expand_vec_perm (enum machine_mode, rtx, rtx, rtx, rtx);
1007*e4b17023SJohn Marino
1008*e4b17023SJohn Marino /* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing
1009*e4b17023SJohn Marino if the target does not have such an insn. */
1010*e4b17023SJohn Marino
1011*e4b17023SJohn Marino static inline enum insn_code
optab_handler(optab op,enum machine_mode mode)1012*e4b17023SJohn Marino optab_handler (optab op, enum machine_mode mode)
1013*e4b17023SJohn Marino {
1014*e4b17023SJohn Marino return (enum insn_code) (op->handlers[(int) mode].insn_code
1015*e4b17023SJohn Marino + (int) CODE_FOR_nothing);
1016*e4b17023SJohn Marino }
1017*e4b17023SJohn Marino
1018*e4b17023SJohn Marino /* Like optab_handler, but for widening_operations that have a TO_MODE and
1019*e4b17023SJohn Marino a FROM_MODE. */
1020*e4b17023SJohn Marino
1021*e4b17023SJohn Marino static inline enum insn_code
widening_optab_handler(optab op,enum machine_mode to_mode,enum machine_mode from_mode)1022*e4b17023SJohn Marino widening_optab_handler (optab op, enum machine_mode to_mode,
1023*e4b17023SJohn Marino enum machine_mode from_mode)
1024*e4b17023SJohn Marino {
1025*e4b17023SJohn Marino if (to_mode == from_mode || from_mode == VOIDmode)
1026*e4b17023SJohn Marino return optab_handler (op, to_mode);
1027*e4b17023SJohn Marino
1028*e4b17023SJohn Marino if (op->widening)
1029*e4b17023SJohn Marino return (enum insn_code) (op->widening->handlers[(int) to_mode][(int) from_mode].insn_code
1030*e4b17023SJohn Marino + (int) CODE_FOR_nothing);
1031*e4b17023SJohn Marino
1032*e4b17023SJohn Marino return CODE_FOR_nothing;
1033*e4b17023SJohn Marino }
1034*e4b17023SJohn Marino
1035*e4b17023SJohn Marino /* Record that insn CODE should be used to implement mode MODE of OP. */
1036*e4b17023SJohn Marino
1037*e4b17023SJohn Marino static inline void
set_optab_handler(optab op,enum machine_mode mode,enum insn_code code)1038*e4b17023SJohn Marino set_optab_handler (optab op, enum machine_mode mode, enum insn_code code)
1039*e4b17023SJohn Marino {
1040*e4b17023SJohn Marino op->handlers[(int) mode].insn_code = (int) code - (int) CODE_FOR_nothing;
1041*e4b17023SJohn Marino }
1042*e4b17023SJohn Marino
1043*e4b17023SJohn Marino /* Like set_optab_handler, but for widening operations that have a TO_MODE
1044*e4b17023SJohn Marino and a FROM_MODE. */
1045*e4b17023SJohn Marino
1046*e4b17023SJohn Marino static inline void
set_widening_optab_handler(optab op,enum machine_mode to_mode,enum machine_mode from_mode,enum insn_code code)1047*e4b17023SJohn Marino set_widening_optab_handler (optab op, enum machine_mode to_mode,
1048*e4b17023SJohn Marino enum machine_mode from_mode, enum insn_code code)
1049*e4b17023SJohn Marino {
1050*e4b17023SJohn Marino if (to_mode == from_mode)
1051*e4b17023SJohn Marino set_optab_handler (op, to_mode, code);
1052*e4b17023SJohn Marino else
1053*e4b17023SJohn Marino {
1054*e4b17023SJohn Marino if (op->widening == NULL)
1055*e4b17023SJohn Marino op->widening = (struct widening_optab_handlers *)
1056*e4b17023SJohn Marino xcalloc (1, sizeof (struct widening_optab_handlers));
1057*e4b17023SJohn Marino
1058*e4b17023SJohn Marino op->widening->handlers[(int) to_mode][(int) from_mode].insn_code
1059*e4b17023SJohn Marino = (int) code - (int) CODE_FOR_nothing;
1060*e4b17023SJohn Marino }
1061*e4b17023SJohn Marino }
1062*e4b17023SJohn Marino
1063*e4b17023SJohn Marino /* Return the insn used to perform conversion OP from mode FROM_MODE
1064*e4b17023SJohn Marino to mode TO_MODE; return CODE_FOR_nothing if the target does not have
1065*e4b17023SJohn Marino such an insn. */
1066*e4b17023SJohn Marino
1067*e4b17023SJohn Marino static inline enum insn_code
convert_optab_handler(convert_optab op,enum machine_mode to_mode,enum machine_mode from_mode)1068*e4b17023SJohn Marino convert_optab_handler (convert_optab op, enum machine_mode to_mode,
1069*e4b17023SJohn Marino enum machine_mode from_mode)
1070*e4b17023SJohn Marino {
1071*e4b17023SJohn Marino return ((enum insn_code)
1072*e4b17023SJohn Marino (op->handlers[(int) to_mode][(int) from_mode].insn_code
1073*e4b17023SJohn Marino + (int) CODE_FOR_nothing));
1074*e4b17023SJohn Marino }
1075*e4b17023SJohn Marino
1076*e4b17023SJohn Marino /* Record that insn CODE should be used to perform conversion OP
1077*e4b17023SJohn Marino from mode FROM_MODE to mode TO_MODE. */
1078*e4b17023SJohn Marino
1079*e4b17023SJohn Marino static inline void
set_convert_optab_handler(convert_optab op,enum machine_mode to_mode,enum machine_mode from_mode,enum insn_code code)1080*e4b17023SJohn Marino set_convert_optab_handler (convert_optab op, enum machine_mode to_mode,
1081*e4b17023SJohn Marino enum machine_mode from_mode, enum insn_code code)
1082*e4b17023SJohn Marino {
1083*e4b17023SJohn Marino op->handlers[(int) to_mode][(int) from_mode].insn_code
1084*e4b17023SJohn Marino = (int) code - (int) CODE_FOR_nothing;
1085*e4b17023SJohn Marino }
1086*e4b17023SJohn Marino
1087*e4b17023SJohn Marino /* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing
1088*e4b17023SJohn Marino if the target does not have such an insn. */
1089*e4b17023SJohn Marino
1090*e4b17023SJohn Marino static inline enum insn_code
direct_optab_handler(direct_optab op,enum machine_mode mode)1091*e4b17023SJohn Marino direct_optab_handler (direct_optab op, enum machine_mode mode)
1092*e4b17023SJohn Marino {
1093*e4b17023SJohn Marino return (enum insn_code) (op->handlers[(int) mode].insn_code
1094*e4b17023SJohn Marino + (int) CODE_FOR_nothing);
1095*e4b17023SJohn Marino }
1096*e4b17023SJohn Marino
1097*e4b17023SJohn Marino /* Record that insn CODE should be used to implement mode MODE of OP. */
1098*e4b17023SJohn Marino
1099*e4b17023SJohn Marino static inline void
set_direct_optab_handler(direct_optab op,enum machine_mode mode,enum insn_code code)1100*e4b17023SJohn Marino set_direct_optab_handler (direct_optab op, enum machine_mode mode,
1101*e4b17023SJohn Marino enum insn_code code)
1102*e4b17023SJohn Marino {
1103*e4b17023SJohn Marino op->handlers[(int) mode].insn_code = (int) code - (int) CODE_FOR_nothing;
1104*e4b17023SJohn Marino }
1105*e4b17023SJohn Marino
1106*e4b17023SJohn Marino extern rtx optab_libfunc (optab optab, enum machine_mode mode);
1107*e4b17023SJohn Marino extern rtx convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
1108*e4b17023SJohn Marino enum machine_mode mode2);
1109*e4b17023SJohn Marino
1110*e4b17023SJohn Marino extern bool insn_operand_matches (enum insn_code icode, unsigned int opno,
1111*e4b17023SJohn Marino rtx operand);
1112*e4b17023SJohn Marino
1113*e4b17023SJohn Marino /* Describes the type of an expand_operand. Each value is associated
1114*e4b17023SJohn Marino with a create_*_operand function; see the comments above those
1115*e4b17023SJohn Marino functions for details. */
1116*e4b17023SJohn Marino enum expand_operand_type {
1117*e4b17023SJohn Marino EXPAND_FIXED,
1118*e4b17023SJohn Marino EXPAND_OUTPUT,
1119*e4b17023SJohn Marino EXPAND_INPUT,
1120*e4b17023SJohn Marino EXPAND_CONVERT_TO,
1121*e4b17023SJohn Marino EXPAND_CONVERT_FROM,
1122*e4b17023SJohn Marino EXPAND_ADDRESS,
1123*e4b17023SJohn Marino EXPAND_INTEGER
1124*e4b17023SJohn Marino };
1125*e4b17023SJohn Marino
1126*e4b17023SJohn Marino /* Information about an operand for instruction expansion. */
1127*e4b17023SJohn Marino struct expand_operand {
1128*e4b17023SJohn Marino /* The type of operand. */
1129*e4b17023SJohn Marino ENUM_BITFIELD (expand_operand_type) type : 8;
1130*e4b17023SJohn Marino
1131*e4b17023SJohn Marino /* True if any conversion should treat VALUE as being unsigned
1132*e4b17023SJohn Marino rather than signed. Only meaningful for certain types. */
1133*e4b17023SJohn Marino unsigned int unsigned_p : 1;
1134*e4b17023SJohn Marino
1135*e4b17023SJohn Marino /* Unused; available for future use. */
1136*e4b17023SJohn Marino unsigned int unused : 7;
1137*e4b17023SJohn Marino
1138*e4b17023SJohn Marino /* The mode passed to the convert_*_operand function. It has a
1139*e4b17023SJohn Marino type-dependent meaning. */
1140*e4b17023SJohn Marino ENUM_BITFIELD (machine_mode) mode : 16;
1141*e4b17023SJohn Marino
1142*e4b17023SJohn Marino /* The value of the operand. */
1143*e4b17023SJohn Marino rtx value;
1144*e4b17023SJohn Marino };
1145*e4b17023SJohn Marino
1146*e4b17023SJohn Marino /* Initialize OP with the given fields. Initialise the other fields
1147*e4b17023SJohn Marino to their default values. */
1148*e4b17023SJohn Marino
1149*e4b17023SJohn Marino static inline void
create_expand_operand(struct expand_operand * op,enum expand_operand_type type,rtx value,enum machine_mode mode,bool unsigned_p)1150*e4b17023SJohn Marino create_expand_operand (struct expand_operand *op,
1151*e4b17023SJohn Marino enum expand_operand_type type,
1152*e4b17023SJohn Marino rtx value, enum machine_mode mode,
1153*e4b17023SJohn Marino bool unsigned_p)
1154*e4b17023SJohn Marino {
1155*e4b17023SJohn Marino op->type = type;
1156*e4b17023SJohn Marino op->unsigned_p = unsigned_p;
1157*e4b17023SJohn Marino op->unused = 0;
1158*e4b17023SJohn Marino op->mode = mode;
1159*e4b17023SJohn Marino op->value = value;
1160*e4b17023SJohn Marino }
1161*e4b17023SJohn Marino
1162*e4b17023SJohn Marino /* Make OP describe an operand that must use rtx X, even if X is volatile. */
1163*e4b17023SJohn Marino
1164*e4b17023SJohn Marino static inline void
create_fixed_operand(struct expand_operand * op,rtx x)1165*e4b17023SJohn Marino create_fixed_operand (struct expand_operand *op, rtx x)
1166*e4b17023SJohn Marino {
1167*e4b17023SJohn Marino create_expand_operand (op, EXPAND_FIXED, x, VOIDmode, false);
1168*e4b17023SJohn Marino }
1169*e4b17023SJohn Marino
1170*e4b17023SJohn Marino /* Make OP describe an output operand that must have mode MODE.
1171*e4b17023SJohn Marino X, if nonnull, is a suggestion for where the output should be stored.
1172*e4b17023SJohn Marino It is OK for VALUE to be inconsistent with MODE, although it will just
1173*e4b17023SJohn Marino be ignored in that case. */
1174*e4b17023SJohn Marino
1175*e4b17023SJohn Marino static inline void
create_output_operand(struct expand_operand * op,rtx x,enum machine_mode mode)1176*e4b17023SJohn Marino create_output_operand (struct expand_operand *op, rtx x,
1177*e4b17023SJohn Marino enum machine_mode mode)
1178*e4b17023SJohn Marino {
1179*e4b17023SJohn Marino create_expand_operand (op, EXPAND_OUTPUT, x, mode, false);
1180*e4b17023SJohn Marino }
1181*e4b17023SJohn Marino
1182*e4b17023SJohn Marino /* Make OP describe an input operand that must have mode MODE and
1183*e4b17023SJohn Marino value VALUE; MODE cannot be VOIDmode. The backend may request that
1184*e4b17023SJohn Marino VALUE be copied into a different kind of rtx before being passed
1185*e4b17023SJohn Marino as an operand. */
1186*e4b17023SJohn Marino
1187*e4b17023SJohn Marino static inline void
create_input_operand(struct expand_operand * op,rtx value,enum machine_mode mode)1188*e4b17023SJohn Marino create_input_operand (struct expand_operand *op, rtx value,
1189*e4b17023SJohn Marino enum machine_mode mode)
1190*e4b17023SJohn Marino {
1191*e4b17023SJohn Marino create_expand_operand (op, EXPAND_INPUT, value, mode, false);
1192*e4b17023SJohn Marino }
1193*e4b17023SJohn Marino
1194*e4b17023SJohn Marino /* Like create_input_operand, except that VALUE must first be converted
1195*e4b17023SJohn Marino to mode MODE. UNSIGNED_P says whether VALUE is unsigned. */
1196*e4b17023SJohn Marino
1197*e4b17023SJohn Marino static inline void
create_convert_operand_to(struct expand_operand * op,rtx value,enum machine_mode mode,bool unsigned_p)1198*e4b17023SJohn Marino create_convert_operand_to (struct expand_operand *op, rtx value,
1199*e4b17023SJohn Marino enum machine_mode mode, bool unsigned_p)
1200*e4b17023SJohn Marino {
1201*e4b17023SJohn Marino create_expand_operand (op, EXPAND_CONVERT_TO, value, mode, unsigned_p);
1202*e4b17023SJohn Marino }
1203*e4b17023SJohn Marino
1204*e4b17023SJohn Marino /* Make OP describe an input operand that should have the same value
1205*e4b17023SJohn Marino as VALUE, after any mode conversion that the backend might request.
1206*e4b17023SJohn Marino If VALUE is a CONST_INT, it should be treated as having mode MODE.
1207*e4b17023SJohn Marino UNSIGNED_P says whether VALUE is unsigned. */
1208*e4b17023SJohn Marino
1209*e4b17023SJohn Marino static inline void
create_convert_operand_from(struct expand_operand * op,rtx value,enum machine_mode mode,bool unsigned_p)1210*e4b17023SJohn Marino create_convert_operand_from (struct expand_operand *op, rtx value,
1211*e4b17023SJohn Marino enum machine_mode mode, bool unsigned_p)
1212*e4b17023SJohn Marino {
1213*e4b17023SJohn Marino create_expand_operand (op, EXPAND_CONVERT_FROM, value, mode, unsigned_p);
1214*e4b17023SJohn Marino }
1215*e4b17023SJohn Marino
1216*e4b17023SJohn Marino extern void create_convert_operand_from_type (struct expand_operand *op,
1217*e4b17023SJohn Marino rtx value, tree type);
1218*e4b17023SJohn Marino
1219*e4b17023SJohn Marino /* Make OP describe an input Pmode address operand. VALUE is the value
1220*e4b17023SJohn Marino of the address, but it may need to be converted to Pmode first. */
1221*e4b17023SJohn Marino
1222*e4b17023SJohn Marino static inline void
create_address_operand(struct expand_operand * op,rtx value)1223*e4b17023SJohn Marino create_address_operand (struct expand_operand *op, rtx value)
1224*e4b17023SJohn Marino {
1225*e4b17023SJohn Marino create_expand_operand (op, EXPAND_ADDRESS, value, Pmode, false);
1226*e4b17023SJohn Marino }
1227*e4b17023SJohn Marino
1228*e4b17023SJohn Marino /* Make OP describe an input operand that has value INTVAL and that has
1229*e4b17023SJohn Marino no inherent mode. This function should only be used for operands that
1230*e4b17023SJohn Marino are always expand-time constants. The backend may request that INTVAL
1231*e4b17023SJohn Marino be copied into a different kind of rtx, but it must specify the mode
1232*e4b17023SJohn Marino of that rtx if so. */
1233*e4b17023SJohn Marino
1234*e4b17023SJohn Marino static inline void
create_integer_operand(struct expand_operand * op,HOST_WIDE_INT intval)1235*e4b17023SJohn Marino create_integer_operand (struct expand_operand *op, HOST_WIDE_INT intval)
1236*e4b17023SJohn Marino {
1237*e4b17023SJohn Marino create_expand_operand (op, EXPAND_INTEGER, GEN_INT (intval), VOIDmode, false);
1238*e4b17023SJohn Marino }
1239*e4b17023SJohn Marino
1240*e4b17023SJohn Marino extern bool valid_multiword_target_p (rtx);
1241*e4b17023SJohn Marino
1242*e4b17023SJohn Marino extern bool maybe_legitimize_operands (enum insn_code icode,
1243*e4b17023SJohn Marino unsigned int opno, unsigned int nops,
1244*e4b17023SJohn Marino struct expand_operand *ops);
1245*e4b17023SJohn Marino extern rtx maybe_gen_insn (enum insn_code icode, unsigned int nops,
1246*e4b17023SJohn Marino struct expand_operand *ops);
1247*e4b17023SJohn Marino extern bool maybe_expand_insn (enum insn_code icode, unsigned int nops,
1248*e4b17023SJohn Marino struct expand_operand *ops);
1249*e4b17023SJohn Marino extern bool maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
1250*e4b17023SJohn Marino struct expand_operand *ops);
1251*e4b17023SJohn Marino extern void expand_insn (enum insn_code icode, unsigned int nops,
1252*e4b17023SJohn Marino struct expand_operand *ops);
1253*e4b17023SJohn Marino extern void expand_jump_insn (enum insn_code icode, unsigned int nops,
1254*e4b17023SJohn Marino struct expand_operand *ops);
1255*e4b17023SJohn Marino
1256*e4b17023SJohn Marino extern rtx prepare_operand (enum insn_code, rtx, int, enum machine_mode,
1257*e4b17023SJohn Marino enum machine_mode, int);
1258*e4b17023SJohn Marino
1259*e4b17023SJohn Marino #endif /* GCC_OPTABS_H */
1260