A32: Implement ASIMD VQDMULH (scalar)

This commit is contained in:
Lioncash 2020-06-23 01:35:37 -04:00 committed by merry
parent 2008fda88b
commit ab5efe8632
3 changed files with 31 additions and 2 deletions

View file

@ -75,8 +75,8 @@ INST(asimd_VMLAL_scalar, "VMLAL (scalar)", "1111001U1dzznnnndddd0o1
INST(asimd_VMUL_scalar, "VMUL (scalar)", "1111001Q1Dzznnnndddd100FN1M0mmmm") // ASIMD INST(asimd_VMUL_scalar, "VMUL (scalar)", "1111001Q1Dzznnnndddd100FN1M0mmmm") // ASIMD
INST(asimd_VMULL_scalar, "VMULL (scalar)", "1111001U1Dzznnnndddd1010N1M0mmmm") // ASIMD INST(asimd_VMULL_scalar, "VMULL (scalar)", "1111001U1Dzznnnndddd1010N1M0mmmm") // ASIMD
//INST(asimd_VQDMULL_scalar, "VQDMULL (scalar)", "111100101-BB--------1011-1-0----") // 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_VQDMULH_scalar, "VQDMULH", "1111001Q1Dzznnnndddd1100N1M0mmmm") // ASIMD
//INST(asimd_VQRDMULH, "VQRDMULH", "1111001U1-BB--------1101-1-0----") // ASIMD //INST(asimd_VQRDMULH_scalar, "VQRDMULH", "1111001U1-BB--------1101-1-0----") // ASIMD
// Two registers and a shift amount // Two registers and a shift amount
INST(asimd_SHR, "SHR", "1111001U1Diiiiiidddd0000LQM1mmmm") // ASIMD INST(asimd_SHR, "SHR", "1111001U1Diiiiiidddd0000LQM1mmmm") // ASIMD

View file

@ -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); 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 } // namespace Dynarmic::A32

View file

@ -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_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_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_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 // 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); bool asimd_SHR(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm);