From dc4f83ca6a03f9c3351501bedabd4ad30b28ed34 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Tue, 28 Feb 1995 22:16:31 +0000 Subject: [PATCH] More soft-float/powerpc patches. From-SVN: r9094 --- gcc/config/rs6000/rs6000.md | 120 +++++++++++++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 10 deletions(-) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 0c0b223f7da..1b884debaf5 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) @@ -4056,11 +4057,49 @@ [(set_attr "type" "*,load,*,*,fp,fpload,*") (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\"; @@ -4250,6 +4305,51 @@ [(set_attr "type" "*,load,load,*,*") (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"))] @@ -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 -- 2.30.2