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;
+})
+