diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 145 |
1 files changed, 96 insertions, 49 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 35805b428a2..2675ef3713d 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -637,31 +637,10 @@ mode_supports_vsx_dform_quad (machine_mode mode) } -/* Target cpu costs. */ - -struct processor_costs { - const int mulsi; /* cost of SImode multiplication. */ - const int mulsi_const; /* cost of SImode multiplication by constant. */ - const int mulsi_const9; /* cost of SImode mult by short constant. */ - const int muldi; /* cost of DImode multiplication. */ - const int divsi; /* cost of SImode division. */ - const int divdi; /* cost of DImode division. */ - const int fp; /* cost of simple SFmode and DFmode insns. */ - const int dmul; /* cost of DFmode multiplication (and fmadd). */ - const int sdiv; /* cost of SFmode division (fdivs). */ - const int ddiv; /* cost of DFmode division (fdiv). */ - const int cache_line_size; /* cache line size in bytes. */ - const int l1_cache_size; /* size of l1 cache, in kilobytes. */ - const int l2_cache_size; /* size of l2 cache, in kilobytes. */ - const int simultaneous_prefetches; /* number of parallel prefetch - operations. */ - const int sfdf_convert; /* cost of SF->DF conversion. */ -}; +/* Processor costs (relative to an add) */ const struct processor_costs *rs6000_cost; -/* Processor costs (relative to an add) */ - /* Instruction size costs on 32bit processors. */ static const struct processor_costs size32_cost = { @@ -1749,6 +1728,8 @@ static const struct attribute_spec rs6000_attribute_table[] = #define TARGET_RTX_COSTS rs6000_rtx_costs #undef TARGET_ADDRESS_COST #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0 +#undef TARGET_INSN_COST +#define TARGET_INSN_COST rs6000_insn_cost #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra @@ -5438,9 +5419,6 @@ rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, return 3; case unaligned_load: - if (TARGET_P9_VECTOR) - return 3; - if (TARGET_EFFICIENT_UNALIGNED_VSX) return 1; @@ -10979,7 +10957,8 @@ rs6000_aggregate_candidate (const_tree type, machine_mode *modep) - tree_to_uhwi (TYPE_MIN_VALUE (index))); /* There must be no padding. */ - if (wi::ne_p (TYPE_SIZE (type), count * GET_MODE_BITSIZE (*modep))) + if (wi::to_wide (TYPE_SIZE (type)) + != count * GET_MODE_BITSIZE (*modep)) return -1; return count; @@ -11009,7 +10988,8 @@ rs6000_aggregate_candidate (const_tree type, machine_mode *modep) } /* There must be no padding. */ - if (wi::ne_p (TYPE_SIZE (type), count * GET_MODE_BITSIZE (*modep))) + if (wi::to_wide (TYPE_SIZE (type)) + != count * GET_MODE_BITSIZE (*modep)) return -1; return count; @@ -11041,7 +11021,8 @@ rs6000_aggregate_candidate (const_tree type, machine_mode *modep) } /* There must be no padding. */ - if (wi::ne_p (TYPE_SIZE (type), count * GET_MODE_BITSIZE (*modep))) + if (wi::to_wide (TYPE_SIZE (type)) + != count * GET_MODE_BITSIZE (*modep)) return -1; return count; @@ -15142,14 +15123,15 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target) /* Check whether the 2nd and 3rd arguments are integer constants and in range and prepare arguments. */ STRIP_NOPS (arg1); - if (TREE_CODE (arg1) != INTEGER_CST || wi::geu_p (arg1, 2)) + if (TREE_CODE (arg1) != INTEGER_CST || wi::geu_p (wi::to_wide (arg1), 2)) { error ("argument 2 must be 0 or 1"); return CONST0_RTX (tmode); } STRIP_NOPS (arg2); - if (TREE_CODE (arg2) != INTEGER_CST || wi::geu_p (arg2, 16)) + if (TREE_CODE (arg2) != INTEGER_CST + || wi::geu_p (wi::to_wide (arg2), 16)) { error ("argument 3 must be in the range 0..15"); return CONST0_RTX (tmode); @@ -23300,24 +23282,6 @@ rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) return 1; } -const char * -output_isel (rtx *operands) -{ - enum rtx_code code; - - code = GET_CODE (operands[1]); - - if (code == GE || code == GEU || code == LE || code == LEU || code == NE) - { - gcc_assert (GET_CODE (operands[2]) == REG - && GET_CODE (operands[3]) == REG); - PUT_CODE (operands[1], reverse_condition (code)); - return "isel %0,%3,%2,%j1"; - } - - return "isel %0,%2,%3,%j1"; -} - void rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1) { @@ -34438,7 +34402,8 @@ rs6000_xcoff_asm_output_aligned_decl_common (FILE *stream, size, align2); #ifdef HAVE_GAS_HIDDEN - fputs (rs6000_xcoff_visibility (decl), stream); + if (decl != NULL) + fputs (rs6000_xcoff_visibility (decl), stream); #endif putc ('\n', stream); } @@ -34983,6 +34948,88 @@ rs6000_debug_rtx_costs (rtx x, machine_mode mode, int outer_code, return ret; } +static int +rs6000_insn_cost (rtx_insn *insn, bool speed) +{ + if (recog_memoized (insn) < 0) + return 0; + + if (!speed) + return get_attr_length (insn); + + int cost = get_attr_cost (insn); + if (cost > 0) + return cost; + + int n = get_attr_length (insn) / 4; + enum attr_type type = get_attr_type (insn); + + switch (type) + { + case TYPE_LOAD: + case TYPE_FPLOAD: + case TYPE_VECLOAD: + cost = COSTS_N_INSNS (n + 1); + break; + + case TYPE_MUL: + switch (get_attr_size (insn)) + { + case SIZE_8: + cost = COSTS_N_INSNS (n - 1) + rs6000_cost->mulsi_const9; + break; + case SIZE_16: + cost = COSTS_N_INSNS (n - 1) + rs6000_cost->mulsi_const; + break; + case SIZE_32: + cost = COSTS_N_INSNS (n - 1) + rs6000_cost->mulsi; + break; + case SIZE_64: + cost = COSTS_N_INSNS (n - 1) + rs6000_cost->muldi; + break; + default: + gcc_unreachable (); + } + break; + case TYPE_DIV: + switch (get_attr_size (insn)) + { + case SIZE_32: + cost = COSTS_N_INSNS (n - 1) + rs6000_cost->divsi; + break; + case SIZE_64: + cost = COSTS_N_INSNS (n - 1) + rs6000_cost->divdi; + break; + default: + gcc_unreachable (); + } + break; + + case TYPE_FP: + cost = n * rs6000_cost->fp; + break; + case TYPE_DMUL: + cost = n * rs6000_cost->dmul; + break; + case TYPE_SDIV: + cost = n * rs6000_cost->sdiv; + break; + case TYPE_DDIV: + cost = n * rs6000_cost->ddiv; + break; + + case TYPE_SYNC: + case TYPE_LOAD_L: + cost = COSTS_N_INSNS (n + 2); + break; + + default: + cost = COSTS_N_INSNS (n); + } + + return cost; +} + /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */ static int |