diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-24 18:28:15 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-24 18:28:15 +0000 |
commit | ee65118b7cf6bdb7a115ba1a7e01a94f1617d5a4 (patch) | |
tree | 7a5f81d480a16d01d04ed37f989cde0c027bbf45 /gcc/optabs.h | |
parent | 41622801acdf740c6e7b3f69b4a639b69a078dff (diff) | |
download | gcc-ee65118b7cf6bdb7a115ba1a7e01a94f1617d5a4.tar.gz |
Reduce the size of optabs representation
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189821 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs.h')
-rw-r--r-- | gcc/optabs.h | 960 |
1 files changed, 94 insertions, 866 deletions
diff --git a/gcc/optabs.h b/gcc/optabs.h index 60f83cff8a5..e0be2bac4fd 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -22,656 +22,34 @@ along with GCC; see the file COPYING3. If not see #define GCC_OPTABS_H #include "insn-codes.h" +#include "insn-opinit.h" -/* Optabs are tables saying how to generate insn bodies - for various machine modes and numbers of operands. - Each optab applies to one operation. +typedef enum optab_tag optab; +typedef enum optab_tag convert_optab; +typedef enum optab_tag direct_optab; - For example, add_optab applies to addition. - - The insn_code slot is the enum insn_code that says how to - generate an insn for this operation on a particular machine mode. - It is CODE_FOR_nothing if there is no such insn on the target machine. - - The `lib_call' slot is the name of the library function that - can be used to perform the operation. - - A few optabs, such as move_optab, are used by special code. */ - -struct optab_handlers -{ - enum insn_code insn_code; -}; - -struct widening_optab_handlers -{ - struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES]; -}; - -struct optab_d +struct optab_libcall_d { - enum rtx_code code_; char libcall_suffix; const char *libcall_basename; - void (*libcall_gen)(struct optab_d *, const char *name, char suffix, - enum machine_mode); - struct optab_handlers handlers[NUM_MACHINE_MODES]; - struct widening_optab_handlers *widening; + void (*libcall_gen) (optab, const char *name, + char suffix, enum machine_mode); }; -typedef struct optab_d * optab; -/* A convert_optab is for some sort of conversion operation between - modes. The first array index is the destination mode, the second - is the source mode. */ -struct convert_optab_d +struct convert_optab_libcall_d { - enum rtx_code code_; const char *libcall_basename; - void (*libcall_gen)(struct convert_optab_d *, const char *name, - enum machine_mode, - enum machine_mode); - struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES]; + void (*libcall_gen) (convert_optab, const char *name, + enum machine_mode, enum machine_mode); }; -typedef struct convert_optab_d *convert_optab; /* Given an enum insn_code, access the function to construct the body of that kind of insn. */ #define GEN_FCN(CODE) (insn_data[CODE].genfun) -/* Enumeration of valid indexes into optab_table. */ -enum optab_index -{ - /* Fixed-point operators with signed/unsigned saturation */ - OTI_ssadd, - OTI_usadd, - OTI_sssub, - OTI_ussub, - OTI_ssmul, - OTI_usmul, - OTI_ssdiv, - OTI_usdiv, - OTI_ssneg, - OTI_usneg, - OTI_ssashl, - OTI_usashl, - - OTI_add, - OTI_addv, - OTI_sub, - OTI_subv, - - /* Signed and fp multiply */ - OTI_smul, - OTI_smulv, - /* Signed multiply, return high word */ - OTI_smul_highpart, - OTI_umul_highpart, - /* Signed multiply with result one machine mode wider than args */ - OTI_smul_widen, - OTI_umul_widen, - /* Widening multiply of one unsigned and one signed operand. */ - OTI_usmul_widen, - /* Signed multiply and add with the result and addend one machine mode - wider than the multiplicand and multiplier. */ - OTI_smadd_widen, - /* Unsigned multiply and add with the result and addend one machine mode - wider than the multiplicand and multiplier. */ - OTI_umadd_widen, - /* Signed multiply and add with the result and addend one machine mode - wider than the multiplicand and multiplier. - All involved operations are saturating. */ - OTI_ssmadd_widen, - /* Unsigned multiply and add with the result and addend one machine mode - wider than the multiplicand and multiplier. - All involved operations are saturating. */ - OTI_usmadd_widen, - /* Signed multiply and subtract the result and minuend one machine mode - wider than the multiplicand and multiplier. */ - OTI_smsub_widen, - /* Unsigned multiply and subtract the result and minuend one machine mode - wider than the multiplicand and multiplier. */ - OTI_umsub_widen, - /* Signed multiply and subtract the result and minuend one machine mode - wider than the multiplicand and multiplier. - All involved operations are saturating. */ - OTI_ssmsub_widen, - /* Unsigned multiply and subtract the result and minuend one machine mode - wider than the multiplicand and multiplier. - All involved operations are saturating. */ - OTI_usmsub_widen, - - /* Signed divide */ - OTI_sdiv, - OTI_sdivv, - /* Signed divide-and-remainder in one */ - OTI_sdivmod, - OTI_udiv, - OTI_udivmod, - /* Signed remainder */ - OTI_smod, - OTI_umod, - /* Floating point remainder functions */ - OTI_fmod, - OTI_remainder, - /* Convert float to integer in float fmt */ - OTI_ftrunc, - - /* Logical and */ - OTI_and, - /* Logical or */ - OTI_ior, - /* Logical xor */ - OTI_xor, - - /* Arithmetic shift left */ - OTI_ashl, - /* Logical shift right */ - OTI_lshr, - /* Arithmetic shift right */ - OTI_ashr, - /* Rotate left */ - OTI_rotl, - /* Rotate right */ - OTI_rotr, - - /* Arithmetic shift left of vector by vector */ - OTI_vashl, - /* Logical shift right of vector by vector */ - OTI_vlshr, - /* Arithmetic shift right of vector by vector */ - OTI_vashr, - /* Rotate left of vector by vector */ - OTI_vrotl, - /* Rotate right of vector by vector */ - OTI_vrotr, - - /* Signed and floating-point minimum value */ - OTI_smin, - /* Signed and floating-point maximum value */ - OTI_smax, - /* Unsigned minimum value */ - OTI_umin, - /* Unsigned maximum value */ - OTI_umax, - /* Power */ - OTI_pow, - /* Arc tangent of y/x */ - OTI_atan2, - /* Floating multiply/add */ - OTI_fma, - OTI_fms, - OTI_fnma, - OTI_fnms, - - /* Move instruction. */ - OTI_mov, - /* Move, preserving high part of register. */ - OTI_movstrict, - /* Move, with a misaligned memory. */ - OTI_movmisalign, - /* Nontemporal store. */ - OTI_storent, - - /* Unary operations */ - /* Negation */ - OTI_neg, - OTI_negv, - /* Abs value */ - OTI_abs, - OTI_absv, - /* Byteswap */ - OTI_bswap, - /* Bitwise not */ - OTI_one_cmpl, - /* Bit scanning and counting */ - OTI_ffs, - OTI_clz, - OTI_ctz, - OTI_clrsb, - OTI_popcount, - OTI_parity, - /* Square root */ - OTI_sqrt, - /* Sine-Cosine */ - OTI_sincos, - /* Sine */ - OTI_sin, - /* Inverse sine */ - OTI_asin, - /* Cosine */ - OTI_cos, - /* Inverse cosine */ - OTI_acos, - /* Exponential */ - OTI_exp, - /* Base-10 Exponential */ - OTI_exp10, - /* Base-2 Exponential */ - OTI_exp2, - /* Exponential - 1*/ - OTI_expm1, - /* Load exponent of a floating point number */ - OTI_ldexp, - /* Multiply floating-point number by integral power of radix */ - OTI_scalb, - /* Mantissa of a floating-point number */ - OTI_significand, - /* Radix-independent exponent */ - OTI_logb, - OTI_ilogb, - /* Natural Logarithm */ - OTI_log, - /* Base-10 Logarithm */ - OTI_log10, - /* Base-2 Logarithm */ - OTI_log2, - /* logarithm of 1 plus argument */ - OTI_log1p, - /* Rounding functions */ - OTI_floor, - OTI_ceil, - OTI_btrunc, - OTI_round, - OTI_nearbyint, - OTI_rint, - /* Tangent */ - OTI_tan, - /* Inverse tangent */ - OTI_atan, - /* Copy sign */ - OTI_copysign, - /* Signbit */ - OTI_signbit, - /* Test for infinite value */ - OTI_isinf, - - /* Compare insn; two operands. Used only for libcalls. */ - OTI_cmp, - OTI_ucmp, - - /* Floating point comparison optabs - used primarily for libfuncs */ - OTI_eq, - OTI_ne, - OTI_gt, - OTI_ge, - OTI_lt, - OTI_le, - OTI_unord, - - /* String length */ - OTI_strlen, - - /* Combined compare & jump/move/store flags/trap operations. */ - OTI_cbranch, - OTI_cmov, - OTI_cstore, - OTI_ctrap, - - /* Push instruction. */ - OTI_push, - - /* Conditional add instruction. */ - OTI_addcc, - - /* Reduction operations on a vector operand. */ - OTI_reduc_smax, - OTI_reduc_umax, - OTI_reduc_smin, - OTI_reduc_umin, - OTI_reduc_splus, - OTI_reduc_uplus, - - /* Summation, with result machine mode one or more wider than args. */ - OTI_ssum_widen, - OTI_usum_widen, - - /* Dot product, with result machine mode one or more wider than args. */ - OTI_sdot_prod, - OTI_udot_prod, - - /* Set specified field of vector operand. */ - OTI_vec_set, - /* Extract specified field of vector operand. */ - OTI_vec_extract, - /* Initialize vector operand. */ - OTI_vec_init, - /* Whole vector shift. The shift amount is in bits. */ - OTI_vec_shl, - OTI_vec_shr, - /* Extract specified elements from vectors, for vector load. */ - OTI_vec_realign_load, - /* Widening multiplication. The high/low/even/odd part of the - resulting vector of products is returned. */ - OTI_vec_widen_umult_hi, - OTI_vec_widen_umult_lo, - OTI_vec_widen_smult_hi, - OTI_vec_widen_smult_lo, - OTI_vec_widen_umult_even, - OTI_vec_widen_umult_odd, - OTI_vec_widen_smult_even, - OTI_vec_widen_smult_odd, - /* Widening shift left. - The high/low part of the resulting vector is returned. */ - OTI_vec_widen_ushiftl_hi, - OTI_vec_widen_ushiftl_lo, - OTI_vec_widen_sshiftl_hi, - OTI_vec_widen_sshiftl_lo, - /* Extract and widen the high/low part of a vector of signed or - floating point elements. */ - OTI_vec_unpacks_hi, - OTI_vec_unpacks_lo, - /* Extract and widen the high/low part of a vector of unsigned - elements. */ - OTI_vec_unpacku_hi, - OTI_vec_unpacku_lo, - - /* Extract, convert to floating point and widen the high/low part of - a vector of signed or unsigned integer elements. */ - OTI_vec_unpacks_float_hi, - OTI_vec_unpacks_float_lo, - OTI_vec_unpacku_float_hi, - OTI_vec_unpacku_float_lo, - - /* Narrow (demote) and merge the elements of two vectors. */ - OTI_vec_pack_trunc, - OTI_vec_pack_usat, - OTI_vec_pack_ssat, - - /* Convert to signed/unsigned integer, narrow and merge elements - of two vectors of floating point elements. */ - OTI_vec_pack_sfix_trunc, - OTI_vec_pack_ufix_trunc, - - /* Perform a raise to the power of integer. */ - OTI_powi, - - /* Atomic compare and swap. */ - OTI_sync_compare_and_swap, - - /* Atomic exchange with acquire semantics. */ - OTI_sync_lock_test_and_set, - - /* This second set is atomic operations in which we return the value - that existed in memory before the operation. */ - OTI_sync_old_add, - OTI_sync_old_sub, - OTI_sync_old_ior, - OTI_sync_old_and, - OTI_sync_old_xor, - OTI_sync_old_nand, - - /* This third set is atomic operations in which we return the value - that resulted after performing the operation. */ - OTI_sync_new_add, - OTI_sync_new_sub, - OTI_sync_new_ior, - OTI_sync_new_and, - OTI_sync_new_xor, - OTI_sync_new_nand, - - OTI_MAX -}; - -#define unknown_optab NULL - -#define ssadd_optab (&optab_table[OTI_ssadd]) -#define usadd_optab (&optab_table[OTI_usadd]) -#define sssub_optab (&optab_table[OTI_sssub]) -#define ussub_optab (&optab_table[OTI_ussub]) -#define ssmul_optab (&optab_table[OTI_ssmul]) -#define usmul_optab (&optab_table[OTI_usmul]) -#define ssdiv_optab (&optab_table[OTI_ssdiv]) -#define usdiv_optab (&optab_table[OTI_usdiv]) -#define ssneg_optab (&optab_table[OTI_ssneg]) -#define usneg_optab (&optab_table[OTI_usneg]) -#define ssashl_optab (&optab_table[OTI_ssashl]) -#define usashl_optab (&optab_table[OTI_usashl]) - -#define add_optab (&optab_table[OTI_add]) -#define sub_optab (&optab_table[OTI_sub]) -#define smul_optab (&optab_table[OTI_smul]) -#define addv_optab (&optab_table[OTI_addv]) -#define subv_optab (&optab_table[OTI_subv]) -#define smul_highpart_optab (&optab_table[OTI_smul_highpart]) -#define umul_highpart_optab (&optab_table[OTI_umul_highpart]) -#define smul_widen_optab (&optab_table[OTI_smul_widen]) -#define umul_widen_optab (&optab_table[OTI_umul_widen]) -#define usmul_widen_optab (&optab_table[OTI_usmul_widen]) -#define smadd_widen_optab (&optab_table[OTI_smadd_widen]) -#define umadd_widen_optab (&optab_table[OTI_umadd_widen]) -#define ssmadd_widen_optab (&optab_table[OTI_ssmadd_widen]) -#define usmadd_widen_optab (&optab_table[OTI_usmadd_widen]) -#define smsub_widen_optab (&optab_table[OTI_smsub_widen]) -#define umsub_widen_optab (&optab_table[OTI_umsub_widen]) -#define ssmsub_widen_optab (&optab_table[OTI_ssmsub_widen]) -#define usmsub_widen_optab (&optab_table[OTI_usmsub_widen]) -#define sdiv_optab (&optab_table[OTI_sdiv]) -#define smulv_optab (&optab_table[OTI_smulv]) -#define sdivv_optab (&optab_table[OTI_sdivv]) -#define sdivmod_optab (&optab_table[OTI_sdivmod]) -#define udiv_optab (&optab_table[OTI_udiv]) -#define udivmod_optab (&optab_table[OTI_udivmod]) -#define smod_optab (&optab_table[OTI_smod]) -#define umod_optab (&optab_table[OTI_umod]) -#define fmod_optab (&optab_table[OTI_fmod]) -#define remainder_optab (&optab_table[OTI_remainder]) -#define ftrunc_optab (&optab_table[OTI_ftrunc]) -#define and_optab (&optab_table[OTI_and]) -#define ior_optab (&optab_table[OTI_ior]) -#define xor_optab (&optab_table[OTI_xor]) -#define ashl_optab (&optab_table[OTI_ashl]) -#define lshr_optab (&optab_table[OTI_lshr]) -#define ashr_optab (&optab_table[OTI_ashr]) -#define rotl_optab (&optab_table[OTI_rotl]) -#define rotr_optab (&optab_table[OTI_rotr]) -#define vashl_optab (&optab_table[OTI_vashl]) -#define vlshr_optab (&optab_table[OTI_vlshr]) -#define vashr_optab (&optab_table[OTI_vashr]) -#define vrotl_optab (&optab_table[OTI_vrotl]) -#define vrotr_optab (&optab_table[OTI_vrotr]) -#define smin_optab (&optab_table[OTI_smin]) -#define smax_optab (&optab_table[OTI_smax]) -#define umin_optab (&optab_table[OTI_umin]) -#define umax_optab (&optab_table[OTI_umax]) -#define pow_optab (&optab_table[OTI_pow]) -#define atan2_optab (&optab_table[OTI_atan2]) -#define fma_optab (&optab_table[OTI_fma]) -#define fms_optab (&optab_table[OTI_fms]) -#define fnma_optab (&optab_table[OTI_fnma]) -#define fnms_optab (&optab_table[OTI_fnms]) - -#define mov_optab (&optab_table[OTI_mov]) -#define movstrict_optab (&optab_table[OTI_movstrict]) -#define movmisalign_optab (&optab_table[OTI_movmisalign]) -#define storent_optab (&optab_table[OTI_storent]) - -#define neg_optab (&optab_table[OTI_neg]) -#define negv_optab (&optab_table[OTI_negv]) -#define abs_optab (&optab_table[OTI_abs]) -#define absv_optab (&optab_table[OTI_absv]) -#define one_cmpl_optab (&optab_table[OTI_one_cmpl]) -#define bswap_optab (&optab_table[OTI_bswap]) -#define ffs_optab (&optab_table[OTI_ffs]) -#define clz_optab (&optab_table[OTI_clz]) -#define ctz_optab (&optab_table[OTI_ctz]) -#define clrsb_optab (&optab_table[OTI_clrsb]) -#define popcount_optab (&optab_table[OTI_popcount]) -#define parity_optab (&optab_table[OTI_parity]) -#define sqrt_optab (&optab_table[OTI_sqrt]) -#define sincos_optab (&optab_table[OTI_sincos]) -#define sin_optab (&optab_table[OTI_sin]) -#define asin_optab (&optab_table[OTI_asin]) -#define cos_optab (&optab_table[OTI_cos]) -#define acos_optab (&optab_table[OTI_acos]) -#define exp_optab (&optab_table[OTI_exp]) -#define exp10_optab (&optab_table[OTI_exp10]) -#define exp2_optab (&optab_table[OTI_exp2]) -#define expm1_optab (&optab_table[OTI_expm1]) -#define ldexp_optab (&optab_table[OTI_ldexp]) -#define scalb_optab (&optab_table[OTI_scalb]) -#define significand_optab (&optab_table[OTI_significand]) -#define logb_optab (&optab_table[OTI_logb]) -#define ilogb_optab (&optab_table[OTI_ilogb]) -#define log_optab (&optab_table[OTI_log]) -#define log10_optab (&optab_table[OTI_log10]) -#define log2_optab (&optab_table[OTI_log2]) -#define log1p_optab (&optab_table[OTI_log1p]) -#define floor_optab (&optab_table[OTI_floor]) -#define ceil_optab (&optab_table[OTI_ceil]) -#define btrunc_optab (&optab_table[OTI_btrunc]) -#define round_optab (&optab_table[OTI_round]) -#define nearbyint_optab (&optab_table[OTI_nearbyint]) -#define rint_optab (&optab_table[OTI_rint]) -#define tan_optab (&optab_table[OTI_tan]) -#define atan_optab (&optab_table[OTI_atan]) -#define copysign_optab (&optab_table[OTI_copysign]) -#define signbit_optab (&optab_table[OTI_signbit]) -#define isinf_optab (&optab_table[OTI_isinf]) - -#define cmp_optab (&optab_table[OTI_cmp]) -#define ucmp_optab (&optab_table[OTI_ucmp]) - -#define eq_optab (&optab_table[OTI_eq]) -#define ne_optab (&optab_table[OTI_ne]) -#define gt_optab (&optab_table[OTI_gt]) -#define ge_optab (&optab_table[OTI_ge]) -#define lt_optab (&optab_table[OTI_lt]) -#define le_optab (&optab_table[OTI_le]) -#define unord_optab (&optab_table[OTI_unord]) - -#define strlen_optab (&optab_table[OTI_strlen]) - -#define cbranch_optab (&optab_table[OTI_cbranch]) -#define cmov_optab (&optab_table[OTI_cmov]) -#define cstore_optab (&optab_table[OTI_cstore]) -#define ctrap_optab (&optab_table[OTI_ctrap]) - -#define push_optab (&optab_table[OTI_push]) -#define addcc_optab (&optab_table[OTI_addcc]) - -#define reduc_smax_optab (&optab_table[OTI_reduc_smax]) -#define reduc_umax_optab (&optab_table[OTI_reduc_umax]) -#define reduc_smin_optab (&optab_table[OTI_reduc_smin]) -#define reduc_umin_optab (&optab_table[OTI_reduc_umin]) -#define reduc_splus_optab (&optab_table[OTI_reduc_splus]) -#define reduc_uplus_optab (&optab_table[OTI_reduc_uplus]) - -#define ssum_widen_optab (&optab_table[OTI_ssum_widen]) -#define usum_widen_optab (&optab_table[OTI_usum_widen]) -#define sdot_prod_optab (&optab_table[OTI_sdot_prod]) -#define udot_prod_optab (&optab_table[OTI_udot_prod]) - -#define vec_set_optab (&optab_table[OTI_vec_set]) -#define vec_extract_optab (&optab_table[OTI_vec_extract]) -#define vec_init_optab (&optab_table[OTI_vec_init]) -#define vec_shl_optab (&optab_table[OTI_vec_shl]) -#define vec_shr_optab (&optab_table[OTI_vec_shr]) -#define vec_realign_load_optab (&optab_table[OTI_vec_realign_load]) -#define vec_widen_umult_hi_optab (&optab_table[OTI_vec_widen_umult_hi]) -#define vec_widen_umult_lo_optab (&optab_table[OTI_vec_widen_umult_lo]) -#define vec_widen_smult_hi_optab (&optab_table[OTI_vec_widen_smult_hi]) -#define vec_widen_smult_lo_optab (&optab_table[OTI_vec_widen_smult_lo]) -#define vec_widen_umult_even_optab (&optab_table[OTI_vec_widen_umult_even]) -#define vec_widen_umult_odd_optab (&optab_table[OTI_vec_widen_umult_odd]) -#define vec_widen_smult_even_optab (&optab_table[OTI_vec_widen_smult_even]) -#define vec_widen_smult_odd_optab (&optab_table[OTI_vec_widen_smult_odd]) -#define vec_widen_ushiftl_hi_optab (&optab_table[OTI_vec_widen_ushiftl_hi]) -#define vec_widen_ushiftl_lo_optab (&optab_table[OTI_vec_widen_ushiftl_lo]) -#define vec_widen_sshiftl_hi_optab (&optab_table[OTI_vec_widen_sshiftl_hi]) -#define vec_widen_sshiftl_lo_optab (&optab_table[OTI_vec_widen_sshiftl_lo]) -#define vec_unpacks_hi_optab (&optab_table[OTI_vec_unpacks_hi]) -#define vec_unpacks_lo_optab (&optab_table[OTI_vec_unpacks_lo]) -#define vec_unpacku_hi_optab (&optab_table[OTI_vec_unpacku_hi]) -#define vec_unpacku_lo_optab (&optab_table[OTI_vec_unpacku_lo]) -#define vec_unpacks_float_hi_optab (&optab_table[OTI_vec_unpacks_float_hi]) -#define vec_unpacks_float_lo_optab (&optab_table[OTI_vec_unpacks_float_lo]) -#define vec_unpacku_float_hi_optab (&optab_table[OTI_vec_unpacku_float_hi]) -#define vec_unpacku_float_lo_optab (&optab_table[OTI_vec_unpacku_float_lo]) -#define vec_pack_trunc_optab (&optab_table[OTI_vec_pack_trunc]) -#define vec_pack_ssat_optab (&optab_table[OTI_vec_pack_ssat]) -#define vec_pack_usat_optab (&optab_table[OTI_vec_pack_usat]) -#define vec_pack_sfix_trunc_optab (&optab_table[OTI_vec_pack_sfix_trunc]) -#define vec_pack_ufix_trunc_optab (&optab_table[OTI_vec_pack_ufix_trunc]) - -#define powi_optab (&optab_table[OTI_powi]) - -#define sync_compare_and_swap_optab \ - (&optab_table[(int) OTI_sync_compare_and_swap]) -#define sync_lock_test_and_set_optab \ - (&optab_table[(int) OTI_sync_lock_test_and_set]) -#define sync_old_add_optab (&optab_table[(int) OTI_sync_old_add]) -#define sync_old_sub_optab (&optab_table[(int) OTI_sync_old_sub]) -#define sync_old_ior_optab (&optab_table[(int) OTI_sync_old_ior]) -#define sync_old_and_optab (&optab_table[(int) OTI_sync_old_and]) -#define sync_old_xor_optab (&optab_table[(int) OTI_sync_old_xor]) -#define sync_old_nand_optab (&optab_table[(int) OTI_sync_old_nand]) -#define sync_new_add_optab (&optab_table[(int) OTI_sync_new_add]) -#define sync_new_sub_optab (&optab_table[(int) OTI_sync_new_sub]) -#define sync_new_ior_optab (&optab_table[(int) OTI_sync_new_ior]) -#define sync_new_and_optab (&optab_table[(int) OTI_sync_new_and]) -#define sync_new_xor_optab (&optab_table[(int) OTI_sync_new_xor]) -#define sync_new_nand_optab (&optab_table[(int) OTI_sync_new_nand]) - -/* Conversion optabs have their own table and indexes. */ -enum convert_optab_index -{ - COI_sext, - COI_zext, - COI_trunc, - - COI_sfix, - COI_ufix, - - COI_sfixtrunc, - COI_ufixtrunc, - - COI_sfloat, - COI_ufloat, - - COI_lrint, - COI_lround, - COI_lfloor, - COI_lceil, - - COI_fract, - COI_fractuns, - COI_satfract, - COI_satfractuns, - - COI_vec_load_lanes, - COI_vec_store_lanes, - - /* Vector conditional operations. */ - COI_vcond, - COI_vcondu, - - COI_MAX -}; - -#define sext_optab (&convert_optab_table[COI_sext]) -#define zext_optab (&convert_optab_table[COI_zext]) -#define trunc_optab (&convert_optab_table[COI_trunc]) -#define sfix_optab (&convert_optab_table[COI_sfix]) -#define ufix_optab (&convert_optab_table[COI_ufix]) -#define sfixtrunc_optab (&convert_optab_table[COI_sfixtrunc]) -#define ufixtrunc_optab (&convert_optab_table[COI_ufixtrunc]) -#define sfloat_optab (&convert_optab_table[COI_sfloat]) -#define ufloat_optab (&convert_optab_table[COI_ufloat]) -#define lrint_optab (&convert_optab_table[COI_lrint]) -#define lround_optab (&convert_optab_table[COI_lround]) -#define lfloor_optab (&convert_optab_table[COI_lfloor]) -#define lceil_optab (&convert_optab_table[COI_lceil]) -#define fract_optab (&convert_optab_table[COI_fract]) -#define fractuns_optab (&convert_optab_table[COI_fractuns]) -#define satfract_optab (&convert_optab_table[COI_satfract]) -#define satfractuns_optab (&convert_optab_table[COI_satfractuns]) -#define vec_load_lanes_optab (&convert_optab_table[COI_vec_load_lanes]) -#define vec_store_lanes_optab (&convert_optab_table[COI_vec_store_lanes]) -#define vcond_optab (&convert_optab_table[(int) COI_vcond]) -#define vcondu_optab (&convert_optab_table[(int) COI_vcondu]) - -/* Contains the optab used for each rtx code. */ -extern optab code_to_optab_[NUM_RTX_CODE + 1]; +/* Contains the optab used for each rtx code, and vice-versa. */ +extern const optab code_to_optab_[NUM_RTX_CODE]; +extern const enum rtx_code optab_to_code_[NUM_OPTABS]; static inline optab code_to_optab (enum rtx_code code) @@ -679,176 +57,23 @@ code_to_optab (enum rtx_code code) return code_to_optab_[code]; } -#define optab_to_code(op) ((op)->code_) - - -typedef rtx (*rtxfun) (rtx); - -/* Enumerates operations that have a named .md pattern associated - with them, but which are not implemented as library functions. */ -enum direct_optab_index +static inline enum rtx_code +optab_to_code (optab op) { -#ifdef HAVE_conditional_move - /* Conditional move operations. */ - DOI_movcc, -#endif + return optab_to_code_[op]; +} - /* Operations that use a scratch register to perform input and output - reloads of special objects. */ - DOI_reload_in, - DOI_reload_out, - - /* Block move operation. */ - DOI_movmem, - - /* Block set operation. */ - DOI_setmem, - - /* Various types of block compare operation. */ - DOI_cmpstr, - DOI_cmpstrn, - DOI_cmpmem, - - /* Atomic clear with release semantics. */ - DOI_sync_lock_release, - - /* Atomic operation with no resulting value. */ - DOI_sync_add, - DOI_sync_sub, - DOI_sync_ior, - DOI_sync_and, - DOI_sync_xor, - DOI_sync_nand, - - /* Atomic operations with memory model parameters. */ - DOI_atomic_exchange, - DOI_atomic_compare_and_swap, - DOI_atomic_load, - DOI_atomic_store, - DOI_atomic_add_fetch, - DOI_atomic_sub_fetch, - DOI_atomic_and_fetch, - DOI_atomic_nand_fetch, - DOI_atomic_xor_fetch, - DOI_atomic_or_fetch, - DOI_atomic_fetch_add, - DOI_atomic_fetch_sub, - DOI_atomic_fetch_and, - DOI_atomic_fetch_nand, - DOI_atomic_fetch_xor, - DOI_atomic_fetch_or, - DOI_atomic_add, - DOI_atomic_sub, - DOI_atomic_and, - DOI_atomic_nand, - DOI_atomic_xor, - DOI_atomic_or, - DOI_atomic_always_lock_free, - DOI_atomic_is_lock_free, - DOI_atomic_thread_fence, - DOI_atomic_signal_fence, - - /* Vector permutation. */ - DOI_vec_perm, - DOI_vec_perm_const, - - DOI_MAX -}; +extern const struct convert_optab_libcall_d convlib_def[NUM_CONVLIB_OPTABS]; +extern const struct optab_libcall_d normlib_def[NUM_NORMLIB_OPTABS]; -/* A structure that says which insn should be used to perform an operation - in a particular mode. */ -struct direct_optab_d -{ - struct optab_handlers handlers[NUM_MACHINE_MODES]; -}; -typedef struct direct_optab_d *direct_optab; +/* Returns the active icode for the given (encoded) optab. */ +extern enum insn_code raw_optab_handler (unsigned); +extern bool swap_optab_enable (optab, enum machine_mode, bool); -#ifdef HAVE_conditional_move -#define movcc_optab (&direct_optab_table[(int) DOI_movcc]) -#endif -#define reload_in_optab (&direct_optab_table[(int) DOI_reload_in]) -#define reload_out_optab (&direct_optab_table[(int) DOI_reload_out]) -#define movmem_optab (&direct_optab_table[(int) DOI_movmem]) -#define setmem_optab (&direct_optab_table[(int) DOI_setmem]) -#define cmpstr_optab (&direct_optab_table[(int) DOI_cmpstr]) -#define cmpstrn_optab (&direct_optab_table[(int) DOI_cmpstrn]) -#define cmpmem_optab (&direct_optab_table[(int) DOI_cmpmem]) -#define sync_lock_release_optab \ - (&direct_optab_table[(int) DOI_sync_lock_release]) -#define sync_add_optab (&direct_optab_table[(int) DOI_sync_add]) -#define sync_sub_optab (&direct_optab_table[(int) DOI_sync_sub]) -#define sync_ior_optab (&direct_optab_table[(int) DOI_sync_ior]) -#define sync_and_optab (&direct_optab_table[(int) DOI_sync_and]) -#define sync_xor_optab (&direct_optab_table[(int) DOI_sync_xor]) -#define sync_nand_optab (&direct_optab_table[(int) DOI_sync_nand]) - -#define atomic_exchange_optab \ - (&direct_optab_table[(int) DOI_atomic_exchange]) -#define atomic_compare_and_swap_optab \ - (&direct_optab_table[(int) DOI_atomic_compare_and_swap]) -#define atomic_load_optab \ - (&direct_optab_table[(int) DOI_atomic_load]) -#define atomic_store_optab \ - (&direct_optab_table[(int) DOI_atomic_store]) -#define atomic_add_fetch_optab \ - (&direct_optab_table[(int) DOI_atomic_add_fetch]) -#define atomic_sub_fetch_optab \ - (&direct_optab_table[(int) DOI_atomic_sub_fetch]) -#define atomic_and_fetch_optab \ - (&direct_optab_table[(int) DOI_atomic_and_fetch]) -#define atomic_nand_fetch_optab \ - (&direct_optab_table[(int) DOI_atomic_nand_fetch]) -#define atomic_xor_fetch_optab \ - (&direct_optab_table[(int) DOI_atomic_xor_fetch]) -#define atomic_or_fetch_optab \ - (&direct_optab_table[(int) DOI_atomic_or_fetch]) -#define atomic_fetch_add_optab \ - (&direct_optab_table[(int) DOI_atomic_fetch_add]) -#define atomic_fetch_sub_optab \ - (&direct_optab_table[(int) DOI_atomic_fetch_sub]) -#define atomic_fetch_and_optab \ - (&direct_optab_table[(int) DOI_atomic_fetch_and]) -#define atomic_fetch_nand_optab \ - (&direct_optab_table[(int) DOI_atomic_fetch_nand]) -#define atomic_fetch_xor_optab \ - (&direct_optab_table[(int) DOI_atomic_fetch_xor]) -#define atomic_fetch_or_optab \ - (&direct_optab_table[(int) DOI_atomic_fetch_or]) -#define atomic_add_optab \ - (&direct_optab_table[(int) DOI_atomic_add]) -#define atomic_sub_optab \ - (&direct_optab_table[(int) DOI_atomic_sub]) -#define atomic_and_optab \ - (&direct_optab_table[(int) DOI_atomic_and]) -#define atomic_nand_optab \ - (&direct_optab_table[(int) DOI_atomic_nand]) -#define atomic_xor_optab \ - (&direct_optab_table[(int) DOI_atomic_xor]) -#define atomic_or_optab \ - (&direct_optab_table[(int) DOI_atomic_or]) -#define atomic_always_lock_free_optab \ - (&direct_optab_table[(int) DOI_atomic_always_lock_free]) -#define atomic_is_lock_free_optab \ - (&direct_optab_table[(int) DOI_atomic_is_lock_free]) -#define atomic_thread_fence_optab \ - (&direct_optab_table[(int) DOI_atomic_thread_fence]) -#define atomic_signal_fence_optab \ - (&direct_optab_table[(int) DOI_atomic_signal_fence]) - -#define vec_perm_optab (&direct_optab_table[DOI_vec_perm]) -#define vec_perm_const_optab (&direct_optab_table[(int) DOI_vec_perm_const]) - /* Target-dependent globals. */ struct target_optabs { - /* Tables of patterns that may have an associated libcall. */ - struct optab_d x_optab_table[(int) OTI_MAX]; - - /* Tables of patterns for converting one mode to another. */ - struct convert_optab_d x_convert_optab_table[(int) COI_MAX]; - - /* Tables of patterns for direct optabs (i.e. those which cannot be - implemented using a libcall). */ - struct direct_optab_d x_direct_optab_table[(int) DOI_MAX]; + /* Patterns that are used by optabs that are enabled for this target. */ + bool pat_enable[NUM_OPTAB_PATTERNS]; }; extern struct target_optabs default_target_optabs; @@ -857,13 +82,6 @@ extern struct target_optabs *this_target_optabs; #else #define this_target_optabs (&default_target_optabs) #endif - -#define optab_table \ - (this_target_optabs->x_optab_table) -#define convert_optab_table \ - (this_target_optabs->x_convert_optab_table) -#define direct_optab_table \ - (this_target_optabs->x_direct_optab_table) /* Define functions given in optabs.c. */ @@ -1036,49 +254,9 @@ extern rtx expand_mult_highpart (enum machine_mode, rtx, rtx, rtx, bool); static inline enum insn_code optab_handler (optab op, enum machine_mode mode) { - return op->handlers[(int) mode].insn_code; -} - -/* Like optab_handler, but for widening_operations that have a TO_MODE and - a FROM_MODE. */ - -static inline enum insn_code -widening_optab_handler (optab op, enum machine_mode to_mode, - enum machine_mode from_mode) -{ - if (to_mode == from_mode || from_mode == VOIDmode) - return optab_handler (op, to_mode); - - if (op->widening) - return op->widening->handlers[(int) to_mode][(int) from_mode].insn_code; - - return CODE_FOR_nothing; -} - -/* Record that insn CODE should be used to implement mode MODE of OP. */ - -static inline void -set_optab_handler (optab op, enum machine_mode mode, enum insn_code code) -{ - op->handlers[(int) mode].insn_code = code; -} - -/* Like set_optab_handler, but for widening operations that have a TO_MODE - and a FROM_MODE. */ - -static inline void -set_widening_optab_handler (optab op, enum machine_mode to_mode, - enum machine_mode from_mode, enum insn_code code) -{ - if (to_mode == from_mode) - set_optab_handler (op, to_mode, code); - else - { - if (op->widening == NULL) - op->widening = XCNEW (struct widening_optab_handlers); - - op->widening->handlers[(int) to_mode][(int) from_mode].insn_code = code; - } + unsigned scode = (op << 16) | mode; + gcc_assert (op > LAST_CONV_OPTAB); + return raw_optab_handler (scode); } /* Return the insn used to perform conversion OP from mode FROM_MODE @@ -1089,17 +267,28 @@ static inline enum insn_code convert_optab_handler (convert_optab op, enum machine_mode to_mode, enum machine_mode from_mode) { - return op->handlers[(int) to_mode][(int) from_mode].insn_code; + unsigned scode = (op << 16) | (from_mode << 8) | to_mode; + gcc_assert (op > unknown_optab && op <= LAST_CONV_OPTAB); + return raw_optab_handler (scode); } -/* Record that insn CODE should be used to perform conversion OP - from mode FROM_MODE to mode TO_MODE. */ +/* Like optab_handler, but for widening_operations that have a + TO_MODE and a FROM_MODE. */ -static inline void -set_convert_optab_handler (convert_optab op, enum machine_mode to_mode, - enum machine_mode from_mode, enum insn_code code) +static inline enum insn_code +widening_optab_handler (optab op, enum machine_mode to_mode, + enum machine_mode from_mode) { - op->handlers[(int) to_mode][(int) from_mode].insn_code = code; + unsigned scode = (op << 16) | to_mode; + if (to_mode != from_mode && from_mode != VOIDmode) + { + /* ??? Why does find_widening_optab_handler_and_mode attempt to + widen things that can't be widened? E.g. add_optab... */ + if (op > LAST_CONV_OPTAB) + return CODE_FOR_nothing; + scode |= from_mode << 8; + } + return raw_optab_handler (scode); } /* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing @@ -1108,16 +297,7 @@ set_convert_optab_handler (convert_optab op, enum machine_mode to_mode, static inline enum insn_code direct_optab_handler (direct_optab op, enum machine_mode mode) { - return op->handlers[(int) mode].insn_code; -} - -/* Record that insn CODE should be used to implement mode MODE of OP. */ - -static inline void -set_direct_optab_handler (direct_optab op, enum machine_mode mode, - enum insn_code code) -{ - op->handlers[(int) mode].insn_code = code; + return optab_handler (op, mode); } /* Return true if UNOPTAB is for a trapping-on-overflow operation. */ @@ -1292,4 +472,52 @@ extern void expand_jump_insn (enum insn_code icode, unsigned int nops, extern rtx prepare_operand (enum insn_code, rtx, int, enum machine_mode, enum machine_mode, int); +extern void gen_int_libfunc (optab, const char *, char, enum machine_mode); +extern void gen_fp_libfunc (optab, const char *, char, enum machine_mode); +extern void gen_fixed_libfunc (optab, const char *, char, enum machine_mode); +extern void gen_signed_fixed_libfunc (optab, const char *, char, + enum machine_mode); +extern void gen_unsigned_fixed_libfunc (optab, const char *, char, + enum machine_mode); +extern void gen_int_fp_libfunc (optab, const char *, char, enum machine_mode); +extern void gen_intv_fp_libfunc (optab, const char *, char, enum machine_mode); +extern void gen_int_fp_fixed_libfunc (optab, const char *, char, + enum machine_mode); +extern void gen_int_fp_signed_fixed_libfunc (optab, const char *, char, + enum machine_mode); +extern void gen_int_fixed_libfunc (optab, const char *, char, + enum machine_mode); +extern void gen_int_signed_fixed_libfunc (optab, const char *, char, + enum machine_mode); +extern void gen_int_unsigned_fixed_libfunc (optab, const char *, char, + enum machine_mode); + +extern void gen_interclass_conv_libfunc (convert_optab, const char *, + enum machine_mode, enum machine_mode); +extern void gen_int_to_fp_conv_libfunc (convert_optab, const char *, + enum machine_mode, enum machine_mode); +extern void gen_ufloat_conv_libfunc (convert_optab, const char *, + enum machine_mode, enum machine_mode); +extern void gen_int_to_fp_nondecimal_conv_libfunc (convert_optab, + const char *, + enum machine_mode, + enum machine_mode); +extern void gen_fp_to_int_conv_libfunc (convert_optab, const char *, + enum machine_mode, enum machine_mode); +extern void gen_intraclass_conv_libfunc (convert_optab, const char *, + enum machine_mode, enum machine_mode); +extern void gen_trunc_conv_libfunc (convert_optab, const char *, + enum machine_mode, enum machine_mode); +extern void gen_extend_conv_libfunc (convert_optab, const char *, + enum machine_mode, enum machine_mode); +extern void gen_fract_conv_libfunc (convert_optab, const char *, + enum machine_mode, enum machine_mode); +extern void gen_fractuns_conv_libfunc (convert_optab, const char *, + enum machine_mode, enum machine_mode); +extern void gen_satfract_conv_libfunc (convert_optab, const char *, + enum machine_mode, enum machine_mode); +extern void gen_satfractuns_conv_libfunc (convert_optab, const char *, + enum machine_mode, + enum machine_mode); + #endif /* GCC_OPTABS_H */ |