A64: Implement SQDMULH's by-element scalar variant
This commit is contained in:
parent
40f0576995
commit
f5fb496e7e
3 changed files with 28 additions and 2 deletions
|
@ -497,7 +497,7 @@ INST(FCVTZU_fix_1, "FCVTZU (vector, fixed-point)", "01111
|
|||
//INST(SQDMLAL_elt_1, "SQDMLAL, SQDMLAL2 (by element)", "01011111zzLMmmmm0011H0nnnnnddddd")
|
||||
//INST(SQDMLSL_elt_1, "SQDMLSL, SQDMLSL2 (by element)", "01011111zzLMmmmm0111H0nnnnnddddd")
|
||||
//INST(SQDMULL_elt_1, "SQDMULL, SQDMULL2 (by element)", "01011111zzLMmmmm1011H0nnnnnddddd")
|
||||
//INST(SQDMULH_elt_1, "SQDMULH (by element)", "01011111zzLMmmmm1100H0nnnnnddddd")
|
||||
INST(SQDMULH_elt_1, "SQDMULH (by element)", "01011111zzLMmmmm1100H0nnnnnddddd")
|
||||
//INST(SQRDMULH_elt_1, "SQRDMULH (by element)", "01011111zzLMmmmm1101H0nnnnnddddd")
|
||||
//INST(FMLA_elt_1, "FMLA (by element)", "0101111100LMmmmm0001H0nnnnnddddd")
|
||||
INST(FMLA_elt_2, "FMLA (by element)", "010111111zLMmmmm0001H0nnnnnddddd")
|
||||
|
|
|
@ -606,7 +606,7 @@ struct TranslatorVisitor final {
|
|||
bool SQDMLAL_elt_1(Imm<2> size, bool L, bool M, Vec Vm, bool H, Reg Rn, Vec Vd);
|
||||
bool SQDMLSL_elt_1(Imm<2> size, bool L, bool M, Vec Vm, bool H, Reg Rn, Vec Vd);
|
||||
bool SQDMULL_elt_1(Imm<2> size, bool L, bool M, Vec Vm, bool H, Reg Rn, Vec Vd);
|
||||
bool SQDMULH_elt_1(Imm<2> size, bool L, bool M, Vec Vm, bool H, Vec Vn, Vec Vd);
|
||||
bool SQDMULH_elt_1(Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd);
|
||||
bool SQRDMULH_elt_1(Imm<2> size, bool L, bool M, Vec Vm, bool H, Vec Vn, Vec Vd);
|
||||
bool FMLA_elt_1(Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd);
|
||||
bool FMLA_elt_2(bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* General Public License version 2 or any later version.
|
||||
*/
|
||||
|
||||
#include <utility>
|
||||
#include "frontend/A64/translate/impl/impl.h"
|
||||
|
||||
namespace Dynarmic::A64 {
|
||||
|
@ -58,4 +59,29 @@ bool TranslatorVisitor::FMUL_elt_2(bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm
|
|||
return MultiplyByElement(*this, sz, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::None);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SQDMULH_elt_1(Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
if (size == 0b00 || size == 0b11) {
|
||||
return UnallocatedEncoding();
|
||||
}
|
||||
|
||||
const size_t esize = 8 << size.ZeroExtend();
|
||||
const auto [index, Vmhi] = [=] {
|
||||
if (size == 0b01) {
|
||||
return std::make_pair(concatenate(H, L, M).ZeroExtend(), Imm<1>{0});
|
||||
}
|
||||
|
||||
return std::make_pair(concatenate(H, L).ZeroExtend(), M);
|
||||
}();
|
||||
const Vec Vm = concatenate(Vmhi, Vmlo).ZeroExtend<Vec>();
|
||||
|
||||
const IR::UAny operand1 = V_scalar(esize, Vn);
|
||||
const IR::UAny operand2 = ir.VectorGetElement(esize, V(128, Vm), index);
|
||||
const auto result = ir.SignedSaturatedDoublingMultiplyReturnHigh(operand1, operand2);
|
||||
|
||||
ir.OrQC(result.overflow);
|
||||
|
||||
V_scalar(esize, Vd, result.result);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A64
|
||||
|
|
Loading…
Reference in a new issue