aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-11-07 13:35:16 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2001-11-07 12:35:16 +0000
commitb972dd0201d69cfd0a422292706c1d0b8b4f1b2d (patch)
tree03db7da381d0f1ca3f877597e7c68578266a36ab
parentab901443dc4df860aef92b4f4b8189771663f994 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/config/i386/i386.c1
-rw-r--r--gcc/config/i386/i386.h58
-rw-r--r--gcc/expmed.c4
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. */