From db8a9bb5cf88bf9f9f6e44dcdb6d6cfc182e50e9 Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 20:28:33 -0500 Subject: [PATCH] ARMEmitter: Handle SVE SDIV (predicated) --- .../Core/ArchHelpers/CodeEmitter/SVEOps.inl | 18 ++++++++++++------ .../FEXCore/unittests/Emitter/SVE_Tests.cpp | 5 ++++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index dc58a89c0..4d0eb9b0e 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -663,19 +663,25 @@ public: // SVE integer multiply vectors (predicated) void mul(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) { constexpr uint32_t Op = 0b0000'0100'0001'0000'0000'0000'0000'0000; - SVEIntegerMulVectorsPredicated(Op, 0b00, size, zd, pg, zn, zm); + SVEIntegerMulDivVectorsPredicated(Op, 0b00, size, zd, pg, zn, zm); } void smulh(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) { constexpr uint32_t Op = 0b0000'0100'0001'0000'0000'0000'0000'0000; - SVEIntegerMulVectorsPredicated(Op, 0b10, size, zd, pg, zn, zm); + SVEIntegerMulDivVectorsPredicated(Op, 0b10, size, zd, pg, zn, zm); } void umulh(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) { constexpr uint32_t Op = 0b0000'0100'0001'0000'0000'0000'0000'0000; - SVEIntegerMulVectorsPredicated(Op, 0b11, size, zd, pg, zn, zm); + SVEIntegerMulDivVectorsPredicated(Op, 0b11, size, zd, pg, zn, zm); } // SVE integer divide vectors (predicated) - // XXX: + void sdiv(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) { + LOGMAN_THROW_AA_FMT(size == SubRegSize::i32Bit || size == SubRegSize::i64Bit, + "Predicated divide only handles 32-bit or 64-bit elements"); + constexpr uint32_t Op = 0b0000'0100'0001'0100'0000'0000'0000'0000; + SVEIntegerMulDivVectorsPredicated(Op, 0b00, size, zd, pg, zn, zm); + } + // SVE bitwise logical operations (predicated) void orr(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zdn, FEXCore::ARMEmitter::ZRegister zm) { LOGMAN_THROW_AA_FMT(size != FEXCore::ARMEmitter::SubRegSize::i128Bit, "Can't use 128-bit size"); @@ -3999,9 +4005,9 @@ private: dc32(Instr); } - void SVEIntegerMulVectorsPredicated(uint32_t op, uint32_t opc, SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) { + void SVEIntegerMulDivVectorsPredicated(uint32_t op, uint32_t opc, SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) { LOGMAN_THROW_AA_FMT(zd.Idx() == zn.Idx(), "zd and zn must be the same register"); - LOGMAN_THROW_AA_FMT(pg <= PReg::p7, "Add/Sub operation can only use p0-p7 as a governing predicate"); + LOGMAN_THROW_AA_FMT(pg <= PReg::p7, "Mul/Div operation can only use p0-p7 as a governing predicate"); uint32_t Instr = op; Instr |= FEXCore::ToUnderlying(size) << 22; diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index e856e1950..731678d41 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -541,7 +541,10 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer multiply vectors ( } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer divide vectors (predicated)") { - // TODO: Implement in emitter. + TEST_SINGLE(sdiv(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "sdiv z30.s, p7/m, z30.s, z29.s"); + TEST_SINGLE(sdiv(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "sdiv z30.d, p7/m, z30.d, z29.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise logical operations (predicated)") {