VFPv3: Implement VMOV (immediate)
This commit is contained in:
parent
7f77a04900
commit
59db2c191a
4 changed files with 50 additions and 1 deletions
|
@ -14,7 +14,7 @@ INST(vfp_VFMA, "VFMA", "cccc11101D10nnnndddd101zN
|
||||||
INST(vfp_VFMS, "VFMS", "cccc11101D10nnnndddd101zN1M0mmmm") // VFPv4
|
INST(vfp_VFMS, "VFMS", "cccc11101D10nnnndddd101zN1M0mmmm") // VFPv4
|
||||||
|
|
||||||
// Other floating-point data-processing instructions
|
// Other floating-point data-processing instructions
|
||||||
//INST(vfp_VMOV_imm, "VMOV (immediate)", "cccc11101D11vvvvdddd101z0000vvvv") // VFPv3
|
INST(vfp_VMOV_imm, "VMOV (immediate)", "cccc11101D11vvvvdddd101z0000vvvv") // VFPv3
|
||||||
INST(vfp_VMOV_reg, "VMOV (reg)", "cccc11101D110000dddd101z01M0mmmm") // VFPv2
|
INST(vfp_VMOV_reg, "VMOV (reg)", "cccc11101D110000dddd101z01M0mmmm") // VFPv2
|
||||||
INST(vfp_VABS, "VABS", "cccc11101D110000dddd101z11M0mmmm") // VFPv2
|
INST(vfp_VABS, "VABS", "cccc11101D110000dddd101z11M0mmmm") // VFPv2
|
||||||
INST(vfp_VNEG, "VNEG", "cccc11101D110001dddd101z01M0mmmm") // VFPv2
|
INST(vfp_VNEG, "VNEG", "cccc11101D110001dddd101z01M0mmmm") // VFPv2
|
||||||
|
|
|
@ -1232,6 +1232,24 @@ public:
|
||||||
return fmt::format("vfma{}.{} {}, {}, {}", CondToString(cond), sz ? "f64" : "f32", FPRegStr(sz, Vd, D), FPRegStr(sz, Vn, N), FPRegStr(sz, Vm, M));
|
return fmt::format("vfma{}.{} {}, {}, {}", CondToString(cond), sz ? "f64" : "f32", FPRegStr(sz, Vd, D), FPRegStr(sz, Vn, N), FPRegStr(sz, Vm, M));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string vfp_VMOV_imm(Cond cond, bool D, Imm<4> imm4H, size_t Vd, bool sz, Imm<4> imm4L) {
|
||||||
|
const auto imm8 = concatenate(imm4H, imm4L);
|
||||||
|
|
||||||
|
if (sz) {
|
||||||
|
const u64 sign = static_cast<u64>(imm8.Bit<7>());
|
||||||
|
const u64 exp = (imm8.Bit<6>() ? 0x3FC : 0x400) | imm8.Bits<4, 5, u64>();
|
||||||
|
const u64 fract = imm8.Bits<0, 3, u64>() << 48;
|
||||||
|
const u64 immediate = (sign << 63) | (exp << 52) | fract;
|
||||||
|
return fmt::format("vmov{}.f64 {}, #0x{:016x}", CondToString(cond), FPRegStr(sz, Vd, D), immediate);
|
||||||
|
} else {
|
||||||
|
const u32 sign = static_cast<u32>(imm8.Bit<7>());
|
||||||
|
const u32 exp = (imm8.Bit<6>() ? 0x7C : 0x80) | imm8.Bits<4, 5>();
|
||||||
|
const u32 fract = imm8.Bits<0, 3>() << 19;
|
||||||
|
const u32 immediate = (sign << 31) | (exp << 23) | fract;
|
||||||
|
return fmt::format("vmov{}.f32 {}, #0x{:08x}", CondToString(cond), FPRegStr(sz, Vd, D), immediate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string vfp_VMOV_u32_f64(Cond cond, size_t Vd, Reg t, bool D){
|
std::string vfp_VMOV_u32_f64(Cond cond, size_t Vd, Reg t, bool D){
|
||||||
return fmt::format("vmov{}.32 {}, {}", CondToString(cond), FPRegStr(true, Vd, D), t);
|
return fmt::format("vmov{}.32 {}, {}", CondToString(cond), FPRegStr(true, Vd, D), t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -377,6 +377,7 @@ struct ArmTranslatorVisitor final {
|
||||||
bool vfp_VFMS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm);
|
bool vfp_VFMS(Cond cond, bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm);
|
||||||
|
|
||||||
// Floating-point move instructions
|
// Floating-point move instructions
|
||||||
|
bool vfp_VMOV_imm(Cond cond, bool D, Imm<4> imm4H, size_t Vd, bool sz, Imm<4> imm4L);
|
||||||
bool vfp_VMOV_u32_f64(Cond cond, size_t Vd, Reg t, bool D);
|
bool vfp_VMOV_u32_f64(Cond cond, size_t Vd, Reg t, bool D);
|
||||||
bool vfp_VMOV_f64_u32(Cond cond, size_t Vn, Reg t, bool N);
|
bool vfp_VMOV_f64_u32(Cond cond, size_t Vn, Reg t, bool N);
|
||||||
bool vfp_VMOV_u32_f32(Cond cond, size_t Vn, Reg t, bool N);
|
bool vfp_VMOV_u32_f32(Cond cond, size_t Vn, Reg t, bool N);
|
||||||
|
|
|
@ -482,6 +482,36 @@ bool ArmTranslatorVisitor::vfp_VMOV_f64_2u32(Cond cond, Reg t2, Reg t, bool M, s
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VMOV<c>.F64 <Dd>, #<imm>
|
||||||
|
// VMOV<c>.F32 <Sd>, #<imm>
|
||||||
|
bool ArmTranslatorVisitor::vfp_VMOV_imm(Cond cond, bool D, Imm<4> imm4H, size_t Vd, bool sz, Imm<4> imm4L) {
|
||||||
|
if (!ConditionPassed(cond)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ir.current_location.FPSCR().Stride() != 1 || ir.current_location.FPSCR().Len() != 1) {
|
||||||
|
return UndefinedInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto d = ToExtReg(sz, Vd, D);
|
||||||
|
const auto imm8 = concatenate(imm4H, imm4L);
|
||||||
|
|
||||||
|
if (sz) {
|
||||||
|
const u64 sign = static_cast<u64>(imm8.Bit<7>());
|
||||||
|
const u64 exp = (imm8.Bit<6>() ? 0x3FC : 0x400) | imm8.Bits<4, 5, u64>();
|
||||||
|
const u64 fract = imm8.Bits<0, 3, u64>() << 48;
|
||||||
|
const u64 immediate = (sign << 63) | (exp << 52) | fract;
|
||||||
|
ir.SetExtendedRegister(d, ir.Imm64(immediate));
|
||||||
|
} else {
|
||||||
|
const u32 sign = static_cast<u32>(imm8.Bit<7>());
|
||||||
|
const u32 exp = (imm8.Bit<6>() ? 0x7C : 0x80) | imm8.Bits<4, 5>();
|
||||||
|
const u32 fract = imm8.Bits<0, 3>() << 19;
|
||||||
|
const u32 immediate = (sign << 31) | (exp << 23) | fract;
|
||||||
|
ir.SetExtendedRegister(d, ir.Imm32(immediate));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// VMOV<c>.F64 <Dd>, <Dm>
|
// VMOV<c>.F64 <Dd>, <Dm>
|
||||||
// VMOV<c>.F32 <Sd>, <Sm>
|
// VMOV<c>.F32 <Sd>, <Sm>
|
||||||
bool ArmTranslatorVisitor::vfp_VMOV_reg(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
|
bool ArmTranslatorVisitor::vfp_VMOV_reg(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
|
||||||
|
|
Loading…
Reference in a new issue