summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r--gcc/config/rs6000/rs6000.md99
1 files changed, 49 insertions, 50 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index daa16a4fbad..7719ec3bad8 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -8018,47 +8018,39 @@
;; Don't have reload use general registers to load a constant. It is
;; less efficient than loading the constant into an FP register, since
;; it will probably be used there.
+
+;; The move constraints are ordered to prefer floating point registers before
+;; general purpose registers to avoid doing a store and a load to get the value
+;; into a floating point register when it is needed for a floating point
+;; operation. Prefer traditional floating point registers over VSX registers,
+;; since the D-form version of the memory instructions does not need a GPR for
+;; reloading.
+
(define_insn "*movdf_hardfloat32"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,ws,?wa,ws,?wa,Z,?Z,m,d,d,wa,!r,!r,!r")
- (match_operand:DF 1 "input_operand" "r,Y,r,ws,wa,Z,Z,ws,wa,d,m,d,j,G,H,F"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=m,d,d,ws,?wa,Z,?Z,ws,?wa,wa,Y,r,!r,!r,!r,!r")
+ (match_operand:DF 1 "input_operand" "d,m,d,Z,Z,ws,wa,ws,wa,j,r,Y,r,G,H,F"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
- "*
-{
- switch (which_alternative)
- {
- default:
- gcc_unreachable ();
- case 0:
- case 1:
- case 2:
- return \"#\";
- case 3:
- case 4:
- return \"xxlor %x0,%x1,%x1\";
- case 5:
- case 6:
- return \"lxsd%U1x %x0,%y1\";
- case 7:
- case 8:
- return \"stxsd%U0x %x1,%y0\";
- case 9:
- return \"stfd%U0%X0 %1,%0\";
- case 10:
- return \"lfd%U1%X1 %0,%1\";
- case 11:
- return \"fmr %0,%1\";
- case 12:
- return \"xxlxor %x0,%x0,%x0\";
- case 13:
- case 14:
- case 15:
- return \"#\";
- }
-}"
- [(set_attr "type" "store,load,two,fp,fp,fpload,fpload,fpstore,fpstore,fpstore,fpload,fp,vecsimple,*,*,*")
- (set_attr "length" "8,8,8,4,4,4,4,4,4,4,4,4,4,8,12,16")])
+ "@
+ stfd%U0%X0 %1,%0
+ lfd%U1%X1 %0,%1
+ fmr %0,%1
+ lxsd%U1x %x0,%y1
+ lxsd%U1x %x0,%y1
+ stxsd%U0x %x1,%y0
+ stxsd%U0x %x1,%y0
+ xxlor %x0,%x1,%x1
+ xxlor %x0,%x1,%x1
+ xxlxor %x0,%x0,%x0
+ #
+ #
+ #
+ #
+ #
+ #"
+ [(set_attr "type" "fpstore,fpload,fp,fpload,fpload,fpstore,fpstore,vecsimple,vecsimple,vecsimple,store,load,two,fp,fp,*")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8,8,8,8,12,16")])
(define_insn "*movdf_softfloat32"
[(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
@@ -8131,25 +8123,25 @@
; ld/std require word-aligned displacements -> 'Y' constraint.
; List Y->r and r->Y before r->r for reload.
(define_insn "*movdf_hardfloat64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,ws,?wa,ws,?wa,Z,?Z,m,d,d,wa,*c*l,!r,*h,!r,!r,!r")
- (match_operand:DF 1 "input_operand" "r,Y,r,ws,wa,Z,Z,ws,wa,d,m,d,j,r,h,0,G,H,F"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=m,d,d,Y,r,!r,ws,?wa,Z,?Z,ws,?wa,wa,*c*l,!r,*h,!r,!r,!r")
+ (match_operand:DF 1 "input_operand" "d,m,d,r,Y,r,Z,Z,ws,wa,ws,wa,j,r,h,0,G,H,F"))]
"TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_DOUBLE_FLOAT
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
"@
+ stfd%U0%X0 %1,%0
+ lfd%U1%X1 %0,%1
+ fmr %0,%1
std%U0%X0 %1,%0
ld%U1%X1 %0,%1
mr %0,%1
- xxlor %x0,%x1,%x1
- xxlor %x0,%x1,%x1
lxsd%U1x %x0,%y1
lxsd%U1x %x0,%y1
stxsd%U0x %x1,%y0
stxsd%U0x %x1,%y0
- stfd%U0%X0 %1,%0
- lfd%U1%X1 %0,%1
- fmr %0,%1
+ xxlor %x0,%x1,%x1
+ xxlor %x0,%x1,%x1
xxlxor %x0,%x0,%x0
mt%0 %1
mf%1 %0
@@ -8157,7 +8149,7 @@
#
#
#"
- [(set_attr "type" "store,load,*,fp,fp,fpload,fpload,fpstore,fpstore,fpstore,fpload,fp,vecsimple,mtjmpr,mfjmpr,*,*,*,*")
+ [(set_attr "type" "fpstore,fpload,fp,store,load,*,fpload,fpload,fpstore,fpstore,vecsimple,vecsimple,vecsimple,mtjmpr,mfjmpr,*,*,*,*")
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16")])
(define_insn "*movdf_softfloat64"
@@ -10370,15 +10362,22 @@
"TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
"addis %0,%1+%3@u(%2)")
-(define_insn "*largetoc_low<mode>"
- [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
- (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b,!*r")
- (match_operand:P 2 "" "")))]
- "TARGET_TOC && TARGET_CMODEL != CMODEL_SMALL"
+(define_insn "*largetoc_low"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,!*r")
+ (match_operand:DI 2 "" "")))]
+ "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
"@
addi %0,%1,%2@l
addic %0,%1,%2@l")
+(define_insn "*largetoc_low_aix<mode>"
+ [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+ (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
+ (match_operand:P 2 "" "")))]
+ "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
+ "la %0,%2@l(%1)")
+
(define_insn_and_split "*tocref<mode>"
[(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
(match_operand:P 1 "small_toc_ref" "R"))]