From 4cca2f6915c01e593b785577aff1dfa9347b35ff Mon Sep 17 00:00:00 2001 From: Lioncache Date: Wed, 30 Jul 2025 11:07:08 -0400 Subject: [PATCH] ASIMDOps: Move base opcode into ASIMDAcrossLanes() --- CodeEmitter/CodeEmitter/ASIMDOps.inl | 171 ++++++++++++--------------- 1 file changed, 74 insertions(+), 97 deletions(-) diff --git a/CodeEmitter/CodeEmitter/ASIMDOps.inl b/CodeEmitter/CodeEmitter/ASIMDOps.inl index 7261b7262..5a58ec5a4 100644 --- a/CodeEmitter/CodeEmitter/ASIMDOps.inl +++ b/CodeEmitter/CodeEmitter/ASIMDOps.inl @@ -1363,136 +1363,113 @@ public: ///< size is the destination size. ///< source size is the next size up. template - void saddlv(ARMEmitter::SubRegSize size, T rd, T rn) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "64-bit subregsize not supported"); + void saddlv(SubRegSize size, T rd, T rn) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "64-bit subregsize not supported"); } - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i8Bit, "Destination 8-bit subregsize unsupported"); - constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; - const auto ConvertedSize = size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i32Bit : - size == ARMEmitter::SubRegSize::i32Bit ? ARMEmitter::SubRegSize::i16Bit : - ARMEmitter::SubRegSize::i8Bit; + LOGMAN_THROW_A_FMT(size != SubRegSize::i8Bit, "Destination 8-bit subregsize unsupported"); - ASIMDAcrossLanes(Op, 0, ConvertedSize, 0b00011, rd, rn); + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i32Bit : + size == SubRegSize::i32Bit ? SubRegSize::i16Bit : + SubRegSize::i8Bit; + + ASIMDAcrossLanes(0, ConvertedSize, 0b00011, rd, rn); } template - void smaxv(ARMEmitter::SubRegSize size, T rd, T rn) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i32Bit && size != ARMEmitter::SubRegSize::i64Bit, "32/64-bit subregsize not " - "supported"); + void smaxv(SubRegSize size, T rd, T rn) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i32Bit && size != SubRegSize::i64Bit, "32/64-bit subregsize not supported"); } - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Destination 64-bit subregsize unsupported"); - constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; - ASIMDAcrossLanes(Op, 0, size, 0b01010, rd, rn); + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Destination 64-bit subregsize unsupported"); + ASIMDAcrossLanes(0, size, 0b01010, rd, rn); } template - void sminv(ARMEmitter::SubRegSize size, T rd, T rn) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i32Bit && size != ARMEmitter::SubRegSize::i64Bit, "32/64-bit subregsize not " - "supported"); + void sminv(SubRegSize size, T rd, T rn) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i32Bit && size != SubRegSize::i64Bit, "32/64-bit subregsize not supported"); } - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Destination 64-bit subregsize unsupported"); - constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; - ASIMDAcrossLanes(Op, 0, size, 0b11010, rd, rn); + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Destination 64-bit subregsize unsupported"); + ASIMDAcrossLanes(0, size, 0b11010, rd, rn); } template - void addv(ARMEmitter::SubRegSize size, T rd, T rn) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i32Bit && size != ARMEmitter::SubRegSize::i64Bit, "32/64-bit subregsize not " - "supported"); + void addv(SubRegSize size, T rd, T rn) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i32Bit && size != SubRegSize::i64Bit, "32/64-bit subregsize not supported"); } - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Destination 64-bit subregsize unsupported"); - constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; - ASIMDAcrossLanes(Op, 0, size, 0b11011, rd, rn); + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Destination 64-bit subregsize unsupported"); + ASIMDAcrossLanes(0, size, 0b11011, rd, rn); } template - void uaddlv(ARMEmitter::SubRegSize size, T rd, T rn) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "64-bit subregsize not supported"); + void uaddlv(SubRegSize size, T rd, T rn) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "64-bit subregsize not supported"); } - constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; - const auto ConvertedSize = size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i32Bit : - size == ARMEmitter::SubRegSize::i32Bit ? ARMEmitter::SubRegSize::i16Bit : - ARMEmitter::SubRegSize::i8Bit; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i32Bit : + size == SubRegSize::i32Bit ? SubRegSize::i16Bit : + SubRegSize::i8Bit; - ASIMDAcrossLanes(Op, 1, ConvertedSize, 0b00011, rd, rn); + ASIMDAcrossLanes(1, ConvertedSize, 0b00011, rd, rn); } template - void umaxv(ARMEmitter::SubRegSize size, T rd, T rn) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i32Bit && size != ARMEmitter::SubRegSize::i64Bit, "32/64-bit subregsize not " - "supported"); + void umaxv(SubRegSize size, T rd, T rn) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i32Bit && size != SubRegSize::i64Bit, "32/64-bit subregsize not supported"); } - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Destination 64-bit subregsize unsupported"); - constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; - ASIMDAcrossLanes(Op, 1, size, 0b01010, rd, rn); + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Destination 64-bit subregsize unsupported"); + ASIMDAcrossLanes(1, size, 0b01010, rd, rn); } template - void uminv(ARMEmitter::SubRegSize size, T rd, T rn) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i32Bit && size != ARMEmitter::SubRegSize::i64Bit, "32/64-bit subregsize not " - "supported"); + void uminv(SubRegSize size, T rd, T rn) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i32Bit && size != SubRegSize::i64Bit, "32/64-bit subregsize not supported"); } - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Destination 64-bit subregsize unsupported"); - constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; - ASIMDAcrossLanes(Op, 1, size, 0b11010, rd, rn); + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Destination 64-bit subregsize unsupported"); + ASIMDAcrossLanes(1, size, 0b11010, rd, rn); } template - void fmaxnmv(ARMEmitter::SubRegSize size, T rd, T rn) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i32Bit, "32-bit subregsize not supported"); + void fmaxnmv(SubRegSize size, T rd, T rn) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i32Bit, "32-bit subregsize not supported"); } - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i8Bit && size != ARMEmitter::SubRegSize::i64Bit, "Destination 8/64-bit subregsize " - "unsupported"); - constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; - const auto ConvertedSize = size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + LOGMAN_THROW_A_FMT(size != SubRegSize::i8Bit && size != SubRegSize::i64Bit, "Destination 8/64-bit subregsize unsupported"); + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; + const auto U = size == SubRegSize::i16Bit ? 0 : 1; + ASIMDAcrossLanes(U, ConvertedSize, 0b01100, rd, rn); + } + template + void fmaxv(SubRegSize size, T rd, T rn) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i32Bit, "32-bit subregsize not supported"); + } + LOGMAN_THROW_A_FMT(size != SubRegSize::i8Bit && size != SubRegSize::i64Bit, "Destination 8/64-bit subregsize unsupported"); + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; const auto U = size == ARMEmitter::SubRegSize::i16Bit ? 0 : 1; - ASIMDAcrossLanes(Op, U, ConvertedSize, 0b01100, rd, rn); + ASIMDAcrossLanes(U, ConvertedSize, 0b01111, rd, rn); } template - void fmaxv(ARMEmitter::SubRegSize size, T rd, T rn) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i32Bit, "32-bit subregsize not supported"); + void fminnmv(SubRegSize size, T rd, T rn) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i32Bit, "32-bit subregsize not supported"); } - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i8Bit && size != ARMEmitter::SubRegSize::i64Bit, "Destination 8/64-bit subregsize " - "unsupported"); - constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; - const auto ConvertedSize = size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + LOGMAN_THROW_A_FMT(size != SubRegSize::i8Bit && size != SubRegSize::i64Bit, "Destination 8/64-bit subregsize unsupported"); + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i64Bit : SubRegSize::i32Bit; + const auto U = size == SubRegSize::i16Bit ? 0 : 1; - const auto U = size == ARMEmitter::SubRegSize::i16Bit ? 0 : 1; - - ASIMDAcrossLanes(Op, U, ConvertedSize, 0b01111, rd, rn); + ASIMDAcrossLanes(U, ConvertedSize, 0b01100, rd, rn); } template - void fminnmv(ARMEmitter::SubRegSize size, T rd, T rn) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i32Bit, "32-bit subregsize not supported"); + void fminv(SubRegSize size, T rd, T rn) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i32Bit, "32-bit subregsize not supported"); } - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i8Bit && size != ARMEmitter::SubRegSize::i64Bit, "Destination 8/64-bit subregsize " - "unsupported"); - constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; - const auto ConvertedSize = size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i64Bit : ARMEmitter::SubRegSize::i32Bit; + LOGMAN_THROW_A_FMT(size != SubRegSize::i8Bit && size != SubRegSize::i64Bit, "Destination 8/64-bit subregsize unsupported"); + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i64Bit : SubRegSize::i32Bit; + const auto U = size == SubRegSize::i16Bit ? 0 : 1; - const auto U = size == ARMEmitter::SubRegSize::i16Bit ? 0 : 1; - - ASIMDAcrossLanes(Op, U, ConvertedSize, 0b01100, rd, rn); - } - template - void fminv(ARMEmitter::SubRegSize size, T rd, T rn) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i32Bit, "32-bit subregsize not supported"); - } - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i8Bit && size != ARMEmitter::SubRegSize::i64Bit, "Destination 8/64-bit subregsize " - "unsupported"); - constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; - const auto ConvertedSize = size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i64Bit : ARMEmitter::SubRegSize::i32Bit; - - const auto U = size == ARMEmitter::SubRegSize::i16Bit ? 0 : 1; - - ASIMDAcrossLanes(Op, U, ConvertedSize, 0b01111, rd, rn); + ASIMDAcrossLanes(U, ConvertedSize, 0b01111, rd, rn); } // Advanced SIMD three different @@ -4476,10 +4453,10 @@ private: // Advanced SIMD across lanes template - void ASIMDAcrossLanes(uint32_t Op, uint32_t U, ARMEmitter::SubRegSize size, uint32_t opcode, T rd, T rn) { - constexpr uint32_t Q = std::is_same_v ? 1U << 30 : 0; + void ASIMDAcrossLanes(uint32_t U, SubRegSize size, uint32_t opcode, T rd, T rn) { + constexpr uint32_t Q = std::is_same_v ? 1U << 30 : 0; - uint32_t Instr = Op; + uint32_t Instr = 0b0000'1110'0011'0000'0000'10U << 10; Instr |= Q; Instr |= U << 29; Instr |= FEXCore::ToUnderlying(size) << 22;