https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89310

--- Comment #5 from luoxhu at gcc dot gnu.org ---
Thanks.  I copied the code from movsf_from_si to make a define_insn_and_split
for "movsf_from_si2", but we don't have define_insn for rldicr, so I use
gen_anddi3 instead, any comment?

foo:
.LFB0:
        .cfi_startproc
        rldicr 3,3,0,31
        mtvsrd 1,3
        xscvspdpn 1,1
        blr


diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 4fcd6a94022..92c237edfad 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -7593,6 +7593,48 @@ (define_insn_and_split "movsf_from_si"
            "*,          *,         p9v,       p8v,       *,         *,
             p8v,        p8v,       p8v,       *")])

+(define_insn_and_split "movsf_from_si2"
+  [(set (match_operand:SF 0 "nonimmediate_operand"
+           "=!r,       f,         v,         wa,        m,         Z,
+            Z,         wa,        ?r,        !r")
+           (unspec:SF [
+            (subreg:SI (ashiftrt:DI
+              (match_operand:DI 1 "input_operand"
+          "m,         m,         wY,        Z,         r,         f,
+          wa,        r,         wa,        r")
+         (const_int 32)) 0)]
+                  UNSPEC_SF_FROM_SI))
+   (clobber (match_scratch:DI 2
+           "=X,        X,         X,         X,         X,         X,
+             X,         r,         X,         X"))]
+  "TARGET_NO_SF_SUBREG
+   && (register_operand (operands[0], SFmode)
+       || register_operand (operands[1], SImode))"
+   "#"
+  "&& !reload_completed
+   && vsx_reg_sfsubreg_ok (operands[0], SFmode)"
+  [(const_int 0)]
+{
+  rtx op0 = operands[0];
+  rtx op1 = operands[1];
+  rtx tmp = gen_reg_rtx (DImode);
+
+  emit_insn (gen_anddi3 (tmp, op1, GEN_INT(0xFFFFFFFF00000000ULL)));
+  emit_insn (gen_p8_mtvsrd_sf (op0, tmp));
+  emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
+  DONE;
+})
+

Reply via email to