+2003-01-28 Richard Henderson <rth@redhat.com>
+
+ * target.h (targetm.address_cost): New.
+ * target-def.h (TARGET_ADDRESS_COST): New.
+ (TARGET_RTX_COSTS): Uncomment. Oops.
+ * cse.c (address_cost): Use new target hook.
+ (default_address_cost): New.
+ * output.h (default_address_cost): Declare.
+ * hooks.c (hook_int_rtx_0): New.
+ * hooks.h (hook_int_rtx_0): Declare.
+ * loop.c (combine_givs_p): Remove if 0 code.
+ * system.h (ADDRESS_COST): Poison.
+
+ * config/alpha/alpha.c, config/alpha/alpha.h, config/d30v/d30v.c,
+ config/d30v/d30v.h, config/ia64/ia64.c, config/ia64/ia64.h,
+ config/m32r/m32r.c, config/m32r/m32r.h, config/mcore/mcore.c,
+ config/mcore/mcore.h, config/mmix/mmix.c, config/mmix/mmix.h,
+ config/rs6000/rs6000.c, config/rs6000/rs6000.h, config/sparc/sparc.c,
+ config/sparc/sparc.h, config/v850/v850.c, config/v850/v850.h,
+ config/xtensa/xtensa.c, config/xtensa/xtensa.h
+ (TARGET_ADDRESS_COST): Define as hook_int_rtx_0.
+ (ADDRESS_COST): Remove.
+
+ * config/arc/arc-protos.h, config/arc/arc.c, config/arc/arc.h,
+ config/avr/avr-protos.h, config/avr/avr.c, config/avr/avr.h,
+ config/c4x/c4x-protos.h, config/c4x/c4x.c, config/c4x/c4x.h,
+ config/dsp16xx/dsp16xx-protos.h, config/dsp16xx/dsp16xx.c,
+ config/dsp16xx/dsp16xx.h, config/i386/i386-protos.h,
+ config/i386/i386.c, config/i386/i386.h, config/i960/i960-protos.h,
+ config/i960/i960.c, config/i960/i960.h, config/ip2k/ip2k-protos.h,
+ config/ip2k/ip2k.c, config/ip2k/ip2k.h, config/mips/mips-protos.h,
+ config/mips/mips.c, config/mips/mips.h,
+ config/m68hc11/m68hc11-protos.h, config/m68hc11/m68hc11.c,
+ config/m68hc11/m68hc11.h, config/ns32k/ns32k-protos.h,
+ config/ns32k/ns32k.c, config/ns32k/ns32k.h, config/pa/pa-protos.h,
+ config/pa/pa.c, config/pa/pa.h, config/s390/s390-protos.h,
+ config/s390/s390.c, config/s390/s390.h, config/vax/vax-protos.h,
+ config/vax/vax.c, config/vax/vax.h
+ (foo_address_cost): Make static.
+ (TARGET_ADDRESS_COST): New.
+ (ADDRESS_COST): Remove.
+
+ * config/arm/arm.h, config/arm/arm.c, config/m88k/m88k.h,
+ config/m88k/m88k.c, config/romp/romp.h, config/romp/romp.c,
+ config/sh/sh.c, config/sh/sh.h, config/stormy16/stormy16.c,
+ config/stormy16/stormy16.h
+ (ADDRESS_COST): Move code ...
+ (foo_address_cost): ... here.
+ (TARGET_ADDRESS_COST): New.
+
+ * config/m32r/m32r.c (m32r_address_cost): Remove.
+ * config/m32r/m32r-protos.h: Update.
+
+ * config/mmix/mmix.c (mmix_address_cost): Remove.
+ * config/mmix/mmix-protos.h: Update.
+
+ * config/mn10300/mn10300.c (mn10300_address_cost_1): Rename from
+ mn10300_address_cost; move unsig allocation ...
+ (mn10300_address_cost): ... here.
+ (TARGET_ADDRESS_COST): New.
+ * config/mn10300/mn10300-protos.h: Update.
+ * config/mn10300/mn10300.h (ADDRESS_COST): Remove.
+
2003-01-28 Vladimir Makarov <vmakarov@redhat.com>
* haifa-sched.c (schedule_insn): Return necessary cycle advance
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS alpha_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
struct gcc_target targetm = TARGET_INITIALIZER;
\f
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
{ if (GET_CODE (ADDR) == AND) goto LABEL; }
-/* Compute the cost of an address. For the Alpha, all valid addresses are
- the same cost. */
-
-#define ADDRESS_COST(X) 0
-
/* Machine-dependent reorg pass. */
#define MACHINE_DEPENDENT_REORG(X) alpha_reorg(X)
\f
extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int arc_double_limm_p PARAMS ((rtx));
-extern int arc_address_cost PARAMS ((rtx));
extern int arc_eligible_for_epilogue_delay PARAMS ((rtx, int));
extern void arc_initialize_trampoline PARAMS ((rtx, rtx, rtx));
extern void arc_print_operand PARAMS ((FILE *, rtx, int));
static void arc_encode_section_info PARAMS ((tree, int));
static void arc_internal_label PARAMS ((FILE *, const char *, unsigned long));
static bool arc_rtx_costs PARAMS ((rtx, int, int, int *));
+static int arc_address_cost PARAMS ((rtx));
\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS arc_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST arc_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
\f
/* Cost functions. */
+/* Compute a (partial) cost for rtx X. Return true if the complete
+ cost has been computed, and false if subexpressions should be
+ scanned. In either case, *TOTAL contains the cost result. */
+
+static bool
+arc_rtx_costs (x, code, outer_code, total)
+ rtx x;
+ int code;
+ int outer_code ATTRIBUTE_UNUSED;
+ int *total;
+{
+ switch (code)
+ {
+ /* Small integers are as cheap as registers. 4 byte values can
+ be fetched as immediate constants - let's give that the cost
+ of an extra insn. */
+ case CONST_INT:
+ if (SMALL_INT (INTVAL (x)))
+ {
+ *total = 0;
+ return true;
+ }
+ /* FALLTHRU */
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case CONST_DOUBLE:
+ {
+ rtx high, low;
+ split_double (x, &high, &low);
+ *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (high))
+ + !SMALL_INT (INTVAL (low)));
+ return true;
+ }
+
+ /* Encourage synth_mult to find a synthetic multiply when reasonable.
+ If we need more than 12 insns to do a multiply, then go out-of-line,
+ since the call overhead will be < 10% of the cost of the multiply. */
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ if (TARGET_SHIFTER)
+ *total = COSTS_N_INSNS (1);
+ else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
+ *total = COSTS_N_INSNS (16);
+ else
+ *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
+ return false;
+
+ default:
+ return false;
+ }
+}
+
+
/* Provide the costs of an addressing mode that contains ADDR.
If ADDR is not a valid address, its cost is irrelevant. */
-int
+static int
arc_address_cost (addr)
rtx addr;
{
switch (GET_CODE (addr))
{
case REG :
- /* This is handled in the macro that calls us.
- It's here for documentation. */
return 1;
case LABEL_REF :
arc_ccfsm_at_label (prefix, labelno);
default_internal_label (stream, prefix, labelno);
}
-\f
-/* Compute a (partial) cost for rtx X. Return true if the complete
- cost has been computed, and false if subexpressions should be
- scanned. In either case, *TOTAL contains the cost result. */
-
-static bool
-arc_rtx_costs (x, code, outer_code, total)
- rtx x;
- int code;
- int outer_code ATTRIBUTE_UNUSED;
- int *total;
-{
- switch (code)
- {
- /* Small integers are as cheap as registers. 4 byte values can
- be fetched as immediate constants - let's give that the cost
- of an extra insn. */
- case CONST_INT:
- if (SMALL_INT (INTVAL (x)))
- {
- *total = 0;
- return true;
- }
- /* FALLTHRU */
-
- case CONST:
- case LABEL_REF:
- case SYMBOL_REF:
- *total = COSTS_N_INSNS (1);
- return true;
-
- case CONST_DOUBLE:
- {
- rtx high, low;
- split_double (x, &high, &low);
- *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (high))
- + !SMALL_INT (INTVAL (low)));
- return true;
- }
-
- /* Encourage synth_mult to find a synthetic multiply when reasonable.
- If we need more than 12 insns to do a multiply, then go out-of-line,
- since the call overhead will be < 10% of the cost of the multiply. */
- case ASHIFT:
- case ASHIFTRT:
- case LSHIFTRT:
- if (TARGET_SHIFTER)
- *total = COSTS_N_INSNS (1);
- else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
- *total = COSTS_N_INSNS (16);
- else
- *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
- return false;
-
- default:
- return false;
- }
-}
\f
/* Costs. */
-/* Compute the cost of an address. */
-#define ADDRESS_COST(ADDR) (REG_P (ADDR) ? 1 : arc_address_cost (ADDR))
-
/* Compute extra cost of moving data between one register class
and another. */
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) 2
static int arm_rtx_costs_1 PARAMS ((rtx, enum rtx_code,
enum rtx_code));
static bool arm_rtx_costs PARAMS ((rtx, int, int, int*));
+static int arm_address_cost PARAMS ((rtx));
#undef Hint
#undef Mmode
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS arm_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST arm_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
return true;
}
+/* All address computations that can be done are free, but rtx cost returns
+ the same for practically all of them. So we weight the different types
+ of address here in the order (most pref first):
+ PRE/POST_INC/DEC, SHIFT or NON-INT sum, INT sum, REG, MEM or LABEL. */
+
+static int
+arm_address_cost (X)
+ rtx X;
+{
+#define ARM_ADDRESS_COST(X) \
+ (10 - ((GET_CODE (X) == MEM || GET_CODE (X) == LABEL_REF \
+ || GET_CODE (X) == SYMBOL_REF) \
+ ? 0 \
+ : ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC \
+ || GET_CODE (X) == POST_INC || GET_CODE (X) == POST_DEC) \
+ ? 10 \
+ : (((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS) \
+ ? 6 + (GET_CODE (XEXP (X, 1)) == CONST_INT ? 2 \
+ : ((GET_RTX_CLASS (GET_CODE (XEXP (X, 0))) == '2' \
+ || GET_RTX_CLASS (GET_CODE (XEXP (X, 0))) == 'c' \
+ || GET_RTX_CLASS (GET_CODE (XEXP (X, 1))) == '2' \
+ || GET_RTX_CLASS (GET_CODE (XEXP (X, 1))) == 'c') \
+ ? 1 : 0)) \
+ : 4)))))
+
+#define THUMB_ADDRESS_COST(X) \
+ ((GET_CODE (X) == REG \
+ || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
+ && GET_CODE (XEXP (X, 1)) == CONST_INT)) \
+ ? 1 : 2)
+
+ return (TARGET_ARM ? ARM_ADDRESS_COST (X) : THUMB_ADDRESS_COST (X));
+}
+
static int
arm_adjust_cost (insn, link, dep, cost)
rtx insn;
((GET_MODE_SIZE (M) < 4 ? 8 : 2 * GET_MODE_SIZE (M)) \
* (CLASS == LO_REGS ? 1 : 2)))
-/* All address computations that can be done are free, but rtx cost returns
- the same for practically all of them. So we weight the different types
- of address here in the order (most pref first):
- PRE/POST_INC/DEC, SHIFT or NON-INT sum, INT sum, REG, MEM or LABEL. */
-#define ARM_ADDRESS_COST(X) \
- (10 - ((GET_CODE (X) == MEM || GET_CODE (X) == LABEL_REF \
- || GET_CODE (X) == SYMBOL_REF) \
- ? 0 \
- : ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC \
- || GET_CODE (X) == POST_INC || GET_CODE (X) == POST_DEC) \
- ? 10 \
- : (((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS) \
- ? 6 + (GET_CODE (XEXP (X, 1)) == CONST_INT ? 2 \
- : ((GET_RTX_CLASS (GET_CODE (XEXP (X, 0))) == '2' \
- || GET_RTX_CLASS (GET_CODE (XEXP (X, 0))) == 'c' \
- || GET_RTX_CLASS (GET_CODE (XEXP (X, 1))) == '2' \
- || GET_RTX_CLASS (GET_CODE (XEXP (X, 1))) == 'c') \
- ? 1 : 0)) \
- : 4)))))
-
-#define THUMB_ADDRESS_COST(X) \
- ((GET_CODE (X) == REG \
- || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
- && GET_CODE (XEXP (X, 1)) == CONST_INT)) \
- ? 1 : 2)
-
-#define ADDRESS_COST(X) \
- (TARGET_ARM ? ARM_ADDRESS_COST (X) : THUMB_ADDRESS_COST (X))
-
/* Try to generate sequences that don't involve branches, we can then use
conditional instructions */
#define BRANCH_COST \
extern enum reg_class preferred_reload_class PARAMS ((rtx x,
enum reg_class class));
-extern int avr_address_cost PARAMS ((rtx x));
extern int extra_constraint PARAMS ((rtx x, int c));
extern rtx legitimize_address PARAMS ((rtx x, rtx oldx,
enum machine_mode mode));
static void avr_asm_out_dtor PARAMS ((rtx, int));
static int default_rtx_costs PARAMS ((rtx, enum rtx_code, enum rtx_code));
static bool avr_rtx_costs PARAMS ((rtx, int, int, int *));
+static int avr_address_cost PARAMS ((rtx));
/* Allocate registers from r25 to r8 for parameters for function calls */
#define FIRST_CUM_REG 26
#define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS avr_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST avr_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Calculate the cost of a memory address */
-int
+static int
avr_address_cost (x)
rtx x;
{
is a suitable definition for this macro on machines where anything
`CONSTANT_P' is valid. */
-#define ADDRESS_COST(ADDRESS) avr_address_cost (ADDRESS)
-
-/* An expression giving the cost of an addressing mode that contains
- ADDRESS. If not defined, the cost is computed from the ADDRESS
- expression and the `CONST_COSTS' values.
-
- For most CISC machines, the default cost is a good approximation
- of the true cost of the addressing mode. However, on RISC
- machines, all instructions normally have the same length and
- execution time. Hence all addresses will have equal costs.
-
- In cases where more than one form of an address is known, the form
- with the lowest cost will be used. If multiple forms have the
- same, lowest, cost, the one that is the most complex will be used.
-
- For example, suppose an address that is equal to the sum of a
- register and a constant is used twice in the same basic block.
- When this macro is not defined, the address will be computed in a
- register and memory references will be indirect through that
- register. On machines where the cost of the addressing mode
- containing the sum is no higher than that of a simple indirect
- reference, this will produce an additional instruction and
- possibly require an additional register. Proper specification of
- this macro eliminates this overhead for such machines.
-
- Similar use of this macro is made in strength reduction of loops.
-
- ADDRESS need not be valid as an address. In such a case, the cost
- is not relevant and can be any value; invalid addresses need not be
- assigned a different cost.
-
- On machines where an address involving more than one register is as
- cheap as an address computation involving only one register,
- defining `ADDRESS_COST' to reflect this can cause two registers to
- be live over a region of code where only one would have been if
- `ADDRESS_COST' were not defined in that manner. This effect should
- be considered in the definition of this macro. Equivalent costs
- should probably only be given to addresses with different numbers
- of registers on machines with lots of registers.
-
- This macro will normally either not be defined or be defined as a
- constant. */
-
#define REGISTER_MOVE_COST(MODE, FROM, TO) ((FROM) == STACK_REG ? 6 \
: (TO) == STACK_REG ? 12 \
: 2)
extern struct rtx_def *c4x_legitimize_address PARAMS ((rtx,
enum machine_mode));
-extern int c4x_address_cost PARAMS ((rtx));
-
extern void c4x_print_operand PARAMS ((FILE *, rtx, int));
extern void c4x_print_operand_address PARAMS ((FILE *, rtx));
static void c4x_encode_section_info PARAMS ((tree, int));
static void c4x_globalize_label PARAMS ((FILE *, const char *));
static bool c4x_rtx_costs PARAMS ((rtx, int, int, int *));
+static int c4x_address_cost PARAMS ((rtx));
\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_BYTE_OP
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS c4x_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST c4x_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
if it is worthwhile storing a common address into a register.
Unfortunately, the C4x address cost depends on other operands. */
-int
+static int
c4x_address_cost (addr)
rtx addr;
{
/* Descripting Relative Cost of Operations. */
-/* Compute the cost of an address. This is meant to approximate the size
- and/or execution delay of an insn using that address. The value of this
- macro only matters for valid addresses. We handle the most common address
- without a call to c4x_address_cost. */
-
-#define ADDRESS_COST(ADDR) (REG_P (ADDR) ? 1 : c4x_address_cost (ADDR))
-
#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
if (REG_P (OP1) && ! REG_P (OP0)) \
{ \
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS d30v_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
struct gcc_target targetm = TARGET_INITIALIZER;
\f
\f
/* Describing Relative Costs of Operations */
-/* An expression giving the cost of an addressing mode that contains ADDRESS.
- If not defined, the cost is computed from the ADDRESS expression and the
- `CONST_COSTS' values.
-
- For most CISC machines, the default cost is a good approximation of the true
- cost of the addressing mode. However, on RISC machines, all instructions
- normally have the same length and execution time. Hence all addresses will
- have equal costs.
-
- In cases where more than one form of an address is known, the form with the
- lowest cost will be used. If multiple forms have the same, lowest, cost,
- the one that is the most complex will be used.
-
- For example, suppose an address that is equal to the sum of a register and a
- constant is used twice in the same basic block. When this macro is not
- defined, the address will be computed in a register and memory references
- will be indirect through that register. On machines where the cost of the
- addressing mode containing the sum is no higher than that of a simple
- indirect reference, this will produce an additional instruction and possibly
- require an additional register. Proper specification of this macro
- eliminates this overhead for such machines.
-
- Similar use of this macro is made in strength reduction of loops.
-
- ADDRESS need not be valid as an address. In such a case, the cost is not
- relevant and can be any value; invalid addresses need not be assigned a
- different cost.
-
- On machines where an address involving more than one register is as cheap as
- an address computation involving only one register, defining `ADDRESS_COST'
- to reflect this can cause two registers to be live over a region of code
- where only one would have been if `ADDRESS_COST' were not defined in that
- manner. This effect should be considered in the definition of this macro.
- Equivalent costs should probably only be given to addresses with different
- numbers of registers on machines with lots of registers.
-
- This macro will normally either not be defined or be defined as a constant. */
-#define ADDRESS_COST(ADDRESS) 0
-
/* A C expression for the cost of moving data from a register in class FROM to
one in class TO. The classes are expressed using the enumeration values
such as `GENERAL_REGS'. A value of 4 is the default; other values are
extern void print_operand_address PARAMS ((FILE *, rtx));
extern void output_dsp16xx_float_const PARAMS ((rtx *));
extern void emit_1600_core_shift PARAMS ((enum rtx_code, rtx *, int));
-extern int dsp16xx_address_cost PARAMS ((rtx));
extern int symbolic_address_p PARAMS ((rtx));
extern int uns_comparison_operator PARAMS ((rtx, enum machine_mode));
#endif /* RTX_CODE */
static void dsp16xx_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void dsp16xx_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static bool dsp16xx_rtx_costs PARAMS ((rtx, int, int, int *));
+static int dsp16xx_address_cost PARAMS ((rtx));
\f
/* Initialize the GCC target structure. */
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS dsp16xx_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST dsp16xx_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
fprintf (file, "int\n");
}
-int
+static int
dsp16xx_address_cost (addr)
rtx addr;
{
\f
/* DESCRIBING RELATIVE COSTS OF OPERATIONS */
-/* An expression giving the cost of an addressing mode that contains
- address. */
-#define ADDRESS_COST(ADDR) dsp16xx_address_cost (ADDR)
-
/* A c expression for the cost of moving data from a register in
class FROM to one in class TO. The classes are expressed using
the enumeration values such as GENERAL_REGS. A value of 2 is
extern void ix86_split_ashldi PARAMS ((rtx *, rtx));
extern void ix86_split_ashrdi PARAMS ((rtx *, rtx));
extern void ix86_split_lshrdi PARAMS ((rtx *, rtx));
-extern int ix86_address_cost PARAMS ((rtx));
extern rtx ix86_find_base_term PARAMS ((rtx));
extern rtx assign_386_stack_local PARAMS ((enum machine_mode, int));
};
static int ix86_decompose_address PARAMS ((rtx, struct ix86_address *));
+static int ix86_address_cost PARAMS ((rtx));
static bool ix86_cannot_force_const_mem PARAMS ((rtx));
static void ix86_encode_section_info PARAMS ((tree, int)) ATTRIBUTE_UNUSED;
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS ix86_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST ix86_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
the address into a reg and make a new pseudo. But not if the address
requires to two regs - that would mean more pseudos with longer
lifetimes. */
-int
+static int
ix86_address_cost (x)
rtx x;
{
so give the MEM rtx a byte's mode. */
#define FUNCTION_MODE QImode
\f
-/* An expression giving the cost of an addressing mode that contains
- ADDRESS. If not defined, the cost is computed from the ADDRESS
- expression and the `CONST_COSTS' values.
-
- For most CISC machines, the default cost is a good approximation
- of the true cost of the addressing mode. However, on RISC
- machines, all instructions normally have the same length and
- execution time. Hence all addresses will have equal costs.
-
- In cases where more than one form of an address is known, the form
- with the lowest cost will be used. If multiple forms have the
- same, lowest, cost, the one that is the most complex will be used.
-
- For example, suppose an address that is equal to the sum of a
- register and a constant is used twice in the same basic block.
- When this macro is not defined, the address will be computed in a
- register and memory references will be indirect through that
- register. On machines where the cost of the addressing mode
- containing the sum is no higher than that of a simple indirect
- reference, this will produce an additional instruction and
- possibly require an additional register. Proper specification of
- this macro eliminates this overhead for such machines.
-
- Similar use of this macro is made in strength reduction of loops.
-
- ADDRESS need not be valid as an address. In such a case, the cost
- is not relevant and can be any value; invalid addresses need not be
- assigned a different cost.
-
- On machines where an address involving more than one register is as
- cheap as an address computation involving only one register,
- defining `ADDRESS_COST' to reflect this can cause two registers to
- be live over a region of code where only one would have been if
- `ADDRESS_COST' were not defined in that manner. This effect should
- be considered in the definition of this macro. Equivalent costs
- should probably only be given to addresses with different numbers
- of registers on machines with lots of registers.
-
- This macro will normally either not be defined or be defined as a
- constant.
-
- For i386, it is better to use a complex address than let gcc copy
- the address into a reg and make a new pseudo. But not if the address
- requires to two regs - that would mean more pseudos with longer
- lifetimes. */
-
-#define ADDRESS_COST(RTX) \
- ix86_address_cost (RTX)
-
/* A C expression for the cost of moving data from a register in class FROM to
one in class TO. The classes are expressed using the enumeration values
such as `GENERAL_REGS'. A value of 2 is the default; other values are
extern int power2_operand PARAMS ((rtx, enum machine_mode));
extern int cmplpower2_operand PARAMS ((rtx, enum machine_mode));
extern enum machine_mode select_cc_mode PARAMS ((RTX_CODE, rtx));
-extern int i960_address_cost PARAMS ((rtx));
extern int emit_move_sequence PARAMS ((rtx *, enum machine_mode));
extern int i960_bypass PARAMS ((rtx, rtx, rtx, int));
extern void i960_print_operand_addr PARAMS ((FILE *, rtx));
static void i960_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
static bool i960_rtx_costs PARAMS ((rtx, int, int, int *));
+static int i960_address_cost PARAMS ((rtx));
/* Save the operands last given to a compare for use when we
generate a scc or bcc insn. */
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS i960_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST i960_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* ??? Try using just RTX_COST, i.e. not defining ADDRESS_COST. */
-int
+static int
i960_address_cost (x)
rtx x;
{
-#if 0
- /* Handled before calling here. */
if (GET_CODE (x) == REG)
return 1;
-#endif
+
/* This is a MEMA operand -- it's free. */
if (GET_CODE (x) == CONST_INT
&& INTVAL (x) >= 0
#ifndef WIND_RIVER
#define TARGET_MEM_FUNCTIONS 1
#endif
-
-/* The i960 offers addressing modes which are "as cheap as a register".
- See i960.c (or gcc.texinfo) for details. */
-
-#define ADDRESS_COST(RTX) \
- (GET_CODE (RTX) == REG ? 1 : i960_address_cost (RTX))
\f
/* Control the assembler format that we output. */
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS ia64_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
struct gcc_target targetm = TARGET_INITIALIZER;
\f
\f
/* Describing Relative Costs of Operations */
-/* An expression giving the cost of an addressing mode that contains ADDRESS.
- If not defined, the cost is computed from the ADDRESS expression and the
- `CONST_COSTS' values. */
-
-#define ADDRESS_COST(ADDRESS) 0
-
/* A C expression for the cost of moving data from a register in class FROM to
one in class TO, using MODE. */
#ifdef RTX_CODE
extern int legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
extern void machine_dependent_reorg PARAMS ((rtx));
-extern int ip2k_address_cost PARAMS ((rtx));
extern int ip2k_extra_constraint PARAMS ((rtx, int));
extern rtx legitimize_address PARAMS ((rtx, rtx, enum machine_mode, rtx));
extern int adjust_insn_length PARAMS ((rtx insn, int len));
static tree ip2k_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static bool ip2k_rtx_costs PARAMS ((rtx, int, int, int *));
+static int ip2k_address_cost PARAMS ((rtx));
const struct attribute_spec ip2k_attribute_table[];
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS ip2k_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST ip2k_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
/* Calculate the cost of a memory address. */
-int
+static int
ip2k_address_cost (x)
rtx x;
{
is a suitable definition for this macro on machines where anything
`CONSTANT_P' is valid. */
-#define ADDRESS_COST(ADDRESS) ip2k_address_cost (ADDRESS)
-
-/* An expression giving the cost of an addressing mode that contains
- ADDRESS. If not defined, the cost is computed from the ADDRESS
- expression and the `CONST_COSTS' values.
-
- For most CISC machines, the default cost is a good approximation
- of the true cost of the addressing mode. However, on RISC
- machines, all instructions normally have the same length and
- execution time. Hence all addresses will have equal costs.
-
- In cases where more than one form of an address is known, the form
- with the lowest cost will be used. If multiple forms have the
- same, lowest, cost, the one that is the most complex will be used.
-
- For example, suppose an address that is equal to the sum of a
- register and a constant is used twice in the same basic block.
- When this macro is not defined, the address will be computed in a
- register and memory references will be indirect through that
- register. On machines where the cost of the addressing mode
- containing the sum is no higher than that of a simple indirect
- reference, this will produce an additional instruction and
- possibly require an additional register. Proper specification of
- this macro eliminates this overhead for such machines.
-
- Similar use of this macro is made in strength reduction of loops.
-
- ADDRESS need not be valid as an address. In such a case, the cost
- is not relevant and can be any value; invalid addresses need not be
- assigned a different cost.
-
- On machines where an address involving more than one register is as
- cheap as an address computation involving only one register,
- defining `ADDRESS_COST' to reflect this can cause two registers to
- be live over a region of code where only one would have been if
- `ADDRESS_COST' were not defined in that manner. This effect should
- be considered in the definition of this macro. Equivalent costs
- should probably only be given to addresses with different numbers
- of registers on machines with lots of registers.
-
- This macro will normally either not be defined or be defined as a
- constant. */
-
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) 7
/* A C expression for the cost of moving data from a register in class
FROM to one in class TO. The classes are expressed using the
extern void m32r_expand_block_move PARAMS ((rtx *));
extern void m32r_print_operand PARAMS ((FILE *, rtx, int));
extern void m32r_print_operand_address PARAMS ((FILE *, rtx));
-extern int m32r_address_cost PARAMS ((rtx));
extern int m32r_not_same_reg PARAMS ((rtx, rtx));
#ifdef HAVE_MACHINE_MODES
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS m32r_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
struct gcc_target targetm = TARGET_INITIALIZER;
\f
return false;
}
}
-
-/* Provide the costs of an addressing mode that contains ADDR.
- If ADDR is not a valid address, its cost is irrelevant.
-
- This function is trivial at the moment. This code doesn't live
- in m32r.h so it's easy to experiment. */
-
-int
-m32r_address_cost (addr)
- rtx addr ATTRIBUTE_UNUSED;
-{
- return 1;
-}
\f
/* Type of function DECL.
\f
/* Costs. */
-/* Compute the cost of an address. */
-#define ADDRESS_COST(ADDR) m32r_address_cost (ADDR)
-
/* Compute extra cost of moving data between one register class
and another. */
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) 2
int));
extern int m68hc11_register_move_cost PARAMS((enum machine_mode,
enum reg_class, enum reg_class));
-extern int m68hc11_address_cost PARAMS((rtx));
-
extern void m68hc11_emit_libcall PARAMS((const char*, enum rtx_code,
enum machine_mode, enum machine_mode,
static int register_indirect_p PARAMS((rtx, enum machine_mode, int));
static rtx m68hc11_expand_compare PARAMS((enum rtx_code, rtx, rtx));
static int must_parenthesize PARAMS ((rtx));
+static int m68hc11_address_cost PARAMS ((rtx));
static int m68hc11_shift_cost PARAMS ((enum machine_mode, rtx, int));
static int m68hc11_rtx_costs_1 PARAMS ((rtx, enum rtx_code, enum rtx_code));
static bool m68hc11_rtx_costs PARAMS ((rtx, int, int, int *));
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS m68hc11_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST m68hc11_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Provide the costs of an addressing mode that contains ADDR.
If ADDR is not a valid address, its cost is irrelevant. */
-int
+static int
m68hc11_address_cost (addr)
rtx addr;
{
#define NOTICE_UPDATE_CC(EXP, INSN) \
m68hc11_notice_update_cc ((EXP), (INSN))
-/* An expression giving the cost of an addressing mode that contains
- ADDRESS. */
-
-#define ADDRESS_COST(RTX) m68hc11_address_cost (RTX)
-
/* Move costs between classes of registers */
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
(m68hc11_register_move_cost (MODE, CLASS1, CLASS2))
static void m88k_internal_label PARAMS ((FILE *, const char *, unsigned long));
#endif
static bool m88k_rtx_costs PARAMS ((rtx, int, int, int *));
+static int m88k_address_cost PARAMS ((rtx));
\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_BYTE_OP
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS m88k_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST m88k_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
return false;
}
}
+
+/* Provide the costs of an addressing mode that contains ADDR.
+ If ADDR is not a valid address, its cost is irrelevant.
+ REG+REG is made slightly more expensive because it might keep
+ a register live for longer than we might like. */
+static int
+m88k_address_cost (x)
+ rtx x;
+{
+ switch (GET_CODE (x))
+ {
+ case REG:
+ case LO_SUM:
+ case MULT:
+ return 1;
+ case HIGH:
+ return 2;
+ case PLUS:
+ return (REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1))) ? 2 : 1;
+ default:
+ return 4;
+ }
+}
state with CC_STATUS_INIT for now. */
#define CC_STATUS_INIT m88k_volatile_code = '\0'
-/* Provide the costs of an addressing mode that contains ADDR.
- If ADDR is not a valid address, its cost is irrelevant.
- REG+REG is made slightly more expensive because it might keep
- a register live for longer than we might like. */
-#define ADDRESS_COST(ADDR) \
- (GET_CODE (ADDR) == REG ? 1 : \
- GET_CODE (ADDR) == LO_SUM ? 1 : \
- GET_CODE (ADDR) == HIGH ? 2 : \
- GET_CODE (ADDR) == MULT ? 1 : \
- GET_CODE (ADDR) != PLUS ? 4 : \
- (REG_P (XEXP (ADDR, 0)) && REG_P (XEXP (ADDR, 1))) ? 2 : 1)
-
/* A C expressions returning the cost of moving data of MODE from a register
to or from memory. This is more costly than between registers. */
#define MEMORY_MOVE_COST(MODE,CLASS,IN) 4
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS mcore_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
struct gcc_target targetm = TARGET_INITIALIZER;
\f
#define Pmode SImode
#define FUNCTION_MODE Pmode
-/* provide the cost for an address calculation.
- All addressing modes cost the same on the MCore. */
-#define ADDRESS_COST(RTX) 1
-
/* Compute extra cost of moving data between one register class
and another. All register moves are cheap. */
#define REGISTER_MOVE_COST(MODE, SRCCLASS, DSTCLASS) 2
extern void mips_emit_fcc_reload PARAMS ((rtx, rtx, rtx));
extern void mips_set_return_address PARAMS ((rtx, rtx));
extern void machine_dependent_reorg PARAMS ((rtx));
-extern int mips_address_cost PARAMS ((rtx));
extern void mips_count_memory_refs PARAMS ((rtx, int));
extern HOST_WIDE_INT mips_debugger_offset PARAMS ((rtx, HOST_WIDE_INT));
extern int mips_check_split PARAMS ((rtx, enum machine_mode));
static int mips_use_dfa_pipeline_interface PARAMS ((void));
static void mips_encode_section_info PARAMS ((tree, int));
static bool mips_rtx_costs PARAMS ((rtx, int, int, int *));
+static int mips_address_cost PARAMS ((rtx));
/* Structure to be filled in by compute_frame_size with register
#define TARGET_VALID_POINTER_MODE mips_valid_pointer_mode
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS mips_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST mips_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Provide the costs of an addressing mode that contains ADDR.
If ADDR is not a valid address, its cost is irrelevant. */
-int
+static int
mips_address_cost (addr)
rtx addr;
{
switch (GET_CODE (addr))
{
+ case REG:
+ return 1;
+
case LO_SUM:
return 1;
#define FUNCTION_MODE (Pmode == DImode ? DImode : SImode)
\f
-/* An expression giving the cost of an addressing mode that
- contains ADDRESS. If not defined, the cost is computed from the
- form of the ADDRESS expression and the `CONST_COSTS' values.
-
- For most CISC machines, the default cost is a good approximation
- of the true cost of the addressing mode. However, on RISC
- machines, all instructions normally have the same length and
- execution time. Hence all addresses will have equal costs.
-
- In cases where more than one form of an address is known, the
- form with the lowest cost will be used. If multiple forms have
- the same, lowest, cost, the one that is the most complex will be
- used.
-
- For example, suppose an address that is equal to the sum of a
- register and a constant is used twice in the same basic block.
- When this macro is not defined, the address will be computed in
- a register and memory references will be indirect through that
- register. On machines where the cost of the addressing mode
- containing the sum is no higher than that of a simple indirect
- reference, this will produce an additional instruction and
- possibly require an additional register. Proper specification
- of this macro eliminates this overhead for such machines.
-
- Similar use of this macro is made in strength reduction of loops.
-
- ADDRESS need not be valid as an address. In such a case, the
- cost is not relevant and can be any value; invalid addresses
- need not be assigned a different cost.
-
- On machines where an address involving more than one register is
- as cheap as an address computation involving only one register,
- defining `ADDRESS_COST' to reflect this can cause two registers
- to be live over a region of code where only one would have been
- if `ADDRESS_COST' were not defined in that manner. This effect
- should be considered in the definition of this macro.
- Equivalent costs should probably only be given to addresses with
- different numbers of registers on machines with lots of registers.
-
- This macro will normally either not be defined or be defined as
- a constant. */
-
-#define ADDRESS_COST(ADDR) (REG_P (ADDR) ? 1 : mips_address_cost (ADDR))
-
/* A C expression for the cost of moving data from a register in
class FROM to one in class TO. The classes are expressed using
the enumeration values such as `GENERAL_REGS'. A value of 2 is
extern int mmix_constant_address_p PARAMS ((rtx));
extern int mmix_legitimate_address PARAMS ((enum machine_mode, rtx, int));
extern int mmix_legitimate_constant_p PARAMS ((rtx));
-extern int mmix_address_cost PARAMS ((rtx));
extern void mmix_print_operand PARAMS ((FILE *, rtx, int));
extern void mmix_print_operand_address PARAMS ((FILE *, rtx));
extern void mmix_machine_dependent_reorg PARAMS ((rtx));
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS mmix_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
struct gcc_target targetm = TARGET_INITIALIZER;
return false;
}
-/* ADDRESS_COST. */
-
-int
-mmix_address_cost (addr)
- rtx addr ATTRIBUTE_UNUSED;
-{
- /* There's no difference in the address costs and we have lots of
- registers. Some targets use constant 0, many others use 1 to say
- this. Let's start with 1. */
- return 1;
-}
-
/* REGISTER_MOVE_COST. */
int
/* Node: Costs */
-#define ADDRESS_COST(ADDRESS) mmix_address_cost (ADDRESS)
-
/* The special registers can only move to and from general regs, and we
need to check that their constraints match, so say 3 for them. */
/* WARNING: gcc-2.7.2.2 i686-pc-linux-gnulibc1 (as shipped with RH 4.2)
extern int call_address_operand PARAMS ((rtx, enum machine_mode));
extern int impossible_plus_operand PARAMS ((rtx, enum machine_mode));
extern int const_8bit_operand PARAMS ((rtx, enum machine_mode));
-
-extern int mn10300_address_cost PARAMS ((rtx, int *));
#endif /* RTX_CODE */
#ifdef TREE_CODE
|| regs_ever_live[16] || regs_ever_live[17]))
+static int mn10300_address_cost_1 PARAMS ((rtx, int *));
+static int mn10300_address_cost PARAMS ((rtx));
static bool mn10300_rtx_costs PARAMS ((rtx, int, int, int *));
\f
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS mn10300_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST mn10300_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
return x;
}
-int
-mn10300_address_cost (x, unsig)
+static int
+mn10300_address_cost_1 (x, unsig)
rtx x;
int *unsig;
{
- int _s = 0;
- if (unsig == 0)
- unsig = &_s;
-
switch (GET_CODE (x))
{
case REG:
case ASHIFT:
case AND:
case IOR:
- return (mn10300_address_cost (XEXP (x, 0), unsig)
- + mn10300_address_cost (XEXP (x, 1), unsig));
+ return (mn10300_address_cost_1 (XEXP (x, 0), unsig)
+ + mn10300_address_cost_1 (XEXP (x, 1), unsig));
case EXPR_LIST:
case SUBREG:
case MEM:
- return ADDRESS_COST (XEXP (x, 0));
+ return mn10300_address_cost (XEXP (x, 0));
case ZERO_EXTEND:
*unsig = 1;
- return mn10300_address_cost (XEXP (x, 0), unsig);
+ return mn10300_address_cost_1 (XEXP (x, 0), unsig);
case CONST_INT:
if (INTVAL (x) == 0)
switch (GET_CODE (XEXP (x, 0)))
{
case MEM:
- return ADDRESS_COST (XEXP (x, 0));
+ return mn10300_address_cost (XEXP (x, 0));
case REG:
return 1;
}
}
+static int
+mn10300_address_cost (x)
+ rtx x;
+{
+ int s = 0;
+ return mn10300_address_cost_1 (x, &s);
+}
+
static bool
mn10300_rtx_costs (x, code, outer_code, total)
rtx x;
(CLASS1 == EXTENDED_REGS || CLASS2 == EXTENDED_REGS) ? 4 : \
4)
-#define ADDRESS_COST(X) mn10300_address_cost((X), 0)
-
/* Nonzero if access to memory by bytes or half words is no faster
than accessing full words. */
#define SLOW_BYTE_ACCESS 1
/* Prototypes for functions in ns32k.c */
#ifdef RTX_CODE
-extern int calc_address_cost PARAMS ((rtx));
extern enum reg_class secondary_reload_class PARAMS ((enum reg_class,
enum machine_mode, rtx));
extern int reg_or_mem_operand PARAMS ((rtx, enum machine_mode));
static void ns32k_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static void ns32k_encode_section_info PARAMS ((tree, int));
static bool ns32k_rtx_costs PARAMS ((rtx, int, int, int *));
+static int ns32k_address_cost PARAMS ((rtx));
\f
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS ns32k_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST ns32k_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
#endif
-/* ADDRESS_COST calls this. This function is not optimal
+/* TARGET_ADDRESS_COST calls this. This function is not optimal
for the 32032 & 32332, but it probably is better than
the default. */
-int
-calc_address_cost (operand)
+static int
+ns32k_address_cost (operand)
rtx operand;
{
- int i;
int cost = 0;
- if (GET_CODE (operand) == MEM)
- cost += 3;
- if (GET_CODE (operand) == MULT)
- cost += 2;
+
switch (GET_CODE (operand))
{
case REG:
cost += 1;
break;
+
case POST_DEC:
case PRE_DEC:
break;
+
case CONST_INT:
if (INTVAL (operand) <= 7 && INTVAL (operand) >= -8)
break;
case CONST_DOUBLE:
cost += 5;
break;
+
case MEM:
- cost += calc_address_cost (XEXP (operand, 0));
+ cost += ns32k_address_cost (XEXP (operand, 0)) + 3;
break;
+
case MULT:
+ cost += 2;
+ /* FALLTHRU */
case PLUS:
- for (i = 0; i < GET_RTX_LENGTH (GET_CODE (operand)); i++)
- {
- cost += calc_address_cost (XEXP (operand, i));
- }
+ cost += ns32k_address_cost (XEXP (operand, 0));
+ cost += ns32k_address_cost (XEXP (operand, 1));
+ break;
+
default:
break;
}
+
return cost;
}
is a byte address (for indexing purposes)
so give the MEM rtx a byte's mode. */
#define FUNCTION_MODE QImode
-
-/* Compute the cost of address ADDRESS. */
-
-#define ADDRESS_COST(RTX) calc_address_cost (RTX)
-
\f
/* Tell final.c how to eliminate redundant test instructions. */
extern int arith11_operand PARAMS ((rtx, enum machine_mode));
extern int adddi3_operand PARAMS ((rtx, enum machine_mode));
extern int symbolic_expression_p PARAMS ((rtx));
-extern int hppa_address_cost PARAMS ((rtx));
extern int symbolic_memory_operand PARAMS ((rtx, enum machine_mode));
extern int pa_adjust_insn_length PARAMS ((rtx, int));
extern int int11_operand PARAMS ((rtx, enum machine_mode));
#endif
#endif
+static int hppa_address_cost PARAMS ((rtx));
static bool hppa_rtx_costs PARAMS ((rtx, int, int, int *));
static inline rtx force_mode PARAMS ((enum machine_mode, rtx));
static void pa_combine_instructions PARAMS ((rtx));
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS hppa_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hppa_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
It is no coincidence that this has the same structure
as GO_IF_LEGITIMATE_ADDRESS. */
-int
+
+static int
hppa_address_cost (X)
rtx X;
{
- if (GET_CODE (X) == PLUS)
+ switch (GET_CODE (X))
+ {
+ case REG:
+ case PLUS:
+ case LO_SUM:
return 1;
- else if (GET_CODE (X) == LO_SUM)
- return 1;
- else if (GET_CODE (X) == HIGH)
- return 2;
- return 4;
+ case HIGH:
+ return 2;
+ default:
+ return 4;
+ }
}
/* Compute a (partial) cost for rtx X. Return true if the complete
few bits. */
#define SHIFT_COUNT_TRUNCATED 1
-#define ADDRESS_COST(RTX) \
- (GET_CODE (RTX) == REG ? 1 : hppa_address_cost (RTX))
-
/* Compute extra cost of moving data between one register class
and another.
unsigned HOST_WIDE_INT));
static void romp_encode_section_info PARAMS ((tree, int));
static bool romp_rtx_costs PARAMS ((rtx, int, int, int *));
+static int romp_address_cost PARAMS ((rtx));
\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ENCODE_SECTION_INFO romp_encode_section_info
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS romp_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST romp_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
return false;
}
}
+
+/* For the ROMP, everything is cost 0 except for addresses involving
+ symbolic constants, which are cost 1. */
+
+static int
+romp_address_cost (x)
+ rtx x;
+{
+ return
+ ((GET_CODE (x) == SYMBOL_REF
+ && ! CONSTANT_POOL_ADDRESS_P (x))
+ || GET_CODE (x) == LABEL_REF
+ || (GET_CODE (x) == CONST
+ && ! constant_pool_address_operand (x, Pmode))
+ || (GET_CODE (x) == PLUS
+ && ((GET_CODE (XEXP (x, 1)) == SYMBOL_REF
+ && ! CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
+ || GET_CODE (XEXP (x, 1)) == LABEL_REF
+ || GET_CODE (XEXP (x, 1)) == CONST)));
+}
/* #define SHIFT_COUNT_TRUNCATED */
-/* Compute the cost of an address. This is meant to approximate the size
- and/or execution delay of an insn using that address. If the cost is
- approximated by the RTL complexity, including CONST_COSTS above, as
- is usually the case for CISC machines, this macro should not be defined.
- For aggressively RISCy machines, only one insn format is allowed, so
- this macro should be a constant. The value of this macro only matters
- for valid addresses.
-
- For the ROMP, everything is cost 0 except for addresses involving
- symbolic constants, which are cost 1. */
-
-#define ADDRESS_COST(RTX) \
- ((GET_CODE (RTX) == SYMBOL_REF \
- && ! CONSTANT_POOL_ADDRESS_P (RTX)) \
- || GET_CODE (RTX) == LABEL_REF \
- || (GET_CODE (RTX) == CONST \
- && ! constant_pool_address_operand (RTX, Pmode)) \
- || (GET_CODE (RTX) == PLUS \
- && ((GET_CODE (XEXP (RTX, 1)) == SYMBOL_REF \
- && ! CONSTANT_POOL_ADDRESS_P (XEXP (RTX, 0))) \
- || GET_CODE (XEXP (RTX, 1)) == LABEL_REF \
- || GET_CODE (XEXP (RTX, 1)) == CONST)))
-
/* Adjust the length of an INSN. LENGTH is the currently-computed length and
should be adjusted to reflect any required changes. This macro is used when
there is some systematic length adjustment required that would be difficult
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS rs6000_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
struct gcc_target targetm = TARGET_INITIALIZER;
\f
#define SHIFT_COUNT_TRUNCATED (TARGET_POWER ? 1 : 0)
-/* Compute the cost of an address. This is meant to approximate the size
- and/or execution delay of an insn using that address. If the cost is
- approximated by the RTL complexity, including CONST_COSTS above, as
- is usually the case for CISC machines, this macro should not be defined.
- For aggressively RISCy machines, only one insn format is allowed, so
- this macro should be a constant. The value of this macro only matters
- for valid addresses.
-
- For the RS/6000, everything is cost 0. */
-
-#define ADDRESS_COST(RTX) 0
-
/* Adjust the length of an INSN. LENGTH is the currently-computed length and
should be adjusted to reflect any required changes. This macro is used when
there is some systematic length adjustment required that would be difficult
extern void s390_function_profiler PARAMS ((FILE *, int));
#ifdef RTX_CODE
-extern int s390_address_cost PARAMS ((rtx));
extern int q_constraint PARAMS ((rtx));
extern int const0_operand PARAMS ((rtx, enum machine_mode));
extern int consttable_operand PARAMS ((rtx, enum machine_mode));
static int s390_issue_rate PARAMS ((void));
static int s390_use_dfa_pipeline_interface PARAMS ((void));
static bool s390_rtx_costs PARAMS ((rtx, int, int, int *));
+static int s390_address_cost PARAMS ((rtx));
#undef TARGET_ASM_ALIGNED_HI_OP
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS s390_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST s390_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
/* Return the cost of an address rtx ADDR. */
-int
+static int
s390_address_cost (addr)
rtx addr;
{
/* Relative costs of operations. */
-/* An expression giving the cost of an addressing mode that contains
- ADDRESS. If not defined, the cost is computed from the ADDRESS
- expression and the `CONST_COSTS' values. */
-#define ADDRESS_COST(RTX) s390_address_cost ((RTX))
-
/* On s390, copy between fprs and gprs is expensive. */
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
(( ( reg_classes_intersect_p ((CLASS1), GENERAL_REGS) \
static int addsubcosts PARAMS ((rtx));
static int multcosts PARAMS ((rtx));
static bool sh_rtx_costs PARAMS ((rtx, int, int, int *));
+static int sh_address_cost PARAMS ((rtx));
\f
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS sh_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST sh_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
}
}
+/* Compute the cost of an address. For the SH, all valid addresses are
+ the same cost. Use a slightly higher cost for reg + reg addressing,
+ since it increases pressure on r0. */
+
+static int
+sh_address_cost (X)
+ rtx X;
+{
+ return (GET_CODE (X) == PLUS
+ && ! CONSTANT_P (XEXP (X, 1))
+ && ! TARGET_SHMEDIA ? 1 : 0);
+}
/* Code to expand a shift. */
((GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == LABEL_REF) \
&& nonpic_symbol_mentioned_p (X))
\f
-/* Compute the cost of an address. For the SH, all valid addresses are
- the same cost. Use a slightly higher cost for reg + reg addressing,
- since it increases pressure on r0. */
-
-#define ADDRESS_COST(X) (GET_CODE (X) == PLUS && ! CONSTANT_P (XEXP (X, 1)) \
- && ! TARGET_SHMEDIA \
- ? 1 : 0)
-
/* Compute extra cost of moving data between one register class
and another. */
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS sparc_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
struct gcc_target targetm = TARGET_INITIALIZER;
\f
: (sparc_cpu == PROCESSOR_ULTRASPARC3 \
? 9 : 3))
-#define ADDRESS_COST(RTX) 1
-
#define PREFETCH_BLOCK \
((sparc_cpu == PROCESSOR_ULTRASPARC \
|| sparc_cpu == PROCESSOR_ULTRASPARC3) \
static void xstormy16_init_builtins PARAMS ((void));
static rtx xstormy16_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
static bool xstormy16_rtx_costs PARAMS ((rtx, int, int, int *));
+static int xstormy16_address_cost PARAMS ((rtx));
/* Define the information needed to generate branch and scc insns. This is
stored from the compare operation. */
}
}
+static int
+xstormy16_address_cost (x)
+ rtx x;
+{
+ return (GET_CODE (x) == CONST_INT ? 2
+ : GET_CODE (x) == PLUS ? 7
+ : 5);
+}
/* Branches are handled as follows:
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS xstormy16_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST xstormy16_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Describing Relative Costs of Operations */
-/* An expression giving the cost of an addressing mode that contains ADDRESS.
- If not defined, the cost is computed from the ADDRESS expression and the
- `CONST_COSTS' values.
-
- For most CISC machines, the default cost is a good approximation of the true
- cost of the addressing mode. However, on RISC machines, all instructions
- normally have the same length and execution time. Hence all addresses will
- have equal costs.
-
- In cases where more than one form of an address is known, the form with the
- lowest cost will be used. If multiple forms have the same, lowest, cost,
- the one that is the most complex will be used.
-
- For example, suppose an address that is equal to the sum of a register and a
- constant is used twice in the same basic block. When this macro is not
- defined, the address will be computed in a register and memory references
- will be indirect through that register. On machines where the cost of the
- addressing mode containing the sum is no higher than that of a simple
- indirect reference, this will produce an additional instruction and possibly
- require an additional register. Proper specification of this macro
- eliminates this overhead for such machines.
-
- Similar use of this macro is made in strength reduction of loops.
-
- ADDRESS need not be valid as an address. In such a case, the cost is not
- relevant and can be any value; invalid addresses need not be assigned a
- different cost.
-
- On machines where an address involving more than one register is as cheap as
- an address computation involving only one register, defining `ADDRESS_COST'
- to reflect this can cause two registers to be live over a region of code
- where only one would have been if `ADDRESS_COST' were not defined in that
- manner. This effect should be considered in the definition of this macro.
- Equivalent costs should probably only be given to addresses with different
- numbers of registers on machines with lots of registers.
-
- This macro will normally either not be defined or be defined as a
- constant. */
-#define ADDRESS_COST(ADDRESS) \
- (GET_CODE (ADDRESS) == CONST_INT ? 2 \
- : GET_CODE (ADDRESS) == PLUS ? 7 \
- : 5)
-
/* A C expression for the cost of moving data of mode MODE from a
register in class FROM to one in class TO. The classes are
expressed using the enumeration values such as `GENERAL_REGS'. A
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS v850_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
struct gcc_target targetm = TARGET_INITIALIZER;
\f
#define CC_NO_CARRY CC_NO_OVERFLOW
#define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc(EXP, INSN)
-/* All addressing modes have the same cost on the V850 series. */
-#define ADDRESS_COST(ADDR) 1
-
/* Nonzero if access to memory by bytes or half words is no faster
than accessing full words. */
#define SLOW_BYTE_ACCESS 1
extern void split_quadword_operands PARAMS ((rtx *, rtx *, int));
extern void print_operand_address PARAMS ((FILE *, rtx));
extern int vax_float_literal PARAMS ((rtx));
-extern int vax_address_cost PARAMS ((rtx));
-extern int vax_rtx_cost PARAMS ((rtx));
extern int reg_was_0_p PARAMS ((rtx, rtx));
#endif /* RTX_CODE */
static void vax_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void vax_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
+static int vax_address_cost_1 PARAMS ((rtx));
+static int vax_address_cost PARAMS ((rtx));
static int vax_rtx_costs_1 PARAMS ((rtx, enum rtx_code, enum rtx_code));
static bool vax_rtx_costs PARAMS ((rtx, int, int, int *));
\f
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS vax_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST vax_address_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
2 - indirect */
-int
-vax_address_cost (addr)
+static int
+vax_address_cost_1 (addr)
register rtx addr;
{
int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
return reg + indexed + indir + offset + predec;
}
+static int
+vax_address_cost (x)
+ rtx x;
+{
+ return (1 + (GET_CODE (x) == REG ? 0 : vax_address_cost_1 (x)));
+}
+
/* Cost of an expression on a VAX. This version has costs tuned for the
CVAX chip (found in the VAX 3 series) with comments for variations on
other models. */
x = XEXP (x, 0);
if (GET_CODE (x) == REG || GET_CODE (x) == POST_INC)
return c;
- return c + vax_address_cost (x);
+ return c + vax_address_cost_1 (x);
default:
c = 3;
break;
case MEM:
c += 1; /* 2 on VAX 2 */
if (GET_CODE (XEXP (op, 0)) != REG)
- c += vax_address_cost (XEXP (op, 0));
+ c += vax_address_cost_1 (XEXP (op, 0));
break;
case REG:
case SUBREG:
#define TARGET_FLOAT_FORMAT VAX_FLOAT_FORMAT
-#define ADDRESS_COST(RTX) (1 + (GET_CODE (RTX) == REG ? 0 : vax_address_cost(RTX)))
-
/* Specify the cost of a branch insn; roughly the number of extra insns that
should be added to avoid a branch.
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS xtensa_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
struct gcc_target targetm = TARGET_INITIALIZER;
\f
indexing purposes) so give the MEM rtx a words's mode. */
#define FUNCTION_MODE SImode
-/* An expression giving the cost of an addressing mode that
- contains ADDRESS. */
-#define ADDRESS_COST(ADDR) 1
-
/* A C expression for the cost of moving data from a register in
class FROM to one in class TO. The classes are expressed using
the enumeration values such as 'GENERAL_REGS'. A value of 2 is
rtx x;
enum machine_mode mode;
{
- /* The ADDRESS_COST macro does not deal with ADDRESSOF nodes. But,
+ /* The address_cost target hook does not deal with ADDRESSOF nodes. But,
during CSE, such nodes are present. Using an ADDRESSOF node which
refers to the address of a REG is a good thing because we can then
turn (MEM (ADDRESSSOF (REG))) into just plain REG. */
/* We may be asked for cost of various unusual addresses, such as operands
of push instruction. It is not worthwhile to complicate writing
- of ADDRESS_COST macro by such cases. */
+ of the target hook by such cases. */
if (!memory_address_p (mode, x))
return 1000;
-#ifdef ADDRESS_COST
- return ADDRESS_COST (x);
-#else
- return rtx_cost (x, MEM);
-#endif
+
+ return (*targetm.address_cost) (x);
}
+/* If the target doesn't override, compute the cost as with arithmetic. */
+
+int
+default_address_cost (x)
+ rtx x;
+{
+ return rtx_cost (x, MEM);
+}
\f
static struct cse_reg_info *
get_cse_reg_info (regno)
return 1;
}
+int
+hook_int_rtx_0 (a)
+ rtx a ATTRIBUTE_UNUSED;
+{
+ return 0;
+}
+
void
hook_void_tree (a)
tree a ATTRIBUTE_UNUSED;
void hook_void_tree_treeptr PARAMS ((tree, tree *));
int hook_int_tree_tree_1 PARAMS ((tree, tree));
+int hook_int_rtx_0 PARAMS ((rtx));
bool default_can_output_mi_thunk_no_vcall
PARAMS ((tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
the expression of G2 in terms of G1 can be used. */
if (ret != NULL_RTX
&& g2->giv_type == DEST_ADDR
- && memory_address_p (GET_MODE (g2->mem), ret)
- /* ??? Looses, especially with -fforce-addr, where *g2->location
- will always be a register, and so anything more complicated
- gets discarded. */
-#if 0
-#ifdef ADDRESS_COST
- && ADDRESS_COST (tem) <= ADDRESS_COST (*g2->location)
-#else
- && rtx_cost (tem, MEM) <= rtx_cost (*g2->location, MEM)
-#endif
-#endif
- )
- {
- return ret;
- }
+ && memory_address_p (GET_MODE (g2->mem), ret))
+ return ret;
return NULL_RTX;
}
extern void assemble_vtable_entry PARAMS ((struct rtx_def *, HOST_WIDE_INT));
extern void assemble_vtable_inherit PARAMS ((struct rtx_def *,
struct rtx_def *));
+
+extern int default_address_cost PARAMS ((rtx));
ASM_OUTPUT_DESTRUCTOR SIGNED_CHAR_SPEC MAX_CHAR_TYPE_SIZE \
WCHAR_UNSIGNED UNIQUE_SECTION SELECT_SECTION SELECT_RTX_SECTION \
ENCODE_SECTION_INFO STRIP_NAME_ENCODING ASM_GLOBALIZE_LABEL \
- ASM_OUTPUT_MI_THUNK CONST_COSTS RTX_COSTS DEFAULT_RTX_COSTS
+ ASM_OUTPUT_MI_THUNK CONST_COSTS RTX_COSTS DEFAULT_RTX_COSTS \
+ ADDRESS_COST
/* Other obsolete target macros, or macros that used to be in target
headers and were not used, and may be obsolete or may never have
TARGET_SCHED_INIT_DFA_BUBBLES, \
TARGET_SCHED_DFA_BUBBLE}
-/* All in tree.c. */
+/* In tree.c. */
#define TARGET_MERGE_DECL_ATTRIBUTES merge_decl_attributes
#define TARGET_MERGE_TYPE_ATTRIBUTES merge_type_attributes
#define TARGET_ATTRIBUTE_TABLE NULL
+/* In cse.c. */
+#define TARGET_ADDRESS_COST default_address_cost
+
/* In builtins.c. */
#define TARGET_INIT_BUILTINS default_init_builtins
#define TARGET_EXPAND_BUILTIN default_expand_builtin
#define TARGET_INSERT_ATTRIBUTES hook_void_tree_treeptr
#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_tree_false
#define TARGET_MS_BITFIELD_LAYOUT_P hook_bool_tree_false
-/* #define TARGET_RTX_COSTS hook_bool_rtx_int_int_intp_false */
+#define TARGET_RTX_COSTS hook_bool_rtx_int_int_intp_false
#ifndef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P hook_bool_tree_false
TARGET_STRIP_NAME_ENCODING, \
TARGET_VALID_POINTER_MODE, \
TARGET_RTX_COSTS, \
+ TARGET_ADDRESS_COST, \
TARGET_HAVE_NAMED_SECTIONS, \
TARGET_HAVE_CTORS_DTORS, \
TARGET_HAVE_TLS, \
not necessarily defined at this point. */
bool (* rtx_costs) PARAMS ((rtx x, int code, int outer_code, int *total));
+ /* Compute the cost of X, used as an address. Never called with
+ invalid addresses. */
+ int (* address_cost) PARAMS ((rtx x));
+
/* Leave the boolean fields at the end. */
/* True if arbitrary sections are supported. */