Mercurial > hg > CbC > CbC_gcc
diff gcc/optabs.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/optabs.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/optabs.c Tue Mar 22 17:18:12 2011 +0900 @@ -24,7 +24,7 @@ #include "system.h" #include "coretypes.h" #include "tm.h" -#include "toplev.h" +#include "diagnostic-core.h" /* Include insn-config.h before expr.h so that HAVE_conditional_move is properly defined. */ @@ -44,55 +44,19 @@ #include "basic-block.h" #include "target.h" -/* Each optab contains info on how this target machine - can perform a particular operation - for all sizes and kinds of operands. - - The operation to be performed is often specified - by passing one of these optabs as an argument. - - See expr.h for documentation of these optabs. */ - -#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS -__extension__ struct optab_d optab_table[OTI_MAX] - = { [0 ... OTI_MAX - 1].handlers[0 ... NUM_MACHINE_MODES - 1].insn_code - = CODE_FOR_nothing }; -#else -/* init_insn_codes will do runtime initialization otherwise. */ -struct optab_d optab_table[OTI_MAX]; +struct target_optabs default_target_optabs; +struct target_libfuncs default_target_libfuncs; +#if SWITCHABLE_TARGET +struct target_optabs *this_target_optabs = &default_target_optabs; +struct target_libfuncs *this_target_libfuncs = &default_target_libfuncs; #endif -rtx libfunc_table[LTI_MAX]; - -/* Tables of patterns for converting one mode to another. */ -#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS -__extension__ struct convert_optab_d convert_optab_table[COI_MAX] - = { [0 ... COI_MAX - 1].handlers[0 ... NUM_MACHINE_MODES - 1] - [0 ... NUM_MACHINE_MODES - 1].insn_code - = CODE_FOR_nothing }; -#else -/* init_convert_optab will do runtime initialization otherwise. */ -struct convert_optab_d convert_optab_table[COI_MAX]; -#endif +#define libfunc_hash \ + (this_target_libfuncs->x_libfunc_hash) /* Contains the optab used for each rtx code. */ optab code_to_optab[NUM_RTX_CODE + 1]; -#ifdef HAVE_conditional_move -/* Indexed by the machine mode, gives the insn code to make a conditional - move insn. This is not indexed by the rtx-code like bcc_gen_fctn and - setcc_gen_code to cut down on the number of named patterns. Consider a day - when a lot more rtx codes are conditional (eg: for the ARM). */ - -enum insn_code movcc_gen_code[NUM_MACHINE_MODES]; -#endif - -/* Indexed by the machine mode, gives the insn code for vector conditional - operation. */ - -enum insn_code vcond_gen_code[NUM_MACHINE_MODES]; -enum insn_code vcondu_gen_code[NUM_MACHINE_MODES]; - static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *, enum machine_mode *); static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int); @@ -107,19 +71,7 @@ #define DECIMAL_PREFIX "dpd_" #endif - -/* Info about libfunc. We use same hashtable for normal optabs and conversion - optab. In the first case mode2 is unused. */ -struct GTY(()) libfunc_entry { - size_t optab; - enum machine_mode mode1, mode2; - rtx libfunc; -}; - -/* Hash table used to convert declarations into nodes. */ -static GTY((param_is (struct libfunc_entry))) htab_t libfunc_hash; - -/* Used for attribute_hash. */ +/* Used for libfunc_hash. */ static hashval_t hash_libfunc (const void *p) @@ -130,7 +82,7 @@ ^ e->optab); } -/* Used for optab_hash. */ +/* Used for libfunc_hash. */ static int eq_libfunc (const void *p, const void *q) @@ -351,7 +303,7 @@ return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab; case LSHIFT_EXPR: - if (VECTOR_MODE_P (TYPE_MODE (type))) + if (TREE_CODE (type) == VECTOR_TYPE) { if (subtype == optab_vector) return TYPE_SATURATING (type) ? NULL : vashl_optab; @@ -363,7 +315,7 @@ return ashl_optab; case RSHIFT_EXPR: - if (VECTOR_MODE_P (TYPE_MODE (type))) + if (TREE_CODE (type) == VECTOR_TYPE) { if (subtype == optab_vector) return TYPE_UNSIGNED (type) ? vlshr_optab : vashr_optab; @@ -373,7 +325,7 @@ return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab; case LROTATE_EXPR: - if (VECTOR_MODE_P (TYPE_MODE (type))) + if (TREE_CODE (type) == VECTOR_TYPE) { if (subtype == optab_vector) return vrotl_optab; @@ -383,7 +335,7 @@ return rotl_optab; case RROTATE_EXPR: - if (VECTOR_MODE_P (TYPE_MODE (type))) + if (TREE_CODE (type) == VECTOR_TYPE) { if (subtype == optab_vector) return vrotr_optab; @@ -407,6 +359,23 @@ case DOT_PROD_EXPR: return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab; + case WIDEN_MULT_PLUS_EXPR: + return (TYPE_UNSIGNED (type) + ? (TYPE_SATURATING (type) + ? usmadd_widen_optab : umadd_widen_optab) + : (TYPE_SATURATING (type) + ? ssmadd_widen_optab : smadd_widen_optab)); + + case WIDEN_MULT_MINUS_EXPR: + return (TYPE_UNSIGNED (type) + ? (TYPE_SATURATING (type) + ? usmsub_widen_optab : umsub_widen_optab) + : (TYPE_SATURATING (type) + ? ssmsub_widen_optab : smsub_widen_optab)); + + case FMA_EXPR: + return fma_optab; + case REDUC_MAX_EXPR: return TYPE_UNSIGNED (type) ? reduc_umax_optab : reduc_smax_optab; @@ -546,7 +515,12 @@ tmode0 = TYPE_MODE (TREE_TYPE (oprnd0)); widen_pattern_optab = optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default); - icode = (int) optab_handler (widen_pattern_optab, tmode0)->insn_code; + if (ops->code == WIDEN_MULT_PLUS_EXPR + || ops->code == WIDEN_MULT_MINUS_EXPR) + icode = (int) optab_handler (widen_pattern_optab, + TYPE_MODE (TREE_TYPE (ops->op2))); + else + icode = (int) optab_handler (widen_pattern_optab, tmode0); gcc_assert (icode != CODE_FOR_nothing); xmode0 = insn_data[icode].operand[1].mode; @@ -671,7 +645,7 @@ expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0, rtx op1, rtx op2, rtx target, int unsignedp) { - int icode = (int) optab_handler (ternary_optab, mode)->insn_code; + int icode = (int) optab_handler (ternary_optab, mode); enum machine_mode mode0 = insn_data[icode].operand[1].mode; enum machine_mode mode1 = insn_data[icode].operand[2].mode; enum machine_mode mode2 = insn_data[icode].operand[3].mode; @@ -679,8 +653,7 @@ rtx pat; rtx xop0 = op0, xop1 = op1, xop2 = op2; - gcc_assert (optab_handler (ternary_optab, mode)->insn_code - != CODE_FOR_nothing); + gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing); if (!target || !insn_data[icode].operand[0].predicate (target, mode)) temp = gen_reg_rtx (mode); @@ -800,7 +773,7 @@ gcc_unreachable (); } - icode = optab_handler (shift_optab, mode)->insn_code; + icode = optab_handler (shift_optab, mode); gcc_assert (icode != CODE_FOR_nothing); mode1 = insn_data[icode].operand[1].mode; @@ -1286,7 +1259,7 @@ /* OP1_HIGH should now be dead. */ adjust = expand_binop (word_mode, add_optab, adjust, temp, - adjust, 0, OPTAB_DIRECT); + NULL_RTX, 0, OPTAB_DIRECT); if (target && !REG_P (target)) target = NULL_RTX; @@ -1303,8 +1276,7 @@ product_high = operand_subword (product, high, 1, mode); adjust = expand_binop (word_mode, add_optab, product_high, adjust, - REG_P (product_high) ? product_high : adjust, - 0, OPTAB_DIRECT); + NULL_RTX, 0, OPTAB_DIRECT); emit_move_insn (product_high, adjust); return product; } @@ -1417,7 +1389,7 @@ rtx target, int unsignedp, enum optab_methods methods, rtx last) { - int icode = (int) optab_handler (binoptab, mode)->insn_code; + int icode = (int) optab_handler (binoptab, mode); enum machine_mode mode0 = insn_data[icode].operand[1].mode; enum machine_mode mode1 = insn_data[icode].operand[2].mode; enum machine_mode tmp_mode; @@ -1574,7 +1546,7 @@ /* If we can do it with a three-operand insn, do so. */ if (methods != OPTAB_MUST_WIDEN - && optab_handler (binoptab, mode)->insn_code != CODE_FOR_nothing) + && optab_handler (binoptab, mode) != CODE_FOR_nothing) { temp = expand_binop_directly (mode, binoptab, op0, op1, target, unsignedp, methods, last); @@ -1585,9 +1557,9 @@ /* If we were trying to rotate, and that didn't work, try rotating the other direction before falling back to shifts and bitwise-or. */ if (((binoptab == rotl_optab - && optab_handler (rotr_optab, mode)->insn_code != CODE_FOR_nothing) + && optab_handler (rotr_optab, mode) != CODE_FOR_nothing) || (binoptab == rotr_optab - && optab_handler (rotl_optab, mode)->insn_code != CODE_FOR_nothing)) + && optab_handler (rotl_optab, mode) != CODE_FOR_nothing)) && mclass == MODE_INT) { optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab); @@ -1614,8 +1586,8 @@ if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode - && ((optab_handler ((unsignedp ? umul_widen_optab : smul_widen_optab), - GET_MODE_WIDER_MODE (mode))->insn_code) + && (optab_handler ((unsignedp ? umul_widen_optab : smul_widen_optab), + GET_MODE_WIDER_MODE (mode)) != CODE_FOR_nothing)) { temp = expand_binop (GET_MODE_WIDER_MODE (mode), @@ -1643,12 +1615,12 @@ wider_mode != VOIDmode; wider_mode = GET_MODE_WIDER_MODE (wider_mode)) { - if (optab_handler (binoptab, wider_mode)->insn_code != CODE_FOR_nothing + if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing || (binoptab == smul_optab && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode - && ((optab_handler ((unsignedp ? umul_widen_optab - : smul_widen_optab), - GET_MODE_WIDER_MODE (wider_mode))->insn_code) + && (optab_handler ((unsignedp ? umul_widen_optab + : smul_widen_optab), + GET_MODE_WIDER_MODE (wider_mode)) != CODE_FOR_nothing))) { rtx xop0 = op0, xop1 = op1; @@ -1715,7 +1687,7 @@ if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab) && mclass == MODE_INT && GET_MODE_SIZE (mode) > UNITS_PER_WORD - && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing) + && optab_handler (binoptab, word_mode) != CODE_FOR_nothing) { int i; rtx insns; @@ -1759,9 +1731,9 @@ && mclass == MODE_INT && (CONST_INT_P (op1) || optimize_insn_for_speed_p ()) && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD - && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing - && optab_handler (ashl_optab, word_mode)->insn_code != CODE_FOR_nothing - && optab_handler (lshr_optab, word_mode)->insn_code != CODE_FOR_nothing) + && optab_handler (binoptab, word_mode) != CODE_FOR_nothing + && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing + && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing) { unsigned HOST_WIDE_INT shift_mask, double_shift_mask; enum machine_mode op1_mode; @@ -1829,8 +1801,8 @@ && mclass == MODE_INT && CONST_INT_P (op1) && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD - && optab_handler (ashl_optab, word_mode)->insn_code != CODE_FOR_nothing - && optab_handler (lshr_optab, word_mode)->insn_code != CODE_FOR_nothing) + && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing + && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing) { rtx insns; rtx into_target, outof_target; @@ -1941,7 +1913,7 @@ if ((binoptab == add_optab || binoptab == sub_optab) && mclass == MODE_INT && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD - && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing) + && optab_handler (binoptab, word_mode) != CODE_FOR_nothing) { unsigned int i; optab otheroptab = binoptab == add_optab ? sub_optab : add_optab; @@ -2038,7 +2010,7 @@ if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD) { - if (optab_handler (mov_optab, mode)->insn_code != CODE_FOR_nothing + if (optab_handler (mov_optab, mode) != CODE_FOR_nothing || ! rtx_equal_p (target, xtarget)) { rtx temp = emit_move_insn (target, xtarget); @@ -2067,13 +2039,12 @@ if (binoptab == smul_optab && mclass == MODE_INT && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD - && optab_handler (smul_optab, word_mode)->insn_code != CODE_FOR_nothing - && optab_handler (add_optab, word_mode)->insn_code != CODE_FOR_nothing) + && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing + && optab_handler (add_optab, word_mode) != CODE_FOR_nothing) { rtx product = NULL_RTX; - if (optab_handler (umul_widen_optab, mode)->insn_code - != CODE_FOR_nothing) + if (optab_handler (umul_widen_optab, mode) != CODE_FOR_nothing) { product = expand_doubleword_mult (mode, op0, op1, target, true, methods); @@ -2082,8 +2053,7 @@ } if (product == NULL_RTX - && optab_handler (smul_widen_optab, mode)->insn_code - != CODE_FOR_nothing) + && optab_handler (smul_widen_optab, mode) != CODE_FOR_nothing) { product = expand_doubleword_mult (mode, op0, op1, target, false, methods); @@ -2093,7 +2063,7 @@ if (product != NULL_RTX) { - if (optab_handler (mov_optab, mode)->insn_code != CODE_FOR_nothing) + if (optab_handler (mov_optab, mode) != CODE_FOR_nothing) { temp = emit_move_insn (target ? target : product, product); set_unique_reg_note (temp, @@ -2174,8 +2144,7 @@ wider_mode != VOIDmode; wider_mode = GET_MODE_WIDER_MODE (wider_mode)) { - if ((optab_handler (binoptab, wider_mode)->insn_code - != CODE_FOR_nothing) + if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing || (methods == OPTAB_LIB && optab_libfunc (binoptab, wider_mode))) { @@ -2251,7 +2220,7 @@ /* Try widening to a signed int. Make a fake signed optab that hides any signed insn for direct use. */ wide_soptab = *soptab; - optab_handler (&wide_soptab, mode)->insn_code = CODE_FOR_nothing; + set_optab_handler (&wide_soptab, mode, CODE_FOR_nothing); /* We don't want to generate new hash table entries from this fake optab. */ wide_soptab.libcall_gen = NULL; @@ -2313,9 +2282,9 @@ /* Record where to go back to if we fail. */ last = get_last_insn (); - if (optab_handler (unoptab, mode)->insn_code != CODE_FOR_nothing) - { - int icode = (int) optab_handler (unoptab, mode)->insn_code; + if (optab_handler (unoptab, mode) != CODE_FOR_nothing) + { + int icode = (int) optab_handler (unoptab, mode); enum machine_mode mode0 = insn_data[icode].operand[2].mode; rtx pat; rtx xop0 = op0; @@ -2351,8 +2320,7 @@ wider_mode != VOIDmode; wider_mode = GET_MODE_WIDER_MODE (wider_mode)) { - if (optab_handler (unoptab, wider_mode)->insn_code - != CODE_FOR_nothing) + if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing) { rtx t0 = gen_reg_rtx (wider_mode); rtx t1 = gen_reg_rtx (wider_mode); @@ -2406,9 +2374,9 @@ /* Record where to go back to if we fail. */ last = get_last_insn (); - if (optab_handler (binoptab, mode)->insn_code != CODE_FOR_nothing) - { - int icode = (int) optab_handler (binoptab, mode)->insn_code; + if (optab_handler (binoptab, mode) != CODE_FOR_nothing) + { + int icode = (int) optab_handler (binoptab, mode); enum machine_mode mode0 = insn_data[icode].operand[1].mode; enum machine_mode mode1 = insn_data[icode].operand[2].mode; rtx pat; @@ -2468,8 +2436,7 @@ wider_mode != VOIDmode; wider_mode = GET_MODE_WIDER_MODE (wider_mode)) { - if (optab_handler (binoptab, wider_mode)->insn_code - != CODE_FOR_nothing) + if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing) { rtx t0 = gen_reg_rtx (wider_mode); rtx t1 = gen_reg_rtx (wider_mode); @@ -2570,8 +2537,7 @@ wider_mode != VOIDmode; wider_mode = GET_MODE_WIDER_MODE (wider_mode)) { - if (optab_handler (clz_optab, wider_mode)->insn_code - != CODE_FOR_nothing) + if (optab_handler (clz_optab, wider_mode) != CODE_FOR_nothing) { rtx xop0, temp, last; @@ -2683,7 +2649,7 @@ for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode; wider_mode = GET_MODE_WIDER_MODE (wider_mode)) - if (optab_handler (bswap_optab, wider_mode)->insn_code != CODE_FOR_nothing) + if (optab_handler (bswap_optab, wider_mode) != CODE_FOR_nothing) goto found; return NULL_RTX; @@ -2745,8 +2711,7 @@ for (wider_mode = mode; wider_mode != VOIDmode; wider_mode = GET_MODE_WIDER_MODE (wider_mode)) { - if (optab_handler (popcount_optab, wider_mode)->insn_code - != CODE_FOR_nothing) + if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing) { rtx xop0, temp, last; @@ -2787,7 +2752,7 @@ { rtx seq, temp; - if (optab_handler (clz_optab, mode)->insn_code == CODE_FOR_nothing) + if (optab_handler (clz_optab, mode) == CODE_FOR_nothing) return 0; start_sequence (); @@ -2830,7 +2795,7 @@ bool defined_at_zero = false; rtx temp, seq; - if (optab_handler (ctz_optab, mode)->insn_code != CODE_FOR_nothing) + if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing) { start_sequence (); @@ -2840,7 +2805,7 @@ defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2); } - else if (optab_handler (clz_optab, mode)->insn_code != CODE_FOR_nothing) + else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing) { start_sequence (); temp = expand_ctz (mode, op0, 0); @@ -3018,9 +2983,9 @@ expand_unop_direct (enum machine_mode mode, optab unoptab, rtx op0, rtx target, int unsignedp) { - if (optab_handler (unoptab, mode)->insn_code != CODE_FOR_nothing) - { - int icode = (int) optab_handler (unoptab, mode)->insn_code; + if (optab_handler (unoptab, mode) != CODE_FOR_nothing) + { + int icode = (int) optab_handler (unoptab, mode); enum machine_mode mode0 = insn_data[icode].operand[1].mode; rtx xop0 = op0; rtx last = get_last_insn (); @@ -3097,7 +3062,7 @@ return temp; if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD - && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing) + && optab_handler (unoptab, word_mode) != CODE_FOR_nothing) { temp = expand_doubleword_clz (mode, op0, target); if (temp) @@ -3115,7 +3080,7 @@ return temp; if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD - && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing) + && optab_handler (unoptab, word_mode) != CODE_FOR_nothing) { temp = expand_doubleword_bswap (mode, op0, target); if (temp) @@ -3130,7 +3095,7 @@ wider_mode != VOIDmode; wider_mode = GET_MODE_WIDER_MODE (wider_mode)) { - if (optab_handler (unoptab, wider_mode)->insn_code != CODE_FOR_nothing) + if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing) { rtx xop0 = op0; rtx last = get_last_insn (); @@ -3170,7 +3135,7 @@ if (unoptab == one_cmpl_optab && mclass == MODE_INT && GET_MODE_SIZE (mode) > UNITS_PER_WORD - && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing) + && optab_handler (unoptab, word_mode) != CODE_FOR_nothing) { int i; rtx insns; @@ -3292,8 +3257,7 @@ wider_mode != VOIDmode; wider_mode = GET_MODE_WIDER_MODE (wider_mode)) { - if ((optab_handler (unoptab, wider_mode)->insn_code - != CODE_FOR_nothing) + if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing || optab_libfunc (unoptab, wider_mode)) { rtx xop0 = op0; @@ -3386,7 +3350,7 @@ } /* If we have a MAX insn, we can do this as MAX (x, -x). */ - if (optab_handler (smax_optab, mode)->insn_code != CODE_FOR_nothing + if (optab_handler (smax_optab, mode) != CODE_FOR_nothing && !HONOR_SIGNED_ZEROS (mode)) { rtx last = get_last_insn (); @@ -3489,7 +3453,7 @@ return NULL_RTX; /* If we have a MAX insn, we can do this as MAX (x, ~x). */ - if (optab_handler (smax_optab, mode)->insn_code != CODE_FOR_nothing) + if (optab_handler (smax_optab, mode) != CODE_FOR_nothing) { rtx last = get_last_insn (); @@ -3543,7 +3507,7 @@ /* Check if the back end provides an insn that handles signbit for the argument's mode. */ - icode = (int) signbit_optab->handlers [(int) mode].insn_code; + icode = (int) optab_handler (signbit_optab, mode); if (icode != CODE_FOR_nothing) { imode = insn_data[icode].operand[0].mode; @@ -3743,8 +3707,8 @@ if (fmt->signbit_ro >= 0 && (GET_CODE (op0) == CONST_DOUBLE - || (optab_handler (neg_optab, mode)->insn_code != CODE_FOR_nothing - && optab_handler (abs_optab, mode)->insn_code != CODE_FOR_nothing))) + || (optab_handler (neg_optab, mode) != CODE_FOR_nothing + && optab_handler (abs_optab, mode) != CODE_FOR_nothing))) { temp = expand_copysign_absneg (mode, op0, op1, target, fmt->signbit_ro, op0_is_abs); @@ -3880,7 +3844,7 @@ /* If we're using non-call exceptions, a libcall corresponding to an operation that may trap may also trap. */ /* ??? See the comment in front of make_reg_eh_region_note. */ - if (flag_non_call_exceptions && may_trap_p (equiv)) + if (cfun->can_throw_non_call_exceptions && may_trap_p (equiv)) { for (insn = insns; insn; insn = NEXT_INSN (insn)) if (CALL_P (insn)) @@ -3956,8 +3920,7 @@ } last = emit_move_insn (target, result); - if (optab_handler (mov_optab, GET_MODE (target))->insn_code - != CODE_FOR_nothing) + if (optab_handler (mov_optab, GET_MODE (target)) != CODE_FOR_nothing) set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv)); if (final_dest != target) @@ -3983,15 +3946,15 @@ int icode; if (purpose == ccp_jump - && (icode = optab_handler (cbranch_optab, mode)->insn_code) != CODE_FOR_nothing + && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing && insn_data[icode].operand[0].predicate (test, mode)) return 1; if (purpose == ccp_store_flag - && (icode = optab_handler (cstore_optab, mode)->insn_code) != CODE_FOR_nothing + && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing && insn_data[icode].operand[1].predicate (test, mode)) return 1; if (purpose == ccp_cmov - && optab_handler (cmov_optab, mode)->insn_code != CODE_FOR_nothing) + && optab_handler (cmov_optab, mode) != CODE_FOR_nothing) return 1; mode = GET_MODE_WIDER_MODE (mode); @@ -4077,11 +4040,11 @@ cmp_mode != VOIDmode; cmp_mode = GET_MODE_WIDER_MODE (cmp_mode)) { - cmp_code = cmpmem_optab[cmp_mode]; + cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode); if (cmp_code == CODE_FOR_nothing) - cmp_code = cmpstr_optab[cmp_mode]; + cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode); if (cmp_code == CODE_FOR_nothing) - cmp_code = cmpstrn_optab[cmp_mode]; + cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode); if (cmp_code == CODE_FOR_nothing) continue; @@ -4126,7 +4089,7 @@ /* Don't allow operands to the compare to trap, as that can put the compare and branch in different basic blocks. */ - if (flag_non_call_exceptions) + if (cfun->can_throw_non_call_exceptions) { if (may_trap_p (x)) x = force_reg (mode, x); @@ -4147,7 +4110,7 @@ do { enum insn_code icode; - icode = optab_handler (cbranch_optab, cmp_mode)->insn_code; + icode = optab_handler (cbranch_optab, cmp_mode); if (icode != CODE_FOR_nothing && insn_data[icode].operand[0].predicate (test, VOIDmode)) { @@ -4266,7 +4229,7 @@ mclass = GET_MODE_CLASS (mode); optab_mode = (mclass == MODE_CC) ? CCmode : mode; - icode = optab_handler (cbranch_optab, optab_mode)->insn_code; + icode = optab_handler (cbranch_optab, optab_mode); gcc_assert (icode != CODE_FOR_nothing); gcc_assert (insn_data[icode].operand[0].predicate (test, VOIDmode)); @@ -4331,6 +4294,7 @@ enum rtx_code reversed = reverse_condition_maybe_unordered (comparison); enum machine_mode orig_mode = GET_MODE (x); enum machine_mode mode, cmp_mode; + rtx true_rtx, false_rtx; rtx value, target, insns, equiv; rtx libfunc = 0; bool reversed_p = false; @@ -4354,8 +4318,7 @@ } if (code_to_optab[reversed] - && (libfunc = optab_libfunc (code_to_optab[reversed], mode)) - && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed)) + && (libfunc = optab_libfunc (code_to_optab[reversed], mode))) { comparison = reversed; reversed_p = true; @@ -4374,6 +4337,51 @@ /* Attach a REG_EQUAL note describing the semantics of the libcall to the RTL. The allows the RTL optimizers to delete the libcall if the condition can be determined at compile-time. */ + if (comparison == UNORDERED + || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)) + { + true_rtx = const_true_rtx; + false_rtx = const0_rtx; + } + else + { + switch (comparison) + { + case EQ: + true_rtx = const0_rtx; + false_rtx = const_true_rtx; + break; + + case NE: + true_rtx = const_true_rtx; + false_rtx = const0_rtx; + break; + + case GT: + true_rtx = const1_rtx; + false_rtx = const0_rtx; + break; + + case GE: + true_rtx = const0_rtx; + false_rtx = constm1_rtx; + break; + + case LT: + true_rtx = constm1_rtx; + false_rtx = const0_rtx; + break; + + case LE: + true_rtx = const0_rtx; + false_rtx = const1_rtx; + break; + + default: + gcc_unreachable (); + } + } + if (comparison == UNORDERED) { rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x); @@ -4385,47 +4393,8 @@ { equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y); if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)) - { - rtx true_rtx, false_rtx; - - switch (comparison) - { - case EQ: - true_rtx = const0_rtx; - false_rtx = const_true_rtx; - break; - - case NE: - true_rtx = const_true_rtx; - false_rtx = const0_rtx; - break; - - case GT: - true_rtx = const1_rtx; - false_rtx = const0_rtx; - break; - - case GE: - true_rtx = const0_rtx; - false_rtx = constm1_rtx; - break; - - case LT: - true_rtx = constm1_rtx; - false_rtx = const0_rtx; - break; - - case LE: - true_rtx = const0_rtx; - false_rtx = const1_rtx; - break; - - default: - gcc_unreachable (); - } - equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode, - equiv, true_rtx, false_rtx); - } + equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode, + equiv, true_rtx, false_rtx); } start_sequence (); @@ -4438,10 +4407,12 @@ emit_libcall_block (insns, target, value, equiv); if (comparison == UNORDERED - || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)) - comparison = reversed_p ? EQ : NE; - - *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx); + || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison) + || reversed_p) + *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx); + else + *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx); + *pmode = cmp_mode; } @@ -4518,7 +4489,7 @@ if (mode == VOIDmode) mode = GET_MODE (op2); - icode = movcc_gen_code[mode]; + icode = direct_optab_handler (movcc_optab, mode); if (icode == CODE_FOR_nothing) return 0; @@ -4591,7 +4562,7 @@ int can_conditionally_move_p (enum machine_mode mode) { - if (movcc_gen_code[mode] != CODE_FOR_nothing) + if (direct_optab_handler (movcc_optab, mode) != CODE_FOR_nothing) return 1; return 0; @@ -4657,7 +4628,7 @@ if (mode == VOIDmode) mode = GET_MODE (op2); - icode = optab_handler (addcc_optab, mode)->insn_code; + icode = optab_handler (addcc_optab, mode); if (icode == CODE_FOR_nothing) return 0; @@ -4728,7 +4699,7 @@ rtx gen_add2_insn (rtx x, rtx y) { - int icode = (int) optab_handler (add_optab, GET_MODE (x))->insn_code; + int icode = (int) optab_handler (add_optab, GET_MODE (x)); gcc_assert (insn_data[icode].operand[0].predicate (x, insn_data[icode].operand[0].mode)); @@ -4746,7 +4717,7 @@ rtx gen_add3_insn (rtx r0, rtx r1, rtx c) { - int icode = (int) optab_handler (add_optab, GET_MODE (r0))->insn_code; + int icode = (int) optab_handler (add_optab, GET_MODE (r0)); if (icode == CODE_FOR_nothing || !(insn_data[icode].operand[0].predicate @@ -4767,7 +4738,7 @@ gcc_assert (GET_MODE (x) != VOIDmode); - icode = (int) optab_handler (add_optab, GET_MODE (x))->insn_code; + icode = (int) optab_handler (add_optab, GET_MODE (x)); if (icode == CODE_FOR_nothing) return 0; @@ -4788,7 +4759,7 @@ rtx gen_sub2_insn (rtx x, rtx y) { - int icode = (int) optab_handler (sub_optab, GET_MODE (x))->insn_code; + int icode = (int) optab_handler (sub_optab, GET_MODE (x)); gcc_assert (insn_data[icode].operand[0].predicate (x, insn_data[icode].operand[0].mode)); @@ -4806,7 +4777,7 @@ rtx gen_sub3_insn (rtx r0, rtx r1, rtx c) { - int icode = (int) optab_handler (sub_optab, GET_MODE (r0))->insn_code; + int icode = (int) optab_handler (sub_optab, GET_MODE (r0)); if (icode == CODE_FOR_nothing || !(insn_data[icode].operand[0].predicate @@ -4827,7 +4798,7 @@ gcc_assert (GET_MODE (x) != VOIDmode); - icode = (int) optab_handler (sub_optab, GET_MODE (x))->insn_code; + icode = (int) optab_handler (sub_optab, GET_MODE (x)); if (icode == CODE_FOR_nothing) return 0; @@ -4873,7 +4844,7 @@ #endif tab = unsignedp ? zext_optab : sext_optab; - return convert_optab_handler (tab, to_mode, from_mode)->insn_code; + return convert_optab_handler (tab, to_mode, from_mode); } /* Generate the body of an insn to extend Y (with mode MFROM) @@ -4904,7 +4875,7 @@ enum insn_code icode; tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab; - icode = convert_optab_handler (tab, fixmode, fltmode)->insn_code; + icode = convert_optab_handler (tab, fixmode, fltmode); if (icode != CODE_FOR_nothing) { *truncp_ptr = 0; @@ -4915,9 +4886,9 @@ for this to work. We need to rework the fix* and ftrunc* patterns and documentation. */ tab = unsignedp ? ufix_optab : sfix_optab; - icode = convert_optab_handler (tab, fixmode, fltmode)->insn_code; + icode = convert_optab_handler (tab, fixmode, fltmode); if (icode != CODE_FOR_nothing - && optab_handler (ftrunc_optab, fltmode)->insn_code != CODE_FOR_nothing) + && optab_handler (ftrunc_optab, fltmode) != CODE_FOR_nothing) { *truncp_ptr = 1; return icode; @@ -4934,7 +4905,7 @@ convert_optab tab; tab = unsignedp ? ufloat_optab : sfloat_optab; - return convert_optab_handler (tab, fltmode, fixmode)->insn_code; + return convert_optab_handler (tab, fltmode, fixmode); } /* Generate code to convert FROM to floating point @@ -5268,8 +5239,7 @@ emit_label (lab2); - if (optab_handler (mov_optab, GET_MODE (to))->insn_code - != CODE_FOR_nothing) + if (optab_handler (mov_optab, GET_MODE (to)) != CODE_FOR_nothing) { /* Make a place for a REG_NOTE and add it. */ insn = emit_move_insn (to, to); @@ -5356,7 +5326,7 @@ tab = satp ? satfract_optab : fract_optab; this_code = satp ? SAT_FRACT : FRACT_CONVERT; } - code = tab->handlers[to_mode][from_mode].insn_code; + code = convert_optab_handler (tab, to_mode, from_mode); if (code != CODE_FOR_nothing) { emit_unop_insn (code, to, from, this_code); @@ -5397,7 +5367,7 @@ for (imode = GET_MODE (to); imode != VOIDmode; imode = GET_MODE_WIDER_MODE (imode)) { - icode = convert_optab_handler (tab, imode, fmode)->insn_code; + icode = convert_optab_handler (tab, imode, fmode); if (icode != CODE_FOR_nothing) { rtx last = get_last_insn (); @@ -5427,7 +5397,7 @@ have_insn_for (enum rtx_code code, enum machine_mode mode) { return (code_to_optab[(int) code] != 0 - && (optab_handler (code_to_optab[(int) code], mode)->insn_code + && (optab_handler (code_to_optab[(int) code], mode) != CODE_FOR_nothing)); } @@ -5436,27 +5406,9 @@ static void init_insn_codes (void) { - unsigned int i; - - for (i = 0; i < (unsigned int) OTI_MAX; i++) - { - unsigned int j; - optab op; - - op = &optab_table[i]; - for (j = 0; j < NUM_MACHINE_MODES; j++) - optab_handler (op, j)->insn_code = CODE_FOR_nothing; - } - for (i = 0; i < (unsigned int) COI_MAX; i++) - { - unsigned int j, k; - convert_optab op; - - op = &convert_optab_table[i]; - for (j = 0; j < NUM_MACHINE_MODES; j++) - for (k = 0; k < NUM_MACHINE_MODES; k++) - convert_optab_handler (op, j, k)->insn_code = CODE_FOR_nothing; - } + memset (optab_table, 0, sizeof (optab_table)); + memset (convert_optab_table, 0, sizeof (convert_optab_table)); + memset (direct_optab_table, 0, sizeof (direct_optab_table)); } /* Initialize OP's code to CODE, and write it into the code_to_optab table. */ @@ -6075,7 +6027,7 @@ /* See if we have already created a libfunc decl for this function. */ id = get_identifier (name); - hash = htab_hash_string (name); + hash = IDENTIFIER_HASH_VALUE (id); slot = htab_find_slot_with_hash (libfunc_decls, id, hash, INSERT); decl = (tree) *slot; if (decl == NULL) @@ -6098,7 +6050,7 @@ hashval_t hash; id = get_identifier (name); - hash = htab_hash_string (name); + hash = IDENTIFIER_HASH_VALUE (id); slot = htab_find_slot_with_hash (libfunc_decls, id, hash, NO_INSERT); gcc_assert (slot); decl = (tree) *slot; @@ -6124,7 +6076,7 @@ val = 0; slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT); if (*slot == NULL) - *slot = GGC_NEW (struct libfunc_entry); + *slot = ggc_alloc_libfunc_entry (); (*slot)->optab = (size_t) (optable - &optab_table[0]); (*slot)->mode1 = mode; (*slot)->mode2 = VOIDmode; @@ -6151,7 +6103,7 @@ val = 0; slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT); if (*slot == NULL) - *slot = GGC_NEW (struct libfunc_entry); + *slot = ggc_alloc_libfunc_entry (); (*slot)->optab = (size_t) (optable - &convert_optab_table[0]); (*slot)->mode1 = tmode; (*slot)->mode2 = fmode; @@ -6164,30 +6116,15 @@ void init_optabs (void) { - unsigned int i; - static bool reinit; - - libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL); - /* Start by initializing all tables to contain CODE_FOR_nothing. */ - -#ifdef HAVE_conditional_move - for (i = 0; i < NUM_MACHINE_MODES; i++) - movcc_gen_code[i] = CODE_FOR_nothing; -#endif - - for (i = 0; i < NUM_MACHINE_MODES; i++) - { - vcond_gen_code[i] = CODE_FOR_nothing; - vcondu_gen_code[i] = CODE_FOR_nothing; - } - -#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS - /* We statically initialize the insn_codes with CODE_FOR_nothing. */ - if (reinit) - init_insn_codes (); -#else - init_insn_codes (); -#endif + if (libfunc_hash) + { + htab_empty (libfunc_hash); + /* We statically initialize the insn_codes with the equivalent of + CODE_FOR_nothing. Repeat the process if reinitialising. */ + init_insn_codes (); + } + else + libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL); init_optab (add_optab, PLUS); init_optabv (addv_optab, PLUS); @@ -6242,6 +6179,10 @@ init_optab (umax_optab, UMAX); init_optab (pow_optab, UNKNOWN); init_optab (atan2_optab, UNKNOWN); + init_optab (fma_optab, FMA); + init_optab (fms_optab, UNKNOWN); + init_optab (fnma_optab, UNKNOWN); + init_optab (fnms_optab, UNKNOWN); /* These three have codes assigned exclusively for the sake of have_insn_for. */ @@ -6378,39 +6319,6 @@ init_convert_optab (satfract_optab, SAT_FRACT); init_convert_optab (satfractuns_optab, UNSIGNED_SAT_FRACT); - for (i = 0; i < NUM_MACHINE_MODES; i++) - { - movmem_optab[i] = CODE_FOR_nothing; - cmpstr_optab[i] = CODE_FOR_nothing; - cmpstrn_optab[i] = CODE_FOR_nothing; - cmpmem_optab[i] = CODE_FOR_nothing; - setmem_optab[i] = CODE_FOR_nothing; - - sync_add_optab[i] = CODE_FOR_nothing; - sync_sub_optab[i] = CODE_FOR_nothing; - sync_ior_optab[i] = CODE_FOR_nothing; - sync_and_optab[i] = CODE_FOR_nothing; - sync_xor_optab[i] = CODE_FOR_nothing; - sync_nand_optab[i] = CODE_FOR_nothing; - sync_old_add_optab[i] = CODE_FOR_nothing; - sync_old_sub_optab[i] = CODE_FOR_nothing; - sync_old_ior_optab[i] = CODE_FOR_nothing; - sync_old_and_optab[i] = CODE_FOR_nothing; - sync_old_xor_optab[i] = CODE_FOR_nothing; - sync_old_nand_optab[i] = CODE_FOR_nothing; - sync_new_add_optab[i] = CODE_FOR_nothing; - sync_new_sub_optab[i] = CODE_FOR_nothing; - sync_new_ior_optab[i] = CODE_FOR_nothing; - sync_new_and_optab[i] = CODE_FOR_nothing; - sync_new_xor_optab[i] = CODE_FOR_nothing; - sync_new_nand_optab[i] = CODE_FOR_nothing; - sync_compare_and_swap[i] = CODE_FOR_nothing; - sync_lock_test_and_set[i] = CODE_FOR_nothing; - sync_lock_release[i] = CODE_FOR_nothing; - - reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing; - } - /* Fill in the optabs with the insns we support. */ init_all_optabs (); @@ -6661,14 +6569,12 @@ /* Allow the target to add more libcalls or rename some, etc. */ targetm.init_libfuncs (); - - reinit = true; } /* Print information about the current contents of the optabs on STDERR. */ -void +DEBUG_FUNCTION void debug_optab_libfuncs (void) { int i; @@ -6732,7 +6638,7 @@ if (mode == VOIDmode) return 0; - icode = optab_handler (ctrap_optab, mode)->insn_code; + icode = optab_handler (ctrap_optab, mode); if (icode == CODE_FOR_nothing) return 0; @@ -6866,9 +6772,9 @@ enum insn_code icode = CODE_FOR_nothing; if (TYPE_UNSIGNED (type)) - icode = vcondu_gen_code[mode]; + icode = direct_optab_handler (vcondu_optab, mode); else - icode = vcond_gen_code[mode]; + icode = direct_optab_handler (vcond_optab, mode); return icode; } @@ -6966,7 +6872,8 @@ expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target) { enum machine_mode mode = GET_MODE (mem); - enum insn_code icode = sync_compare_and_swap[mode]; + enum insn_code icode + = direct_optab_handler (sync_compare_and_swap_optab, mode); if (icode == CODE_FOR_nothing) return NULL_RTX; @@ -7003,10 +6910,11 @@ /* If the target supports a compare-and-swap pattern that simultaneously sets some flag for success, then use it. Otherwise use the regular compare-and-swap and follow that immediately with a compare insn. */ - icode = sync_compare_and_swap[mode]; + icode = direct_optab_handler (sync_compare_and_swap_optab, mode); if (icode == CODE_FOR_nothing) return NULL_RTX; + do_pending_stack_adjust (); do { start_sequence (); @@ -7081,7 +6989,7 @@ /* If the target supports a compare-and-swap pattern that simultaneously sets some flag for success, then use it. Otherwise use the regular compare-and-swap and follow that immediately with a compare insn. */ - icode = sync_compare_and_swap[mode]; + icode = direct_optab_handler (sync_compare_and_swap_optab, mode); if (icode == CODE_FOR_nothing) return false; @@ -7125,26 +7033,26 @@ switch (code) { case PLUS: - icode = sync_add_optab[mode]; + icode = direct_optab_handler (sync_add_optab, mode); break; case IOR: - icode = sync_ior_optab[mode]; + icode = direct_optab_handler (sync_ior_optab, mode); break; case XOR: - icode = sync_xor_optab[mode]; + icode = direct_optab_handler (sync_xor_optab, mode); break; case AND: - icode = sync_and_optab[mode]; + icode = direct_optab_handler (sync_and_optab, mode); break; case NOT: - icode = sync_nand_optab[mode]; + icode = direct_optab_handler (sync_nand_optab, mode); break; case MINUS: - icode = sync_sub_optab[mode]; + icode = direct_optab_handler (sync_sub_optab, mode); if (icode == CODE_FOR_nothing || CONST_INT_P (val)) { - icode = sync_add_optab[mode]; + icode = direct_optab_handler (sync_add_optab, mode); if (icode != CODE_FOR_nothing) { val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1); @@ -7175,7 +7083,8 @@ /* Failing that, generate a compare-and-swap loop in which we perform the operation with normal arithmetic instructions. */ - if (sync_compare_and_swap[mode] != CODE_FOR_nothing) + if (direct_optab_handler (sync_compare_and_swap_optab, mode) + != CODE_FOR_nothing) { rtx t0 = gen_reg_rtx (mode), t1; @@ -7220,34 +7129,34 @@ switch (code) { case PLUS: - old_code = sync_old_add_optab[mode]; - new_code = sync_new_add_optab[mode]; + old_code = direct_optab_handler (sync_old_add_optab, mode); + new_code = direct_optab_handler (sync_new_add_optab, mode); break; case IOR: - old_code = sync_old_ior_optab[mode]; - new_code = sync_new_ior_optab[mode]; + old_code = direct_optab_handler (sync_old_ior_optab, mode); + new_code = direct_optab_handler (sync_new_ior_optab, mode); break; case XOR: - old_code = sync_old_xor_optab[mode]; - new_code = sync_new_xor_optab[mode]; + old_code = direct_optab_handler (sync_old_xor_optab, mode); + new_code = direct_optab_handler (sync_new_xor_optab, mode); break; case AND: - old_code = sync_old_and_optab[mode]; - new_code = sync_new_and_optab[mode]; + old_code = direct_optab_handler (sync_old_and_optab, mode); + new_code = direct_optab_handler (sync_new_and_optab, mode); break; case NOT: - old_code = sync_old_nand_optab[mode]; - new_code = sync_new_nand_optab[mode]; + old_code = direct_optab_handler (sync_old_nand_optab, mode); + new_code = direct_optab_handler (sync_new_nand_optab, mode); break; case MINUS: - old_code = sync_old_sub_optab[mode]; - new_code = sync_new_sub_optab[mode]; + old_code = direct_optab_handler (sync_old_sub_optab, mode); + new_code = direct_optab_handler (sync_new_sub_optab, mode); if ((old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing) || CONST_INT_P (val)) { - old_code = sync_old_add_optab[mode]; - new_code = sync_new_add_optab[mode]; + old_code = direct_optab_handler (sync_old_add_optab, mode); + new_code = direct_optab_handler (sync_new_add_optab, mode); if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing) { val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1); @@ -7337,7 +7246,8 @@ /* Failing that, generate a compare-and-swap loop in which we perform the operation with normal arithmetic instructions. */ - if (sync_compare_and_swap[mode] != CODE_FOR_nothing) + if (direct_optab_handler (sync_compare_and_swap_optab, mode) + != CODE_FOR_nothing) { rtx t0 = gen_reg_rtx (mode), t1; @@ -7386,7 +7296,7 @@ rtx insn; /* If the target supports the test-and-set directly, great. */ - icode = sync_lock_test_and_set[mode]; + icode = direct_optab_handler (sync_lock_test_and_set_optab, mode); if (icode != CODE_FOR_nothing) { if (!target || !insn_data[icode].operand[0].predicate (target, mode)) @@ -7406,7 +7316,8 @@ } /* Otherwise, use a compare-and-swap loop for the exchange. */ - if (sync_compare_and_swap[mode] != CODE_FOR_nothing) + if (direct_optab_handler (sync_compare_and_swap_optab, mode) + != CODE_FOR_nothing) { if (!target || !register_operand (target, mode)) target = gen_reg_rtx (mode);