190075Sobrien/* Definitions for code generation pass of GNU compiler.
2169689Skan   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
3169689Skan   Free Software Foundation, Inc.
490075Sobrien
590075SobrienThis file is part of GCC.
690075Sobrien
790075SobrienGCC is free software; you can redistribute it and/or modify
890075Sobrienit under the terms of the GNU General Public License as published by
990075Sobrienthe Free Software Foundation; either version 2, or (at your option)
1090075Sobrienany later version.
1190075Sobrien
1290075SobrienGCC is distributed in the hope that it will be useful,
1390075Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1490075SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1590075SobrienGNU General Public License for more details.
1690075Sobrien
1790075SobrienYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to
19169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor,
20169689SkanBoston, MA 02110-1301, USA.  */
2190075Sobrien
2290075Sobrien#ifndef GCC_OPTABS_H
2390075Sobrien#define GCC_OPTABS_H
2490075Sobrien
2590075Sobrien#include "insn-codes.h"
2690075Sobrien
2790075Sobrien/* Optabs are tables saying how to generate insn bodies
2890075Sobrien   for various machine modes and numbers of operands.
2990075Sobrien   Each optab applies to one operation.
3090075Sobrien   For example, add_optab applies to addition.
3190075Sobrien
3290075Sobrien   The insn_code slot is the enum insn_code that says how to
3390075Sobrien   generate an insn for this operation on a particular machine mode.
3490075Sobrien   It is CODE_FOR_nothing if there is no such insn on the target machine.
3590075Sobrien
3690075Sobrien   The `lib_call' slot is the name of the library function that
3790075Sobrien   can be used to perform the operation.
3890075Sobrien
3990075Sobrien   A few optabs, such as move_optab and cmp_optab, are used
4090075Sobrien   by special code.  */
4190075Sobrien
42132718Skanstruct optab_handlers GTY(())
43132718Skan{
44132718Skan  enum insn_code insn_code;
45132718Skan  rtx libfunc;
46132718Skan};
47132718Skan
48117395Skanstruct optab GTY(())
4990075Sobrien{
5090075Sobrien  enum rtx_code code;
51132718Skan  struct optab_handlers handlers[NUM_MACHINE_MODES];
52117395Skan};
53117395Skantypedef struct optab * optab;
5490075Sobrien
55132718Skan/* A convert_optab is for some sort of conversion operation between
56132718Skan   modes.  The first array index is the destination mode, the second
57132718Skan   is the source mode.  */
58132718Skanstruct convert_optab GTY(())
59132718Skan{
60132718Skan  enum rtx_code code;
61132718Skan  struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
62132718Skan};
63132718Skantypedef struct convert_optab *convert_optab;
64132718Skan
6590075Sobrien/* Given an enum insn_code, access the function to construct
6690075Sobrien   the body of that kind of insn.  */
67132718Skan#define GEN_FCN(CODE) (insn_data[CODE].genfun)
6890075Sobrien
6990075Sobrien/* Enumeration of valid indexes into optab_table.  */
7090075Sobrienenum optab_index
7190075Sobrien{
7290075Sobrien  OTI_add,
7390075Sobrien  OTI_addv,
7490075Sobrien  OTI_sub,
7590075Sobrien  OTI_subv,
7690075Sobrien
7790075Sobrien  /* Signed and fp multiply */
7890075Sobrien  OTI_smul,
7990075Sobrien  OTI_smulv,
8090075Sobrien  /* Signed multiply, return high word */
8190075Sobrien  OTI_smul_highpart,
8290075Sobrien  OTI_umul_highpart,
8390075Sobrien  /* Signed multiply with result one machine mode wider than args */
8490075Sobrien  OTI_smul_widen,
8590075Sobrien  OTI_umul_widen,
86169689Skan  /* Widening multiply of one unsigned and one signed operand.  */
87169689Skan  OTI_usmul_widen,
8890075Sobrien
8990075Sobrien  /* Signed divide */
9090075Sobrien  OTI_sdiv,
9190075Sobrien  OTI_sdivv,
9290075Sobrien  /* Signed divide-and-remainder in one */
9390075Sobrien  OTI_sdivmod,
9490075Sobrien  OTI_udiv,
9590075Sobrien  OTI_udivmod,
9690075Sobrien  /* Signed remainder */
9790075Sobrien  OTI_smod,
9890075Sobrien  OTI_umod,
99169689Skan  /* Floating point remainder functions */
100169689Skan  OTI_fmod,
101169689Skan  OTI_drem,
10290075Sobrien  /* Convert float to integer in float fmt */
10390075Sobrien  OTI_ftrunc,
10490075Sobrien
10590075Sobrien  /* Logical and */
10690075Sobrien  OTI_and,
10790075Sobrien  /* Logical or */
10890075Sobrien  OTI_ior,
10990075Sobrien  /* Logical xor */
11090075Sobrien  OTI_xor,
11190075Sobrien
11290075Sobrien  /* Arithmetic shift left */
11390075Sobrien  OTI_ashl,
11490075Sobrien  /* Logical shift right */
115132718Skan  OTI_lshr,
11690075Sobrien  /* Arithmetic shift right */
11790075Sobrien  OTI_ashr,
11890075Sobrien  /* Rotate left */
11990075Sobrien  OTI_rotl,
12090075Sobrien  /* Rotate right */
12190075Sobrien  OTI_rotr,
12290075Sobrien  /* Signed and floating-point minimum value */
12390075Sobrien  OTI_smin,
12490075Sobrien  /* Signed and floating-point maximum value */
12590075Sobrien  OTI_smax,
12690075Sobrien  /* Unsigned minimum value */
12790075Sobrien  OTI_umin,
12890075Sobrien  /* Unsigned maximum value */
12990075Sobrien  OTI_umax,
130132718Skan  /* Power */
131132718Skan  OTI_pow,
132132718Skan  /* Arc tangent of y/x */
133132718Skan  OTI_atan2,
13490075Sobrien
13590075Sobrien  /* Move instruction.  */
13690075Sobrien  OTI_mov,
13790075Sobrien  /* Move, preserving high part of register.  */
13890075Sobrien  OTI_movstrict,
139169689Skan  /* Move, with a misaligned memory.  */
140169689Skan  OTI_movmisalign,
14190075Sobrien
14290075Sobrien  /* Unary operations */
14390075Sobrien  /* Negation */
14490075Sobrien  OTI_neg,
14590075Sobrien  OTI_negv,
14690075Sobrien  /* Abs value */
14790075Sobrien  OTI_abs,
14890075Sobrien  OTI_absv,
149259563Spfg  /* Byteswap */
150259563Spfg  OTI_bswap,
15190075Sobrien  /* Bitwise not */
15290075Sobrien  OTI_one_cmpl,
153132718Skan  /* Bit scanning and counting */
15490075Sobrien  OTI_ffs,
155132718Skan  OTI_clz,
156132718Skan  OTI_ctz,
157132718Skan  OTI_popcount,
158132718Skan  OTI_parity,
15990075Sobrien  /* Square root */
16090075Sobrien  OTI_sqrt,
161169689Skan  /* Sine-Cosine */
162169689Skan  OTI_sincos,
16390075Sobrien  /* Sine */
16490075Sobrien  OTI_sin,
165169689Skan  /* Inverse sine */
166169689Skan  OTI_asin,
16790075Sobrien  /* Cosine */
16890075Sobrien  OTI_cos,
169169689Skan  /* Inverse cosine */
170169689Skan  OTI_acos,
171117395Skan  /* Exponential */
172117395Skan  OTI_exp,
173169689Skan  /* Base-10 Exponential */
174169689Skan  OTI_exp10,
175169689Skan  /* Base-2 Exponential */
176169689Skan  OTI_exp2,
177169689Skan  /* Exponential - 1*/
178169689Skan  OTI_expm1,
179169689Skan  /* Load exponent of a floating point number */
180169689Skan  OTI_ldexp,
181169689Skan  /* Radix-independent exponent */
182169689Skan  OTI_logb,
183169689Skan  OTI_ilogb,
184117395Skan  /* Natural Logarithm */
185117395Skan  OTI_log,
186169689Skan  /* Base-10 Logarithm */
187169689Skan  OTI_log10,
188169689Skan  /* Base-2 Logarithm */
189169689Skan  OTI_log2,
190169689Skan  /* logarithm of 1 plus argument */
191169689Skan  OTI_log1p,
192132718Skan  /* Rounding functions */
193132718Skan  OTI_floor,
194169689Skan  OTI_lfloor,
195132718Skan  OTI_ceil,
196169689Skan  OTI_lceil,
197169689Skan  OTI_btrunc,
198132718Skan  OTI_round,
199132718Skan  OTI_nearbyint,
200169689Skan  OTI_rint,
201169689Skan  OTI_lrint,
202132718Skan  /* Tangent */
203132718Skan  OTI_tan,
204132718Skan  /* Inverse tangent */
205132718Skan  OTI_atan,
206169689Skan  /* Copy sign */
207169689Skan  OTI_copysign,
20890075Sobrien
20990075Sobrien  /* Compare insn; two operands.  */
21090075Sobrien  OTI_cmp,
21190075Sobrien  /* Used only for libcalls for unsigned comparisons.  */
21290075Sobrien  OTI_ucmp,
21390075Sobrien  /* tst insn; compare one operand against 0 */
21490075Sobrien  OTI_tst,
21590075Sobrien
216132718Skan  /* Floating point comparison optabs - used primarily for libfuncs */
217132718Skan  OTI_eq,
218132718Skan  OTI_ne,
219132718Skan  OTI_gt,
220132718Skan  OTI_ge,
221132718Skan  OTI_lt,
222132718Skan  OTI_le,
223132718Skan  OTI_unord,
224132718Skan
22590075Sobrien  /* String length */
22690075Sobrien  OTI_strlen,
22790075Sobrien
22890075Sobrien  /* Combined compare & jump/store flags/move operations.  */
22990075Sobrien  OTI_cbranch,
23090075Sobrien  OTI_cmov,
23190075Sobrien  OTI_cstore,
232132718Skan
23390075Sobrien  /* Push instruction.  */
23490075Sobrien  OTI_push,
23590075Sobrien
236132718Skan  /* Conditional add instruction.  */
237132718Skan  OTI_addcc,
238132718Skan
239169689Skan  /* Reduction operations on a vector operand.  */
240169689Skan  OTI_reduc_smax,
241169689Skan  OTI_reduc_umax,
242169689Skan  OTI_reduc_smin,
243169689Skan  OTI_reduc_umin,
244169689Skan  OTI_reduc_splus,
245169689Skan  OTI_reduc_uplus,
246169689Skan
247169689Skan  /* Summation, with result machine mode one or more wider than args.  */
248169689Skan  OTI_ssum_widen,
249169689Skan  OTI_usum_widen,
250169689Skan
251169689Skan  /* Dot product, with result machine mode one or more wider than args.  */
252169689Skan  OTI_sdot_prod,
253169689Skan  OTI_udot_prod,
254169689Skan
255132718Skan  /* Set specified field of vector operand.  */
256132718Skan  OTI_vec_set,
257132718Skan  /* Extract specified field of vector operand.  */
258132718Skan  OTI_vec_extract,
259132718Skan  /* Initialize vector operand.  */
260132718Skan  OTI_vec_init,
261169689Skan  /* Whole vector shift. The shift amount is in bits.  */
262169689Skan  OTI_vec_shl,
263169689Skan  OTI_vec_shr,
264169689Skan  /* Extract specified elements from vectors, for vector load.  */
265169689Skan  OTI_vec_realign_load,
266132718Skan
267169689Skan  /* Perform a raise to the power of integer.  */
268169689Skan  OTI_powi,
269169689Skan
27090075Sobrien  OTI_MAX
27190075Sobrien};
27290075Sobrien
273117395Skanextern GTY(()) optab optab_table[OTI_MAX];
27490075Sobrien
27590075Sobrien#define add_optab (optab_table[OTI_add])
27690075Sobrien#define sub_optab (optab_table[OTI_sub])
27790075Sobrien#define smul_optab (optab_table[OTI_smul])
27890075Sobrien#define addv_optab (optab_table[OTI_addv])
27990075Sobrien#define subv_optab (optab_table[OTI_subv])
28090075Sobrien#define smul_highpart_optab (optab_table[OTI_smul_highpart])
28190075Sobrien#define umul_highpart_optab (optab_table[OTI_umul_highpart])
28290075Sobrien#define smul_widen_optab (optab_table[OTI_smul_widen])
28390075Sobrien#define umul_widen_optab (optab_table[OTI_umul_widen])
284169689Skan#define usmul_widen_optab (optab_table[OTI_usmul_widen])
28590075Sobrien#define sdiv_optab (optab_table[OTI_sdiv])
28690075Sobrien#define smulv_optab (optab_table[OTI_smulv])
28790075Sobrien#define sdivv_optab (optab_table[OTI_sdivv])
28890075Sobrien#define sdivmod_optab (optab_table[OTI_sdivmod])
28990075Sobrien#define udiv_optab (optab_table[OTI_udiv])
29090075Sobrien#define udivmod_optab (optab_table[OTI_udivmod])
29190075Sobrien#define smod_optab (optab_table[OTI_smod])
29290075Sobrien#define umod_optab (optab_table[OTI_umod])
293169689Skan#define fmod_optab (optab_table[OTI_fmod])
294169689Skan#define drem_optab (optab_table[OTI_drem])
29590075Sobrien#define ftrunc_optab (optab_table[OTI_ftrunc])
29690075Sobrien#define and_optab (optab_table[OTI_and])
29790075Sobrien#define ior_optab (optab_table[OTI_ior])
29890075Sobrien#define xor_optab (optab_table[OTI_xor])
29990075Sobrien#define ashl_optab (optab_table[OTI_ashl])
30090075Sobrien#define lshr_optab (optab_table[OTI_lshr])
30190075Sobrien#define ashr_optab (optab_table[OTI_ashr])
30290075Sobrien#define rotl_optab (optab_table[OTI_rotl])
30390075Sobrien#define rotr_optab (optab_table[OTI_rotr])
30490075Sobrien#define smin_optab (optab_table[OTI_smin])
30590075Sobrien#define smax_optab (optab_table[OTI_smax])
30690075Sobrien#define umin_optab (optab_table[OTI_umin])
30790075Sobrien#define umax_optab (optab_table[OTI_umax])
308132718Skan#define pow_optab (optab_table[OTI_pow])
309132718Skan#define atan2_optab (optab_table[OTI_atan2])
31090075Sobrien
31190075Sobrien#define mov_optab (optab_table[OTI_mov])
31290075Sobrien#define movstrict_optab (optab_table[OTI_movstrict])
313169689Skan#define movmisalign_optab (optab_table[OTI_movmisalign])
31490075Sobrien
31590075Sobrien#define neg_optab (optab_table[OTI_neg])
31690075Sobrien#define negv_optab (optab_table[OTI_negv])
31790075Sobrien#define abs_optab (optab_table[OTI_abs])
31890075Sobrien#define absv_optab (optab_table[OTI_absv])
31990075Sobrien#define one_cmpl_optab (optab_table[OTI_one_cmpl])
320259563Spfg#define bswap_optab (optab_table[OTI_bswap])
32190075Sobrien#define ffs_optab (optab_table[OTI_ffs])
322132718Skan#define clz_optab (optab_table[OTI_clz])
323132718Skan#define ctz_optab (optab_table[OTI_ctz])
324132718Skan#define popcount_optab (optab_table[OTI_popcount])
325132718Skan#define parity_optab (optab_table[OTI_parity])
32690075Sobrien#define sqrt_optab (optab_table[OTI_sqrt])
327169689Skan#define sincos_optab (optab_table[OTI_sincos])
32890075Sobrien#define sin_optab (optab_table[OTI_sin])
329169689Skan#define asin_optab (optab_table[OTI_asin])
33090075Sobrien#define cos_optab (optab_table[OTI_cos])
331169689Skan#define acos_optab (optab_table[OTI_acos])
332117395Skan#define exp_optab (optab_table[OTI_exp])
333169689Skan#define exp10_optab (optab_table[OTI_exp10])
334169689Skan#define exp2_optab (optab_table[OTI_exp2])
335169689Skan#define expm1_optab (optab_table[OTI_expm1])
336169689Skan#define ldexp_optab (optab_table[OTI_ldexp])
337169689Skan#define logb_optab (optab_table[OTI_logb])
338169689Skan#define ilogb_optab (optab_table[OTI_ilogb])
339117395Skan#define log_optab (optab_table[OTI_log])
340169689Skan#define log10_optab (optab_table[OTI_log10])
341169689Skan#define log2_optab (optab_table[OTI_log2])
342169689Skan#define log1p_optab (optab_table[OTI_log1p])
343132718Skan#define floor_optab (optab_table[OTI_floor])
344169689Skan#define lfloor_optab (optab_table[OTI_lfloor])
345132718Skan#define ceil_optab (optab_table[OTI_ceil])
346169689Skan#define lceil_optab (optab_table[OTI_lceil])
347169689Skan#define btrunc_optab (optab_table[OTI_btrunc])
348132718Skan#define round_optab (optab_table[OTI_round])
349132718Skan#define nearbyint_optab (optab_table[OTI_nearbyint])
350169689Skan#define rint_optab (optab_table[OTI_rint])
351169689Skan#define lrint_optab (optab_table[OTI_lrint])
352132718Skan#define tan_optab (optab_table[OTI_tan])
353132718Skan#define atan_optab (optab_table[OTI_atan])
354169689Skan#define copysign_optab (optab_table[OTI_copysign])
35590075Sobrien
35690075Sobrien#define cmp_optab (optab_table[OTI_cmp])
35790075Sobrien#define ucmp_optab (optab_table[OTI_ucmp])
35890075Sobrien#define tst_optab (optab_table[OTI_tst])
35990075Sobrien
360132718Skan#define eq_optab (optab_table[OTI_eq])
361132718Skan#define ne_optab (optab_table[OTI_ne])
362132718Skan#define gt_optab (optab_table[OTI_gt])
363132718Skan#define ge_optab (optab_table[OTI_ge])
364132718Skan#define lt_optab (optab_table[OTI_lt])
365132718Skan#define le_optab (optab_table[OTI_le])
366132718Skan#define unord_optab (optab_table[OTI_unord])
367132718Skan
36890075Sobrien#define strlen_optab (optab_table[OTI_strlen])
36990075Sobrien
37090075Sobrien#define cbranch_optab (optab_table[OTI_cbranch])
37190075Sobrien#define cmov_optab (optab_table[OTI_cmov])
37290075Sobrien#define cstore_optab (optab_table[OTI_cstore])
37390075Sobrien#define push_optab (optab_table[OTI_push])
374132718Skan#define addcc_optab (optab_table[OTI_addcc])
37590075Sobrien
376169689Skan#define reduc_smax_optab (optab_table[OTI_reduc_smax])
377169689Skan#define reduc_umax_optab (optab_table[OTI_reduc_umax])
378169689Skan#define reduc_smin_optab (optab_table[OTI_reduc_smin])
379169689Skan#define reduc_umin_optab (optab_table[OTI_reduc_umin])
380169689Skan#define reduc_splus_optab (optab_table[OTI_reduc_splus])
381169689Skan#define reduc_uplus_optab (optab_table[OTI_reduc_uplus])
382169689Skan
383169689Skan#define ssum_widen_optab (optab_table[OTI_ssum_widen])
384169689Skan#define usum_widen_optab (optab_table[OTI_usum_widen])
385169689Skan#define sdot_prod_optab (optab_table[OTI_sdot_prod])
386169689Skan#define udot_prod_optab (optab_table[OTI_udot_prod])
387169689Skan
388132718Skan#define vec_set_optab (optab_table[OTI_vec_set])
389132718Skan#define vec_extract_optab (optab_table[OTI_vec_extract])
390132718Skan#define vec_init_optab (optab_table[OTI_vec_init])
391169689Skan#define vec_shl_optab (optab_table[OTI_vec_shl])
392169689Skan#define vec_shr_optab (optab_table[OTI_vec_shr])
393169689Skan#define vec_realign_load_optab (optab_table[OTI_vec_realign_load])
39490075Sobrien
395169689Skan#define powi_optab (optab_table[OTI_powi])
396169689Skan
397132718Skan/* Conversion optabs have their own table and indexes.  */
398132718Skanenum convert_optab_index
399132718Skan{
400169689Skan  COI_sext,
401169689Skan  COI_zext,
402169689Skan  COI_trunc,
40390075Sobrien
404169689Skan  COI_sfix,
405169689Skan  COI_ufix,
406132718Skan
407169689Skan  COI_sfixtrunc,
408169689Skan  COI_ufixtrunc,
409132718Skan
410169689Skan  COI_sfloat,
411169689Skan  COI_ufloat,
412132718Skan
413169689Skan  COI_MAX
414132718Skan};
415132718Skan
416169689Skanextern GTY(()) convert_optab convert_optab_table[COI_MAX];
417132718Skan
418169689Skan#define sext_optab (convert_optab_table[COI_sext])
419169689Skan#define zext_optab (convert_optab_table[COI_zext])
420169689Skan#define trunc_optab (convert_optab_table[COI_trunc])
421169689Skan#define sfix_optab (convert_optab_table[COI_sfix])
422169689Skan#define ufix_optab (convert_optab_table[COI_ufix])
423169689Skan#define sfixtrunc_optab (convert_optab_table[COI_sfixtrunc])
424169689Skan#define ufixtrunc_optab (convert_optab_table[COI_ufixtrunc])
425169689Skan#define sfloat_optab (convert_optab_table[COI_sfloat])
426169689Skan#define ufloat_optab (convert_optab_table[COI_ufloat])
427132718Skan
42890075Sobrien/* These arrays record the insn_code of insns that may be needed to
42990075Sobrien   perform input and output reloads of special objects.  They provide a
43090075Sobrien   place to pass a scratch register.  */
43190075Sobrienextern enum insn_code reload_in_optab[NUM_MACHINE_MODES];
43290075Sobrienextern enum insn_code reload_out_optab[NUM_MACHINE_MODES];
43390075Sobrien
43490075Sobrien/* Contains the optab used for each rtx code.  */
435132718Skanextern GTY(()) optab code_to_optab[NUM_RTX_CODE + 1];
43690075Sobrien
43790075Sobrien
438132718Skantypedef rtx (*rtxfun) (rtx);
43990075Sobrien
440169689Skan/* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...)
44190075Sobrien   gives the gen_function to make a branch to test that condition.  */
44290075Sobrien
44390075Sobrienextern rtxfun bcc_gen_fctn[NUM_RTX_CODE];
44490075Sobrien
445169689Skan/* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...)
44690075Sobrien   gives the insn code to make a store-condition insn
44790075Sobrien   to test that condition.  */
44890075Sobrien
44990075Sobrienextern enum insn_code setcc_gen_code[NUM_RTX_CODE];
45090075Sobrien
45190075Sobrien#ifdef HAVE_conditional_move
45290075Sobrien/* Indexed by the machine mode, gives the insn code to make a conditional
45390075Sobrien   move insn.  */
45490075Sobrien
45590075Sobrienextern enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
45690075Sobrien#endif
45790075Sobrien
458169689Skan/* Indexed by the machine mode, gives the insn code for vector conditional
459169689Skan   operation.  */
460169689Skan
461169689Skanextern enum insn_code vcond_gen_code[NUM_MACHINE_MODES];
462169689Skanextern enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
463169689Skan
46490075Sobrien/* This array records the insn_code of insns to perform block moves.  */
465169689Skanextern enum insn_code movmem_optab[NUM_MACHINE_MODES];
46690075Sobrien
467169689Skan/* This array records the insn_code of insns to perform block sets.  */
468169689Skanextern enum insn_code setmem_optab[NUM_MACHINE_MODES];
46990075Sobrien
470132718Skan/* These arrays record the insn_code of two different kinds of insns
471132718Skan   to perform block compares.  */
472132718Skanextern enum insn_code cmpstr_optab[NUM_MACHINE_MODES];
473169689Skanextern enum insn_code cmpstrn_optab[NUM_MACHINE_MODES];
474132718Skanextern enum insn_code cmpmem_optab[NUM_MACHINE_MODES];
475132718Skan
476169689Skan/* Synchronization primitives.  This first set is atomic operation for
477169689Skan   which we don't care about the resulting value.  */
478169689Skanextern enum insn_code sync_add_optab[NUM_MACHINE_MODES];
479169689Skanextern enum insn_code sync_sub_optab[NUM_MACHINE_MODES];
480169689Skanextern enum insn_code sync_ior_optab[NUM_MACHINE_MODES];
481169689Skanextern enum insn_code sync_and_optab[NUM_MACHINE_MODES];
482169689Skanextern enum insn_code sync_xor_optab[NUM_MACHINE_MODES];
483169689Skanextern enum insn_code sync_nand_optab[NUM_MACHINE_MODES];
484169689Skan
485169689Skan/* This second set is atomic operations in which we return the value
486169689Skan   that existed in memory before the operation.  */
487169689Skanextern enum insn_code sync_old_add_optab[NUM_MACHINE_MODES];
488169689Skanextern enum insn_code sync_old_sub_optab[NUM_MACHINE_MODES];
489169689Skanextern enum insn_code sync_old_ior_optab[NUM_MACHINE_MODES];
490169689Skanextern enum insn_code sync_old_and_optab[NUM_MACHINE_MODES];
491169689Skanextern enum insn_code sync_old_xor_optab[NUM_MACHINE_MODES];
492169689Skanextern enum insn_code sync_old_nand_optab[NUM_MACHINE_MODES];
493169689Skan
494169689Skan/* This third set is atomic operations in which we return the value
495169689Skan   that resulted after performing the operation.  */
496169689Skanextern enum insn_code sync_new_add_optab[NUM_MACHINE_MODES];
497169689Skanextern enum insn_code sync_new_sub_optab[NUM_MACHINE_MODES];
498169689Skanextern enum insn_code sync_new_ior_optab[NUM_MACHINE_MODES];
499169689Skanextern enum insn_code sync_new_and_optab[NUM_MACHINE_MODES];
500169689Skanextern enum insn_code sync_new_xor_optab[NUM_MACHINE_MODES];
501169689Skanextern enum insn_code sync_new_nand_optab[NUM_MACHINE_MODES];
502169689Skan
503169689Skan/* Atomic compare and swap.  */
504169689Skanextern enum insn_code sync_compare_and_swap[NUM_MACHINE_MODES];
505169689Skanextern enum insn_code sync_compare_and_swap_cc[NUM_MACHINE_MODES];
506169689Skan
507169689Skan/* Atomic exchange with acquire semantics.  */
508169689Skanextern enum insn_code sync_lock_test_and_set[NUM_MACHINE_MODES];
509169689Skan
510169689Skan/* Atomic clear with release semantics.  */
511169689Skanextern enum insn_code sync_lock_release[NUM_MACHINE_MODES];
512169689Skan
51390075Sobrien/* Define functions given in optabs.c.  */
51490075Sobrien
515169689Skanextern rtx expand_widen_pattern_expr (tree exp, rtx op0, rtx op1, rtx wide_op,
516169689Skan                                      rtx target, int unsignedp);
517169689Skan
518169689Skanextern rtx expand_ternary_op (enum machine_mode mode, optab ternary_optab,
519169689Skan			      rtx op0, rtx op1, rtx op2, rtx target,
520169689Skan			      int unsignedp);
521169689Skan
52290075Sobrien/* Expand a binary operation given optab and rtx operands.  */
523132718Skanextern rtx expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int,
524132718Skan			 enum optab_methods);
52590075Sobrien
526169689Skanextern bool force_expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int,
527169689Skan				enum optab_methods);
528169689Skan
52990075Sobrien/* Expand a binary operation with both signed and unsigned forms.  */
530132718Skanextern rtx sign_expand_binop (enum machine_mode, optab, optab, rtx, rtx,
531132718Skan			      rtx, int, enum optab_methods);
53290075Sobrien
533169689Skan/* Generate code to perform an operation on one operand with two results.  */
534169689Skanextern int expand_twoval_unop (optab, rtx, rtx, rtx, int);
535169689Skan
53690075Sobrien/* Generate code to perform an operation on two operands with two results.  */
537132718Skanextern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int);
53890075Sobrien
539169689Skan/* Generate code to perform an operation on two operands with two
540169689Skan   results, using a library function.  */
541169689Skanextern bool expand_twoval_binop_libfunc (optab, rtx, rtx, rtx, rtx,
542169689Skan					 enum rtx_code);
543169689Skan
54490075Sobrien/* Expand a unary arithmetic operation given optab rtx operand.  */
545132718Skanextern rtx expand_unop (enum machine_mode, optab, rtx, rtx, int);
54690075Sobrien
54790075Sobrien/* Expand the absolute value operation.  */
548132718Skanextern rtx expand_abs_nojump (enum machine_mode, rtx, rtx, int);
549132718Skanextern rtx expand_abs (enum machine_mode, rtx, rtx, int, int);
55090075Sobrien
551169689Skan/* Expand the copysign operation.  */
552169689Skanextern rtx expand_copysign (rtx, rtx, rtx);
55390075Sobrien
55490075Sobrien/* Generate an instruction with a given INSN_CODE with an output and
55590075Sobrien   an input.  */
556132718Skanextern void emit_unop_insn (int, rtx, rtx, enum rtx_code);
55790075Sobrien
55890075Sobrien/* Emit code to perform a series of operations on a multi-word quantity, one
55990075Sobrien   word at a time.  */
560132718Skanextern rtx emit_no_conflict_block (rtx, rtx, rtx, rtx, rtx);
56190075Sobrien
56290075Sobrien/* Emit one rtl insn to compare two rtx's.  */
563132718Skanextern void emit_cmp_insn (rtx, rtx, enum rtx_code, rtx, enum machine_mode,
564132718Skan			   int);
56590075Sobrien
56690075Sobrien/* The various uses that a comparison can have; used by can_compare_p:
56790075Sobrien   jumps, conditional moves, store flag operations.  */
56890075Sobrienenum can_compare_purpose
56990075Sobrien{
57090075Sobrien  ccp_jump,
57190075Sobrien  ccp_cmov,
57290075Sobrien  ccp_store_flag
57390075Sobrien};
57490075Sobrien
575169689Skan/* Return the optab used for computing the given operation on the type
576169689Skan   given by the second argument.  */
577169689Skanextern optab optab_for_tree_code (enum tree_code, tree);
578169689Skan
57990075Sobrien/* Nonzero if a compare of mode MODE can be done straightforwardly
58090075Sobrien   (without splitting it into pieces).  */
581132718Skanextern int can_compare_p (enum rtx_code, enum machine_mode,
582132718Skan			  enum can_compare_purpose);
58390075Sobrien
58490075Sobrien/* Return the INSN_CODE to use for an extend operation.  */
585132718Skanextern enum insn_code can_extend_p (enum machine_mode, enum machine_mode, int);
58690075Sobrien
58790075Sobrien/* Generate the body of an insn to extend Y (with mode MFROM)
58890075Sobrien   into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
589132718Skanextern rtx gen_extend_insn (rtx, rtx, enum machine_mode,
590132718Skan			    enum machine_mode, int);
59190075Sobrien
592132718Skan/* Call this to reset the function entry for one optab.  */
593132718Skanextern void set_optab_libfunc (optab, enum machine_mode, const char *);
594132718Skanextern void set_conv_libfunc (convert_optab, enum machine_mode,
595132718Skan			      enum machine_mode, const char *);
596132718Skan
59790075Sobrien/* Generate code for a FLOAT_EXPR.  */
598132718Skanextern void expand_float (rtx, rtx, int);
59990075Sobrien
60090075Sobrien/* Generate code for a FIX_EXPR.  */
601132718Skanextern void expand_fix (rtx, rtx, int);
60290075Sobrien
603169689Skan/* Return tree if target supports vector operations for COND_EXPR.  */
604169689Skanbool expand_vec_cond_expr_p (tree, enum machine_mode);
605169689Skan
606169689Skan/* Generate code for VEC_COND_EXPR.  */
607169689Skanextern rtx expand_vec_cond_expr (tree, rtx);
608169689Skan
609169689Skan/* Generate code for VEC_LSHIFT_EXPR and VEC_RSHIFT_EXPR.  */
610169689Skanextern rtx expand_vec_shift_expr (tree, rtx);
611169689Skan
61290075Sobrien#endif /* GCC_OPTABS_H */
613