From 19ad19193e10de2887345b16eeb754ab68fe0a28 Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 20:09:22 -0500 Subject: [PATCH 01/15] ARMEmitter: Handle SVE MUL (predicated) --- .../Core/ArchHelpers/CodeEmitter/SVEOps.inl | 19 ++++++++++++++++++- .../FEXCore/unittests/Emitter/SVE_Tests.cpp | 9 ++++++++- 2 files changed, 26 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 cdfcdbe87..c938da6e2 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -661,7 +661,11 @@ public: } // SVE integer multiply vectors (predicated) - // XXX: + 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); + } + // SVE integer divide vectors (predicated) // XXX: // SVE bitwise logical operations (predicated) @@ -3987,6 +3991,19 @@ private: dc32(Instr); } + void SVEIntegerMulVectorsPredicated(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 9dde27cb3..9619d24b3 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -512,7 +512,14 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer min/max/difference } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer multiply vectors (predicated)") { - // TODO: Implement in emitter. + TEST_SINGLE(mul(SubRegSize::i8Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "mul z30.b, p7/m, z30.b, z29.b"); + TEST_SINGLE(mul(SubRegSize::i16Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "mul z30.h, p7/m, z30.h, z29.h"); + TEST_SINGLE(mul(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "mul z30.s, p7/m, z30.s, z29.s"); + TEST_SINGLE(mul(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "mul z30.d, p7/m, z30.d, z29.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer divide vectors (predicated)") { From 3a98190119afb7120ea50d384d809db8e764082e Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 20:16:36 -0500 Subject: [PATCH 02/15] ARMEmitter: Handle SVE SMULH (predicated) --- .../Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl | 4 ++++ External/FEXCore/unittests/Emitter/SVE_Tests.cpp | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index c938da6e2..77a660d22 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -665,6 +665,10 @@ public: constexpr uint32_t Op = 0b0000'0100'0001'0000'0000'0000'0000'0000; SVEIntegerMulVectorsPredicated(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); + } // SVE integer divide vectors (predicated) // XXX: diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index 9619d24b3..87f9d83f7 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -520,6 +520,15 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer multiply vectors ( "mul z30.s, p7/m, z30.s, z29.s"); TEST_SINGLE(mul(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), "mul z30.d, p7/m, z30.d, z29.d"); + + TEST_SINGLE(smulh(SubRegSize::i8Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "smulh z30.b, p7/m, z30.b, z29.b"); + TEST_SINGLE(smulh(SubRegSize::i16Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "smulh z30.h, p7/m, z30.h, z29.h"); + TEST_SINGLE(smulh(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "smulh z30.s, p7/m, z30.s, z29.s"); + TEST_SINGLE(smulh(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "smulh z30.d, p7/m, z30.d, z29.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer divide vectors (predicated)") { From f8a1c43c06510445a54e8050ea5053b2cf68cae9 Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 20:26:00 -0500 Subject: [PATCH 03/15] ARMEmitter: Handle SVE UMULH (predicated) --- .../Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl | 4 ++++ External/FEXCore/unittests/Emitter/SVE_Tests.cpp | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index 77a660d22..dc58a89c0 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -669,6 +669,10 @@ public: constexpr uint32_t Op = 0b0000'0100'0001'0000'0000'0000'0000'0000; SVEIntegerMulVectorsPredicated(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); + } // SVE integer divide vectors (predicated) // XXX: diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index 87f9d83f7..e856e1950 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -529,6 +529,15 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer multiply vectors ( "smulh z30.s, p7/m, z30.s, z29.s"); TEST_SINGLE(smulh(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), "smulh z30.d, p7/m, z30.d, z29.d"); + + TEST_SINGLE(umulh(SubRegSize::i8Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "umulh z30.b, p7/m, z30.b, z29.b"); + TEST_SINGLE(umulh(SubRegSize::i16Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "umulh z30.h, p7/m, z30.h, z29.h"); + TEST_SINGLE(umulh(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "umulh z30.s, p7/m, z30.s, z29.s"); + TEST_SINGLE(umulh(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "umulh z30.d, p7/m, z30.d, z29.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer divide vectors (predicated)") { From db8a9bb5cf88bf9f9f6e44dcdb6d6cfc182e50e9 Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 20:28:33 -0500 Subject: [PATCH 04/15] 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)") { From 848e5561ce6ebba23abf9ead105a7f1d991bd276 Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 20:35:29 -0500 Subject: [PATCH 05/15] ARMEmitter: Handle SVE UDIV (predicated) --- .../Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl | 6 ++++++ External/FEXCore/unittests/Emitter/SVE_Tests.cpp | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index 4d0eb9b0e..bc8bb4224 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -681,6 +681,12 @@ public: constexpr uint32_t Op = 0b0000'0100'0001'0100'0000'0000'0000'0000; SVEIntegerMulDivVectorsPredicated(Op, 0b00, size, zd, pg, zn, zm); } + void udiv(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, 0b01, 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) { diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index 731678d41..42183ce5b 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -545,6 +545,11 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer divide vectors (pr "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_SINGLE(udiv(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "udiv z30.s, p7/m, z30.s, z29.s"); + TEST_SINGLE(udiv(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "udiv z30.d, p7/m, z30.d, z29.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise logical operations (predicated)") { From 870115dd5deaf272f9381cc6ddd8794de0c6499e Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 20:37:13 -0500 Subject: [PATCH 06/15] ARMEmitter: Handle SVE SDIVR (predicated) --- .../Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl | 6 ++++++ External/FEXCore/unittests/Emitter/SVE_Tests.cpp | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index bc8bb4224..19cffec95 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -687,6 +687,12 @@ public: constexpr uint32_t Op = 0b0000'0100'0001'0100'0000'0000'0000'0000; SVEIntegerMulDivVectorsPredicated(Op, 0b01, size, zd, pg, zn, zm); } + void sdivr(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, 0b10, 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) { diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index 42183ce5b..e7513a1ea 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -550,6 +550,11 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer divide vectors (pr "udiv z30.s, p7/m, z30.s, z29.s"); TEST_SINGLE(udiv(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), "udiv z30.d, p7/m, z30.d, z29.d"); + + TEST_SINGLE(sdivr(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "sdivr z30.s, p7/m, z30.s, z29.s"); + TEST_SINGLE(sdivr(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "sdivr z30.d, p7/m, z30.d, z29.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise logical operations (predicated)") { From ecd711e6914e6163edbd49bea8931da297060f19 Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 20:44:12 -0500 Subject: [PATCH 07/15] ARMEmitter: Handle SVE UDIVR (predicated) --- .../Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl | 6 ++++++ External/FEXCore/unittests/Emitter/SVE_Tests.cpp | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index 19cffec95..805dad937 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -693,6 +693,12 @@ public: constexpr uint32_t Op = 0b0000'0100'0001'0100'0000'0000'0000'0000; SVEIntegerMulDivVectorsPredicated(Op, 0b10, size, zd, pg, zn, zm); } + void udivr(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, 0b11, 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) { diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index e7513a1ea..e7c10d9fd 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -555,6 +555,11 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer divide vectors (pr "sdivr z30.s, p7/m, z30.s, z29.s"); TEST_SINGLE(sdivr(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), "sdivr z30.d, p7/m, z30.d, z29.d"); + + TEST_SINGLE(udivr(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "udivr z30.s, p7/m, z30.s, z29.s"); + TEST_SINGLE(udivr(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29), + "udivr z30.d, p7/m, z30.d, z29.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise logical operations (predicated)") { From 4f9530cec342fcbd66c54df25ea41ab6a3fa3c0d Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 20:58:06 -0500 Subject: [PATCH 08/15] ARMEmitter: Handle SVE SADDV (predicated) --- .../Core/ArchHelpers/CodeEmitter/SVEOps.inl | 20 ++++++++++++++++++- .../FEXCore/unittests/Emitter/SVE_Tests.cpp | 4 +++- 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 805dad937..c8ae8b3c3 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -728,7 +728,13 @@ public: // SVE Integer Reduction // SVE integer add reduction (predicated) - // XXX: + void saddv(SubRegSize size, DRegister vd, PRegister pg, ZRegister zn) { + LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, + "saddv may only use 8-bit, 16-bit, or 32-bit elements."); + constexpr uint32_t Op = 0b0000'0100'0000'0000'0010'0000'0000'0000; + SVEIntegerAddReductionPredicated(Op, 0b00, size, vd, pg, zn); + } + // SVE integer min/max reduction (predicated) void smaxv(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn) { LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i8Bit || size == FEXCore::ARMEmitter::SubRegSize::i16Bit || size == FEXCore::ARMEmitter::SubRegSize::i32Bit, "Invalid subregsize size"); @@ -4036,6 +4042,18 @@ private: dc32(Instr); } + void SVEIntegerAddReductionPredicated(uint32_t op, uint32_t opc, SubRegSize size, DRegister vd, PRegister pg, ZRegister zn) { + LOGMAN_THROW_AA_FMT(pg <= PReg::p7, "Integer reduction 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 |= zn.Idx() << 5; + Instr |= vd.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 e7c10d9fd..04de953b0 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -589,7 +589,9 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise logical operations } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer add reduction (predicated)") { - // TODO: Implement in emitter. + TEST_SINGLE(saddv(SubRegSize::i8Bit, DReg::d30, PReg::p7, ZReg::z29), "saddv d30, p7, z29.b"); + TEST_SINGLE(saddv(SubRegSize::i16Bit, DReg::d30, PReg::p7, ZReg::z29), "saddv d30, p7, z29.h"); + TEST_SINGLE(saddv(SubRegSize::i32Bit, DReg::d30, PReg::p7, ZReg::z29), "saddv d30, p7, z29.s"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer min/max reduction (predicated)") { TEST_SINGLE(smaxv(SubRegSize::i8Bit, ZReg::z30, PReg::p6, ZReg::z29), "smaxv b30, p6, z29.b"); From 51c9f7090470b8e456bbc02a6b3c46a9410f6b60 Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 21:03:57 -0500 Subject: [PATCH 09/15] ARMEmitter: Handle SVE UADDV (predicated) --- .../Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl | 6 ++++++ External/FEXCore/unittests/Emitter/SVE_Tests.cpp | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index c8ae8b3c3..8651aca69 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -734,6 +734,12 @@ public: constexpr uint32_t Op = 0b0000'0100'0000'0000'0010'0000'0000'0000; SVEIntegerAddReductionPredicated(Op, 0b00, size, vd, pg, zn); } + void uaddv(SubRegSize size, DRegister vd, PRegister pg, ZRegister zn) { + LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, + "uaddv may only use 8-bit, 16-bit, or 32-bit elements."); + constexpr uint32_t Op = 0b0000'0100'0000'0000'0010'0000'0000'0000; + SVEIntegerAddReductionPredicated(Op, 0b01, size, vd, pg, zn); + } // SVE integer min/max reduction (predicated) void smaxv(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn) { diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index 04de953b0..3d6a228c9 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -592,6 +592,10 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer add reduction (pre TEST_SINGLE(saddv(SubRegSize::i8Bit, DReg::d30, PReg::p7, ZReg::z29), "saddv d30, p7, z29.b"); TEST_SINGLE(saddv(SubRegSize::i16Bit, DReg::d30, PReg::p7, ZReg::z29), "saddv d30, p7, z29.h"); TEST_SINGLE(saddv(SubRegSize::i32Bit, DReg::d30, PReg::p7, ZReg::z29), "saddv d30, p7, z29.s"); + + TEST_SINGLE(uaddv(SubRegSize::i8Bit, DReg::d30, PReg::p7, ZReg::z29), "uaddv d30, p7, z29.b"); + TEST_SINGLE(uaddv(SubRegSize::i16Bit, DReg::d30, PReg::p7, ZReg::z29), "uaddv d30, p7, z29.h"); + TEST_SINGLE(uaddv(SubRegSize::i32Bit, DReg::d30, PReg::p7, ZReg::z29), "uaddv d30, p7, z29.s"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer min/max reduction (predicated)") { TEST_SINGLE(smaxv(SubRegSize::i8Bit, ZReg::z30, PReg::p6, ZReg::z29), "smaxv b30, p6, z29.b"); From 02861f41ebcdc4c4954b2b7d36fcc8497629b2b5 Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 21:26:06 -0500 Subject: [PATCH 10/15] ARMEmitter: Handle SVE ORV (predicated) --- .../Core/ArchHelpers/CodeEmitter/SVEOps.inl | 12 ++++++++---- External/FEXCore/unittests/Emitter/SVE_Tests.cpp | 5 ++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index 8651aca69..17b977dcf 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -732,13 +732,13 @@ public: LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, "saddv may only use 8-bit, 16-bit, or 32-bit elements."); constexpr uint32_t Op = 0b0000'0100'0000'0000'0010'0000'0000'0000; - SVEIntegerAddReductionPredicated(Op, 0b00, size, vd, pg, zn); + SVEReductionOperation(Op, 0b00, size, vd, pg, zn); } void uaddv(SubRegSize size, DRegister vd, PRegister pg, ZRegister zn) { LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, "uaddv may only use 8-bit, 16-bit, or 32-bit elements."); constexpr uint32_t Op = 0b0000'0100'0000'0000'0010'0000'0000'0000; - SVEIntegerAddReductionPredicated(Op, 0b01, size, vd, pg, zn); + SVEReductionOperation(Op, 0b01, size, vd, pg, zn); } // SVE integer min/max reduction (predicated) @@ -774,7 +774,10 @@ public: } // SVE bitwise logical reduction (predicated) - // XXX + void orv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { + constexpr uint32_t Op = 0b0000'0100'0001'1000'0010'0000'0000'0000; + SVEReductionOperation(Op, 0b00, size, vd, pg, zn); + } // SVE Bitwise Shift - Predicated // SVE bitwise shift by immediate (predicated) @@ -4048,7 +4051,8 @@ private: dc32(Instr); } - void SVEIntegerAddReductionPredicated(uint32_t op, uint32_t opc, SubRegSize size, DRegister vd, PRegister pg, ZRegister zn) { + void SVEReductionOperation(uint32_t op, uint32_t opc, SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { + LOGMAN_THROW_AA_FMT(size != SubRegSize::i128Bit, "Can't use 128-bit element size for reduction operation"); LOGMAN_THROW_AA_FMT(pg <= PReg::p7, "Integer reduction operation can only use p0-p7 as a governing predicate"); uint32_t Instr = op; diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index 3d6a228c9..84fe7cb4a 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -635,7 +635,10 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE constructive prefix (predi //TEST_SINGLE(movprfx(SubRegSize::i128Bit, ZReg::z30, PReg::p6.Zeroing(), ZReg::z29), "movprfx z30.q, p6/z, z29.q"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise logical reduction (predicated)") { - // TODO: Implement in emitter. + TEST_SINGLE(orv(SubRegSize::i8Bit, VReg::v30, PReg::p7, ZReg::z29), "orv b30, p7, z29.b"); + TEST_SINGLE(orv(SubRegSize::i16Bit, VReg::v30, PReg::p7, ZReg::z29), "orv h30, p7, z29.h"); + TEST_SINGLE(orv(SubRegSize::i32Bit, VReg::v30, PReg::p7, ZReg::z29), "orv s30, p7, z29.s"); + TEST_SINGLE(orv(SubRegSize::i64Bit, VReg::v30, PReg::p7, ZReg::z29), "orv d30, p7, z29.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise shift by immediate (predicated)") { TEST_SINGLE(asr(SubRegSize::i8Bit, ZReg::z30, PReg::p6.Merging(), ZReg::z30, 1), "asr z30.b, p6/m, z30.b, #1"); From 3508f7a66773e2b861022bc7f5a1335d4497f277 Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 21:27:34 -0500 Subject: [PATCH 11/15] ARMEmitter: Handle SVE EORV (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 17b977dcf..d39761c6e 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -778,6 +778,10 @@ public: constexpr uint32_t Op = 0b0000'0100'0001'1000'0010'0000'0000'0000; SVEReductionOperation(Op, 0b00, size, vd, pg, zn); } + void eorv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { + constexpr uint32_t Op = 0b0000'0100'0001'1000'0010'0000'0000'0000; + SVEReductionOperation(Op, 0b01, size, vd, pg, zn); + } // SVE Bitwise Shift - Predicated // SVE bitwise shift by immediate (predicated) diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index 84fe7cb4a..a428733a1 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -639,6 +639,11 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise logical reduction TEST_SINGLE(orv(SubRegSize::i16Bit, VReg::v30, PReg::p7, ZReg::z29), "orv h30, p7, z29.h"); TEST_SINGLE(orv(SubRegSize::i32Bit, VReg::v30, PReg::p7, ZReg::z29), "orv s30, p7, z29.s"); TEST_SINGLE(orv(SubRegSize::i64Bit, VReg::v30, PReg::p7, ZReg::z29), "orv d30, p7, z29.d"); + + TEST_SINGLE(eorv(SubRegSize::i8Bit, VReg::v30, PReg::p7, ZReg::z29), "eorv b30, p7, z29.b"); + TEST_SINGLE(eorv(SubRegSize::i16Bit, VReg::v30, PReg::p7, ZReg::z29), "eorv h30, p7, z29.h"); + TEST_SINGLE(eorv(SubRegSize::i32Bit, VReg::v30, PReg::p7, ZReg::z29), "eorv s30, p7, z29.s"); + TEST_SINGLE(eorv(SubRegSize::i64Bit, VReg::v30, PReg::p7, ZReg::z29), "eorv d30, p7, z29.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise shift by immediate (predicated)") { TEST_SINGLE(asr(SubRegSize::i8Bit, ZReg::z30, PReg::p6.Merging(), ZReg::z30, 1), "asr z30.b, p6/m, z30.b, #1"); From db8317caf86d482f2feee45bce26d7d7fadfa0d2 Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 21:29:08 -0500 Subject: [PATCH 12/15] ARMEmitter: Handle SVE ANDV (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 d39761c6e..5809864c4 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -782,6 +782,10 @@ public: constexpr uint32_t Op = 0b0000'0100'0001'1000'0010'0000'0000'0000; SVEReductionOperation(Op, 0b01, size, vd, pg, zn); } + void andv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { + constexpr uint32_t Op = 0b0000'0100'0001'1000'0010'0000'0000'0000; + SVEReductionOperation(Op, 0b10, size, vd, pg, zn); + } // SVE Bitwise Shift - Predicated // SVE bitwise shift by immediate (predicated) diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index a428733a1..4d3ad26f5 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -644,6 +644,11 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise logical reduction TEST_SINGLE(eorv(SubRegSize::i16Bit, VReg::v30, PReg::p7, ZReg::z29), "eorv h30, p7, z29.h"); TEST_SINGLE(eorv(SubRegSize::i32Bit, VReg::v30, PReg::p7, ZReg::z29), "eorv s30, p7, z29.s"); TEST_SINGLE(eorv(SubRegSize::i64Bit, VReg::v30, PReg::p7, ZReg::z29), "eorv d30, p7, z29.d"); + + TEST_SINGLE(andv(SubRegSize::i8Bit, VReg::v30, PReg::p7, ZReg::z29), "andv b30, p7, z29.b"); + TEST_SINGLE(andv(SubRegSize::i16Bit, VReg::v30, PReg::p7, ZReg::z29), "andv h30, p7, z29.h"); + TEST_SINGLE(andv(SubRegSize::i32Bit, VReg::v30, PReg::p7, ZReg::z29), "andv s30, p7, z29.s"); + TEST_SINGLE(andv(SubRegSize::i64Bit, VReg::v30, PReg::p7, ZReg::z29), "andv d30, p7, z29.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise shift by immediate (predicated)") { TEST_SINGLE(asr(SubRegSize::i8Bit, ZReg::z30, PReg::p6.Merging(), ZReg::z30, 1), "asr z30.b, p6/m, z30.b, #1"); From dac075b8716af11be897fb8d95af9c0f564e27c8 Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 21:36:25 -0500 Subject: [PATCH 13/15] ARMEmitter: Move min/max reduction over to generic reduction helper Also enforces the use of a VRegister for the destination argument like the manual. --- .../Core/ArchHelpers/CodeEmitter/SVEOps.inl | 37 ++++++----------- .../Interface/Core/JIT/Arm64/VectorOps.cpp | 2 +- .../FEXCore/unittests/Emitter/SVE_Tests.cpp | 40 +++++++++---------- 3 files changed, 33 insertions(+), 46 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index 5809864c4..e20c0b4a8 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -742,25 +742,25 @@ public: } // SVE integer min/max reduction (predicated) - void smaxv(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn) { - LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i8Bit || size == FEXCore::ARMEmitter::SubRegSize::i16Bit || size == FEXCore::ARMEmitter::SubRegSize::i32Bit, "Invalid subregsize size"); + void smaxv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { + LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, "Invalid subregsize size"); constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13; - SVEIntegerMinMaxReduction(Op, 0, 0, size, pg, zn, zd); + SVEReductionOperation(Op, 0b00, size, vd, pg, zn); } - void umaxv(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn) { - LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i8Bit || size == FEXCore::ARMEmitter::SubRegSize::i16Bit || size == FEXCore::ARMEmitter::SubRegSize::i32Bit, "Invalid subregsize size"); + void umaxv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { + LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, "Invalid subregsize size"); constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13; - SVEIntegerMinMaxReduction(Op, 0, 1, size, pg, zn, zd); + SVEReductionOperation(Op, 0b01, size, vd, pg, zn); } - void sminv(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn) { - LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i8Bit || size == FEXCore::ARMEmitter::SubRegSize::i16Bit || size == FEXCore::ARMEmitter::SubRegSize::i32Bit, "Invalid subregsize size"); + void sminv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { + LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, "Invalid subregsize size"); constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13; - SVEIntegerMinMaxReduction(Op, 1, 0, size, pg, zn, zd); + SVEReductionOperation(Op, 0b10, size, vd, pg, zn); } - void uminv(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn) { - LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i8Bit || size == FEXCore::ARMEmitter::SubRegSize::i16Bit || size == FEXCore::ARMEmitter::SubRegSize::i32Bit, "Invalid subregsize size"); + void uminv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { + LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, "Invalid subregsize size"); constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13; - SVEIntegerMinMaxReduction(Op, 1, 1, size, pg, zn, zd); + SVEReductionOperation(Op, 0b11, size, vd, pg, zn); } // SVE constructive prefix (predicated) @@ -3868,19 +3868,6 @@ private: dc32(Instr); } - // SVE integer min/max reduction (predicated) - void SVEIntegerMinMaxReduction(uint32_t Op, uint32_t op, uint32_t U, FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn, FEXCore::ARMEmitter::ZRegister zd) { - uint32_t Instr = Op; - - Instr |= FEXCore::ToUnderlying(size) << 22; - Instr |= op << 17; - Instr |= U << 16; - Instr |= pg.Idx() << 10; - Instr |= Encode_rn(zn); - Instr |= Encode_rd(zd); - dc32(Instr); - } - // SVE constructive prefix (predicated) void SVEConstructivePrefixPredicated(uint32_t Op, uint32_t opc, uint32_t M, FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn, FEXCore::ARMEmitter::ZRegister zd) { uint32_t Instr = Op; diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp index af0c2b171..932ee64ae 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp @@ -423,7 +423,7 @@ DEF_OP(VUMinV) { const auto Pred = OpSize == 16 ? PRED_TMP_16B : PRED_TMP_32B; - uminv(SubRegSize, Dst.Z(), Pred, Vector.Z()); + uminv(SubRegSize, Dst, Pred, Vector.Z()); } else { // Vector uminv(SubRegSize, Dst.Q(), Vector.Q()); diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index 4d3ad26f5..a46061e59 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -598,29 +598,29 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer add reduction (pre TEST_SINGLE(uaddv(SubRegSize::i32Bit, DReg::d30, PReg::p7, ZReg::z29), "uaddv d30, p7, z29.s"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer min/max reduction (predicated)") { - TEST_SINGLE(smaxv(SubRegSize::i8Bit, ZReg::z30, PReg::p6, ZReg::z29), "smaxv b30, p6, z29.b"); - TEST_SINGLE(smaxv(SubRegSize::i16Bit, ZReg::z30, PReg::p6, ZReg::z29), "smaxv h30, p6, z29.h"); - TEST_SINGLE(smaxv(SubRegSize::i32Bit, ZReg::z30, PReg::p6, ZReg::z29), "smaxv s30, p6, z29.s"); - //TEST_SINGLE(smaxv(SubRegSize::i64Bit, ZReg::z30, PReg::p6, ZReg::z29), "smaxv d30, p6, z29.d"); - //TEST_SINGLE(smaxv(SubRegSize::i128Bit, ZReg::z30, PReg::p6, ZReg::z29), "smaxv q30, p6, z29.q"); + TEST_SINGLE(smaxv(SubRegSize::i8Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv b30, p6, z29.b"); + TEST_SINGLE(smaxv(SubRegSize::i16Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv h30, p6, z29.h"); + TEST_SINGLE(smaxv(SubRegSize::i32Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv s30, p6, z29.s"); + //TEST_SINGLE(smaxv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv d30, p6, z29.d"); + //TEST_SINGLE(smaxv(SubRegSize::i128Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv q30, p6, z29.q"); - TEST_SINGLE(umaxv(SubRegSize::i8Bit, ZReg::z30, PReg::p6, ZReg::z29), "umaxv b30, p6, z29.b"); - TEST_SINGLE(umaxv(SubRegSize::i16Bit, ZReg::z30, PReg::p6, ZReg::z29), "umaxv h30, p6, z29.h"); - TEST_SINGLE(umaxv(SubRegSize::i32Bit, ZReg::z30, PReg::p6, ZReg::z29), "umaxv s30, p6, z29.s"); - //TEST_SINGLE(umaxv(SubRegSize::i64Bit, ZReg::z30, PReg::p6, ZReg::z29), "umaxv d30, p6, z29.d"); - //TEST_SINGLE(umaxv(SubRegSize::i128Bit, ZReg::z30, PReg::p6, ZReg::z29), "umaxv q30, p6, z29.q"); + TEST_SINGLE(umaxv(SubRegSize::i8Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv b30, p6, z29.b"); + TEST_SINGLE(umaxv(SubRegSize::i16Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv h30, p6, z29.h"); + TEST_SINGLE(umaxv(SubRegSize::i32Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv s30, p6, z29.s"); + //TEST_SINGLE(umaxv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv d30, p6, z29.d"); + //TEST_SINGLE(umaxv(SubRegSize::i128Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv q30, p6, z29.q"); - TEST_SINGLE(sminv(SubRegSize::i8Bit, ZReg::z30, PReg::p6, ZReg::z29), "sminv b30, p6, z29.b"); - TEST_SINGLE(sminv(SubRegSize::i16Bit, ZReg::z30, PReg::p6, ZReg::z29), "sminv h30, p6, z29.h"); - TEST_SINGLE(sminv(SubRegSize::i32Bit, ZReg::z30, PReg::p6, ZReg::z29), "sminv s30, p6, z29.s"); - //TEST_SINGLE(sminv(SubRegSize::i64Bit, ZReg::z30, PReg::p6, ZReg::z29), "sminv d30, p6, z29.d"); - //TEST_SINGLE(sminv(SubRegSize::i128Bit, ZReg::z30, PReg::p6, ZReg::z29), "sminv q30, p6, z29.q"); + TEST_SINGLE(sminv(SubRegSize::i8Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv b30, p6, z29.b"); + TEST_SINGLE(sminv(SubRegSize::i16Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv h30, p6, z29.h"); + TEST_SINGLE(sminv(SubRegSize::i32Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv s30, p6, z29.s"); + //TEST_SINGLE(sminv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv d30, p6, z29.d"); + //TEST_SINGLE(sminv(SubRegSize::i128Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv q30, p6, z29.q"); - TEST_SINGLE(uminv(SubRegSize::i8Bit, ZReg::z30, PReg::p6, ZReg::z29), "uminv b30, p6, z29.b"); - TEST_SINGLE(uminv(SubRegSize::i16Bit, ZReg::z30, PReg::p6, ZReg::z29), "uminv h30, p6, z29.h"); - TEST_SINGLE(uminv(SubRegSize::i32Bit, ZReg::z30, PReg::p6, ZReg::z29), "uminv s30, p6, z29.s"); - //TEST_SINGLE(uminv(SubRegSize::i64Bit, ZReg::z30, PReg::p6, ZReg::z29), "uminv d30, p6, z29.d"); - //TEST_SINGLE(uminv(SubRegSize::i128Bit, ZReg::z30, PReg::p6, ZReg::z29), "uminv q30, p6, z29.q"); + TEST_SINGLE(uminv(SubRegSize::i8Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv b30, p6, z29.b"); + TEST_SINGLE(uminv(SubRegSize::i16Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv h30, p6, z29.h"); + TEST_SINGLE(uminv(SubRegSize::i32Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv s30, p6, z29.s"); + //TEST_SINGLE(uminv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv d30, p6, z29.d"); + //TEST_SINGLE(uminv(SubRegSize::i128Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv q30, p6, z29.q"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE constructive prefix (predicated)") { TEST_SINGLE(movprfx(SubRegSize::i8Bit, ZReg::z30, PReg::p6.Merging(), ZReg::z29), "movprfx z30.b, p6/m, z29.b"); From 5563a51b84645a2fced3975714966ee8260a84bd Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 21:52:40 -0500 Subject: [PATCH 14/15] ARMEmitter: Allow 64-bit variants of min/max reduction The instructions allow specifying 64-bit element sizes. With this, we can also completely remove the size checking from the functions, since the general SVE integer reduction operation already checks for invalid sizes for us. --- .../Core/ArchHelpers/CodeEmitter/SVEOps.inl | 4 ---- External/FEXCore/unittests/Emitter/SVE_Tests.cpp | 12 ++++-------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index e20c0b4a8..63a0fa99f 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -743,22 +743,18 @@ public: // SVE integer min/max reduction (predicated) void smaxv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { - LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, "Invalid subregsize size"); constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13; SVEReductionOperation(Op, 0b00, size, vd, pg, zn); } void umaxv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { - LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, "Invalid subregsize size"); constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13; SVEReductionOperation(Op, 0b01, size, vd, pg, zn); } void sminv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { - LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, "Invalid subregsize size"); constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13; SVEReductionOperation(Op, 0b10, size, vd, pg, zn); } void uminv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { - LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, "Invalid subregsize size"); constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13; SVEReductionOperation(Op, 0b11, size, vd, pg, zn); } diff --git a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp index a46061e59..49ca57f56 100644 --- a/External/FEXCore/unittests/Emitter/SVE_Tests.cpp +++ b/External/FEXCore/unittests/Emitter/SVE_Tests.cpp @@ -601,26 +601,22 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer min/max reduction TEST_SINGLE(smaxv(SubRegSize::i8Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv b30, p6, z29.b"); TEST_SINGLE(smaxv(SubRegSize::i16Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv h30, p6, z29.h"); TEST_SINGLE(smaxv(SubRegSize::i32Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv s30, p6, z29.s"); - //TEST_SINGLE(smaxv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv d30, p6, z29.d"); - //TEST_SINGLE(smaxv(SubRegSize::i128Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv q30, p6, z29.q"); + TEST_SINGLE(smaxv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv d30, p6, z29.d"); TEST_SINGLE(umaxv(SubRegSize::i8Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv b30, p6, z29.b"); TEST_SINGLE(umaxv(SubRegSize::i16Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv h30, p6, z29.h"); TEST_SINGLE(umaxv(SubRegSize::i32Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv s30, p6, z29.s"); - //TEST_SINGLE(umaxv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv d30, p6, z29.d"); - //TEST_SINGLE(umaxv(SubRegSize::i128Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv q30, p6, z29.q"); + TEST_SINGLE(umaxv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv d30, p6, z29.d"); TEST_SINGLE(sminv(SubRegSize::i8Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv b30, p6, z29.b"); TEST_SINGLE(sminv(SubRegSize::i16Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv h30, p6, z29.h"); TEST_SINGLE(sminv(SubRegSize::i32Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv s30, p6, z29.s"); - //TEST_SINGLE(sminv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv d30, p6, z29.d"); - //TEST_SINGLE(sminv(SubRegSize::i128Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv q30, p6, z29.q"); + TEST_SINGLE(sminv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv d30, p6, z29.d"); TEST_SINGLE(uminv(SubRegSize::i8Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv b30, p6, z29.b"); TEST_SINGLE(uminv(SubRegSize::i16Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv h30, p6, z29.h"); TEST_SINGLE(uminv(SubRegSize::i32Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv s30, p6, z29.s"); - //TEST_SINGLE(uminv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv d30, p6, z29.d"); - //TEST_SINGLE(uminv(SubRegSize::i128Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv q30, p6, z29.q"); + TEST_SINGLE(uminv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv d30, p6, z29.d"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE constructive prefix (predicated)") { TEST_SINGLE(movprfx(SubRegSize::i8Bit, ZReg::z30, PReg::p6.Merging(), ZReg::z29), "movprfx z30.b, p6/m, z29.b"); From 3f6edf7b5aedcc78786cebdade3dfa13b4583dac Mon Sep 17 00:00:00 2001 From: Lioncache Date: Fri, 3 Feb 2023 21:58:44 -0500 Subject: [PATCH 15/15] ARMEmitter: Clarify SVEReductionOperation as working on integer ops --- .../Core/ArchHelpers/CodeEmitter/SVEOps.inl | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl index 63a0fa99f..128bba1eb 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/CodeEmitter/SVEOps.inl @@ -732,31 +732,31 @@ public: LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, "saddv may only use 8-bit, 16-bit, or 32-bit elements."); constexpr uint32_t Op = 0b0000'0100'0000'0000'0010'0000'0000'0000; - SVEReductionOperation(Op, 0b00, size, vd, pg, zn); + SVEIntegerReductionOperation(Op, 0b00, size, vd, pg, zn); } void uaddv(SubRegSize size, DRegister vd, PRegister pg, ZRegister zn) { LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit, "uaddv may only use 8-bit, 16-bit, or 32-bit elements."); constexpr uint32_t Op = 0b0000'0100'0000'0000'0010'0000'0000'0000; - SVEReductionOperation(Op, 0b01, size, vd, pg, zn); + SVEIntegerReductionOperation(Op, 0b01, size, vd, pg, zn); } // SVE integer min/max reduction (predicated) void smaxv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13; - SVEReductionOperation(Op, 0b00, size, vd, pg, zn); + SVEIntegerReductionOperation(Op, 0b00, size, vd, pg, zn); } void umaxv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13; - SVEReductionOperation(Op, 0b01, size, vd, pg, zn); + SVEIntegerReductionOperation(Op, 0b01, size, vd, pg, zn); } void sminv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13; - SVEReductionOperation(Op, 0b10, size, vd, pg, zn); + SVEIntegerReductionOperation(Op, 0b10, size, vd, pg, zn); } void uminv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13; - SVEReductionOperation(Op, 0b11, size, vd, pg, zn); + SVEIntegerReductionOperation(Op, 0b11, size, vd, pg, zn); } // SVE constructive prefix (predicated) @@ -772,15 +772,15 @@ public: // SVE bitwise logical reduction (predicated) void orv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { constexpr uint32_t Op = 0b0000'0100'0001'1000'0010'0000'0000'0000; - SVEReductionOperation(Op, 0b00, size, vd, pg, zn); + SVEIntegerReductionOperation(Op, 0b00, size, vd, pg, zn); } void eorv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { constexpr uint32_t Op = 0b0000'0100'0001'1000'0010'0000'0000'0000; - SVEReductionOperation(Op, 0b01, size, vd, pg, zn); + SVEIntegerReductionOperation(Op, 0b01, size, vd, pg, zn); } void andv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { constexpr uint32_t Op = 0b0000'0100'0001'1000'0010'0000'0000'0000; - SVEReductionOperation(Op, 0b10, size, vd, pg, zn); + SVEIntegerReductionOperation(Op, 0b10, size, vd, pg, zn); } // SVE Bitwise Shift - Predicated @@ -4042,7 +4042,7 @@ private: dc32(Instr); } - void SVEReductionOperation(uint32_t op, uint32_t opc, SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { + void SVEIntegerReductionOperation(uint32_t op, uint32_t opc, SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) { LOGMAN_THROW_AA_FMT(size != SubRegSize::i128Bit, "Can't use 128-bit element size for reduction operation"); LOGMAN_THROW_AA_FMT(pg <= PReg::p7, "Integer reduction operation can only use p0-p7 as a governing predicate");