[RS6000] PowerPC64 soft-float
This patch aims to prevent long sequences loading soft-float constants. For 32-bit, it makes sense to load values inline to a gpr with lis, addi, but not so much for 64-bit where a 5 insn sequence might be needed for each gpr. For TFmode in particular, a 10 insn sequence is reduced to 2 loads from memory plus 1 or 2 address setup insns. * config/rs6000/predicates.md (easy_fp_constant): Avoid long dependent insn sequences. * config/rs6000/rs6000.c (num_insns_constant): Support long double constants. * config/rs6000/rs6000.md (mov<mode>_softfloat <FMOVE128>): Adjust length attribute. From-SVN: r266663
This commit is contained in:
parent
ceb8c8c4ca
commit
b49f1a7e7c
4 changed files with 48 additions and 3 deletions
|
@ -1,3 +1,12 @@
|
|||
2018-11-30 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* config/rs6000/predicates.md (easy_fp_constant): Avoid long
|
||||
dependent insn sequences.
|
||||
* config/rs6000/rs6000.c (num_insns_constant): Support long
|
||||
double constants.
|
||||
* config/rs6000/rs6000.md (mov<mode>_softfloat <FMOVE128>): Adjust
|
||||
length attribute.
|
||||
|
||||
2018-11-30 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* config/rs6000/rs6000.c (num_insns_constant_gpr): Renamed from
|
||||
|
|
|
@ -564,9 +564,26 @@
|
|||
{
|
||||
gcc_assert (GET_MODE (op) == mode && SCALAR_FLOAT_MODE_P (mode));
|
||||
|
||||
/* Consider all constants with -msoft-float to be easy. */
|
||||
/* Consider all constants with -msoft-float to be easy when regs are
|
||||
32-bit and thus can be loaded with a maximum of 2 insns. For
|
||||
64-bit avoid long dependent insn sequences. */
|
||||
if (TARGET_SOFT_FLOAT)
|
||||
return 1;
|
||||
{
|
||||
if (!TARGET_POWERPC64)
|
||||
return 1;
|
||||
|
||||
int size = GET_MODE_SIZE (mode);
|
||||
if (size < 8)
|
||||
return 1;
|
||||
|
||||
int load_from_mem_insns = 2;
|
||||
if (size > 8)
|
||||
load_from_mem_insns++;
|
||||
if (TARGET_CMODEL != CMODEL_SMALL)
|
||||
load_from_mem_insns++;
|
||||
if (num_insns_constant (op, mode) <= load_from_mem_insns)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 0.0D is not all zero bits. */
|
||||
if (DECIMAL_FLOAT_MODE_P (mode))
|
||||
|
|
|
@ -5940,6 +5940,25 @@ num_insns_constant (rtx op, machine_mode mode)
|
|||
val |= l[WORDS_BIG_ENDIAN ? 1 : 0] & 0xffffffffUL;
|
||||
mode = DImode;
|
||||
}
|
||||
else if (mode == TFmode || mode == TDmode
|
||||
|| mode == KFmode || mode == IFmode)
|
||||
{
|
||||
long l[4];
|
||||
int insns;
|
||||
|
||||
if (mode == TDmode)
|
||||
REAL_VALUE_TO_TARGET_DECIMAL128 (*rv, l);
|
||||
else
|
||||
REAL_VALUE_TO_TARGET_LONG_DOUBLE (*rv, l);
|
||||
|
||||
val = (unsigned HOST_WIDE_INT) l[WORDS_BIG_ENDIAN ? 0 : 3] << 32;
|
||||
val |= l[WORDS_BIG_ENDIAN ? 1 : 2] & 0xffffffffUL;
|
||||
insns = num_insns_constant_multi (val, DImode);
|
||||
val = (unsigned HOST_WIDE_INT) l[WORDS_BIG_ENDIAN ? 2 : 1] << 32;
|
||||
val |= l[WORDS_BIG_ENDIAN ? 3 : 0] & 0xffffffffUL;
|
||||
insns += num_insns_constant_multi (val, DImode);
|
||||
return insns;
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
|
|
@ -7729,7 +7729,7 @@
|
|||
(const_string "8")
|
||||
(const_string "16"))
|
||||
(if_then_else (match_test "TARGET_POWERPC64")
|
||||
(const_string "40")
|
||||
(const_string "16")
|
||||
(const_string "32"))
|
||||
(if_then_else (match_test "TARGET_POWERPC64")
|
||||
(const_string "8")
|
||||
|
|
Loading…
Add table
Reference in a new issue