arm.c (arm_override_options): Use arm_ld_sched rather than testing a bit in tune_flags.
* arm.c (arm_override_options): Use arm_ld_sched rather than testing a bit in tune_flags. (const_double_needs_minipool): Likewise. Split most of the code out into ... (arm_const_double_inline_cost): ... new function here. * arm-protos.h (arm_const_double_inline_cost): Add prototype. * arm.h (EXTRA_CONSTRAINT_STR_ARM): Add D[abc] constraints for double- word constants of length 2, 3 and 4 insns respectively. (CONSTRAINT_LEN): The 'D' prefix is a 2-letter constraint. * arm.md (arm_movdi, movdf_soft_insn): Add alternatives for D[abc] constraints. Set insn lenghts accordingly. From-SVN: r90962
This commit is contained in:
parent
9eaf7da094
commit
2075b05db6
@ -1,3 +1,17 @@
|
||||
2004-11-20 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* arm.c (arm_override_options): Use arm_ld_sched rather than testing
|
||||
a bit in tune_flags.
|
||||
(const_double_needs_minipool): Likewise. Split most of the code out
|
||||
into ...
|
||||
(arm_const_double_inline_cost): ... new function here.
|
||||
* arm-protos.h (arm_const_double_inline_cost): Add prototype.
|
||||
* arm.h (EXTRA_CONSTRAINT_STR_ARM): Add D[abc] constraints for double-
|
||||
word constants of length 2, 3 and 4 insns respectively.
|
||||
(CONSTRAINT_LEN): The 'D' prefix is a 2-letter constraint.
|
||||
* arm.md (arm_movdi, movdf_soft_insn): Add alternatives for D[abc]
|
||||
constraints. Set insn lenghts accordingly.
|
||||
|
||||
2004-11-19 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* basic-block.h (edge_def): Add dest_idx.
|
||||
|
@ -89,6 +89,7 @@ extern rtx arm_gen_compare_reg (RTX_CODE, rtx, rtx);
|
||||
extern rtx arm_gen_return_addr_mask (void);
|
||||
extern void arm_reload_in_hi (rtx *);
|
||||
extern void arm_reload_out_hi (rtx *);
|
||||
extern int arm_const_double_inline_cost (rtx);
|
||||
extern const char *fp_immediate_constant (rtx);
|
||||
extern const char *output_call (rtx *);
|
||||
extern const char *output_call_mem (rtx *);
|
||||
|
@ -1163,7 +1163,7 @@ arm_override_options (void)
|
||||
/* For processors with load scheduling, it never costs more than
|
||||
2 cycles to load a constant, and the load scheduler may well
|
||||
reduce that to 1. */
|
||||
if (tune_flags & FL_LDSCHED)
|
||||
if (arm_ld_sched)
|
||||
arm_constant_limit = 1;
|
||||
|
||||
/* On XScale the longer latency of a load makes it more difficult
|
||||
@ -7258,43 +7258,52 @@ push_minipool_fix (rtx insn, HOST_WIDE_INT address, rtx *loc,
|
||||
minipool_fix_tail = fix;
|
||||
}
|
||||
|
||||
/* Determine if a CONST_DOUBLE should be pushed to the minipool */
|
||||
static bool
|
||||
const_double_needs_minipool (rtx val)
|
||||
/* Return the cost of synthesising the const_double VAL inline.
|
||||
Returns the number of insns needed, or 99 if we don't know how to
|
||||
do it. */
|
||||
int
|
||||
arm_const_double_inline_cost (rtx val)
|
||||
{
|
||||
long parts[2];
|
||||
|
||||
/* thumb only knows to load a CONST_DOUBLE from memory at the moment */
|
||||
if (TARGET_THUMB)
|
||||
return true;
|
||||
|
||||
|
||||
if (GET_MODE (val) == DFmode)
|
||||
{
|
||||
REAL_VALUE_TYPE r;
|
||||
if (!TARGET_SOFT_FLOAT)
|
||||
return true;
|
||||
return 99;
|
||||
REAL_VALUE_FROM_CONST_DOUBLE (r, val);
|
||||
REAL_VALUE_TO_TARGET_DOUBLE (r, parts);
|
||||
}
|
||||
else if (GET_MODE (val) != VOIDmode)
|
||||
return true;
|
||||
return 99;
|
||||
else
|
||||
{
|
||||
parts[0] = CONST_DOUBLE_LOW (val);
|
||||
parts[1] = CONST_DOUBLE_HIGH (val);
|
||||
}
|
||||
|
||||
return (arm_gen_constant (SET, SImode, NULL_RTX, parts[0],
|
||||
NULL_RTX, NULL_RTX, 0, 0)
|
||||
+ arm_gen_constant (SET, SImode, NULL_RTX, parts[1],
|
||||
NULL_RTX, NULL_RTX, 0, 0));
|
||||
}
|
||||
|
||||
/* Determine if a CONST_DOUBLE should be pushed to the minipool */
|
||||
static bool
|
||||
const_double_needs_minipool (rtx val)
|
||||
{
|
||||
/* thumb only knows to load a CONST_DOUBLE from memory at the moment */
|
||||
if (TARGET_THUMB)
|
||||
return true;
|
||||
|
||||
/* Don't push anything to the minipool if a CONST_DOUBLE can be built with
|
||||
a few ALU insns directly. On balance, the optimum is likely to be around
|
||||
3 insns, except when there are no load delay slots where it should be 4.
|
||||
When optimizing for size, a limit of 3 allows saving at least one word
|
||||
except for cases where a single minipool entry could be shared more than
|
||||
2 times which is rather unlikely to outweight the overall savings. */
|
||||
return ( arm_gen_constant (SET, SImode, NULL_RTX, parts[0],
|
||||
NULL_RTX, NULL_RTX, 0, 0)
|
||||
+ arm_gen_constant (SET, SImode, NULL_RTX, parts[1],
|
||||
NULL_RTX, NULL_RTX, 0, 0)
|
||||
> ((optimize_size || (tune_flags & FL_LDSCHED)) ? 3 : 4));
|
||||
return (arm_const_double_inline_cost (val)
|
||||
> ((optimize_size || arm_ld_sched) ? 3 : 4));
|
||||
}
|
||||
|
||||
/* Scan INSN and note any of its operands that need fixing.
|
||||
|
@ -1309,27 +1309,39 @@ enum reg_class
|
||||
`S' means any symbol that has the SYMBOL_REF_FLAG set or a CONSTANT_POOL
|
||||
address. This means that the symbol is in the text segment and can be
|
||||
accessed without using a load.
|
||||
'D' Prefixes a number of const_double operands where:
|
||||
'Da' is a constant that takes two ARM insns to load.
|
||||
'Db' takes three ARM insns.
|
||||
'Dc' takes four ARM insns, if we allow that in this compilation.
|
||||
'U' Prefixes an extended memory constraint where:
|
||||
'Uv' is an address valid for VFP load/store insns.
|
||||
'Uy' is an address valid for iwmmxt load/store insns.
|
||||
'Uq' is an address valid for ldrsb. */
|
||||
|
||||
#define EXTRA_CONSTRAINT_STR_ARM(OP, C, STR) \
|
||||
(((C) == 'Q') ? (GET_CODE (OP) == MEM \
|
||||
&& GET_CODE (XEXP (OP, 0)) == REG) : \
|
||||
((C) == 'R') ? (GET_CODE (OP) == MEM \
|
||||
&& GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \
|
||||
&& CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \
|
||||
((C) == 'S') ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) : \
|
||||
((C) == 'T') ? cirrus_memory_offset (OP) : \
|
||||
#define EXTRA_CONSTRAINT_STR_ARM(OP, C, STR) \
|
||||
(((C) == 'D') ? (GET_CODE (OP) == CONST_DOUBLE \
|
||||
&& (((STR)[1] == 'a' \
|
||||
&& arm_const_double_inline_cost (OP) == 2) \
|
||||
|| ((STR)[1] == 'b' \
|
||||
&& arm_const_double_inline_cost (OP) == 3) \
|
||||
|| ((STR)[1] == 'c' \
|
||||
&& arm_const_double_inline_cost (OP) == 4 \
|
||||
&& !(optimize_size || arm_ld_sched)))) : \
|
||||
((C) == 'Q') ? (GET_CODE (OP) == MEM \
|
||||
&& GET_CODE (XEXP (OP, 0)) == REG) : \
|
||||
((C) == 'R') ? (GET_CODE (OP) == MEM \
|
||||
&& GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \
|
||||
&& CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \
|
||||
((C) == 'S') ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) : \
|
||||
((C) == 'T') ? cirrus_memory_offset (OP) : \
|
||||
((C) == 'U' && (STR)[1] == 'v') ? arm_coproc_mem_operand (OP, FALSE) : \
|
||||
((C) == 'U' && (STR)[1] == 'y') ? arm_coproc_mem_operand (OP, TRUE) : \
|
||||
((C) == 'U' && (STR)[1] == 'q') \
|
||||
? arm_extendqisi_mem_op (OP, GET_MODE (OP)) \
|
||||
: 0)
|
||||
((C) == 'U' && (STR)[1] == 'q') \
|
||||
? arm_extendqisi_mem_op (OP, GET_MODE (OP)) \
|
||||
: 0)
|
||||
|
||||
#define CONSTRAINT_LEN(C,STR) \
|
||||
((C) == 'U' ? 2 : DEFAULT_CONSTRAINT_LEN (C, STR))
|
||||
(((C) == 'U' || (C) == 'D') ? 2 : DEFAULT_CONSTRAINT_LEN (C, STR))
|
||||
|
||||
#define EXTRA_CONSTRAINT_THUMB(X, C) \
|
||||
((C) == 'Q' ? (GET_CODE (X) == MEM \
|
||||
|
@ -4156,18 +4156,18 @@
|
||||
)
|
||||
|
||||
(define_insn "*arm_movdi"
|
||||
[(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r ,m")
|
||||
(match_operand:DI 1 "di_operand" "rIK,mi,r"))]
|
||||
[(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
|
||||
(match_operand:DI 1 "di_operand" "rIKDa,Db,Dc,mi,r"))]
|
||||
"TARGET_ARM
|
||||
&& !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
|
||||
&& !TARGET_IWMMXT"
|
||||
"*
|
||||
return (output_move_double (operands));
|
||||
"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "*,load2,store2")
|
||||
(set_attr "pool_range" "*,1020,*")
|
||||
(set_attr "neg_pool_range" "*,1008,*")]
|
||||
[(set_attr "length" "8,12,16,8,8")
|
||||
(set_attr "type" "*,*,*,load2,store2")
|
||||
(set_attr "pool_range" "*,*,*,1020,*")
|
||||
(set_attr "neg_pool_range" "*,*,*,1008,*")]
|
||||
)
|
||||
|
||||
;; We can't actually do base+index doubleword loads if the index and
|
||||
@ -5165,13 +5165,13 @@
|
||||
)
|
||||
|
||||
(define_insn "*movdf_soft_insn"
|
||||
[(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,m")
|
||||
(match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
|
||||
[(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
|
||||
(match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
|
||||
"TARGET_ARM && TARGET_SOFT_FLOAT
|
||||
"
|
||||
"* return output_move_double (operands);"
|
||||
[(set_attr "length" "8,8,8")
|
||||
(set_attr "type" "*,load2,store2")
|
||||
[(set_attr "length" "8,12,16,8,8")
|
||||
(set_attr "type" "*,*,*,load2,store2")
|
||||
(set_attr "pool_range" "1020")
|
||||
(set_attr "neg_pool_range" "1008")]
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user