From 5cf9bb261369d6e0a058ff7712ffafc761f22c8e Mon Sep 17 00:00:00 2001 From: Lioncache Date: Thu, 2 Feb 2023 21:37:35 -0500 Subject: [PATCH 1/3] ARMEmitter: Handle ADD (vector, predicated) --- .../Core/ArchHelpers/CodeEmitter/SVEOps.inl | 19 ++++++++++++++++++- .../FEXCore/unittests/Emitter/SVE_Tests.cpp | 5 ++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index a3fbec28f..396c93703 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -602,7 +602,11 @@ public: // SVE Integer Binary Arithmetic - Predicated // SVE integer add/subtract vectors (predicated) - // XXX: + void add(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) { + constexpr uint32_t Op = 0b0000'0100'0000'0000'0000'0000'0000'0000; + SVEAddSubVectorsPredicated(Op, 0b000, size, zd, pg, zn, zm); + } + // SVE integer min/max/difference (predicated) void smax(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"); @@ -3962,6 +3966,19 @@ private: dc32(Instr); } + void SVEAddSubVectorsPredicated(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"); + + uint32_t Instr = op; + Instr |= FEXCore::ToUnderlying(size) << 22; + Instr |= opc << 16; + Instr |= pg.Idx() << 10; + Instr |= zm.Idx() << 5; + Instr |= zd.Idx(); + dc32(Instr); + } + // SVE floating-point round to integral value void frintX(uint32_t opc, FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn) { // opc = round mode diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index 57f0ebaf6..d913b2f5f 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -463,7 +463,10 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer multiply-add writi } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer add/subtract vectors (predicated)") { - // TODO: Implement in emitter. + TEST_SINGLE(add(SubRegSize::i8Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "add z30.b, p7/m, z30.b, z28.b"); + TEST_SINGLE(add(SubRegSize::i16Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "add z30.h, p7/m, z30.h, z28.h"); + TEST_SINGLE(add(SubRegSize::i32Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "add z30.s, p7/m, z30.s, z28.s"); + TEST_SINGLE(add(SubRegSize::i64Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "add z30.d, p7/m, z30.d, z28.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer min/max/difference (predicated)") { From a42ae7d3853e5e8238bdb826323530e76fdf104b Mon Sep 17 00:00:00 2001 From: Lioncache Date: Thu, 2 Feb 2023 21:41:45 -0500 Subject: [PATCH 2/3] ARMEmitter: Handle SUB (vector, predicated) --- .../Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl | 4 ++++ External/FEXCore/unittests/Emitter/SVE_Tests.cpp | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index 396c93703..ca1f833e3 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -606,6 +606,10 @@ public: constexpr uint32_t Op = 0b0000'0100'0000'0000'0000'0000'0000'0000; SVEAddSubVectorsPredicated(Op, 0b000, size, zd, pg, zn, zm); } + void sub(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) { + constexpr uint32_t Op = 0b0000'0100'0000'0000'0000'0000'0000'0000; + SVEAddSubVectorsPredicated(Op, 0b001, size, zd, pg, zn, zm); + } // SVE integer min/max/difference (predicated) void smax(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zdn, FEXCore::ARMEmitter::ZRegister zm) { diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index d913b2f5f..3f5e1b46e 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -467,6 +467,11 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer add/subtract vecto TEST_SINGLE(add(SubRegSize::i16Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "add z30.h, p7/m, z30.h, z28.h"); TEST_SINGLE(add(SubRegSize::i32Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "add z30.s, p7/m, z30.s, z28.s"); TEST_SINGLE(add(SubRegSize::i64Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "add z30.d, p7/m, z30.d, z28.d"); + + TEST_SINGLE(sub(SubRegSize::i8Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "sub z30.b, p7/m, z30.b, z28.b"); + TEST_SINGLE(sub(SubRegSize::i16Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "sub z30.h, p7/m, z30.h, z28.h"); + TEST_SINGLE(sub(SubRegSize::i32Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "sub z30.s, p7/m, z30.s, z28.s"); + TEST_SINGLE(sub(SubRegSize::i64Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "sub z30.d, p7/m, z30.d, z28.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer min/max/difference (predicated)") { From 44f5d788c8546b16532591cc0235c34cfd496b91 Mon Sep 17 00:00:00 2001 From: Lioncache Date: Thu, 2 Feb 2023 21:43:39 -0500 Subject: [PATCH 3/3] ARMEmitter: Handle SUBR (vector, predicated) --- .../Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl | 4 ++++ External/FEXCore/unittests/Emitter/SVE_Tests.cpp | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index ca1f833e3..cdfcdbe87 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -610,6 +610,10 @@ public: constexpr uint32_t Op = 0b0000'0100'0000'0000'0000'0000'0000'0000; SVEAddSubVectorsPredicated(Op, 0b001, size, zd, pg, zn, zm); } + void subr(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) { + constexpr uint32_t Op = 0b0000'0100'0000'0000'0000'0000'0000'0000; + SVEAddSubVectorsPredicated(Op, 0b011, size, zd, pg, zn, zm); + } // SVE integer min/max/difference (predicated) void smax(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zdn, FEXCore::ARMEmitter::ZRegister zm) { diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index 3f5e1b46e..9dde27cb3 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -472,6 +472,11 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer add/subtract vecto TEST_SINGLE(sub(SubRegSize::i16Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "sub z30.h, p7/m, z30.h, z28.h"); TEST_SINGLE(sub(SubRegSize::i32Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "sub z30.s, p7/m, z30.s, z28.s"); TEST_SINGLE(sub(SubRegSize::i64Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "sub z30.d, p7/m, z30.d, z28.d"); + + TEST_SINGLE(subr(SubRegSize::i8Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "subr z30.b, p7/m, z30.b, z28.b"); + TEST_SINGLE(subr(SubRegSize::i16Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "subr z30.h, p7/m, z30.h, z28.h"); + TEST_SINGLE(subr(SubRegSize::i32Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "subr z30.s, p7/m, z30.s, z28.s"); + TEST_SINGLE(subr(SubRegSize::i64Bit, ZReg::z30, PReg::p7, ZReg::z30, ZReg::z28), "subr z30.d, p7/m, z30.d, z28.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer min/max/difference (predicated)") {