aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000
diff options
context:
space:
mode:
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-19 22:37:33 +0000
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-19 22:37:33 +0000
commit2d5ee2b9035db2414ae3535db18550c1d90e52fd (patch)
tree5e637e4c0de219dabaa221d54e60d5940317137c /gcc/config/rs6000
parent28323099addac7faac9e5ca78a2a43ddcbb1e819 (diff)
[gcc]
2015-03-19 Michael Meissner <meissner@linux.vnet.ibm.com> PR target/65240 * config/rs6000/predicates.md (easy_fp_constant): Remove special -ffast-math handling that kept non-0 constants live in the RTL until reload. Remove logic testing the number of instructions it took to create a constant in a GPR that was never used, due to a test for soft-float earlier. (memory_fp_constant): Delete, no longer used. * config/rs6000/rs6000.md (mov<MODE>_hardfloat): Remove alternatives for loading non-0 constants into GPRs for hard floating point that is no longer needed due to changes in easy_fp_constant. Add support for loading 0.0 into GPRs. (mov<mode>_hardfloat32): Likewise. (mov<mode>_hardfloat64): Likewise. (mov<mode>_64bit_dm): Likewise. (movtd_64bit_nodm): Likewise. (pre-reload move FP constant define_split): Delete define_split, since it is no longer used. (extenddftf2_internal): Remove GHF constraints that are not valid for extenddftf2. [gcc/testsuite] 2015-03-19 Michael Meissner <meissner@linux.vnet.ibm.com> PR target/65240 * gcc/testsuite/g++.dg/pr65240.h: Add tests for PR 65240. * gcc/testsuite/g++.dg/pr65240-1.C: Likewise. * gcc/testsuite/g++.dg/pr65240-2.C: Likewise. * gcc/testsuite/g++.dg/pr65240-3.C: Likewise. * gcc/testsuite/g++.dg/pr65240-4.C: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@221524 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r--gcc/config/rs6000/predicates.md88
-rw-r--r--gcc/config/rs6000/rs6000.md61
2 files changed, 37 insertions, 112 deletions
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index b491e407e73..6abb40b5cff 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -432,9 +432,6 @@
(define_predicate "easy_fp_constant"
(match_code "const_double")
{
- long k[4];
- REAL_VALUE_TYPE rv;
-
if (GET_MODE (op) != mode
|| (!SCALAR_FLOAT_MODE_P (mode) && mode != DImode))
return 0;
@@ -446,8 +443,7 @@
return 1;
/* The constant 0.0 is easy under VSX. */
- if ((mode == SFmode || mode == DFmode || mode == SDmode || mode == DDmode)
- && VECTOR_UNIT_VSX_P (DFmode) && op == CONST0_RTX (mode))
+ if (TARGET_VSX && SCALAR_FLOAT_MODE_P (mode) && op == CONST0_RTX (mode))
return 1;
if (DECIMAL_FLOAT_MODE_P (mode))
@@ -464,82 +460,28 @@
return 0;
#endif
+ /* If we have real FPRs, consider floating point constants hard (other than
+ 0.0 under VSX), so that the constant gets pushed to memory during the
+ early RTL phases. This has the advantage that double precision constants
+ that can be represented in single precision without a loss of precision
+ will use single precision loads. */
+
switch (mode)
{
case TFmode:
- if (TARGET_E500_DOUBLE)
- return 0;
-
- REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
-
- return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
- && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1
- && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1
- && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1);
-
case DFmode:
- /* Force constants to memory before reload to utilize
- compress_float_constant.
- Avoid this when flag_unsafe_math_optimizations is enabled
- because RDIV division to reciprocal optimization is not able
- to regenerate the division. */
- if (TARGET_E500_DOUBLE
- || (!reload_in_progress && !reload_completed
- && !flag_unsafe_math_optimizations))
- return 0;
-
- REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
- REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
-
- return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
- && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1);
-
case SFmode:
- /* Force constants to memory before reload to utilize
- compress_float_constant.
- Avoid this when flag_unsafe_math_optimizations is enabled
- because RDIV division to reciprocal optimization is not able
- to regenerate the division. */
- if (!reload_in_progress && !reload_completed
- && !flag_unsafe_math_optimizations)
- return 0;
-
- REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
- REAL_VALUE_TO_TARGET_SINGLE (rv, k[0]);
-
- return num_insns_constant_wide (k[0]) == 1;
-
- case DImode:
- return (num_insns_constant (op, DImode) <= 2);
-
- case SImode:
- return 1;
-
- default:
- gcc_unreachable ();
- }
-})
+ return 0;
-;; Return 1 if the operand must be loaded from memory. This is used by a
-;; define_split to insure constants get pushed to the constant pool before
-;; reload. If -ffast-math is used, easy_fp_constant will allow move insns to
-;; have constants in order not interfere with reciprocal estimation. However,
-;; with -mupper-regs support, these constants must be moved to the constant
-;; pool before register allocation.
+ case DImode:
+ return (num_insns_constant (op, DImode) <= 2);
-(define_predicate "memory_fp_constant"
- (match_code "const_double")
-{
- if (TARGET_VSX && op == CONST0_RTX (mode))
- return 0;
+ case SImode:
+ return 1;
- if (!TARGET_HARD_FLOAT || !TARGET_FPRS
- || (mode == SFmode && !TARGET_SINGLE_FLOAT)
- || (mode == DFmode && !TARGET_DOUBLE_FLOAT))
- return 0;
-
- return 1;
+ default:
+ gcc_unreachable ();
+ }
})
;; Return 1 if the operand is a CONST_VECTOR and can be loaded into a
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 001884cbe58..aec696e385a 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -8048,8 +8048,8 @@
}")
(define_insn "mov<mode>_hardfloat"
- [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,<f32_lr>,<f32_sm>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h,!r,!r")
- (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,<f32_lm>,<f32_sr>,Z,<f32_av>,r,<f32_dm>,r,h,0,G,Fn"))]
+ [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_sm>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h")
+ (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,j,<f32_lm>,<f32_sr>,Z,<f32_av>,r,<f32_dm>,r,h,0"))]
"(gpc_reg_operand (operands[0], <MODE>mode)
|| gpc_reg_operand (operands[1], <MODE>mode))
&& (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
@@ -8060,6 +8060,7 @@
fmr %0,%1
xxlor %x0,%x1,%x1
xxlxor %x0,%x0,%x0
+ li %0,0
<f32_li>
<f32_si>
<f32_lv>
@@ -8068,11 +8069,9 @@
mfvsrwz %0,%x1
mt%0 %1
mf%1 %0
- nop
- #
- #"
- [(set_attr "type" "*,load,store,fp,vecsimple,vecsimple,fpload,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*,*,*")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8")])
+ nop"
+ [(set_attr "type" "*,load,store,fp,vecsimple,vecsimple,integer,fpload,fpstore,fpload,fpstore,mftgpr,mffgpr,mtjmpr,mfjmpr,*")
+ (set_attr "length" "4")])
(define_insn "*mov<mode>_softfloat"
[(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
@@ -8186,9 +8185,12 @@
;; since the D-form version of the memory instructions does not need a GPR for
;; reloading.
+;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
+;; except for 0.0 which can be created on VSX with an xor instruction.
+
(define_insn "*mov<mode>_hardfloat32"
- [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,Y,r,!r,!r,!r,!r")
- (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,r,Y,r,G,H,F"))]
+ [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
+ (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& (gpc_reg_operand (operands[0], <MODE>mode)
|| gpc_reg_operand (operands[1], <MODE>mode))"
@@ -8203,11 +8205,9 @@
#
#
#
- #
- #
#"
- [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,store,load,two,fp,fp,*")
- (set_attr "length" "4,4,4,4,4,4,4,8,8,8,8,12,16")])
+ [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,two,store,load,two")
+ (set_attr "length" "4,4,4,4,4,4,4,8,8,8,8")])
(define_insn "*mov<mode>_softfloat32"
[(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
@@ -8225,8 +8225,8 @@
; ld/std require word-aligned displacements -> 'Y' constraint.
; List Y->r and r->Y before r->r for reload.
(define_insn "*mov<mode>_hardfloat64"
- [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,Y,r,!r,*c*l,!r,*h,!r,!r,!r,r,wg,r,<f64_dm>")
- (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,r,Y,r,r,h,0,G,H,F,wg,r,<f64_dm>,r"))]
+ [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
+ (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,j,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& (gpc_reg_operand (operands[0], <MODE>mode)
|| gpc_reg_operand (operands[1], <MODE>mode))"
@@ -8238,21 +8238,19 @@
stxsd%U0x %x1,%y0
xxlor %x0,%x1,%x1
xxlxor %x0,%x0,%x0
+ li %0,0
std%U0%X0 %1,%0
ld%U1%X1 %0,%1
mr %0,%1
mt%0 %1
mf%1 %0
nop
- #
- #
- #
mftgpr %0,%1
mffgpr %0,%1
mfvsrd %0,%x1
mtvsrd %x0,%1"
- [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,store,load,*,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr,mftgpr,mffgpr")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16,4,4,4,4")])
+ [(set_attr "type" "fpstore,fpload,fp,fpload,fpstore,vecsimple,vecsimple,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
+ (set_attr "length" "4")])
(define_insn "*mov<mode>_softfloat64"
[(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
@@ -8289,7 +8287,7 @@
(define_insn_and_split "*mov<mode>_64bit_dm"
[(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r,r,wm")
- (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jYGHF,r,wm,r"))]
+ (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jY,r,wm,r"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
&& (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
&& (gpc_reg_operand (operands[0], <MODE>mode)
@@ -8302,7 +8300,7 @@
(define_insn_and_split "*movtd_64bit_nodm"
[(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
- (match_operand:TD 1 "input_operand" "d,m,d,j,r,jYGHF,r"))]
+ (match_operand:TD 1 "input_operand" "d,m,d,j,r,jY,r"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
&& (gpc_reg_operand (operands[0], TDmode)
|| gpc_reg_operand (operands[1], TDmode))"
@@ -8314,7 +8312,7 @@
(define_insn_and_split "*mov<mode>_32bit"
[(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
- (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jYGHF,r"))]
+ (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jY,r"))]
"TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], <MODE>mode)
|| gpc_reg_operand (operands[1], <MODE>mode))"
@@ -8336,21 +8334,6 @@
{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
[(set_attr "length" "20,20,16")])
-;; If we are using -ffast-math, easy_fp_constant assumes all constants are
-;; 'easy' in order to allow for reciprocal estimation. Make sure the constant
-;; is in the constant pool before reload occurs. This simplifies accessing
-;; scalars in the traditional Altivec registers.
-
-(define_split
- [(set (match_operand:SFDF 0 "register_operand" "")
- (match_operand:SFDF 1 "memory_fp_constant" ""))]
- "TARGET_<MODE>_FPR && flag_unsafe_math_optimizations
- && !reload_in_progress && !reload_completed && !lra_in_progress"
- [(set (match_dup 0) (match_dup 2))]
-{
- operands[2] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
-})
-
(define_expand "extenddftf2"
[(set (match_operand:TF 0 "nonimmediate_operand" "")
(float_extend:TF (match_operand:DF 1 "input_operand" "")))]
@@ -8382,7 +8365,7 @@
(define_insn_and_split "*extenddftf2_internal"
[(set (match_operand:TF 0 "nonimmediate_operand" "=m,Y,d,&d,r")
- (float_extend:TF (match_operand:DF 1 "input_operand" "d,r,md,md,rmGHF")))
+ (float_extend:TF (match_operand:DF 1 "input_operand" "d,r,md,md,rm")))
(use (match_operand:DF 2 "zero_reg_mem_operand" "d,r,m,d,n"))]
"!TARGET_IEEEQUAD
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT