diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 353 |
1 files changed, 227 insertions, 126 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 70ff5e0f292..130d1ac9be2 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -41,6 +41,7 @@ #include "output.h" #include "basic-block.h" #include "integrate.h" +#include "diagnostic-core.h" #include "toplev.h" #include "ggc.h" #include "hashtab.h" @@ -1030,6 +1031,9 @@ static void rs6000_xcoff_file_start (void); static void rs6000_xcoff_file_end (void); #endif static int rs6000_variable_issue (FILE *, int, rtx, int); +static int rs6000_register_move_cost (enum machine_mode, + reg_class_t, reg_class_t); +static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool); static bool rs6000_rtx_costs (rtx, int, int, int *, bool); static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool); static int rs6000_debug_address_cost (rtx, bool); @@ -1075,6 +1079,8 @@ static bool rs6000_builtin_support_vector_misalignment (enum machine_mode, const_tree, int, bool); +static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt, + tree, int); static void def_builtin (int, const char *, tree, int); static bool rs6000_vector_alignment_reachable (const_tree, bool); @@ -1467,6 +1473,9 @@ static const struct attribute_spec rs6000_attribute_table[] = rs6000_builtin_support_vector_misalignment #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable +#undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST +#define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \ + rs6000_builtin_vectorization_cost #undef TARGET_INIT_BUILTINS #define TARGET_INIT_BUILTINS rs6000_init_builtins @@ -1502,6 +1511,10 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_INVALID_WITHIN_DOLOOP #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop +#undef TARGET_REGISTER_MOVE_COST +#define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost +#undef TARGET_MEMORY_MOVE_COST +#define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS rs6000_rtx_costs #undef TARGET_ADDRESS_COST @@ -2677,11 +2690,23 @@ rs6000_override_options (const char *default_cpu) /* For the newer switches (vsx, dfp, etc.) set some of the older options, unless the user explicitly used the -mno-<option> to disable the code. */ if (TARGET_VSX) - target_flags |= (ISA_2_6_MASKS & (target_flags_explicit & ~ISA_2_6_MASKS)); + target_flags |= (ISA_2_6_MASKS & ~target_flags_explicit); else if (TARGET_DFP) - target_flags |= (ISA_2_5_MASKS & (target_flags_explicit & ~ISA_2_5_MASKS)); + target_flags |= (ISA_2_5_MASKS & ~target_flags_explicit); else if (TARGET_ALTIVEC) - target_flags |= (MASK_PPC_GFXOPT & (target_flags_explicit & ~MASK_PPC_GFXOPT)); + target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit); + + /* E500mc does "better" if we inline more aggressively. Respect the + user's opinion, though. */ + if (rs6000_block_move_inline_limit == 0 + && (rs6000_cpu == PROCESSOR_PPCE500MC + || rs6000_cpu == PROCESSOR_PPCE500MC64)) + rs6000_block_move_inline_limit = 128; + + /* store_one_arg depends on expand_block_move to handle at least the + size of reg_parm_stack_space. */ + if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32)) + rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32); /* Set debug flags */ if (rs6000_debug_name) @@ -3327,18 +3352,24 @@ rs6000_builtin_support_vector_misalignment (enum machine_mode mode, if (TARGET_VSX) { /* Return if movmisalign pattern is not supported for this mode. */ - if (optab_handler (movmisalign_optab, mode)->insn_code == - CODE_FOR_nothing) + if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing) return false; if (misalignment == -1) { - /* misalignment factor is unknown at compile time but we know + /* Misalignment factor is unknown at compile time but we know it's word aligned. */ if (rs6000_vector_alignment_reachable (type, is_packed)) - return true; + { + int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type)); + + if (element_size == 64 || element_size == 32) + return true; + } + return false; } + /* VSX supports word-aligned vector. */ if (misalignment % 4 == 0) return true; @@ -3404,6 +3435,106 @@ rs6000_builtin_vec_perm (tree type, tree *mask_element_type) return d; } + +/* Implement targetm.vectorize.builtin_vectorization_cost. */ +static int +rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, + tree vectype, int misalign) +{ + unsigned elements; + + switch (type_of_cost) + { + case scalar_stmt: + case scalar_load: + case scalar_store: + case vector_stmt: + case vector_load: + case vector_store: + case vec_to_scalar: + case scalar_to_vec: + case cond_branch_not_taken: + case vec_perm: + return 1; + + case cond_branch_taken: + return 3; + + case unaligned_load: + if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN) + { + elements = TYPE_VECTOR_SUBPARTS (vectype); + if (elements == 2) + /* Double word aligned. */ + return 2; + + if (elements == 4) + { + switch (misalign) + { + case 8: + /* Double word aligned. */ + return 2; + + case -1: + /* Unknown misalignment. */ + case 4: + case 12: + /* Word aligned. */ + return 22; + + default: + gcc_unreachable (); + } + } + } + + if (TARGET_ALTIVEC) + /* Misaligned loads are not supported. */ + gcc_unreachable (); + + return 2; + + case unaligned_store: + if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN) + { + elements = TYPE_VECTOR_SUBPARTS (vectype); + if (elements == 2) + /* Double word aligned. */ + return 2; + + if (elements == 4) + { + switch (misalign) + { + case 8: + /* Double word aligned. */ + return 2; + + case -1: + /* Unknown misalignment. */ + case 4: + case 12: + /* Word aligned. */ + return 23; + + default: + gcc_unreachable (); + } + } + } + + if (TARGET_ALTIVEC) + /* Misaligned stores are not supported. */ + gcc_unreachable (); + + return 2; + + default: + gcc_unreachable (); + } +} + /* Handle generic options of the form -mfoo=yes/no. NAME is the option name. VALUE is the option value. @@ -4974,7 +5105,7 @@ rs6000_special_round_type_align (tree type, unsigned int computed, /* Skip all non field decls */ while (field != NULL && TREE_CODE (field) != FIELD_DECL) - field = TREE_CHAIN (field); + field = DECL_CHAIN (field); if (field != NULL && field != type) { @@ -5006,7 +5137,7 @@ darwin_rs6000_special_round_type_align (tree type, unsigned int computed, tree field = TYPE_FIELDS (type); /* Skip all non field decls */ while (field != NULL && TREE_CODE (field) != FIELD_DECL) - field = TREE_CHAIN (field); + field = DECL_CHAIN (field); if (! field) break; /* A packed field does not contribute any extra alignment. */ @@ -5934,6 +6065,17 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, return x; } + /* Likewise for (lo_sum (high ...) ...) output we have generated. */ + if (GET_CODE (x) == LO_SUM + && GET_CODE (XEXP (x, 0)) == HIGH) + { + push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, + BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, + opnum, (enum reload_type)type); + *win = 1; + return x; + } + #if TARGET_MACHO if (DEFAULT_ABI == ABI_DARWIN && flag_pic && GET_CODE (x) == LO_SUM @@ -7444,7 +7586,7 @@ rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum, { tree f; - for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f)) + for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f)) if (TREE_CODE (f) == FIELD_DECL) { HOST_WIDE_INT bitpos = startbitpos; @@ -7844,7 +7986,7 @@ rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type, { tree f; - for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f)) + for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f)) if (TREE_CODE (f) == FIELD_DECL) { HOST_WIDE_INT bitpos = startbitpos; @@ -8671,10 +8813,10 @@ rs6000_build_builtin_va_list (void) TREE_CHAIN (record) = type_decl; TYPE_NAME (record) = type_decl; TYPE_FIELDS (record) = f_gpr; - TREE_CHAIN (f_gpr) = f_fpr; - TREE_CHAIN (f_fpr) = f_res; - TREE_CHAIN (f_res) = f_ovf; - TREE_CHAIN (f_ovf) = f_sav; + DECL_CHAIN (f_gpr) = f_fpr; + DECL_CHAIN (f_fpr) = f_res; + DECL_CHAIN (f_res) = f_ovf; + DECL_CHAIN (f_ovf) = f_sav; layout_type (record); @@ -8699,10 +8841,10 @@ rs6000_va_start (tree valist, rtx nextarg) } f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); - f_fpr = TREE_CHAIN (f_gpr); - f_res = TREE_CHAIN (f_fpr); - f_ovf = TREE_CHAIN (f_res); - f_sav = TREE_CHAIN (f_ovf); + f_fpr = DECL_CHAIN (f_gpr); + f_res = DECL_CHAIN (f_fpr); + f_ovf = DECL_CHAIN (f_res); + f_sav = DECL_CHAIN (f_ovf); valist = build_va_arg_indirect_ref (valist); gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE); @@ -8820,10 +8962,10 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, } f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); - f_fpr = TREE_CHAIN (f_gpr); - f_res = TREE_CHAIN (f_fpr); - f_ovf = TREE_CHAIN (f_res); - f_sav = TREE_CHAIN (f_ovf); + f_fpr = DECL_CHAIN (f_gpr); + f_res = DECL_CHAIN (f_fpr); + f_ovf = DECL_CHAIN (f_res); + f_sav = DECL_CHAIN (f_ovf); valist = build_va_arg_indirect_ref (valist); gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE); @@ -11400,7 +11542,7 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, gcc_assert (TARGET_ALTIVEC); arg = CALL_EXPR_ARG (exp, 0); - gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE); + gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg))); op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL); addr = memory_address (mode, op); if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE) @@ -13078,9 +13220,7 @@ expand_block_move (rtx operands[]) if (bytes <= 0) return 1; - /* store_one_arg depends on expand_block_move to handle at least the size of - reg_parm_stack_space. */ - if (bytes > (TARGET_POWERPC64 ? 64 : 32)) + if (bytes > rs6000_block_move_inline_limit) return 0; for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes) @@ -13682,8 +13822,7 @@ rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) case RESULT_DECL: case SSA_NAME: case REAL_CST: - case INDIRECT_REF: - case ALIGN_INDIRECT_REF: + case MEM_REF: case MISALIGNED_INDIRECT_REF: case VIEW_CONVERT_EXPR: if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode) @@ -14163,7 +14302,7 @@ rs6000_alloc_sdmode_stack_slot (void) } /* Check for any SDmode parameters of the function. */ - for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t)) + for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t)) { if (TREE_TYPE (t) == error_mark_node) continue; @@ -15263,7 +15402,8 @@ print_operand (FILE *file, rtx x, int code) { const char *name = XSTR (x, 0); #if TARGET_MACHO - if (MACHOPIC_INDIRECT + if (darwin_emit_branch_islands + && MACHOPIC_INDIRECT && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION) name = machopic_indirection_name (x, /*stub_p=*/true); #endif @@ -15868,53 +16008,12 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode) } -/* Emit the RTL for an sCOND pattern. */ +/* Emit the RTL for an sISEL pattern. */ void -rs6000_emit_sISEL (enum machine_mode mode, rtx operands[]) +rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[]) { - rtx condition_rtx; - enum machine_mode op_mode; - enum rtx_code cond_code; - rtx result = operands[0]; - - condition_rtx = rs6000_generate_compare (operands[1], mode); - cond_code = GET_CODE (condition_rtx); - - op_mode = GET_MODE (XEXP (operands[1], 0)); - if (op_mode == VOIDmode) - op_mode = GET_MODE (XEXP (operands[1], 1)); - - if (TARGET_POWERPC64 && GET_MODE (result) == DImode) - { - PUT_MODE (condition_rtx, DImode); - if (cond_code == GEU || cond_code == GTU || cond_code == LEU - || cond_code == LTU) - emit_insn (gen_isel_unsigned_di (result, condition_rtx, - force_reg (DImode, const1_rtx), - force_reg (DImode, const0_rtx), - XEXP (condition_rtx, 0))); - else - emit_insn (gen_isel_signed_di (result, condition_rtx, - force_reg (DImode, const1_rtx), - force_reg (DImode, const0_rtx), - XEXP (condition_rtx, 0))); - } - else - { - PUT_MODE (condition_rtx, SImode); - if (cond_code == GEU || cond_code == GTU || cond_code == LEU - || cond_code == LTU) - emit_insn (gen_isel_unsigned_si (result, condition_rtx, - force_reg (SImode, const1_rtx), - force_reg (SImode, const0_rtx), - XEXP (condition_rtx, 0))); - else - emit_insn (gen_isel_signed_si (result, condition_rtx, - force_reg (SImode, const1_rtx), - force_reg (SImode, const0_rtx), - XEXP (condition_rtx, 0))); - } + rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx); } void @@ -16232,7 +16331,7 @@ rs6000_emit_vector_compare (enum rtx_code rcode, if (rev_code == UNKNOWN) return NULL_RTX; - nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code; + nor_code = optab_handler (one_cmpl_optab, dmode); if (nor_code == CODE_FOR_nothing) return NULL_RTX; @@ -16277,7 +16376,7 @@ rs6000_emit_vector_compare (enum rtx_code rcode, gcc_unreachable (); } - ior_code = optab_handler (ior_optab, (int)dmode)->insn_code; + ior_code = optab_handler (ior_optab, dmode); if (ior_code == CODE_FOR_nothing) return NULL_RTX; @@ -16581,6 +16680,9 @@ rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) { rtx condition_rtx, cr; enum machine_mode mode = GET_MODE (dest); + enum rtx_code cond_code; + rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx); + bool signedp; if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode)) return 0; @@ -16589,27 +16691,37 @@ rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) compare, it just looks at the CRx bits set by a previous compare instruction. */ condition_rtx = rs6000_generate_compare (op, mode); + cond_code = GET_CODE (condition_rtx); cr = XEXP (condition_rtx, 0); + signedp = GET_MODE (cr) == CCmode; - if (mode == SImode) - { - if (GET_MODE (cr) == CCmode) - emit_insn (gen_isel_signed_si (dest, condition_rtx, - true_cond, false_cond, cr)); - else - emit_insn (gen_isel_unsigned_si (dest, condition_rtx, - true_cond, false_cond, cr)); - } - else + isel_func = (mode == SImode + ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si) + : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di)); + + switch (cond_code) { - if (GET_MODE (cr) == CCmode) - emit_insn (gen_isel_signed_di (dest, condition_rtx, - true_cond, false_cond, cr)); - else - emit_insn (gen_isel_unsigned_di (dest, condition_rtx, - true_cond, false_cond, cr)); + case LT: case GT: case LTU: case GTU: case EQ: + /* isel handles these directly. */ + break; + + default: + /* We need to swap the sense of the comparison. */ + { + rtx t = true_cond; + true_cond = false_cond; + false_cond = t; + PUT_CODE (condition_rtx, reverse_condition (cond_code)); + } + break; } + false_cond = force_reg (mode, false_cond); + if (true_cond != const0_rtx) + true_cond = force_reg (mode, true_cond); + + emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr)); + return 1; } @@ -16619,13 +16731,10 @@ output_isel (rtx *operands) enum rtx_code code; code = GET_CODE (operands[1]); - if (code == GE || code == GEU || code == LE || code == LEU || code == NE) - { - PUT_CODE (operands[1], reverse_condition (code)); - return "isel %0,%3,%2,%j1"; - } - else - return "isel %0,%2,%3,%j1"; + + gcc_assert (!(code == GE || code == GEU || code == LE || code == LEU || code == NE)); + + return "isel %0,%2,%3,%j1"; } void @@ -20873,7 +20982,7 @@ rs6000_output_function_epilogue (FILE *file, int next_parm_info_bit = 31; for (decl = DECL_ARGUMENTS (current_function_decl); - decl; decl = TREE_CHAIN (decl)) + decl; decl = DECL_CHAIN (decl)) { rtx parameter = DECL_INCOMING_RTL (decl); enum machine_mode mode = GET_MODE (parameter); @@ -24384,14 +24493,6 @@ get_prev_label (tree function_name) return 0; } -#ifndef DARWIN_LINKER_GENERATES_ISLANDS -#define DARWIN_LINKER_GENERATES_ISLANDS 0 -#endif - -/* KEXTs still need branch islands. */ -#define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \ - || flag_mkernel || flag_apple_kext) - /* INSN is either a function call or a millicode call. It may have an unconditional jump in its delay slot. @@ -24402,7 +24503,7 @@ output_call (rtx insn, rtx *operands, int dest_operand_number, int cookie_operand_number) { static char buf[256]; - if (DARWIN_GENERATE_ISLANDS + if (darwin_emit_branch_islands && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF && (INTVAL (operands[cookie_operand_number]) & CALL_LONG)) { @@ -25451,9 +25552,9 @@ rs6000_debug_address_cost (rtx x, bool speed) /* A C expression returning the cost of moving data from a register of class CLASS1 to one of CLASS2. */ -int +static int rs6000_register_move_cost (enum machine_mode mode, - enum reg_class from, enum reg_class to) + reg_class_t from, reg_class_t to) { int ret; @@ -25465,8 +25566,8 @@ rs6000_register_move_cost (enum machine_mode mode, from = to; if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS) - ret = (rs6000_memory_move_cost (mode, from, 0) - + rs6000_memory_move_cost (mode, GENERAL_REGS, 0)); + ret = (rs6000_memory_move_cost (mode, from, false) + + rs6000_memory_move_cost (mode, GENERAL_REGS, false)); /* It's more expensive to move CR_REGS than CR0_REGS because of the shift. */ @@ -25511,9 +25612,9 @@ rs6000_register_move_cost (enum machine_mode mode, /* A C expressions returning the cost of moving data of MODE from a register to or from memory. */ -int -rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass, - int in ATTRIBUTE_UNUSED) +static int +rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass, + bool in ATTRIBUTE_UNUSED) { int ret; @@ -25630,8 +25731,8 @@ rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a) { /* For the simple ops, use the generator function, rather than assuming that the RTL is standard. */ - enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code; - enum insn_code acode = optab_handler (add_optab, mode)->insn_code; + enum insn_code mcode = optab_handler (smul_optab, mode); + enum insn_code acode = optab_handler (add_optab, mode); gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode); gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode); rtx mreg = gen_reg_rtx (mode); @@ -25663,8 +25764,8 @@ rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a) { /* For the simple ops, use the generator function, rather than assuming that the RTL is standard. */ - enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code; - enum insn_code scode = optab_handler (add_optab, mode)->insn_code; + enum insn_code mcode = optab_handler (smul_optab, mode); + enum insn_code scode = optab_handler (add_optab, mode); gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode); gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode); rtx mreg = gen_reg_rtx (mode); @@ -25699,8 +25800,8 @@ rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a) { /* For the simple ops, use the generator function, rather than assuming that the RTL is standard. */ - enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code; - enum insn_code scode = optab_handler (sub_optab, mode)->insn_code; + enum insn_code mcode = optab_handler (smul_optab, mode); + enum insn_code scode = optab_handler (sub_optab, mode); gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode); gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode); rtx mreg = gen_reg_rtx (mode); @@ -25734,7 +25835,7 @@ rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d) { enum machine_mode mode = GET_MODE (dst); rtx x0, e0, e1, y1, u0, v0; - enum insn_code code = optab_handler (smul_optab, mode)->insn_code; + enum insn_code code = optab_handler (smul_optab, mode); gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code); rtx one = rs6000_load_constant_and_splat (mode, dconst1); @@ -25772,7 +25873,7 @@ rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d) { enum machine_mode mode = GET_MODE (dst); rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one; - enum insn_code code = optab_handler (smul_optab, mode)->insn_code; + enum insn_code code = optab_handler (smul_optab, mode); gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code); gcc_assert (code != CODE_FOR_nothing); @@ -25843,7 +25944,7 @@ rs6000_emit_swrsqrt (rtx dst, rtx src) REAL_VALUE_TYPE dconst3_2; int i; rtx halfthree; - enum insn_code code = optab_handler (smul_optab, mode)->insn_code; + enum insn_code code = optab_handler (smul_optab, mode); gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code); gcc_assert (code != CODE_FOR_nothing); |