diff --git a/CodeEmitter/CodeEmitter/ASIMDOps.inl b/CodeEmitter/CodeEmitter/ASIMDOps.inl index 4767033ed..093143bd5 100644 --- a/CodeEmitter/CodeEmitter/ASIMDOps.inl +++ b/CodeEmitter/CodeEmitter/ASIMDOps.inl @@ -302,8 +302,7 @@ public: } // Advanced SIMD copy - template - requires (std::is_same_v || std::is_same_v) + template void dup(SubRegSize size, T rd, T rn, uint32_t Index) { if constexpr (std::is_same_v) { LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit dup"); @@ -325,8 +324,7 @@ public: } // Advanced SIMD three same (FP16) - template - requires (std::is_same_v || std::is_same_v) + template void ASIMDThreeSameFP16(uint32_t U, uint32_t a, uint32_t opcode, T rm, T rn, T rd) { constexpr uint32_t Q = std::is_same_v ? 1U << 30 : 0; constexpr uint32_t Op = 0b0000'1110'0100'0000'0000'01 << 10; @@ -343,8 +341,7 @@ public: } // Advanced SIMD two-register miscellaneous (FP16) - template - requires (std::is_same_v || std::is_same_v) + template void ASIMDTwoRegMiscFP16(uint32_t U, uint32_t a, uint32_t opcode, T rn, T rd) { constexpr uint32_t Q = std::is_same_v ? 1U << 30 : 0; constexpr uint32_t Op = 0b0000'1110'0111'1000'0000'10 << 10; @@ -360,8 +357,7 @@ public: } // Advanced SIMD three-register extension - template - requires (std::is_same_v || std::is_same_v) + template void ASIMDThreeRegisterExt(uint32_t U, uint32_t opcode, ARMEmitter::SubRegSize size, T rm, T rn, T rd) { constexpr uint32_t Q = std::is_same_v ? 1U << 30 : 0; constexpr uint32_t Op = 0b0000'1110'0000'0000'1000'01 << 10; @@ -377,8 +373,7 @@ public: dc32(Instr); } - template - requires (std::is_same_v || std::is_same_v) + template void dup(SubRegSize size, T rd, Register rn) { if constexpr (std::is_same_v) { LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit dup"); @@ -500,282 +495,281 @@ public: } // Advanced SIMD three same (FP16) - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fmaxnm(T rd, T rn, T rm) { ASIMDThreeSameFP16(0, 0, 0b000, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fmla(T rd, T rn, T rm) { ASIMDThreeSameFP16(0, 0, 0b001, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fadd(T rd, T rn, T rm) { ASIMDThreeSameFP16(0, 0, 0b010, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fmulx(T rd, T rn, T rm) { ASIMDThreeSameFP16(0, 0, 0b011, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcmeq(T rd, T rn, T rm) { ASIMDThreeSameFP16(0, 0, 0b100, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fmax(T rd, T rn, T rm) { ASIMDThreeSameFP16(0, 0, 0b110, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void frecps(T rd, T rn, T rm) { ASIMDThreeSameFP16(0, 0, 0b111, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fminnm(T rd, T rn, T rm) { ASIMDThreeSameFP16(0, 1, 0b000, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fmls(T rd, T rn, T rm) { ASIMDThreeSameFP16(0, 1, 0b001, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fsub(T rd, T rn, T rm) { ASIMDThreeSameFP16(0, 1, 0b010, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fmin(T rd, T rn, T rm) { ASIMDThreeSameFP16(0, 1, 0b110, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void frsqrts(T rd, T rn, T rm) { ASIMDThreeSameFP16(0, 1, 0b111, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fmaxnmp(T rd, T rn, T rm) { ASIMDThreeSameFP16(1, 0, 0b000, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void faddp(T rd, T rn, T rm) { ASIMDThreeSameFP16(1, 0, 0b010, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fmul(T rd, T rn, T rm) { ASIMDThreeSameFP16(1, 0, 0b011, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcmge(T rd, T rn, T rm) { ASIMDThreeSameFP16(1, 0, 0b100, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void facge(T rd, T rn, T rm) { ASIMDThreeSameFP16(1, 0, 0b101, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fmaxp(T rd, T rn, T rm) { ASIMDThreeSameFP16(1, 0, 0b110, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fdiv(T rd, T rn, T rm) { ASIMDThreeSameFP16(1, 0, 0b111, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fminnmp(T rd, T rn, T rm) { ASIMDThreeSameFP16(1, 1, 0b000, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fabd(T rd, T rn, T rm) { ASIMDThreeSameFP16(1, 1, 0b010, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcmgt(T rd, T rn, T rm) { ASIMDThreeSameFP16(1, 1, 0b100, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void facgt(T rd, T rn, T rm) { ASIMDThreeSameFP16(1, 1, 0b101, rm, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fminp(T rd, T rn, T rm) { ASIMDThreeSameFP16(1, 1, 0b110, rm, rn, rd); } // Advanced SIMD two-register miscellaneous (FP16) - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void frintn(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 0, 0b11000, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void frintm(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 0, 0b11001, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcvtns(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 0, 0b11010, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcvtms(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 0, 0b11011, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcvtas(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 0, 0b11100, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void scvtf(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 0, 0b11101, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcmgt(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 1, 0b01100, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcmeq(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 1, 0b01101, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcmlt(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 1, 0b01110, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fabs(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 1, 0b01111, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void frintp(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 1, 0b11000, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void frintz(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 1, 0b11001, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcvtps(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 1, 0b11010, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcvtzs(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 1, 0b11011, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void frecpe(T rd, T rn) { ASIMDTwoRegMiscFP16(0, 1, 0b11101, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void frinta(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 0, 0b11000, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void frintx(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 0, 0b11001, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcvtnu(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 0, 0b11010, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcvtmu(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 0, 0b11011, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcvtau(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 0, 0b11100, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void ucvtf(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 0, 0b11101, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcmge(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 1, 0b01100, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcmle(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 1, 0b01101, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fneg(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 1, 0b01111, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void frinti(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 1, 0b11001, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcvtpu(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 1, 0b11010, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fcvtzu(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 1, 0b11011, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void frsqrte(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 1, 0b11101, rn, rd); } - template - requires (size == ARMEmitter::SubRegSize::i16Bit && (std::is_same_v || std::is_same_v)) + template + requires (size == ARMEmitter::SubRegSize::i16Bit) void fsqrt(T rd, T rn) { ASIMDTwoRegMiscFP16(1, 1, 0b11111, rn, rd); } // Advanced SIMD three-register extension - template - requires (std::is_same_v || std::is_same_v) + template void sdot(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { if constexpr (std::is_same_v) { LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "64-bit subregsize not supported"); @@ -783,30 +777,26 @@ public: ASIMDThreeRegisterExt(0, 0b0010, size, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void usdot(T rd, T rn, T rm) { ASIMDThreeRegisterExt(0, 0b0011, ARMEmitter::SubRegSize::i32Bit, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void sqrdmlah(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { if constexpr (std::is_same_v) { LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "64-bit subregsize not supported"); } ASIMDThreeRegisterExt(1, 0b0000, size, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void sqrdmlsh(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { if constexpr (std::is_same_v) { LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "64-bit subregsize not supported"); } ASIMDThreeRegisterExt(1, 0b0001, size, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void udot(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { if constexpr (std::is_same_v) { LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "64-bit subregsize not supported"); @@ -814,8 +804,7 @@ public: ASIMDThreeRegisterExt(1, 0b0010, size, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void fcmla(ARMEmitter::SubRegSize size, T rd, T rn, T rm, ARMEmitter::Rotation Rot) { LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i8Bit, "8-bit subregsize not supported"); @@ -824,8 +813,7 @@ public: } ASIMDThreeRegisterExt(1, 0b1000 | FEXCore::ToUnderlying(Rot), size, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void fcadd(ARMEmitter::SubRegSize size, T rd, T rn, T rm, ARMEmitter::Rotation Rot) { LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i8Bit, "8-bit subregsize not supported"); @@ -836,8 +824,7 @@ public: const uint32_t ConvertedRotation = Rot == ARMEmitter::Rotation::ROTATE_90 ? 0b00 : 0b10; ASIMDThreeRegisterExt(1, 0b1100 | ConvertedRotation, size, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void bfdot(T rd, T rn, T rm) { ASIMDThreeRegisterExt(1, 0b1111, ARMEmitter::SubRegSize::i16Bit, rm, rn, rd); } @@ -861,16 +848,14 @@ public: } // Advanced SIMD two-register miscellaneous - template - requires (std::is_same_v || std::is_same_v) + template void rev64(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "64-bit subregsize not supported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; ASIMD2RegMisc(Op, 0, size, 0b00000, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void rev16(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i8Bit, "Only 8-bit subregsize supported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; @@ -879,8 +864,7 @@ public: ///< size is the destination size. ///< source size is the next size up. - template - requires (std::is_same_v || std::is_same_v) + template void saddlp(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i8Bit, "Destination 8-bit subregsize unsupported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; @@ -892,8 +876,7 @@ public: ASIMD2RegMisc(Op, 0, ConvertedSize, 0b00010, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void suqadd(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"); @@ -902,15 +885,13 @@ public: ASIMD2RegMisc(Op, 0, size, 0b00011, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void cls(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "64-bit subregsize not supported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; ASIMD2RegMisc(Op, 0, size, 0b00100, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void cnt(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i8Bit, "Only 8-bit subregsize supported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; @@ -919,8 +900,7 @@ public: ///< size is the destination size. ///< source size is the next size up. - template - requires (std::is_same_v || std::is_same_v) + template void sadalp(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i8Bit, "Destination 8-bit subregsize unsupported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; @@ -932,8 +912,7 @@ public: ASIMD2RegMisc(Op, 0, ConvertedSize, 0b00110, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void sqabs(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"); @@ -942,8 +921,7 @@ public: ASIMD2RegMisc(Op, 0, size, 0b00111, rd, rn); } // Comparison against zero - template - requires (std::is_same_v || std::is_same_v) + template void cmgt(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"); @@ -952,8 +930,7 @@ public: ASIMD2RegMisc(Op, 0, size, 0b01000, rd, rn); } // Comparison against zero - template - requires (std::is_same_v || std::is_same_v) + template void cmeq(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"); @@ -962,8 +939,7 @@ public: ASIMD2RegMisc(Op, 0, size, 0b01001, rd, rn); } // Comparison against zero - template - requires (std::is_same_v || std::is_same_v) + template void cmlt(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"); @@ -971,8 +947,7 @@ public: constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; ASIMD2RegMisc(Op, 0, size, 0b01010, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void abs(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"); @@ -1053,8 +1028,7 @@ public: ASIMD2RegMisc(Op, 0, ConvertedSize, 0b10111, rd.Q(), rn.Q()); } - template - requires (std::is_same_v || std::is_same_v) + template void frintn(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"); @@ -1066,8 +1040,7 @@ public: ASIMD2RegMisc(Op, 0, ConvertedSize, 0b11000, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void frintm(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"); @@ -1080,8 +1053,7 @@ public: ASIMD2RegMisc(Op, 0, ConvertedSize, 0b11001, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcvtns(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"); @@ -1093,8 +1065,7 @@ public: ASIMD2RegMisc(Op, 0, ConvertedSize, 0b11010, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcvtms(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"); @@ -1106,8 +1077,7 @@ public: ASIMD2RegMisc(Op, 0, ConvertedSize, 0b11011, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcvtas(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"); @@ -1119,8 +1089,7 @@ public: ASIMD2RegMisc(Op, 0, ConvertedSize, 0b11100, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void scvtf(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"); @@ -1132,8 +1101,7 @@ public: ASIMD2RegMisc(Op, 0, ConvertedSize, 0b11101, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void frint32z(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"); @@ -1145,8 +1113,7 @@ public: ASIMD2RegMisc(Op, 0, ConvertedSize, 0b11110, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void frint64z(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"); @@ -1159,8 +1126,7 @@ public: ASIMD2RegMisc(Op, 0, ConvertedSize, 0b11111, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcmgt(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"); @@ -1171,8 +1137,7 @@ public: ASIMD2RegMisc(Op, 0, size, 0b01100, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcmeq(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"); @@ -1183,8 +1148,7 @@ public: ASIMD2RegMisc(Op, 0, size, 0b01101, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcmlt(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"); @@ -1195,8 +1159,7 @@ public: ASIMD2RegMisc(Op, 0, size, 0b01110, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fabs(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"); @@ -1207,8 +1170,7 @@ public: ASIMD2RegMisc(Op, 0, size, 0b01111, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void frintp(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"); @@ -1219,8 +1181,7 @@ public: ASIMD2RegMisc(Op, 0, size, 0b11000, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void frintz(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"); @@ -1231,8 +1192,7 @@ public: ASIMD2RegMisc(Op, 0, size, 0b11001, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcvtps(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"); @@ -1243,8 +1203,7 @@ public: ASIMD2RegMisc(Op, 0, size, 0b11010, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcvtzs(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"); @@ -1255,16 +1214,14 @@ public: ASIMD2RegMisc(Op, 0, size, 0b11011, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void urecpe(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit subregsize supported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; ASIMD2RegMisc(Op, 0, size, 0b11100, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void frecpe(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit & 64-bit subregsize " "supported"); @@ -1272,8 +1229,7 @@ public: ASIMD2RegMisc(Op, 0, size, 0b11101, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void rev32(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i8Bit || size == ARMEmitter::SubRegSize::i16Bit, "Only 8-bit & 16-bit subregsize " "supported"); @@ -1283,8 +1239,7 @@ public: ///< size is the destination size. ///< source size is the next size up. - template - requires (std::is_same_v || std::is_same_v) + template void uaddlp(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i8Bit, "Destination 8-bit subregsize unsupported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; @@ -1296,8 +1251,7 @@ public: ASIMD2RegMisc(Op, 1, ConvertedSize, 0b00010, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void usqadd(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"); @@ -1306,8 +1260,7 @@ public: ASIMD2RegMisc(Op, 1, size, 0b00011, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void clz(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "64-bit subregsize not supported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; @@ -1316,8 +1269,7 @@ public: ///< size is the destination size. ///< source size is the next size up. - template - requires (std::is_same_v || std::is_same_v) + template void uadalp(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i8Bit, "Destination 8-bit subregsize unsupported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; @@ -1329,8 +1281,7 @@ public: ASIMD2RegMisc(Op, 1, ConvertedSize, 0b00110, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void sqneg(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"); @@ -1340,8 +1291,7 @@ public: } // Comparison against zero - template - requires (std::is_same_v || std::is_same_v) + template void cmge(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"); @@ -1350,8 +1300,7 @@ public: ASIMD2RegMisc(Op, 1, size, 0b01000, rd, rn); } // Comparison against zero - template - requires (std::is_same_v || std::is_same_v) + template void cmle(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"); @@ -1359,8 +1308,7 @@ public: constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; ASIMD2RegMisc(Op, 1, size, 0b01001, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void neg(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"); @@ -1441,8 +1389,7 @@ public: ASIMD2RegMisc(Op, 1, ConvertedSize, 0b10110, rd.Q(), rn.Q()); } - template - requires (std::is_same_v || std::is_same_v) + template void frinta(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit & 64-bit subregsize " "supported"); @@ -1453,8 +1400,7 @@ public: ASIMD2RegMisc(Op, 1, ConvertedSize, 0b11000, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void frintx(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit & 64-bit subregsize " "supported"); @@ -1466,8 +1412,7 @@ public: ASIMD2RegMisc(Op, 1, ConvertedSize, 0b11001, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcvtnu(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit & 64-bit subregsize " "supported"); @@ -1478,8 +1423,7 @@ public: ASIMD2RegMisc(Op, 1, ConvertedSize, 0b11010, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcvtmu(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit & 64-bit subregsize " "supported"); @@ -1490,8 +1434,7 @@ public: ASIMD2RegMisc(Op, 1, ConvertedSize, 0b11011, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcvtau(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit & 64-bit subregsize " "supported"); @@ -1502,8 +1445,7 @@ public: ASIMD2RegMisc(Op, 1, ConvertedSize, 0b11100, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void ucvtf(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit & 64-bit subregsize " "supported"); @@ -1514,8 +1456,7 @@ public: ASIMD2RegMisc(Op, 1, ConvertedSize, 0b11101, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void frint32x(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit & 64-bit subregsize " "supported"); @@ -1526,8 +1467,7 @@ public: ASIMD2RegMisc(Op, 1, ConvertedSize, 0b11110, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void frint64x(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit & 64-bit subregsize " "supported"); @@ -1539,31 +1479,27 @@ public: ASIMD2RegMisc(Op, 1, ConvertedSize, 0b11111, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void not_(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i8Bit, "Only 8-bit subregsize supported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; ASIMD2RegMisc(Op, 1, ARMEmitter::SubRegSize::i8Bit, 0b00101, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void mvn(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i8Bit, "Only 8-bit subregsize supported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; ASIMD2RegMisc(Op, 1, ARMEmitter::SubRegSize::i8Bit, 0b00101, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void rbit(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i8Bit, "Only 8-bit subregsize supported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; ASIMD2RegMisc(Op, 1, ARMEmitter::SubRegSize::i16Bit, 0b00101, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcmge(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"); @@ -1573,8 +1509,7 @@ public: constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; ASIMD2RegMisc(Op, 1, size, 0b01100, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcmle(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"); @@ -1585,8 +1520,7 @@ public: ASIMD2RegMisc(Op, 1, size, 0b01101, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fneg(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"); @@ -1597,8 +1531,7 @@ public: ASIMD2RegMisc(Op, 1, size, 0b01111, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void frinti(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"); @@ -1609,8 +1542,7 @@ public: ASIMD2RegMisc(Op, 1, size, 0b11001, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcvtpu(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"); @@ -1620,8 +1552,7 @@ public: constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; ASIMD2RegMisc(Op, 1, size, 0b11010, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fcvtzu(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"); @@ -1632,15 +1563,13 @@ public: ASIMD2RegMisc(Op, 1, size, 0b11011, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void ursqrte(ARMEmitter::SubRegSize size, T rd, T rn) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit & 64-bit subregsize supported"); constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'10 << 10; ASIMD2RegMisc(Op, 1, size, 0b11100, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void frsqrte(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"); @@ -1651,8 +1580,7 @@ public: ASIMD2RegMisc(Op, 1, size, 0b11101, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + template void fsqrt(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"); @@ -1666,8 +1594,7 @@ public: // Advanced SIMD across lanes ///< size is the destination size. ///< source size is the next size up. - template - requires (std::is_same_v || std::is_same_v) + 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"); @@ -1682,8 +1609,7 @@ public: ASIMDAcrossLanes(Op, 0, ConvertedSize, 0b00011, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + 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 " @@ -1693,8 +1619,7 @@ public: constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; ASIMDAcrossLanes(Op, 0, size, 0b01010, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + 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 " @@ -1704,8 +1629,7 @@ public: constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; ASIMDAcrossLanes(Op, 0, size, 0b11010, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + 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 " @@ -1715,8 +1639,7 @@ public: constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; ASIMDAcrossLanes(Op, 0, size, 0b11011, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + 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"); @@ -1729,8 +1652,7 @@ public: ASIMDAcrossLanes(Op, 1, ConvertedSize, 0b00011, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + 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 " @@ -1740,8 +1662,7 @@ public: constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; ASIMDAcrossLanes(Op, 1, size, 0b01010, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + 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 " @@ -1751,8 +1672,7 @@ public: constexpr uint32_t Op = 0b0000'1110'0011'0000'0000'10 << 10; ASIMDAcrossLanes(Op, 1, size, 0b11010, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + 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"); @@ -1769,8 +1689,7 @@ public: ASIMDAcrossLanes(Op, U, ConvertedSize, 0b01100, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + 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"); @@ -1787,8 +1706,7 @@ public: ASIMDAcrossLanes(Op, U, ConvertedSize, 0b01111, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + 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"); @@ -1805,8 +1723,7 @@ public: ASIMDAcrossLanes(Op, U, ConvertedSize, 0b01100, rd, rn); } - template - requires (std::is_same_v || std::is_same_v) + 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"); @@ -3851,8 +3768,7 @@ public: } ASIMDVectorXIndexedElement(0b0, L, M, 0b0111, H, EncodedSubRegSize, rm.Q(), rn.Q(), rd.Q()); } - template - requires (std::is_same_v || std::is_same_v) + template void mul(ARMEmitter::SubRegSize size, T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i16Bit || size == ARMEmitter::SubRegSize::i32Bit, "Invalid destination size"); @@ -3976,8 +3892,7 @@ public: } ASIMDVectorXIndexedElement(0b0, L, M, 0b1011, H, EncodedSubRegSize, rm.Q(), rn.Q(), rd.Q()); } - template - requires (std::is_same_v || std::is_same_v) + template void sqdmulh(ARMEmitter::SubRegSize size, T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i16Bit || size == ARMEmitter::SubRegSize::i32Bit, "Invalid destination size"); @@ -4001,8 +3916,7 @@ public: } ASIMDVectorXIndexedElement(0b0, L, M, 0b1100, H, size, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void sqrdmulh(ARMEmitter::SubRegSize size, T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i16Bit || size == ARMEmitter::SubRegSize::i32Bit, "Invalid destination size"); @@ -4027,8 +3941,7 @@ public: ASIMDVectorXIndexedElement(0b0, L, M, 0b1101, H, size, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void sdot(T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(Index < 4, "Index must be less than the source register size"); @@ -4041,8 +3954,7 @@ public: ASIMDVectorXIndexedElement(0b0, L, M, 0b1110, H, ARMEmitter::SubRegSize::i32Bit, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void sudot(T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(Index < 4, "Index must be less than the source register size"); @@ -4055,8 +3967,7 @@ public: ASIMDVectorXIndexedElement(0b0, L, M, 0b1111, H, ARMEmitter::SubRegSize::i8Bit, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void bfdot(T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(Index < 4, "Index must be less than the source register size"); @@ -4069,8 +3980,7 @@ public: ASIMDVectorXIndexedElement(0b0, L, M, 0b1111, H, ARMEmitter::SubRegSize::i16Bit, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void fmla(ARMEmitter::SubRegSize size, T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i16Bit || size == ARMEmitter::SubRegSize::i32Bit || size == ARMEmitter::SubRegSize::i64Bit, "Invalid destination size"); @@ -4101,8 +4011,7 @@ public: ASIMDVectorXIndexedElement(0b0, L, M, 0b0001, H, EncodedSubRegSize, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void fmls(ARMEmitter::SubRegSize size, T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i16Bit || size == ARMEmitter::SubRegSize::i32Bit || size == ARMEmitter::SubRegSize::i64Bit, "Invalid destination size"); @@ -4133,8 +4042,7 @@ public: ASIMDVectorXIndexedElement(0b0, L, M, 0b0101, H, EncodedSubRegSize, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void fmul(ARMEmitter::SubRegSize size, T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i16Bit || size == ARMEmitter::SubRegSize::i32Bit || size == ARMEmitter::SubRegSize::i64Bit, "Invalid destination size"); @@ -4165,8 +4073,7 @@ public: ASIMDVectorXIndexedElement(0b0, L, M, 0b1001, H, EncodedSubRegSize, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void fmlal(T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(Index < 8, "Index must be less than the source register size"); @@ -4179,8 +4086,7 @@ public: ASIMDVectorXIndexedElement(0b0, L, M, 0b0000, H, ARMEmitter::SubRegSize::i32Bit, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void fmlal2(T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(Index < 8, "Index must be less than the source register size"); @@ -4193,8 +4099,7 @@ public: ASIMDVectorXIndexedElement(0b1, L, M, 0b1000, H, ARMEmitter::SubRegSize::i32Bit, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void fmlsl(T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(Index < 8, "Index must be less than the source register size"); @@ -4207,8 +4112,7 @@ public: ASIMDVectorXIndexedElement(0b0, L, M, 0b0100, H, ARMEmitter::SubRegSize::i32Bit, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void fmlsl2(T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(Index < 8, "Index must be less than the source register size"); @@ -4221,8 +4125,7 @@ public: ASIMDVectorXIndexedElement(0b1, L, M, 0b1100, H, ARMEmitter::SubRegSize::i32Bit, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void usdot(T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(Index < 4, "Index must be less than the source register size"); @@ -4260,8 +4163,7 @@ public: ASIMDVectorXIndexedElement(0b0, L, M, 0b1111, H, ARMEmitter::SubRegSize::i64Bit, rm.Q(), rn.Q(), rd.Q()); } - template - requires (std::is_same_v || std::is_same_v) + template void mla(ARMEmitter::SubRegSize size, T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i16Bit || size == ARMEmitter::SubRegSize::i32Bit, "Invalid destination size"); @@ -4337,8 +4239,7 @@ public: ASIMDVectorXIndexedElement(0b1, L, M, 0b0010, H, EncodedSubRegSize, rm.Q(), rn.Q(), rd.Q()); } - template - requires (std::is_same_v || std::is_same_v) + template void mls(ARMEmitter::SubRegSize size, T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i16Bit || size == ARMEmitter::SubRegSize::i32Bit, "Invalid destination size"); @@ -4465,8 +4366,7 @@ public: ASIMDVectorXIndexedElement(0b1, L, M, 0b1010, H, EncodedSubRegSize, rm.Q(), rn.Q(), rd.Q()); } - template - requires (std::is_same_v || std::is_same_v) + template void sqrdmlah(ARMEmitter::SubRegSize size, T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i16Bit || size == ARMEmitter::SubRegSize::i32Bit, "Invalid destination size"); @@ -4490,8 +4390,7 @@ public: } ASIMDVectorXIndexedElement(0b1, L, M, 0b1101, H, size, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void udot(T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(Index < 4, "Index must be less than the source register size"); @@ -4504,8 +4403,7 @@ public: ASIMDVectorXIndexedElement(0b1, L, M, 0b1110, H, ARMEmitter::SubRegSize::i32Bit, rm, rn, rd); } - template - requires (std::is_same_v || std::is_same_v) + template void sqrdmlsh(ARMEmitter::SubRegSize size, T rd, T rn, T rm, uint32_t Index) { LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i16Bit || size == ARMEmitter::SubRegSize::i32Bit, "Invalid destination size"); @@ -4907,8 +4805,7 @@ private: } // Advanced SIMD two-register miscellaneous - template - requires (std::is_same_v || std::is_same_v) + template void ASIMD2RegMisc(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; @@ -4923,8 +4820,7 @@ private: } // Advanced SIMD across lanes - template - requires (std::is_same_v || std::is_same_v) + 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; @@ -4939,8 +4835,7 @@ private: } // Advanced SIMD three different - template - requires (std::is_same_v || std::is_same_v) + template void ASIMD3Different(uint32_t Op, uint32_t U, uint32_t opcode, ARMEmitter::SubRegSize size, T rd, T rn, T rm) { constexpr uint32_t Q = std::is_same_v ? 1U << 30 : 0; @@ -4956,8 +4851,7 @@ private: } // Advanced SIMD three same - template - requires (std::is_same_v || std::is_same_v) + template void ASIMD3Same(uint32_t Op, uint32_t U, ARMEmitter::SubRegSize size, uint32_t opcode, T rd, T rn, T rm) { constexpr uint32_t Q = std::is_same_v ? 1U << 30 : 0; @@ -4973,8 +4867,7 @@ private: } // Advanced SIMD modified immediate - template - requires (std::is_same_v || std::is_same_v) + template void ASIMDModifiedImm(uint32_t Op, uint32_t op, uint32_t cmode, uint32_t o2, uint32_t imm, T rd) { constexpr uint32_t Q = std::is_same_v ? 1U << 30 : 0; @@ -4997,8 +4890,7 @@ private: } // Advanced SIMD shift by immediate - template - requires (std::is_same_v || std::is_same_v) + template void ASIMDShiftByImm(uint32_t Op, uint32_t U, uint32_t immh, uint32_t immb, uint32_t opcode, T rn, T rd) { constexpr uint32_t Q = std::is_same_v ? 1U << 30 : 0; LOGMAN_THROW_A_FMT(immh != 0, "ImmH needs to not be zero"); @@ -5016,8 +4908,7 @@ private: } // Advanced SIMD vector x indexed element - template - requires (std::is_same_v || std::is_same_v) + template void ASIMDVectorXIndexedElement(uint32_t U, uint32_t L, uint32_t M, uint32_t opcode, uint32_t H, ARMEmitter::SubRegSize size, T rm, T rn, T rd) { constexpr uint32_t Op = 0b0000'1111'0000'0000'0000'00 << 10; constexpr uint32_t Q = std::is_same_v ? 1U << 30 : 0; @@ -5115,8 +5006,7 @@ private: dc32(Instr); } - template - requires (std::is_same_v || std::is_same_v) + template void ASIMDLoadStoreMultipleStructure(uint32_t Op, uint32_t opcode, T rt, ARMEmitter::Register rn, ARMEmitter::Register rm) { constexpr uint32_t Q = std::is_same_v ? 1U << 30 : 0; diff --git a/CodeEmitter/CodeEmitter/Emitter.h b/CodeEmitter/CodeEmitter/Emitter.h index 0213c1977..c48705f08 100644 --- a/CodeEmitter/CodeEmitter/Emitter.h +++ b/CodeEmitter/CodeEmitter/Emitter.h @@ -573,6 +573,10 @@ enum class Rotation : uint32_t { template concept IsXOrWRegister = std::is_same_v || std::is_same_v; +// Concept for contraining some instructions to accept only a QRegister or DRegister. +template +concept IsQOrDRegister = std::is_same_v || std::is_same_v; + // Whether or not a given set of vector registers are sequential // in increasing order as far as the register file is concerned (modulo its size) // diff --git a/CodeEmitter/CodeEmitter/LoadstoreOps.inl b/CodeEmitter/CodeEmitter/LoadstoreOps.inl index 80f867cdb..d7728543d 100644 --- a/CodeEmitter/CodeEmitter/LoadstoreOps.inl +++ b/CodeEmitter/CodeEmitter/LoadstoreOps.inl @@ -416,8 +416,7 @@ public: 0; ASIMDSTLD(Op, Opcode, rt, Index, rn, Reg::r0); } - template - requires (std::is_same_v || std::is_same_v) + template void ld1r(T rt, Register rn) { constexpr uint32_t Op = 0b0000'1101'000 << 21; constexpr uint32_t Opcode = 0b110; @@ -435,8 +434,7 @@ public: 0; ASIMDSTLD(Op, Opcode, rt, Index, rn, Reg::r0); } - template - requires (std::is_same_v || std::is_same_v) + template void ld2r(T rt, T rt2, Register rn) { LOGMAN_THROW_A_FMT(AreVectorsSequential(rt, rt2), "rt and rt2 must be sequential"); constexpr uint32_t Op = 0b0000'1101'000 << 21; @@ -455,8 +453,7 @@ public: 0; ASIMDSTLD(Op, Opcode, rt, Index, rn, Reg::r0); } - template - requires (std::is_same_v || std::is_same_v) + template void ld3r(T rt, T rt2, T rt3, Register rn) { LOGMAN_THROW_A_FMT(AreVectorsSequential(rt, rt2, rt3), "rt, rt2, and rt3 must be sequential"); constexpr uint32_t Op = 0b0000'1101'000 << 21; @@ -475,8 +472,7 @@ public: 0; ASIMDSTLD(Op, Opcode, rt, Index, rn, Reg::r0); } - template - requires (std::is_same_v || std::is_same_v) + template void ld4r(T rt, T rt2, T rt3, T rt4, Register rn) { LOGMAN_THROW_A_FMT(AreVectorsSequential(rt, rt2, rt3, rt4), "rt, rt2, rt3, and rt4 must be sequential"); constexpr uint32_t Op = 0b0000'1101'000 << 21;