Arm64/Emitter: Deduplicate integer unary arithmetic instructions

We can move the opcodes into the underlying implementation along with
the asserts to deduplicate a bit of code.
This commit is contained in:
Lioncache committed 2023-07-19 09:16:33 -04:00
1 parent 2c91b5cff6
commit 5ebd21ca6a
1 file changed
+21 -41
@@ -785,82 +785,58 @@ public:
// SVE integer unary operations (predicated)
void sxtb(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i16Bit || size == FEXCore::ARMEmitter::SubRegSize::i32Bit || size == FEXCore::ARMEmitter::SubRegSize::i64Bit, "Invalid subregsize size");
constexpr uint32_t Op = 0b0000'0100'0001'0000'101 << 13;;
SVEIntegerUnaryPredicated(Op, 0b000, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b10, 0b000, size, pg, zn, zd);
}
void uxtb(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i16Bit || size == FEXCore::ARMEmitter::SubRegSize::i32Bit || size == FEXCore::ARMEmitter::SubRegSize::i64Bit, "Invalid subregsize size");
constexpr uint32_t Op = 0b0000'0100'0001'0000'101 << 13;;
SVEIntegerUnaryPredicated(Op, 0b001, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b10, 0b001, size, pg, zn, zd);
}
void sxth(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i32Bit || size == FEXCore::ARMEmitter::SubRegSize::i64Bit, "Invalid subregsize size");
constexpr uint32_t Op = 0b0000'0100'0001'0000'101 << 13;;
SVEIntegerUnaryPredicated(Op, 0b010, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b10, 0b010, size, pg, zn, zd);
}
void uxth(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i32Bit || size == FEXCore::ARMEmitter::SubRegSize::i64Bit, "Invalid subregsize size");
constexpr uint32_t Op = 0b0000'0100'0001'0000'101 << 13;;
SVEIntegerUnaryPredicated(Op, 0b011, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b10, 0b011, size, pg, zn, zd);
}
void sxtw(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i64Bit, "Invalid subregsize size");
constexpr uint32_t Op = 0b0000'0100'0001'0000'101 << 13;;
SVEIntegerUnaryPredicated(Op, 0b100, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b10, 0b100, size, pg, zn, zd);
}
void uxtw(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i64Bit, "Invalid subregsize size");
constexpr uint32_t Op = 0b0000'0100'0001'0000'101 << 13;;
SVEIntegerUnaryPredicated(Op, 0b101, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b10, 0b101, size, pg, zn, zd);
}
void abs(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_AA_FMT(size != FEXCore::ARMEmitter::SubRegSize::i128Bit, "Can't use 128-bit size");
constexpr uint32_t Op = 0b0000'0100'0001'0000'101 << 13;;
SVEIntegerUnaryPredicated(Op, 0b110, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b10, 0b110, size, pg, zn, zd);
}
void neg(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_AA_FMT(size != FEXCore::ARMEmitter::SubRegSize::i128Bit, "Can't use 128-bit size");
constexpr uint32_t Op = 0b0000'0100'0001'0000'101 << 13;;
SVEIntegerUnaryPredicated(Op, 0b111, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b10, 0b111, size, pg, zn, zd);
}
// SVE bitwise unary operations (predicated)
void cls(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_AA_FMT(size != FEXCore::ARMEmitter::SubRegSize::i128Bit, "Can't use 128-bit size");
constexpr uint32_t Op = 0b0000'0100'0001'1000'101 << 13;
SVEIntegerUnaryPredicated(Op, 0b000, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b11, 0b000, size, pg, zn, zd);
}
void clz(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_AA_FMT(size != FEXCore::ARMEmitter::SubRegSize::i128Bit, "Can't use 128-bit size");
constexpr uint32_t Op = 0b0000'0100'0001'1000'101 << 13;
SVEIntegerUnaryPredicated(Op, 0b001, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b11, 0b001, size, pg, zn, zd);
}
void cnt(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_AA_FMT(size != FEXCore::ARMEmitter::SubRegSize::i128Bit, "Can't use 128-bit size");
constexpr uint32_t Op = 0b0000'0100'0001'1000'101 << 13;
SVEIntegerUnaryPredicated(Op, 0b010, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b11, 0b010, size, pg, zn, zd);
}
void cnot(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_AA_FMT(size != FEXCore::ARMEmitter::SubRegSize::i128Bit, "Can't use 128-bit size");
constexpr uint32_t Op = 0b0000'0100'0001'1000'101 << 13;
SVEIntegerUnaryPredicated(Op, 0b011, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b11, 0b011, size, pg, zn, zd);
}
void fabs(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_AA_FMT(size != FEXCore::ARMEmitter::SubRegSize::i128Bit, "Can't use 128-bit size");
LOGMAN_THROW_AA_FMT(size != FEXCore::ARMEmitter::SubRegSize::i8Bit, "Invalid size");
constexpr uint32_t Op = 0b0000'0100'0001'1000'101 << 13;
SVEIntegerUnaryPredicated(Op, 0b100, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b11, 0b100, size, pg, zn, zd);
}
void fneg(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_AA_FMT(size != FEXCore::ARMEmitter::SubRegSize::i128Bit, "Can't use 128-bit size");
LOGMAN_THROW_AA_FMT(size != FEXCore::ARMEmitter::SubRegSize::i8Bit, "Invalid size");
constexpr uint32_t Op = 0b0000'0100'0001'1000'101 << 13;
SVEIntegerUnaryPredicated(Op, 0b101, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b11, 0b101, size, pg, zn, zd);
}
void not_(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_AA_FMT(size != FEXCore::ARMEmitter::SubRegSize::i128Bit, "Can't use 128-bit size");
constexpr uint32_t Op = 0b0000'0100'0001'1000'101 << 13;
SVEIntegerUnaryPredicated(Op, 0b110, size, pg, zn, zd);
SVEIntegerUnaryPredicated(0b11, 0b110, size, pg, zn, zd);
}
// SVE Bitwise Logical - Unpredicated
@@ -3572,10 +3548,14 @@ private:
}
// SVE bitwise unary operations (predicated)
void SVEIntegerUnaryPredicated(uint32_t Op, uint32_t opc, FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn, FEXCore::ARMEmitter::ZRegister zd) {
uint32_t Instr = Op;
void SVEIntegerUnaryPredicated(uint32_t op0, uint32_t opc, SubRegSize size, PRegister pg, ZRegister zn, ZRegister zd) {
LOGMAN_THROW_AA_FMT(size != SubRegSize::i128Bit, "Can't use 128-bit size");
LOGMAN_THROW_A_FMT(pg <= PReg::p7, "Can only use p0-p7 as a governing predicate");
uint32_t Instr = 0b0000'0100'0000'0000'1010'0000'0000'0000;
Instr |= FEXCore::ToUnderlying(size) << 22;
Instr |= op0 << 19;
Instr |= opc << 16;
Instr |= pg.Idx() << 10;
Instr |= zn.Idx() << 5;