diff --git a/CodeEmitter/CodeEmitter/ASIMDOps.inl b/CodeEmitter/CodeEmitter/ASIMDOps.inl index 413fe3edf..9e0d2827a 100644 --- a/CodeEmitter/CodeEmitter/ASIMDOps.inl +++ b/CodeEmitter/CodeEmitter/ASIMDOps.inl @@ -444,133 +444,6 @@ public: ASIMDScalarCopy(Op, 1, imm5, imm4, rd, rn); } - // Advanced SIMD three same (FP16) - 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) - void fmla(T rd, T rn, T rm) { - ASIMDThreeSameFP16(0, 0, 0b001, rm, rn, rd); - } - - 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) - void fmulx(T rd, T rn, T rm) { - ASIMDThreeSameFP16(0, 0, 0b011, rm, rn, rd); - } - - 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) - void fmax(T rd, T rn, T rm) { - ASIMDThreeSameFP16(0, 0, 0b110, rm, rn, rd); - } - 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) - void fminnm(T rd, T rn, T rm) { - ASIMDThreeSameFP16(0, 1, 0b000, rm, rn, rd); - } - 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) - void fsub(T rd, T rn, T rm) { - ASIMDThreeSameFP16(0, 1, 0b010, rm, rn, rd); - } - 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) - void frsqrts(T rd, T rn, T rm) { - ASIMDThreeSameFP16(0, 1, 0b111, rm, rn, rd); - } - 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) - void faddp(T rd, T rn, T rm) { - ASIMDThreeSameFP16(1, 0, 0b010, rm, rn, rd); - } - 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) - void fcmge(T rd, T rn, T rm) { - ASIMDThreeSameFP16(1, 0, 0b100, rm, rn, rd); - } - 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) - void fmaxp(T rd, T rn, T rm) { - ASIMDThreeSameFP16(1, 0, 0b110, rm, rn, rd); - } - 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) - void fminnmp(T rd, T rn, T rm) { - ASIMDThreeSameFP16(1, 1, 0b000, rm, rn, rd); - } - 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) - void fcmgt(T rd, T rn, T rm) { - ASIMDThreeSameFP16(1, 1, 0b100, rm, rn, rd); - } - 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) - void fminp(T rd, T rn, T rm) { - ASIMDThreeSameFP16(1, 1, 0b110, rm, rn, rd); - } - // Advanced SIMD three-register extension template void sdot(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { @@ -2241,102 +2114,116 @@ public: ASIMD3Same(Op, 0, size, 0b10111, rd, rn, rm); } template - void fmaxnm(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fmaxnm(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(0, 0, 0b000, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 0, ConvertedSize, 0b11000, rd, rn, rm); + ASIMD3Same(Op, 0, ConvertedSize, 0b11000, rd, rn, rm); + } } template - void fmla(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fmla(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(0, 0, 0b001, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 0, ConvertedSize, 0b11001, rd, rn, rm); + ASIMD3Same(Op, 0, ConvertedSize, 0b11001, rd, rn, rm); + } } template - void fadd(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fadd(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(0, 0, 0b010, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 0, ConvertedSize, 0b11010, rd, rn, rm); + ASIMD3Same(Op, 0, ConvertedSize, 0b11010, rd, rn, rm); + } } template - void fmulx(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fmulx(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(0, 0, 0b011, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 0, ConvertedSize, 0b11011, rd, rn, rm); + ASIMD3Same(Op, 0, ConvertedSize, 0b11011, rd, rn, rm); + } } template - void fcmeq(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fcmeq(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(0, 0, 0b100, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 0, ConvertedSize, 0b11100, rd, rn, rm); + ASIMD3Same(Op, 0, ConvertedSize, 0b11100, rd, rn, rm); + } } template - void fmax(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fmax(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(0, 0, 0b110, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 0, ConvertedSize, 0b11110, rd, rn, rm); + ASIMD3Same(Op, 0, ConvertedSize, 0b11110, rd, rn, rm); + } } template - void frecps(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void frecps(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(0, 0, 0b111, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 0, ConvertedSize, 0b11111, rd, rn, rm); + ASIMD3Same(Op, 0, ConvertedSize, 0b11111, rd, rn, rm); + } } template void and_(T rd, T rn, T rm) { @@ -2359,59 +2246,74 @@ public: ASIMD3Same(Op, 0, ARMEmitter::SubRegSize::i16Bit, 0b00011, rd, rn, rm); } template - void fminnm(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fminnm(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - ASIMD3Same(Op, 0, size, 0b11000, rd, rn, rm); + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(0, 1, 0b000, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + ASIMD3Same(Op, 0, size, 0b11000, rd, rn, rm); + } } template - void fmls(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fmls(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - ASIMD3Same(Op, 0, size, 0b11001, rd, rn, rm); + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(0, 1, 0b001, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + ASIMD3Same(Op, 0, size, 0b11001, rd, rn, rm); + } } template - void fsub(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fsub(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - ASIMD3Same(Op, 0, size, 0b11010, rd, rn, rm); + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(0, 1, 0b010, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + ASIMD3Same(Op, 0, size, 0b11010, rd, rn, rm); + } } template - void fmin(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fmin(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - ASIMD3Same(Op, 0, size, 0b11110, rd, rn, rm); + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(0, 1, 0b110, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + ASIMD3Same(Op, 0, size, 0b11110, rd, rn, rm); + } } template - void frsqrts(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void frsqrts(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - ASIMD3Same(Op, 0, size, 0b11111, rd, rn, rm); + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(0, 1, 0b111, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + ASIMD3Same(Op, 0, size, 0b11111, rd, rn, rm); + } } template void orr(T rd, T rn, T rm) { @@ -2582,102 +2484,116 @@ public: ASIMD3Same(Op, 1, size, 0b10110, rd, rn, rm); } template - void fmaxnmp(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fmaxnmp(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(1, 0, 0b000, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 1, ConvertedSize, 0b11000, rd, rn, rm); + ASIMD3Same(Op, 1, ConvertedSize, 0b11000, rd, rn, rm); + } } template - void faddp(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void faddp(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(1, 0, 0b010, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 1, ConvertedSize, 0b11010, rd, rn, rm); + ASIMD3Same(Op, 1, ConvertedSize, 0b11010, rd, rn, rm); + } } template - void fmul(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fmul(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(1, 0, 0b011, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 1, ConvertedSize, 0b11011, rd, rn, rm); + ASIMD3Same(Op, 1, ConvertedSize, 0b11011, rd, rn, rm); + } } template - void fcmge(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fcmge(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(1, 0, 0b100, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 1, ConvertedSize, 0b11100, rd, rn, rm); + ASIMD3Same(Op, 1, ConvertedSize, 0b11100, rd, rn, rm); + } } template - void facge(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void facge(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(1, 0, 0b101, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 1, ConvertedSize, 0b11101, rd, rn, rm); + ASIMD3Same(Op, 1, ConvertedSize, 0b11101, rd, rn, rm); + } } template - void fmaxp(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fmaxp(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(1, 0, 0b110, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 1, ConvertedSize, 0b11110, rd, rn, rm); + ASIMD3Same(Op, 1, ConvertedSize, 0b11110, rd, rn, rm); + } } template - void fdiv(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fdiv(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - const ARMEmitter::SubRegSize ConvertedSize = - size == ARMEmitter::SubRegSize::i64Bit ? ARMEmitter::SubRegSize::i16Bit : ARMEmitter::SubRegSize::i8Bit; + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(1, 0, 0b111, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + const auto ConvertedSize = size == SubRegSize::i64Bit ? SubRegSize::i16Bit : SubRegSize::i8Bit; - ASIMD3Same(Op, 1, ConvertedSize, 0b11111, rd, rn, rm); + ASIMD3Same(Op, 1, ConvertedSize, 0b11111, rd, rn, rm); + } } template void eor(T rd, T rn, T rm) { @@ -2690,59 +2606,74 @@ public: ASIMD3Same(Op, 1, ARMEmitter::SubRegSize::i16Bit, 0b00011, rd, rn, rm); } template - void fminnmp(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fminnmp(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - ASIMD3Same(Op, 1, size, 0b11000, rd, rn, rm); + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(1, 1, 0b000, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + ASIMD3Same(Op, 1, size, 0b11000, rd, rn, rm); + } } template - void fabd(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fabd(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - ASIMD3Same(Op, 1, size, 0b11010, rd, rn, rm); + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(1, 1, 0b010, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + ASIMD3Same(Op, 1, size, 0b11010, rd, rn, rm); + } } template - void fcmgt(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fcmgt(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - ASIMD3Same(Op, 1, size, 0b11100, rd, rn, rm); + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(1, 1, 0b100, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + ASIMD3Same(Op, 1, size, 0b11100, rd, rn, rm); + } } template - void facgt(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void facgt(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - ASIMD3Same(Op, 1, size, 0b11101, rd, rn, rm); + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(1, 1, 0b101, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + ASIMD3Same(Op, 1, size, 0b11101, rd, rn, rm); + } } template - void fminp(ARMEmitter::SubRegSize size, T rd, T rn, T rm) { - if constexpr (std::is_same_v) { - LOGMAN_THROW_A_FMT(size != ARMEmitter::SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); + void fminp(SubRegSize size, T rd, T rn, T rm) { + if constexpr (std::is_same_v) { + LOGMAN_THROW_A_FMT(size != SubRegSize::i64Bit, "Invalid element size with 64-bit {}", __func__); } - LOGMAN_THROW_A_FMT(size == ARMEmitter::SubRegSize::i64Bit || size == ARMEmitter::SubRegSize::i32Bit, "Only 32-bit and 64-bit " - "subregsize supported"); + LOGMAN_THROW_A_FMT(IsStandardFloatSize(size), "Only 16/32/64-bit subregsize supported"); - constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; - ASIMD3Same(Op, 1, size, 0b11110, rd, rn, rm); + if (size == SubRegSize::i16Bit) { + ASIMDThreeSameFP16(1, 1, 0b110, rm, rn, rd); + } else { + constexpr uint32_t Op = 0b0000'1110'0010'0000'0000'01 << 10; + ASIMD3Same(Op, 1, size, 0b11110, rd, rn, rm); + } } template void bit(T rd, T rn, T rm) { diff --git a/FEXCore/unittests/Emitter/ASIMD_Tests.cpp b/FEXCore/unittests/Emitter/ASIMD_Tests.cpp index e43a93ad9..0ff45ca9e 100644 --- a/FEXCore/unittests/Emitter/ASIMD_Tests.cpp +++ b/FEXCore/unittests/Emitter/ASIMD_Tests.cpp @@ -262,30 +262,30 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: ASIMD: Advanced SIMD copy") { TEST_SINGLE(ins(SubRegSize::i64Bit, VReg::v30, 1, VReg::v29, 0), "mov v30.d[1], v29.d[0]"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: ASIMD: Advanced SIMD three same (FP16)") { - TEST_SINGLE(fmaxnm(QReg::q30, QReg::q29, QReg::q28), "fmaxnm v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fmla(QReg::q30, QReg::q29, QReg::q28), "fmla v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fadd(QReg::q30, QReg::q29, QReg::q28), "fadd v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fmulx(QReg::q30, QReg::q29, QReg::q28), "fmulx v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fcmeq(QReg::q30, QReg::q29, QReg::q28), "fcmeq v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fmax(QReg::q30, QReg::q29, QReg::q28), "fmax v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(frecps(QReg::q30, QReg::q29, QReg::q28), "frecps v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fminnm(QReg::q30, QReg::q29, QReg::q28), "fminnm v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fmls(QReg::q30, QReg::q29, QReg::q28), "fmls v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fsub(QReg::q30, QReg::q29, QReg::q28), "fsub v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fmin(QReg::q30, QReg::q29, QReg::q28), "fmin v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(frsqrts(QReg::q30, QReg::q29, QReg::q28), "frsqrts v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fmaxnmp(QReg::q30, QReg::q29, QReg::q28), "fmaxnmp v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(faddp(QReg::q30, QReg::q29, QReg::q28), "faddp v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fmul(QReg::q30, QReg::q29, QReg::q28), "fmul v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fcmge(QReg::q30, QReg::q29, QReg::q28), "fcmge v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(facge(QReg::q30, QReg::q29, QReg::q28), "facge v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fmaxp(QReg::q30, QReg::q29, QReg::q28), "fmaxp v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fdiv(QReg::q30, QReg::q29, QReg::q28), "fdiv v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fminnmp(QReg::q30, QReg::q29, QReg::q28), "fminnmp v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fabd(QReg::q30, QReg::q29, QReg::q28), "fabd v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fcmgt(QReg::q30, QReg::q29, QReg::q28), "fcmgt v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(facgt(QReg::q30, QReg::q29, QReg::q28), "facgt v30.8h, v29.8h, v28.8h"); - TEST_SINGLE(fminp(QReg::q30, QReg::q29, QReg::q28), "fminp v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fmaxnm(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fmaxnm v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fmla(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fmla v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fadd(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fadd v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fmulx(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fmulx v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fcmeq(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fcmeq v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fmax(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fmax v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(frecps(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "frecps v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fminnm(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fminnm v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fmls(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fmls v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fsub(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fsub v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fmin(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fmin v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(frsqrts(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "frsqrts v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fmaxnmp(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fmaxnmp v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(faddp(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "faddp v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fmul(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fmul v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fcmge(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fcmge v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(facge(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "facge v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fmaxp(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fmaxp v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fdiv(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fdiv v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fminnmp(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fminnmp v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fabd(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fabd v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fcmgt(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fcmgt v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(facgt(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "facgt v30.8h, v29.8h, v28.8h"); + TEST_SINGLE(fminp(SubRegSize::i16Bit, QReg::q30, QReg::q29, QReg::q28), "fminp v30.8h, v29.8h, v28.8h"); } TEST_CASE_METHOD(TestDisassembler, "Emitter: ASIMD: Advanced SIMD two-register miscellaneous (FP16)") { TEST_SINGLE(frintn(SubRegSize::i16Bit, QReg::q30, QReg::q29), "frintn v30.8h, v29.8h");