arm.c (const_double_needs_minipool): New function to determine if a CONST_DOUBLE should be pushed to the minipool.

* config/arm/arm.c (const_double_needs_minipool): New function to
determine if a CONST_DOUBLE should be pushed to the minipool.
(note_invalid_constants): Use it.

From-SVN: r90881
This commit is contained in:
Nicolas Pitre 2004-11-18 20:28:04 +00:00 committed by Nicolas Pitre
parent 6e5b508490
commit b9e8bfda53
2 changed files with 48 additions and 1 deletions

View File

@ -1,3 +1,9 @@
2004-11-18 Nicolas Pitre <nico@cam.org>
* config/arm/arm.c (const_double_needs_minipool): New function to
determine if a CONST_DOUBLE should be pushed to the minipool.
(note_invalid_constants): Use it.
2004-11-18 Paul Brook <paul@codesourcery.com>
* config/arm/arm.c (target_float_switch): New variable..

View File

@ -7258,6 +7258,45 @@ 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)
{
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;
REAL_VALUE_FROM_CONST_DOUBLE (r, val);
REAL_VALUE_TO_TARGET_DOUBLE (r, parts);
}
else if (GET_MODE (val) != VOIDmode)
return true;
else
{
parts[0] = CONST_DOUBLE_LOW (val);
parts[1] = CONST_DOUBLE_HIGH (val);
}
/* 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));
}
/* Scan INSN and note any of its operands that need fixing.
If DO_PUSHES is false we do not actually push any of the fixups
needed. The function returns TRUE is any fixups were needed/pushed.
@ -7294,7 +7333,9 @@ note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes)
{
rtx op = recog_data.operand[opno];
if (CONSTANT_P (op))
if (CONSTANT_P (op)
&& (GET_CODE (op) != CONST_DOUBLE
|| const_double_needs_minipool (op)))
{
if (do_pushes)
push_minipool_fix (insn, address, recog_data.operand_loc[opno],