diff options
author | Jan Hubicka <jh@suse.cz> | 2001-11-07 13:35:16 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2001-11-07 12:35:16 +0000 |
commit | b972dd0201d69cfd0a422292706c1d0b8b4f1b2d (patch) | |
tree | 03db7da381d0f1ca3f877597e7c68578266a36ab | |
parent | ab901443dc4df860aef92b4f4b8189771663f994 (diff) | |
download | gcc-b972dd0201d69cfd0a422292706c1d0b8b4f1b2d.zip gcc-b972dd0201d69cfd0a422292706c1d0b8b4f1b2d.tar.gz gcc-b972dd0201d69cfd0a422292706c1d0b8b4f1b2d.tar.bz2 |
expmed.c (expand_mult): Force operand to register before computing cost.
* expmed.c (expand_mult): Force operand to register before computing
cost.
* i386.c (x86_decompose_lea): New global vairable.
* i386.h (x86_decompose_lea): Declare.
(TARGET_DECOMPOSE_LEA): New macro.
(RTX_COST): Handle leas properly.
From-SVN: r46823
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 1 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 58 | ||||
-rw-r--r-- | gcc/expmed.c | 4 |
4 files changed, 47 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f2f2c5b..fcac3da 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +Wed Nov 7 13:33:34 CET 2001 Jan Hubicka <jh@suse.cz> + + * expmed.c (expand_mult): Force operand to register before computing + cost. + * i386.c (x86_decompose_lea): New global vairable. + * i386.h (x86_decompose_lea): Declare. + (TARGET_DECOMPOSE_LEA): New macro. + (RTX_COST): Handle leas properly. + 2001-11-06 Richard Henderson <rth@redhat.com> * config/alpha/elf.h (DO_SELECT_SECTION): TREE_READONLY is not diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 44353a9..47f8e78 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -375,6 +375,7 @@ const int x86_memory_mismatch_stall = m_ATHLON | m_PENT4; const int x86_accumulate_outgoing_args = m_ATHLON | m_PENT4 | m_PPRO; const int x86_prologue_using_move = m_ATHLON | m_PENT4 | m_PPRO; const int x86_epilogue_using_move = m_ATHLON | m_PENT4 | m_PPRO; +const int x86_decompose_lea = m_PENT4; /* In case the avreage insn count for single function invocation is lower than this constant, emit fast (but longer) prologue and diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index a23644a..7edfc28 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -218,7 +218,7 @@ extern const int x86_promote_hi_regs, x86_integer_DFmode_moves; extern const int x86_add_esp_4, x86_add_esp_8, x86_sub_esp_4, x86_sub_esp_8; extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall; extern const int x86_accumulate_outgoing_args, x86_prologue_using_move; -extern const int x86_epilogue_using_move; +extern const int x86_epilogue_using_move, x86_decompose_lea; #define TARGET_USE_LEAVE (x86_use_leave & CPUMASK) #define TARGET_PUSH_MEMORY (x86_push_memory & CPUMASK) @@ -256,6 +256,7 @@ extern const int x86_epilogue_using_move; #define TARGET_MEMORY_MISMATCH_STALL (x86_memory_mismatch_stall & CPUMASK) #define TARGET_PROLOGUE_USING_MOVE (x86_prologue_using_move & CPUMASK) #define TARGET_EPILOGUE_USING_MOVE (x86_epilogue_using_move & CPUMASK) +#define TARGET_DECOMPOSE_LEA (x86_decompose_lea & CPUMASK) #define TARGET_STACK_PROBE (target_flags & MASK_STACK_PROBE) @@ -2485,7 +2486,9 @@ while (0) HOST_WIDE_INT value = INTVAL (XEXP (X, 1)); \ if (value == 1) \ TOPLEVEL_COSTS_N_INSNS (ix86_cost->add); \ - if (value == 2 || value == 3) \ + if ((value == 2 || value == 3) \ + && !TARGET_DECOMPOSE_LEA \ + && ix86_cost->lea <= ix86_cost->shift_const) \ TOPLEVEL_COSTS_N_INSNS (ix86_cost->lea); \ } \ /* fall through */ \ @@ -2546,38 +2549,43 @@ while (0) TOPLEVEL_COSTS_N_INSNS (ix86_cost->divide); \ \ case PLUS: \ - if (GET_CODE (XEXP (X, 0)) == PLUS \ - && GET_CODE (XEXP (XEXP (X, 0), 0)) == MULT \ - && GET_CODE (XEXP (XEXP (XEXP (X, 0), 0), 1)) == CONST_INT \ - && GET_CODE (XEXP (X, 1)) == CONST_INT) \ + if (!TARGET_DECOMPOSE_LEA \ + && INTEGRAL_MODE_P (GET_MODE (X)) \ + && GET_MODE_BITSIZE (GET_MODE (X)) <= GET_MODE_BITSIZE (Pmode)) \ { \ - HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (X, 0), 0), 1)); \ - if (val == 2 || val == 4 || val == 8) \ + if (GET_CODE (XEXP (X, 0)) == PLUS \ + && GET_CODE (XEXP (XEXP (X, 0), 0)) == MULT \ + && GET_CODE (XEXP (XEXP (XEXP (X, 0), 0), 1)) == CONST_INT \ + && CONSTANT_P (XEXP (X, 1))) \ { \ - return (COSTS_N_INSNS (ix86_cost->lea) \ - + rtx_cost (XEXP (XEXP (X, 0), 1), OUTER_CODE) \ - + rtx_cost (XEXP (XEXP (XEXP (X, 0), 0), 0), OUTER_CODE) \ - + rtx_cost (XEXP (X, 1), OUTER_CODE)); \ + HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (X, 0), 0), 1));\ + if (val == 2 || val == 4 || val == 8) \ + { \ + return (COSTS_N_INSNS (ix86_cost->lea) \ + + rtx_cost (XEXP (XEXP (X, 0), 1), OUTER_CODE) \ + + rtx_cost (XEXP (XEXP (XEXP (X, 0), 0), 0), OUTER_CODE) \ + + rtx_cost (XEXP (X, 1), OUTER_CODE)); \ + } \ } \ - } \ - else if (GET_CODE (XEXP (X, 0)) == MULT \ - && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT) \ - { \ - HOST_WIDE_INT val = INTVAL (XEXP (XEXP (X, 0), 1)); \ - if (val == 2 || val == 4 || val == 8) \ + else if (GET_CODE (XEXP (X, 0)) == MULT \ + && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT) \ + { \ + HOST_WIDE_INT val = INTVAL (XEXP (XEXP (X, 0), 1)); \ + if (val == 2 || val == 4 || val == 8) \ + { \ + return (COSTS_N_INSNS (ix86_cost->lea) \ + + rtx_cost (XEXP (XEXP (X, 0), 0), OUTER_CODE) \ + + rtx_cost (XEXP (X, 1), OUTER_CODE)); \ + } \ + } \ + else if (GET_CODE (XEXP (X, 0)) == PLUS) \ { \ return (COSTS_N_INSNS (ix86_cost->lea) \ + rtx_cost (XEXP (XEXP (X, 0), 0), OUTER_CODE) \ + + rtx_cost (XEXP (XEXP (X, 0), 1), OUTER_CODE) \ + rtx_cost (XEXP (X, 1), OUTER_CODE)); \ } \ } \ - else if (GET_CODE (XEXP (X, 0)) == PLUS) \ - { \ - return (COSTS_N_INSNS (ix86_cost->lea) \ - + rtx_cost (XEXP (XEXP (X, 0), 0), OUTER_CODE) \ - + rtx_cost (XEXP (XEXP (X, 0), 1), OUTER_CODE) \ - + rtx_cost (XEXP (X, 1), OUTER_CODE)); \ - } \ \ /* fall through */ \ case AND: \ diff --git a/gcc/expmed.c b/gcc/expmed.c index 10c5141..9435a62 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -2406,6 +2406,10 @@ expand_mult (mode, op0, op1, target, unsignedp) int mult_cost; enum {basic_variant, negate_variant, add_variant} variant = basic_variant; + /* op0 must be register to make mult_cost match the precomputed + shiftadd_cost array. */ + op0 = force_reg (mode, op0); + /* Try to do the computation three ways: multiply by the negative of OP1 and then negate, do the multiplication directly, or do multiplication by OP1 - 1. */ |