xref: /dflybsd-src/contrib/gcc-4.7/gcc/optabs.h (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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