diff options
author | Alan Modra <amodra@gmail.com> | 2018-12-01 00:05:25 +1030 |
---|---|---|
committer | Alan Modra <amodra@gcc.gnu.org> | 2018-12-01 00:05:25 +1030 |
commit | b49f1a7e7c85add83637cf7df46b8fc9b5b299e9 (patch) | |
tree | d3cba1d26194ebe465ba3abbdc1bc4b7e64133af /gcc | |
parent | ceb8c8c4cae47fd07cd7dda74bb31b98ce4adadc (diff) | |
download | gcc-b49f1a7e7c85add83637cf7df46b8fc9b5b299e9.zip gcc-b49f1a7e7c85add83637cf7df46b8fc9b5b299e9.tar.gz gcc-b49f1a7e7c85add83637cf7df46b8fc9b5b299e9.tar.bz2 |
[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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/rs6000/predicates.md | 21 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 19 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 2 |
4 files changed, 48 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 617a3d6..15cbe00 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 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 num_insns_constant_wide. Make static. Revise comment. (num_insns_constant_multi): New function. diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index cf07d5c..94feae2 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -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)) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index fe58bc1..03b983b 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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 (); } diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index d2f6f11..797d5c3 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -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") |