A32: Implement ASIMD VQDMULH (scalar)
This commit is contained in:
parent
2008fda88b
commit
ab5efe8632
3 changed files with 31 additions and 2 deletions
|
@ -75,8 +75,8 @@ INST(asimd_VMLAL_scalar, "VMLAL (scalar)", "1111001U1dzznnnndddd0o1
|
|||
INST(asimd_VMUL_scalar, "VMUL (scalar)", "1111001Q1Dzznnnndddd100FN1M0mmmm") // ASIMD
|
||||
INST(asimd_VMULL_scalar, "VMULL (scalar)", "1111001U1Dzznnnndddd1010N1M0mmmm") // ASIMD
|
||||
//INST(asimd_VQDMULL_scalar, "VQDMULL (scalar)", "111100101-BB--------1011-1-0----") // ASIMD
|
||||
//INST(asimd_VQDMULH, "VQDMULH", "1111001U1-BB--------1100-1-0----") // ASIMD
|
||||
//INST(asimd_VQRDMULH, "VQRDMULH", "1111001U1-BB--------1101-1-0----") // ASIMD
|
||||
INST(asimd_VQDMULH_scalar, "VQDMULH", "1111001Q1Dzznnnndddd1100N1M0mmmm") // ASIMD
|
||||
//INST(asimd_VQRDMULH_scalar, "VQRDMULH", "1111001U1-BB--------1101-1-0----") // ASIMD
|
||||
|
||||
// Two registers and a shift amount
|
||||
INST(asimd_SHR, "SHR", "1111001U1Diiiiiidddd0000LQM1mmmm") // ASIMD
|
||||
|
|
|
@ -127,4 +127,32 @@ bool ArmTranslatorVisitor::asimd_VMULL_scalar(bool U, bool D, size_t sz, size_t
|
|||
return ScalarMultiplyLong(*this, U, D, sz, Vn, Vd, N, M, Vm, MultiplyBehavior::Multiply);
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::asimd_VQDMULH_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm) {
|
||||
if (sz == 0b11) {
|
||||
// TODO: This should be a decode error.
|
||||
return UndefinedInstruction();
|
||||
}
|
||||
|
||||
if (sz == 0b00) {
|
||||
return UndefinedInstruction();
|
||||
}
|
||||
|
||||
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn))) {
|
||||
return UndefinedInstruction();
|
||||
}
|
||||
|
||||
const size_t esize = 8U << sz;
|
||||
const auto d = ToVector(Q, Vd, D);
|
||||
const auto n = ToVector(Q, Vn, N);
|
||||
const auto [m, index] = GetScalarLocation(esize, M, Vm);
|
||||
|
||||
const auto scalar = ir.VectorGetElement(esize, ir.GetVector(m), index);
|
||||
const auto reg_n = ir.GetVector(n);
|
||||
const auto reg_m = ir.VectorBroadcast(esize, scalar);
|
||||
const auto result = ir.VectorSignedSaturatedDoublingMultiply(esize, reg_n, reg_m).upper;
|
||||
|
||||
ir.SetVector(d, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
||||
|
|
|
@ -510,6 +510,7 @@ struct ArmTranslatorVisitor final {
|
|||
bool asimd_VMLAL_scalar(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool op, bool N, bool M, size_t Vm);
|
||||
bool asimd_VMUL_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool F, bool N, bool M, size_t Vm);
|
||||
bool asimd_VMULL_scalar(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm);
|
||||
bool asimd_VQDMULH_scalar(bool Q, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool M, size_t Vm);
|
||||
|
||||
// Two registers and a shift amount
|
||||
bool asimd_SHR(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm);
|
||||
|
|
Loading…
Reference in a new issue