A32: Implement ASIMD VMOV (scalar to general-purpose register)
This commit is contained in:
parent
8bbc9fdbb6
commit
7ec22b4e1d
4 changed files with 89 additions and 2 deletions
|
@ -44,6 +44,9 @@ INST(vfp_VMOV_2u32_2f32, "VMOV (2xcore to 2xf32)", "cccc11000100uuuutttt10100
|
|||
INST(vfp_VMOV_2f32_2u32, "VMOV (2xf32 to 2xcore)", "cccc11000101uuuutttt101000M1mmmm") // VFPv2
|
||||
INST(vfp_VMOV_2u32_f64, "VMOV (2xcore to f64)", "cccc11000100uuuutttt101100M1mmmm") // VFPv2
|
||||
INST(vfp_VMOV_f64_2u32, "VMOV (f64 to 2xcore)", "cccc11000101uuuutttt101100M1mmmm") // VFPv2
|
||||
INST(vfp_VMOV_to_i32, "VMOV (i32 to core)" , "cccc111000i1nnnntttt1011N0010000") // VFPv4
|
||||
INST(vfp_VMOV_to_i16, "VMOV (i16 to core)" , "cccc1110U0i1nnnntttt1011Ni110000") // ASIMD
|
||||
INST(vfp_VMOV_to_i8, "VMOV (i8 to core)", "cccc1110U1i1nnnntttt1011Nii10000") // ASIMD
|
||||
INST(vfp_VDUP, "VDUP (from core)", "cccc11101BQ0ddddtttt1011D0E10000") // ASIMD
|
||||
|
||||
// Floating-point system register access
|
||||
|
|
|
@ -1347,6 +1347,21 @@ public:
|
|||
return fmt::format("vmov{} {}, {}, {}", CondToString(cond), t, t2, FPRegStr(true, Vm, M));
|
||||
}
|
||||
|
||||
std::string vfp_VMOV_to_i32(Cond cond, Imm<1> i, size_t Vn, Reg t, bool N) {
|
||||
const size_t index = i.ZeroExtend();
|
||||
return fmt::format("vmov{}.32 {}, {}[{}]", CondToString(cond), t, FPRegStr(true, Vn, N), index);
|
||||
}
|
||||
|
||||
std::string vfp_VMOV_to_i16(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<1> i2) {
|
||||
const size_t index = concatenate(i1, i2).ZeroExtend();
|
||||
return fmt::format("vmov{}.{}16 {}, {}[{}]", CondToString(cond), U ? 'u' : 's', t, FPRegStr(true, Vn, N), index);
|
||||
}
|
||||
|
||||
std::string vfp_VMOV_to_i8(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<2> i2) {
|
||||
const size_t index = concatenate(i1, i2).ZeroExtend();
|
||||
return fmt::format("vmov{}.{}8 {}, {}[{}]", CondToString(cond), U ? 'u' : 's', t, FPRegStr(true, Vn, N), index);
|
||||
}
|
||||
|
||||
std::string vfp_VDUP(Cond cond, Imm<1> B, bool Q, size_t Vd, Reg t, bool D, Imm<1> E) {
|
||||
const size_t esize = 32u >> concatenate(B, E).ZeroExtend();
|
||||
return fmt::format("vdup{}.{} {}, {}", CondToString(cond), esize, VectorStr(Q, Vd, D), t);
|
||||
|
|
|
@ -397,7 +397,6 @@ struct ArmTranslatorVisitor final {
|
|||
bool vfp_VMINNM(bool D, size_t Vn, size_t Vd, bool sz, bool N, bool M, size_t Vm);
|
||||
|
||||
// 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_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);
|
||||
|
@ -406,8 +405,13 @@ struct ArmTranslatorVisitor final {
|
|||
bool vfp_VMOV_2f32_2u32(Cond cond, Reg t2, Reg t, bool M, size_t Vm);
|
||||
bool vfp_VMOV_2u32_f64(Cond cond, Reg t2, Reg t, bool M, size_t Vm);
|
||||
bool vfp_VMOV_f64_2u32(Cond cond, Reg t2, Reg t, bool M, size_t Vm);
|
||||
bool vfp_VMOV_reg(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
|
||||
bool vfp_VMOV_to_i32(Cond cond, Imm<1> i, size_t Vn, Reg t, bool N);
|
||||
bool vfp_VMOV_to_i16(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<1> i2);
|
||||
bool vfp_VMOV_to_i8(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<2> i2);
|
||||
bool vfp_VDUP(Cond cond, Imm<1> B, bool Q, size_t Vd, Reg t, bool D, Imm<1> E);
|
||||
bool vfp_VMOV_imm(Cond cond, bool D, Imm<4> imm4H, size_t Vd, bool sz, Imm<4> imm4L);
|
||||
bool vfp_VMOV_reg(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
|
||||
|
||||
|
||||
// Floating-point misc instructions
|
||||
bool vfp_VABS(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
|
||||
|
|
|
@ -523,6 +523,71 @@ bool ArmTranslatorVisitor::vfp_VMOV_f64_2u32(Cond cond, Reg t2, Reg t, bool M, s
|
|||
return true;
|
||||
}
|
||||
|
||||
// VMOV<c>.{U16,S16} <Rt>, <Dn[x]>
|
||||
bool ArmTranslatorVisitor::vfp_VMOV_to_i32(Cond cond, Imm<1> i, size_t Vn, Reg t, bool N) {
|
||||
if (!ConditionPassed(cond)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t == Reg::R15) {
|
||||
// TODO: v8 removes UPREDICTABLE for R13
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
const size_t index = i.ZeroExtend();
|
||||
const auto n = ToVector(false, Vn, N);
|
||||
|
||||
const auto reg_n = ir.GetVector(n);
|
||||
const auto result = ir.VectorGetElement(32, reg_n, index);
|
||||
|
||||
ir.SetRegister(t, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
// VMOV<c>.{U16,S16} <Rt>, <Dn[x]>
|
||||
bool ArmTranslatorVisitor::vfp_VMOV_to_i16(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<1> i2) {
|
||||
if (!ConditionPassed(cond)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t == Reg::R15) {
|
||||
// TODO: v8 removes UPREDICTABLE for R13
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
const size_t index = concatenate(i1, i2).ZeroExtend();
|
||||
const auto n = ToVector(false, Vn, N);
|
||||
|
||||
const auto reg_n = ir.GetVector(n);
|
||||
const auto scalar = ir.VectorGetElement(16, reg_n, index);
|
||||
const auto result = U ? ir.ZeroExtendToWord(scalar) : ir.SignExtendToWord(scalar);
|
||||
|
||||
ir.SetRegister(t, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
// VMOV<c>.{U8,S8} <Rt>, <Dn[x]>
|
||||
bool ArmTranslatorVisitor::vfp_VMOV_to_i8(Cond cond, bool U, Imm<1> i1, size_t Vn, Reg t, bool N, Imm<2> i2) {
|
||||
if (!ConditionPassed(cond)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t == Reg::R15) {
|
||||
// TODO: v8 removes UPREDICTABLE for R13
|
||||
return UnpredictableInstruction();
|
||||
}
|
||||
|
||||
const size_t index = concatenate(i1, i2).ZeroExtend();
|
||||
const auto n = ToVector(false, Vn, N);
|
||||
|
||||
const auto reg_n = ir.GetVector(n);
|
||||
const auto scalar = ir.VectorGetElement(8, reg_n, index);
|
||||
const auto result = U ? ir.ZeroExtendToWord(scalar) : ir.SignExtendToWord(scalar);
|
||||
|
||||
ir.SetRegister(t, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
// VDUP<c>.{8,16,32} <Qd>, <Rt>
|
||||
// VDUP<c>.{8,16,32} <Dd>, <Rt>
|
||||
bool ArmTranslatorVisitor::vfp_VDUP(Cond cond, Imm<1> B, bool Q, size_t Vd, Reg t, bool D, Imm<1> E) {
|
||||
|
|
Loading…
Reference in a new issue