// Floating-Point Scalar Move Instructions
def VFMV_F_S : RVInstV<0b010000, 0b00000, OPFVV, (outs FPR32:$vd),
(ins VR:$vs2), "vfmv.f.s", "$vd, $vs2">;
-def VFMV_S_F : RVInstV2<0b010000, 0b00000, OPFVF, (outs VR:$vd),
- (ins FPR32:$rs1), "vfmv.s.f", "$vd, $rs1">;
+let Constraints = "$vd = $vd_wb" in
+def VFMV_S_F : RVInstV2<0b010000, 0b00000, OPFVF, (outs VR:$vd_wb),
+ (ins VR:$vd, FPR32:$rs1), "vfmv.s.f", "$vd, $rs1">;
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0, vm = 1
} // Predicates = [HasStdExtV, HasStdExtF]
Constraints = "$rd = $rs1" in
def PseudoVMV_S_X # "_" # m.MX: Pseudo<(outs m.vrclass:$rd),
(ins m.vrclass:$rs1, GPR:$rs2,
- GPR:$vl, ixlenimm:$sew),
+ GPR:$vl, ixlenimm:$sew),
[]>, RISCVVPseudo;
}
}
}
+} // Predicates = [HasStdExtV]
+
+//===----------------------------------------------------------------------===//
+// 17.2. Floating-Point Scalar Move Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasStdExtV, HasStdExtF] in {
+let mayLoad = 0, mayStore = 0, hasSideEffects = 0, usesCustomInserter = 1,
+ Uses = [VL, VTYPE] in {
+ foreach m = MxList.m in {
+ let VLMul = m.value in {
+ let SEWIndex = 2, BaseInstr = VFMV_F_S in
+ def PseudoVFMV_F_S # "_" # m.MX : Pseudo<(outs FPR32:$rd),
+ (ins m.vrclass:$rs2,
+ ixlenimm:$sew),
+ []>, RISCVVPseudo;
+ let VLIndex = 3, SEWIndex = 4, BaseInstr = VFMV_S_F,
+ Constraints = "$rd = $rs1" in
+ def PseudoVFMV_S_F # "_" # m.MX : Pseudo<(outs m.vrclass:$rd),
+ (ins m.vrclass:$rs1, FPR32:$rs2,
+ GPR:$vl, ixlenimm:$sew),
+ []>, RISCVVPseudo;
+ }
+ }
}
+} // Predicates = [HasStdExtV, HasStdExtF]
//===----------------------------------------------------------------------===//
// Patterns.
(vti.Vector $rs1), $rs2, (NoX0 GPR:$vl), vti.SEW)>;
}
} // Predicates = [HasStdExtV]
+
+//===----------------------------------------------------------------------===//
+// 17.2. Floating-Point Scalar Move Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasStdExtV, HasStdExtF] in {
+foreach fvti = AllFloatVectors in {
+ defvar instr = !cast<Instruction>("PseudoVFMV_F_S_" # fvti.LMul.MX);
+ def : Pat<(fvti.Scalar (int_riscv_vfmv_f_s (fvti.Vector fvti.RegClass:$rs2))),
+ // Floating point instructions with a scalar result will always
+ // generate the result in a register of class FPR32. When dealing
+ // with the f64 variant of a pattern we need to promote the FPR32
+ // subregister generated by the instruction to the FPR64 base
+ // register expected by the type in the pattern
+ !cond(!eq(!cast<string>(fvti.ScalarRegClass),
+ !cast<string>(FPR64)):
+ (SUBREG_TO_REG (i32 -1),
+ (instr $rs2, fvti.SEW), sub_32),
+ !eq(!cast<string>(fvti.ScalarRegClass),
+ !cast<string>(FPR16)):
+ (EXTRACT_SUBREG (instr $rs2, fvti.SEW), sub_16),
+ !eq(1, 1):
+ (instr $rs2, fvti.SEW))>;
+
+ def : Pat<(fvti.Vector (int_riscv_vfmv_s_f (fvti.Vector fvti.RegClass:$rs1),
+ (fvti.Scalar fvti.ScalarRegClass:$rs2), GPR:$vl)),
+ (!cast<Instruction>("PseudoVFMV_S_F_" # fvti.LMul.MX)
+ (fvti.Vector $rs1), ToFPR32<fvti.Scalar, fvti.ScalarRegClass, "rs2">.ret,
+ (NoX0 GPR:$vl), fvti.SEW)>;
+}
+} // Predicates = [HasStdExtV, HasStdExtF]