aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMichael Meissner <meissner@gcc.gnu.org>1995-02-28 22:16:31 +0000
committerMichael Meissner <meissner@gcc.gnu.org>1995-02-28 22:16:31 +0000
commitdc4f83ca6a03f9c3351501bedabd4ad30b28ed34 (patch)
treeb4e037a2a689accb3c7288cc421f6b9950897c22 /gcc
parent6e5ea9350ffc2af7ed20212ec6c0650a9023689f (diff)
downloadgcc-dc4f83ca6a03f9c3351501bedabd4ad30b28ed34.zip
gcc-dc4f83ca6a03f9c3351501bedabd4ad30b28ed34.tar.gz
gcc-dc4f83ca6a03f9c3351501bedabd4ad30b28ed34.tar.bz2
More soft-float/powerpc patches.
From-SVN: r9094
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/rs6000/rs6000.md120
1 files changed, 110 insertions, 10 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 0c0b223..1b884de 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -3135,7 +3135,7 @@
(set (match_operand:DF 0 "gpc_reg_operand" "")
(minus:DF (subreg:DF (match_dup 2) 0)
(match_dup 5)))]
- "! TARGET_POWERPC64"
+ "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"
{
operands[2] = gen_reg_rtx (DImode);
@@ -3152,7 +3152,7 @@
(set (match_operand:DF 0 "gpc_reg_operand" "")
(minus:DF (subreg:DF (match_dup 2) 0)
(match_dup 4)))]
- "! TARGET_POWERPC64"
+ "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"
{
operands[2] = gen_reg_rtx (DImode);
@@ -4017,8 +4017,9 @@
(define_insn ""
[(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m")
(match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
- "! TARGET_POWERPC64 && (register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode))"
+ "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
+ && (register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode))"
"*
{
switch (which_alternative)
@@ -4057,10 +4058,48 @@
(set_attr "length" "8,8,8,8,*,*,*")])
(define_insn ""
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r")
+ (match_operand:DF 1 "input_operand" "r,o,r,G"))]
+ "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT
+ && (register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ /* We normally copy the low-numbered register first. However, if
+ the first register operand 0 is the same as the second register of
+ operand 1, we must copy in the opposite order. */
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"mr %L0,%L1\;mr %0,%1\";
+ else
+ return \"mr %0,%1\;mr %L0,%L1\";
+ case 1:
+ /* If the low-address word is used in the address, we must load it
+ last. Otherwise, load it first. Note that we cannot have
+ auto-increment in that case since the address register is known to be
+ dead. */
+ if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
+ operands [1], 0))
+ return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
+ else
+ return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
+ case 2:
+ return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
+ case 3:
+ return \"#\";
+ }
+}"
+ [(set_attr "type" "*,load,*,*")
+ (set_attr "length" "8,8,8,8")])
+
+(define_insn ""
[(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m")
(match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
- "TARGET_POWERPC64 && (register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode))"
+ "TARGET_POWERPC64 && TARGET_HARD_FLOAT
+ && (register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode))"
"@
mr %0,%1
ld%U1%X1 %0,%1
@@ -4070,6 +4109,19 @@
lfd%U1%X1 %0,%1
stfd%U0%X0 %1,%0"
[(set_attr "type" "*,load,*,*,fp,fpload,*")])
+
+(define_insn ""
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r")
+ (match_operand:DF 1 "input_operand" "r,o,r,G"))]
+ "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
+ && (register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode))"
+ "@
+ mr %0,%1
+ ld%U1%X1 %0,%1
+ sd%U0%X0 %1,%0
+ #"
+ [(set_attr "type" "*,load,*,*")])
;; Next come the multi-word integer load and store and the load and store
;; multiple insns.
@@ -4203,12 +4255,15 @@
[(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
(match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
(clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
- "TARGET_MULTIPLE && ! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
- || gpc_reg_operand (operands[1], TImode))"
+ "TARGET_MULTIPLE && TARGET_POWER && ! TARGET_POWERPC64
+ && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
"*
{
switch (which_alternative)
{
+ default:
+ abort ();
+
case 0:
return \"{stsi|stswi} %1,%P0,16\";
@@ -4251,6 +4306,51 @@
(set_attr "length" "*,16,16,*,16")])
(define_insn ""
+ [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r")
+ (match_operand:TI 1 "reg_or_mem_operand" "r,r,m"))
+ (clobber (match_scratch:SI 2 "=X,X,X"))]
+ "TARGET_MULTIPLE && !TARGET_POWER && ! TARGET_POWERPC64
+ && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ default:
+ abort ();
+
+ case 0:
+ return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
+
+ case 1:
+ /* Normally copy registers with lowest numbered register copied first.
+ But copy in the other order if the first register of the output
+ is the second, third, or fourth register in the input. */
+ if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
+ && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
+ return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
+ else
+ return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
+ case 2:
+ /* If the address register is the same as the register for the lowest-
+ addressed word, load it last. Similarly for the next two words.
+ Otherwise load lowest address to highest. */
+ if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
+ operands[1], 0))
+ return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
+ else if (refers_to_regno_p (REGNO (operands[0]) + 1,
+ REGNO (operands[0]) + 2, operands[1], 0))
+ return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
+ else if (refers_to_regno_p (REGNO (operands[0]) + 2,
+ REGNO (operands[0]) + 3, operands[1], 0))
+ return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
+ else
+ return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
+ }
+}"
+ [(set_attr "type" "load,*,*")
+ (set_attr "length" "16,16,16")])
+
+(define_insn ""
[(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
(match_operand:TI 1 "input_operand" "r,m,r"))]
"TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
@@ -4399,7 +4499,7 @@
[(set (match_operand:SI 1 "indirect_operand" "=Q")
(match_operand:SI 2 "gpc_reg_operand" "r"))
(clobber (match_scratch:SI 3 "=q"))])]
- "TARGET_MULTIPLE && !TARGET_POWERPC"
+ "TARGET_MULTIPLE && TARGET_POWER"
"{stsi|stswi} %2,%P1,%O0")
(define_insn ""
@@ -4407,7 +4507,7 @@
[(set (match_operand:SI 1 "indirect_operand" "=Q")
(match_operand:SI 2 "gpc_reg_operand" "r"))
(clobber (match_scratch:SI 3 "X"))])]
- "TARGET_MULTIPLE && TARGET_POWERPC"
+ "TARGET_MULTIPLE && !TARGET_POWER"
"{stsi|stswi} %2,%P1,%O0")
;; Define insns that do load or store with update. Some of these we can