1223328Sgavin/* Definitions for code generation pass of GNU compiler.
2223328Sgavin   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
379971Sobrien   Free Software Foundation, Inc.
479971Sobrien
579971SobrienThis file is part of GCC.
679971Sobrien
779971SobrienGCC is free software; you can redistribute it and/or modify
879971Sobrienit under the terms of the GNU General Public License as published by
979971Sobrienthe Free Software Foundation; either version 2, or (at your option)
1079971Sobrienany later version.
1179971Sobrien
1279971SobrienGCC is distributed in the hope that it will be useful,
1379971Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1479971SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1579971SobrienGNU General Public License for more details.
16121966Smikeh
1779971SobrienYou should have received a copy of the GNU General Public License
1879971Sobrienalong with GCC; see the file COPYING.  If not, write to
1979971Sobrienthe Free Software Foundation, 51 Franklin Street, Fifth Floor,
2079971SobrienBoston, MA 02110-1301, USA.  */
2179971Sobrien
2279971Sobrien#ifndef GCC_OPTABS_H
2379971Sobrien#define GCC_OPTABS_H
2479971Sobrien
2579971Sobrien#include "insn-codes.h"
2679971Sobrien
2779971Sobrien/* Optabs are tables saying how to generate insn bodies
2879971Sobrien   for various machine modes and numbers of operands.
2979971Sobrien   Each optab applies to one operation.
3079971Sobrien   For example, add_optab applies to addition.
3179971Sobrien
3279971Sobrien   The insn_code slot is the enum insn_code that says how to
33223328Sgavin   generate an insn for this operation on a particular machine mode.
34223328Sgavin   It is CODE_FOR_nothing if there is no such insn on the target machine.
35223328Sgavin
36223328Sgavin   The `lib_call' slot is the name of the library function that
37116424Smikeh   can be used to perform the operation.
38116424Smikeh
39116424Smikeh   A few optabs, such as move_optab and cmp_optab, are used
40116424Smikeh   by special code.  */
41116424Smikeh
42223328Sgavinstruct optab_handlers GTY(())
43116424Smikeh{
44116424Smikeh  enum insn_code insn_code;
4579971Sobrien  rtx libfunc;
46116424Smikeh};
47116424Smikeh
48116424Smikehstruct optab GTY(())
49116424Smikeh{
50116424Smikeh  enum rtx_code code;
51116424Smikeh  struct optab_handlers handlers[NUM_MACHINE_MODES];
52116424Smikeh};
53116424Smikehtypedef struct optab * optab;
54116424Smikeh
55116424Smikeh/* A convert_optab is for some sort of conversion operation between
56116424Smikeh   modes.  The first array index is the destination mode, the second
57116424Smikeh   is the source mode.  */
58223328Sgavinstruct convert_optab GTY(())
59223328Sgavin{
6079971Sobrien  enum rtx_code code;
6179971Sobrien  struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
6279971Sobrien};
6379971Sobrientypedef struct convert_optab *convert_optab;
6479971Sobrien
6579971Sobrien/* Given an enum insn_code, access the function to construct
6679971Sobrien   the body of that kind of insn.  */
6779971Sobrien#define GEN_FCN(CODE) (insn_data[CODE].genfun)
6879971Sobrien
6979971Sobrien/* Enumeration of valid indexes into optab_table.  */
7079971Sobrienenum optab_index
7179971Sobrien{
7279971Sobrien  OTI_add,
7379971Sobrien  OTI_addv,
7479971Sobrien  OTI_sub,
7579971Sobrien  OTI_subv,
76223328Sgavin
7779971Sobrien  /* Signed and fp multiply */
7879971Sobrien  OTI_smul,
7979971Sobrien  OTI_smulv,
8079971Sobrien  /* Signed multiply, return high word */
8179971Sobrien  OTI_smul_highpart,
8279971Sobrien  OTI_umul_highpart,
8379971Sobrien  /* Signed multiply with result one machine mode wider than args */
8479971Sobrien  OTI_smul_widen,
8579971Sobrien  OTI_umul_widen,
8679971Sobrien  /* Widening multiply of one unsigned and one signed operand.  */
8779971Sobrien  OTI_usmul_widen,
8879971Sobrien
8979971Sobrien  /* Signed divide */
90223328Sgavin  OTI_sdiv,
9179971Sobrien  OTI_sdivv,
9298247Smikeh  /* Signed divide-and-remainder in one */
93223328Sgavin  OTI_sdivmod,
94223328Sgavin  OTI_udiv,
9579971Sobrien  OTI_udivmod,
9679971Sobrien  /* Signed remainder */
9779971Sobrien  OTI_smod,
9898247Smikeh  OTI_umod,
9979971Sobrien  /* Floating point remainder functions */
10098247Smikeh  OTI_fmod,
10179971Sobrien  OTI_drem,
10279971Sobrien  /* Convert float to integer in float fmt */
103223328Sgavin  OTI_ftrunc,
10479971Sobrien
10579971Sobrien  /* Logical and */
10679971Sobrien  OTI_and,
10779971Sobrien  /* Logical or */
10879971Sobrien  OTI_ior,
10979971Sobrien  /* Logical xor */
11079971Sobrien  OTI_xor,
11179971Sobrien
112223328Sgavin  /* Arithmetic shift left */
11379971Sobrien  OTI_ashl,
11479971Sobrien  /* Logical shift right */
11579971Sobrien  OTI_lshr,
11679971Sobrien  /* Arithmetic shift right */
11779971Sobrien  OTI_ashr,
11879971Sobrien  /* Rotate left */
11979971Sobrien  OTI_rotl,
120223328Sgavin  /* Rotate right */
121223328Sgavin  OTI_rotr,
122223328Sgavin  /* Signed and floating-point minimum value */
12379971Sobrien  OTI_smin,
12479971Sobrien  /* Signed and floating-point maximum value */
12579971Sobrien  OTI_smax,
12679971Sobrien  /* Unsigned minimum value */
12779971Sobrien  OTI_umin,
12879971Sobrien  /* Unsigned maximum value */
12979971Sobrien  OTI_umax,
13079971Sobrien  /* Power */
13179971Sobrien  OTI_pow,
13279971Sobrien  /* Arc tangent of y/x */
13379971Sobrien  OTI_atan2,
13479971Sobrien
13579971Sobrien  /* Move instruction.  */
13679971Sobrien  OTI_mov,
13779971Sobrien  /* Move, preserving high part of register.  */
13879971Sobrien  OTI_movstrict,
13979971Sobrien  /* Move, with a misaligned memory.  */
14079971Sobrien  OTI_movmisalign,
14179971Sobrien
14279971Sobrien  /* Unary operations */
14379971Sobrien  /* Negation */
14479971Sobrien  OTI_neg,
14579971Sobrien  OTI_negv,
146223328Sgavin  /* Abs value */
147223328Sgavin  OTI_abs,
14879971Sobrien  OTI_absv,
14979971Sobrien  /* Bitwise not */
150223328Sgavin  OTI_one_cmpl,
151223328Sgavin  /* Bit scanning and counting */
152223328Sgavin  OTI_ffs,
15379971Sobrien  OTI_clz,
154223328Sgavin  OTI_ctz,
15579971Sobrien  OTI_popcount,
15679971Sobrien  OTI_parity,
15779971Sobrien  /* Square root */
15879971Sobrien  OTI_sqrt,
15979971Sobrien  /* Sine-Cosine */
16079971Sobrien  OTI_sincos,
16179971Sobrien  /* Sine */
16279971Sobrien  OTI_sin,
16379971Sobrien  /* Inverse sine */
16479971Sobrien  OTI_asin,
165223328Sgavin  /* Cosine */
166223328Sgavin  OTI_cos,
16779971Sobrien  /* Inverse cosine */
16879971Sobrien  OTI_acos,
169223328Sgavin  /* Exponential */
170223328Sgavin  OTI_exp,
171223328Sgavin  /* Base-10 Exponential */
172223328Sgavin  OTI_exp10,
17379971Sobrien  /* Base-2 Exponential */
17479971Sobrien  OTI_exp2,
17579971Sobrien  /* Exponential - 1*/
17679971Sobrien  OTI_expm1,
177223328Sgavin  /* Load exponent of a floating point number */
178223328Sgavin  OTI_ldexp,
17979971Sobrien  /* Radix-independent exponent */
18079971Sobrien  OTI_logb,
181223328Sgavin  OTI_ilogb,
182223328Sgavin  /* Natural Logarithm */
183223328Sgavin  OTI_log,
184223328Sgavin  /* Base-10 Logarithm */
18579971Sobrien  OTI_log10,
18679971Sobrien  /* Base-2 Logarithm */
18779971Sobrien  OTI_log2,
18879971Sobrien  /* logarithm of 1 plus argument */
18979971Sobrien  OTI_log1p,
19079971Sobrien  /* Rounding functions */
19179971Sobrien  OTI_floor,
19279971Sobrien  OTI_lfloor,
19379971Sobrien  OTI_ceil,
19479971Sobrien  OTI_lceil,
19579971Sobrien  OTI_btrunc,
19679971Sobrien  OTI_round,
19779971Sobrien  OTI_nearbyint,
19879971Sobrien  OTI_rint,
19979971Sobrien  OTI_lrint,
20079971Sobrien  /* Tangent */
20179971Sobrien  OTI_tan,
20279971Sobrien  /* Inverse tangent */
20379971Sobrien  OTI_atan,
20479971Sobrien  /* Copy sign */
20579971Sobrien  OTI_copysign,
20679971Sobrien
20779971Sobrien  /* Compare insn; two operands.  */
20879971Sobrien  OTI_cmp,
20979971Sobrien  /* Used only for libcalls for unsigned comparisons.  */
21079971Sobrien  OTI_ucmp,
21179971Sobrien  /* tst insn; compare one operand against 0 */
21279971Sobrien  OTI_tst,
21379971Sobrien
21479971Sobrien  /* Floating point comparison optabs - used primarily for libfuncs */
21579971Sobrien  OTI_eq,
21679971Sobrien  OTI_ne,
21779971Sobrien  OTI_gt,
21879971Sobrien  OTI_ge,
21979971Sobrien  OTI_lt,
22079971Sobrien  OTI_le,
22179971Sobrien  OTI_unord,
22279971Sobrien
22379971Sobrien  /* String length */
22479971Sobrien  OTI_strlen,
22579971Sobrien
22679971Sobrien  /* Combined compare & jump/store flags/move operations.  */
22779971Sobrien  OTI_cbranch,
22879971Sobrien  OTI_cmov,
22979971Sobrien  OTI_cstore,
23079971Sobrien
23179971Sobrien  /* Push instruction.  */
23279971Sobrien  OTI_push,
23379971Sobrien
23479971Sobrien  /* Conditional add instruction.  */
23579971Sobrien  OTI_addcc,
23679971Sobrien
23779971Sobrien  /* Reduction operations on a vector operand.  */
23879971Sobrien  OTI_reduc_smax,
23979971Sobrien  OTI_reduc_umax,
24079971Sobrien  OTI_reduc_smin,
24179971Sobrien  OTI_reduc_umin,
24279971Sobrien  OTI_reduc_splus,
24379971Sobrien  OTI_reduc_uplus,
244223328Sgavin
245223328Sgavin  /* Summation, with result machine mode one or more wider than args.  */
246223328Sgavin  OTI_ssum_widen,
247223328Sgavin  OTI_usum_widen,
248223328Sgavin
249223328Sgavin  /* Dot product, with result machine mode one or more wider than args.  */
250223328Sgavin  OTI_sdot_prod,
25179971Sobrien  OTI_udot_prod,
25279971Sobrien
25379971Sobrien  /* Set specified field of vector operand.  */
25479971Sobrien  OTI_vec_set,
25579971Sobrien  /* Extract specified field of vector operand.  */
25679971Sobrien  OTI_vec_extract,
25779971Sobrien  /* Initialize vector operand.  */
25879971Sobrien  OTI_vec_init,
25979971Sobrien  /* Whole vector shift. The shift amount is in bits.  */
26079971Sobrien  OTI_vec_shl,
26179971Sobrien  OTI_vec_shr,
26279971Sobrien  /* Extract specified elements from vectors, for vector load.  */
263223328Sgavin  OTI_vec_realign_load,
26479971Sobrien
26579971Sobrien  /* Perform a raise to the power of integer.  */
26679971Sobrien  OTI_powi,
26779971Sobrien
26879971Sobrien  OTI_MAX
269223328Sgavin};
270223328Sgavin
27179971Sobrienextern GTY(()) optab optab_table[OTI_MAX];
27279971Sobrien
27379971Sobrien#define add_optab (optab_table[OTI_add])
27479971Sobrien#define sub_optab (optab_table[OTI_sub])
27579971Sobrien#define smul_optab (optab_table[OTI_smul])
27679971Sobrien#define addv_optab (optab_table[OTI_addv])
27779971Sobrien#define subv_optab (optab_table[OTI_subv])
27879971Sobrien#define smul_highpart_optab (optab_table[OTI_smul_highpart])
27979971Sobrien#define umul_highpart_optab (optab_table[OTI_umul_highpart])
28079971Sobrien#define smul_widen_optab (optab_table[OTI_smul_widen])
28179971Sobrien#define umul_widen_optab (optab_table[OTI_umul_widen])
28279971Sobrien#define usmul_widen_optab (optab_table[OTI_usmul_widen])
28379971Sobrien#define sdiv_optab (optab_table[OTI_sdiv])
28479971Sobrien#define smulv_optab (optab_table[OTI_smulv])
28579971Sobrien#define sdivv_optab (optab_table[OTI_sdivv])
28679971Sobrien#define sdivmod_optab (optab_table[OTI_sdivmod])
28779971Sobrien#define udiv_optab (optab_table[OTI_udiv])
28879971Sobrien#define udivmod_optab (optab_table[OTI_udivmod])
28979971Sobrien#define smod_optab (optab_table[OTI_smod])
29079971Sobrien#define umod_optab (optab_table[OTI_umod])
29179971Sobrien#define fmod_optab (optab_table[OTI_fmod])
29279971Sobrien#define drem_optab (optab_table[OTI_drem])
29379971Sobrien#define ftrunc_optab (optab_table[OTI_ftrunc])
29479971Sobrien#define and_optab (optab_table[OTI_and])
29579971Sobrien#define ior_optab (optab_table[OTI_ior])
296223328Sgavin#define xor_optab (optab_table[OTI_xor])
297223328Sgavin#define ashl_optab (optab_table[OTI_ashl])
29879971Sobrien#define lshr_optab (optab_table[OTI_lshr])
299223328Sgavin#define ashr_optab (optab_table[OTI_ashr])
300223328Sgavin#define rotl_optab (optab_table[OTI_rotl])
301223328Sgavin#define rotr_optab (optab_table[OTI_rotr])
302223328Sgavin#define smin_optab (optab_table[OTI_smin])
30379971Sobrien#define smax_optab (optab_table[OTI_smax])
30479971Sobrien#define umin_optab (optab_table[OTI_umin])
30579971Sobrien#define umax_optab (optab_table[OTI_umax])
30679971Sobrien#define pow_optab (optab_table[OTI_pow])
30779971Sobrien#define atan2_optab (optab_table[OTI_atan2])
30879971Sobrien
309223328Sgavin#define mov_optab (optab_table[OTI_mov])
310223328Sgavin#define movstrict_optab (optab_table[OTI_movstrict])
31179971Sobrien#define movmisalign_optab (optab_table[OTI_movmisalign])
312223328Sgavin
313223328Sgavin#define neg_optab (optab_table[OTI_neg])
314223328Sgavin#define negv_optab (optab_table[OTI_negv])
315223328Sgavin#define abs_optab (optab_table[OTI_abs])
31679971Sobrien#define absv_optab (optab_table[OTI_absv])
31779971Sobrien#define one_cmpl_optab (optab_table[OTI_one_cmpl])
31879971Sobrien#define ffs_optab (optab_table[OTI_ffs])
31979971Sobrien#define clz_optab (optab_table[OTI_clz])
32079971Sobrien#define ctz_optab (optab_table[OTI_ctz])
32179971Sobrien#define popcount_optab (optab_table[OTI_popcount])
32279971Sobrien#define parity_optab (optab_table[OTI_parity])
32379971Sobrien#define sqrt_optab (optab_table[OTI_sqrt])
32479971Sobrien#define sincos_optab (optab_table[OTI_sincos])
32579971Sobrien#define sin_optab (optab_table[OTI_sin])
326#define asin_optab (optab_table[OTI_asin])
327#define cos_optab (optab_table[OTI_cos])
328#define acos_optab (optab_table[OTI_acos])
329#define exp_optab (optab_table[OTI_exp])
330#define exp10_optab (optab_table[OTI_exp10])
331#define exp2_optab (optab_table[OTI_exp2])
332#define expm1_optab (optab_table[OTI_expm1])
333#define ldexp_optab (optab_table[OTI_ldexp])
334#define logb_optab (optab_table[OTI_logb])
335#define ilogb_optab (optab_table[OTI_ilogb])
336#define log_optab (optab_table[OTI_log])
337#define log10_optab (optab_table[OTI_log10])
338#define log2_optab (optab_table[OTI_log2])
339#define log1p_optab (optab_table[OTI_log1p])
340#define floor_optab (optab_table[OTI_floor])
341#define lfloor_optab (optab_table[OTI_lfloor])
342#define ceil_optab (optab_table[OTI_ceil])
343#define lceil_optab (optab_table[OTI_lceil])
344#define btrunc_optab (optab_table[OTI_btrunc])
345#define round_optab (optab_table[OTI_round])
346#define nearbyint_optab (optab_table[OTI_nearbyint])
347#define rint_optab (optab_table[OTI_rint])
348#define lrint_optab (optab_table[OTI_lrint])
349#define tan_optab (optab_table[OTI_tan])
350#define atan_optab (optab_table[OTI_atan])
351#define copysign_optab (optab_table[OTI_copysign])
352
353#define cmp_optab (optab_table[OTI_cmp])
354#define ucmp_optab (optab_table[OTI_ucmp])
355#define tst_optab (optab_table[OTI_tst])
356
357#define eq_optab (optab_table[OTI_eq])
358#define ne_optab (optab_table[OTI_ne])
359#define gt_optab (optab_table[OTI_gt])
360#define ge_optab (optab_table[OTI_ge])
361#define lt_optab (optab_table[OTI_lt])
362#define le_optab (optab_table[OTI_le])
363#define unord_optab (optab_table[OTI_unord])
364
365#define strlen_optab (optab_table[OTI_strlen])
366
367#define cbranch_optab (optab_table[OTI_cbranch])
368#define cmov_optab (optab_table[OTI_cmov])
369#define cstore_optab (optab_table[OTI_cstore])
370#define push_optab (optab_table[OTI_push])
371#define addcc_optab (optab_table[OTI_addcc])
372
373#define reduc_smax_optab (optab_table[OTI_reduc_smax])
374#define reduc_umax_optab (optab_table[OTI_reduc_umax])
375#define reduc_smin_optab (optab_table[OTI_reduc_smin])
376#define reduc_umin_optab (optab_table[OTI_reduc_umin])
377#define reduc_splus_optab (optab_table[OTI_reduc_splus])
378#define reduc_uplus_optab (optab_table[OTI_reduc_uplus])
379
380#define ssum_widen_optab (optab_table[OTI_ssum_widen])
381#define usum_widen_optab (optab_table[OTI_usum_widen])
382#define sdot_prod_optab (optab_table[OTI_sdot_prod])
383#define udot_prod_optab (optab_table[OTI_udot_prod])
384
385#define vec_set_optab (optab_table[OTI_vec_set])
386#define vec_extract_optab (optab_table[OTI_vec_extract])
387#define vec_init_optab (optab_table[OTI_vec_init])
388#define vec_shl_optab (optab_table[OTI_vec_shl])
389#define vec_shr_optab (optab_table[OTI_vec_shr])
390#define vec_realign_load_optab (optab_table[OTI_vec_realign_load])
391
392#define powi_optab (optab_table[OTI_powi])
393
394/* Conversion optabs have their own table and indexes.  */
395enum convert_optab_index
396{
397  COI_sext,
398  COI_zext,
399  COI_trunc,
400
401  COI_sfix,
402  COI_ufix,
403
404  COI_sfixtrunc,
405  COI_ufixtrunc,
406
407  COI_sfloat,
408  COI_ufloat,
409
410  COI_MAX
411};
412
413extern GTY(()) convert_optab convert_optab_table[COI_MAX];
414
415#define sext_optab (convert_optab_table[COI_sext])
416#define zext_optab (convert_optab_table[COI_zext])
417#define trunc_optab (convert_optab_table[COI_trunc])
418#define sfix_optab (convert_optab_table[COI_sfix])
419#define ufix_optab (convert_optab_table[COI_ufix])
420#define sfixtrunc_optab (convert_optab_table[COI_sfixtrunc])
421#define ufixtrunc_optab (convert_optab_table[COI_ufixtrunc])
422#define sfloat_optab (convert_optab_table[COI_sfloat])
423#define ufloat_optab (convert_optab_table[COI_ufloat])
424
425/* These arrays record the insn_code of insns that may be needed to
426   perform input and output reloads of special objects.  They provide a
427   place to pass a scratch register.  */
428extern enum insn_code reload_in_optab[NUM_MACHINE_MODES];
429extern enum insn_code reload_out_optab[NUM_MACHINE_MODES];
430
431/* Contains the optab used for each rtx code.  */
432extern GTY(()) optab code_to_optab[NUM_RTX_CODE + 1];
433
434
435typedef rtx (*rtxfun) (rtx);
436
437/* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...)
438   gives the gen_function to make a branch to test that condition.  */
439
440extern rtxfun bcc_gen_fctn[NUM_RTX_CODE];
441
442/* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...)
443   gives the insn code to make a store-condition insn
444   to test that condition.  */
445
446extern enum insn_code setcc_gen_code[NUM_RTX_CODE];
447
448#ifdef HAVE_conditional_move
449/* Indexed by the machine mode, gives the insn code to make a conditional
450   move insn.  */
451
452extern enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
453#endif
454
455/* Indexed by the machine mode, gives the insn code for vector conditional
456   operation.  */
457
458extern enum insn_code vcond_gen_code[NUM_MACHINE_MODES];
459extern enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
460
461/* This array records the insn_code of insns to perform block moves.  */
462extern enum insn_code movmem_optab[NUM_MACHINE_MODES];
463
464/* This array records the insn_code of insns to perform block sets.  */
465extern enum insn_code setmem_optab[NUM_MACHINE_MODES];
466
467/* These arrays record the insn_code of two different kinds of insns
468   to perform block compares.  */
469extern enum insn_code cmpstr_optab[NUM_MACHINE_MODES];
470extern enum insn_code cmpstrn_optab[NUM_MACHINE_MODES];
471extern enum insn_code cmpmem_optab[NUM_MACHINE_MODES];
472
473/* Synchronization primitives.  This first set is atomic operation for
474   which we don't care about the resulting value.  */
475extern enum insn_code sync_add_optab[NUM_MACHINE_MODES];
476extern enum insn_code sync_sub_optab[NUM_MACHINE_MODES];
477extern enum insn_code sync_ior_optab[NUM_MACHINE_MODES];
478extern enum insn_code sync_and_optab[NUM_MACHINE_MODES];
479extern enum insn_code sync_xor_optab[NUM_MACHINE_MODES];
480extern enum insn_code sync_nand_optab[NUM_MACHINE_MODES];
481
482/* This second set is atomic operations in which we return the value
483   that existed in memory before the operation.  */
484extern enum insn_code sync_old_add_optab[NUM_MACHINE_MODES];
485extern enum insn_code sync_old_sub_optab[NUM_MACHINE_MODES];
486extern enum insn_code sync_old_ior_optab[NUM_MACHINE_MODES];
487extern enum insn_code sync_old_and_optab[NUM_MACHINE_MODES];
488extern enum insn_code sync_old_xor_optab[NUM_MACHINE_MODES];
489extern enum insn_code sync_old_nand_optab[NUM_MACHINE_MODES];
490
491/* This third set is atomic operations in which we return the value
492   that resulted after performing the operation.  */
493extern enum insn_code sync_new_add_optab[NUM_MACHINE_MODES];
494extern enum insn_code sync_new_sub_optab[NUM_MACHINE_MODES];
495extern enum insn_code sync_new_ior_optab[NUM_MACHINE_MODES];
496extern enum insn_code sync_new_and_optab[NUM_MACHINE_MODES];
497extern enum insn_code sync_new_xor_optab[NUM_MACHINE_MODES];
498extern enum insn_code sync_new_nand_optab[NUM_MACHINE_MODES];
499
500/* Atomic compare and swap.  */
501extern enum insn_code sync_compare_and_swap[NUM_MACHINE_MODES];
502extern enum insn_code sync_compare_and_swap_cc[NUM_MACHINE_MODES];
503
504/* Atomic exchange with acquire semantics.  */
505extern enum insn_code sync_lock_test_and_set[NUM_MACHINE_MODES];
506
507/* Atomic clear with release semantics.  */
508extern enum insn_code sync_lock_release[NUM_MACHINE_MODES];
509
510/* Define functions given in optabs.c.  */
511
512extern rtx expand_widen_pattern_expr (tree exp, rtx op0, rtx op1, rtx wide_op,
513                                      rtx target, int unsignedp);
514
515extern rtx expand_ternary_op (enum machine_mode mode, optab ternary_optab,
516			      rtx op0, rtx op1, rtx op2, rtx target,
517			      int unsignedp);
518
519/* Expand a binary operation given optab and rtx operands.  */
520extern rtx expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int,
521			 enum optab_methods);
522
523extern bool force_expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int,
524				enum optab_methods);
525
526/* Expand a binary operation with both signed and unsigned forms.  */
527extern rtx sign_expand_binop (enum machine_mode, optab, optab, rtx, rtx,
528			      rtx, int, enum optab_methods);
529
530/* Generate code to perform an operation on one operand with two results.  */
531extern int expand_twoval_unop (optab, rtx, rtx, rtx, int);
532
533/* Generate code to perform an operation on two operands with two results.  */
534extern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int);
535
536/* Generate code to perform an operation on two operands with two
537   results, using a library function.  */
538extern bool expand_twoval_binop_libfunc (optab, rtx, rtx, rtx, rtx,
539					 enum rtx_code);
540
541/* Expand a unary arithmetic operation given optab rtx operand.  */
542extern rtx expand_unop (enum machine_mode, optab, rtx, rtx, int);
543
544/* Expand the absolute value operation.  */
545extern rtx expand_abs_nojump (enum machine_mode, rtx, rtx, int);
546extern rtx expand_abs (enum machine_mode, rtx, rtx, int, int);
547
548/* Expand the copysign operation.  */
549extern rtx expand_copysign (rtx, rtx, rtx);
550
551/* Generate an instruction with a given INSN_CODE with an output and
552   an input.  */
553extern void emit_unop_insn (int, rtx, rtx, enum rtx_code);
554
555/* Emit code to perform a series of operations on a multi-word quantity, one
556   word at a time.  */
557extern rtx emit_no_conflict_block (rtx, rtx, rtx, rtx, rtx);
558
559/* Emit one rtl insn to compare two rtx's.  */
560extern void emit_cmp_insn (rtx, rtx, enum rtx_code, rtx, enum machine_mode,
561			   int);
562
563/* The various uses that a comparison can have; used by can_compare_p:
564   jumps, conditional moves, store flag operations.  */
565enum can_compare_purpose
566{
567  ccp_jump,
568  ccp_cmov,
569  ccp_store_flag
570};
571
572/* Return the optab used for computing the given operation on the type
573   given by the second argument.  */
574extern optab optab_for_tree_code (enum tree_code, tree);
575
576/* Nonzero if a compare of mode MODE can be done straightforwardly
577   (without splitting it into pieces).  */
578extern int can_compare_p (enum rtx_code, enum machine_mode,
579			  enum can_compare_purpose);
580
581/* Return the INSN_CODE to use for an extend operation.  */
582extern enum insn_code can_extend_p (enum machine_mode, enum machine_mode, int);
583
584/* Generate the body of an insn to extend Y (with mode MFROM)
585   into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
586extern rtx gen_extend_insn (rtx, rtx, enum machine_mode,
587			    enum machine_mode, int);
588
589/* Call this to reset the function entry for one optab.  */
590extern void set_optab_libfunc (optab, enum machine_mode, const char *);
591extern void set_conv_libfunc (convert_optab, enum machine_mode,
592			      enum machine_mode, const char *);
593
594/* Generate code for a FLOAT_EXPR.  */
595extern void expand_float (rtx, rtx, int);
596
597/* Generate code for a FIX_EXPR.  */
598extern void expand_fix (rtx, rtx, int);
599
600/* Return tree if target supports vector operations for COND_EXPR.  */
601bool expand_vec_cond_expr_p (tree, enum machine_mode);
602
603/* Generate code for VEC_COND_EXPR.  */
604extern rtx expand_vec_cond_expr (tree, rtx);
605
606/* Generate code for VEC_LSHIFT_EXPR and VEC_RSHIFT_EXPR.  */
607extern rtx expand_vec_shift_expr (tree, rtx);
608
609#endif /* GCC_OPTABS_H */
610