Merge pull request #2371 from lioncash/mul

ARMEmitter: Handle SVE predicated mul/div and finish off integer reduction category
This commit is contained in:
Ryan Houdek authored and GitHub committed 2023-02-03 19:36:57 -08:00
commit c0bc5d9748
3 files changed
+180 -54

No files matched your search

@@ -661,9 +661,45 @@ public:
}
// SVE integer multiply vectors (predicated)
// XXX:
void mul(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) {
constexpr uint32_t Op = 0b0000'0100'0001'0000'0000'0000'0000'0000;
SVEIntegerMulDivVectorsPredicated(Op, 0b00, size, zd, pg, zn, zm);
}
void smulh(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) {
constexpr uint32_t Op = 0b0000'0100'0001'0000'0000'0000'0000'0000;
SVEIntegerMulDivVectorsPredicated(Op, 0b10, size, zd, pg, zn, zm);
}
void umulh(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) {
constexpr uint32_t Op = 0b0000'0100'0001'0000'0000'0000'0000'0000;
SVEIntegerMulDivVectorsPredicated(Op, 0b11, size, zd, pg, zn, zm);
}
// SVE integer divide vectors (predicated)
// XXX:
void sdiv(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) {
LOGMAN_THROW_AA_FMT(size == SubRegSize::i32Bit || size == SubRegSize::i64Bit,
"Predicated divide only handles 32-bit or 64-bit elements");
constexpr uint32_t Op = 0b0000'0100'0001'0100'0000'0000'0000'0000;
SVEIntegerMulDivVectorsPredicated(Op, 0b00, size, zd, pg, zn, zm);
}
void udiv(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) {
LOGMAN_THROW_AA_FMT(size == SubRegSize::i32Bit || size == SubRegSize::i64Bit,
"Predicated divide only handles 32-bit or 64-bit elements");
constexpr uint32_t Op = 0b0000'0100'0001'0100'0000'0000'0000'0000;
SVEIntegerMulDivVectorsPredicated(Op, 0b01, size, zd, pg, zn, zm);
}
void sdivr(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) {
LOGMAN_THROW_AA_FMT(size == SubRegSize::i32Bit || size == SubRegSize::i64Bit,
"Predicated divide only handles 32-bit or 64-bit elements");
constexpr uint32_t Op = 0b0000'0100'0001'0100'0000'0000'0000'0000;
SVEIntegerMulDivVectorsPredicated(Op, 0b10, size, zd, pg, zn, zm);
}
void udivr(SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) {
LOGMAN_THROW_AA_FMT(size == SubRegSize::i32Bit || size == SubRegSize::i64Bit,
"Predicated divide only handles 32-bit or 64-bit elements");
constexpr uint32_t Op = 0b0000'0100'0001'0100'0000'0000'0000'0000;
SVEIntegerMulDivVectorsPredicated(Op, 0b11, size, zd, pg, zn, zm);
}
// SVE bitwise logical operations (predicated)
void orr(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegisterMerge pg, FEXCore::ARMEmitter::ZRegister zdn, FEXCore::ARMEmitter::ZRegister zm) {
LOGMAN_THROW_AA_FMT(size != FEXCore::ARMEmitter::SubRegSize::i128Bit, "Can't use 128-bit size");
@@ -692,27 +728,35 @@ public:
// SVE Integer Reduction
// SVE integer add reduction (predicated)
// XXX:
void saddv(SubRegSize size, DRegister vd, PRegister pg, ZRegister zn) {
LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit,
"saddv may only use 8-bit, 16-bit, or 32-bit elements.");
constexpr uint32_t Op = 0b0000'0100'0000'0000'0010'0000'0000'0000;
SVEIntegerReductionOperation(Op, 0b00, size, vd, pg, zn);
}
void uaddv(SubRegSize size, DRegister vd, PRegister pg, ZRegister zn) {
LOGMAN_THROW_A_FMT(size == SubRegSize::i8Bit || size == SubRegSize::i16Bit || size == SubRegSize::i32Bit,
"uaddv may only use 8-bit, 16-bit, or 32-bit elements.");
constexpr uint32_t Op = 0b0000'0100'0000'0000'0010'0000'0000'0000;
SVEIntegerReductionOperation(Op, 0b01, size, vd, pg, zn);
}
// SVE integer min/max reduction (predicated)
void smaxv(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i8Bit || size == FEXCore::ARMEmitter::SubRegSize::i16Bit || size == FEXCore::ARMEmitter::SubRegSize::i32Bit, "Invalid subregsize size");
void smaxv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) {
constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13;
SVEIntegerMinMaxReduction(Op, 0, 0, size, pg, zn, zd);
SVEIntegerReductionOperation(Op, 0b00, size, vd, pg, zn);
}
void umaxv(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i8Bit || size == FEXCore::ARMEmitter::SubRegSize::i16Bit || size == FEXCore::ARMEmitter::SubRegSize::i32Bit, "Invalid subregsize size");
void umaxv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) {
constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13;
SVEIntegerMinMaxReduction(Op, 0, 1, size, pg, zn, zd);
SVEIntegerReductionOperation(Op, 0b01, size, vd, pg, zn);
}
void sminv(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i8Bit || size == FEXCore::ARMEmitter::SubRegSize::i16Bit || size == FEXCore::ARMEmitter::SubRegSize::i32Bit, "Invalid subregsize size");
void sminv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) {
constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13;
SVEIntegerMinMaxReduction(Op, 1, 0, size, pg, zn, zd);
SVEIntegerReductionOperation(Op, 0b10, size, vd, pg, zn);
}
void uminv(FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn) {
LOGMAN_THROW_A_FMT(size == FEXCore::ARMEmitter::SubRegSize::i8Bit || size == FEXCore::ARMEmitter::SubRegSize::i16Bit || size == FEXCore::ARMEmitter::SubRegSize::i32Bit, "Invalid subregsize size");
void uminv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) {
constexpr uint32_t Op = 0b0000'0100'0000'1000'001 << 13;
SVEIntegerMinMaxReduction(Op, 1, 1, size, pg, zn, zd);
SVEIntegerReductionOperation(Op, 0b11, size, vd, pg, zn);
}
// SVE constructive prefix (predicated)
@@ -726,7 +770,18 @@ public:
}
// SVE bitwise logical reduction (predicated)
// XXX
void orv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) {
constexpr uint32_t Op = 0b0000'0100'0001'1000'0010'0000'0000'0000;
SVEIntegerReductionOperation(Op, 0b00, size, vd, pg, zn);
}
void eorv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) {
constexpr uint32_t Op = 0b0000'0100'0001'1000'0010'0000'0000'0000;
SVEIntegerReductionOperation(Op, 0b01, size, vd, pg, zn);
}
void andv(SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) {
constexpr uint32_t Op = 0b0000'0100'0001'1000'0010'0000'0000'0000;
SVEIntegerReductionOperation(Op, 0b10, size, vd, pg, zn);
}
// SVE Bitwise Shift - Predicated
// SVE bitwise shift by immediate (predicated)
@@ -3809,19 +3864,6 @@ private:
dc32(Instr);
}
// SVE integer min/max reduction (predicated)
void SVEIntegerMinMaxReduction(uint32_t Op, uint32_t op, uint32_t U, FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn, FEXCore::ARMEmitter::ZRegister zd) {
uint32_t Instr = Op;
Instr |= FEXCore::ToUnderlying(size) << 22;
Instr |= op << 17;
Instr |= U << 16;
Instr |= pg.Idx() << 10;
Instr |= Encode_rn(zn);
Instr |= Encode_rd(zd);
dc32(Instr);
}
// SVE constructive prefix (predicated)
void SVEConstructivePrefixPredicated(uint32_t Op, uint32_t opc, uint32_t M, FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn, FEXCore::ARMEmitter::ZRegister zd) {
uint32_t Instr = Op;
@@ -3987,6 +4029,32 @@ private:
dc32(Instr);
}
void SVEIntegerMulDivVectorsPredicated(uint32_t op, uint32_t opc, SubRegSize size, ZRegister zd, PRegisterMerge pg, ZRegister zn, ZRegister zm) {
LOGMAN_THROW_AA_FMT(zd.Idx() == zn.Idx(), "zd and zn must be the same register");
LOGMAN_THROW_AA_FMT(pg <= PReg::p7, "Mul/Div operation can only use p0-p7 as a governing predicate");
uint32_t Instr = op;
Instr |= FEXCore::ToUnderlying(size) << 22;
Instr |= opc << 16;
Instr |= pg.Idx() << 10;
Instr |= zm.Idx() << 5;
Instr |= zd.Idx();
dc32(Instr);
}
void SVEIntegerReductionOperation(uint32_t op, uint32_t opc, SubRegSize size, VRegister vd, PRegister pg, ZRegister zn) {
LOGMAN_THROW_AA_FMT(size != SubRegSize::i128Bit, "Can't use 128-bit element size for reduction operation");
LOGMAN_THROW_AA_FMT(pg <= PReg::p7, "Integer reduction operation can only use p0-p7 as a governing predicate");
uint32_t Instr = op;
Instr |= FEXCore::ToUnderlying(size) << 22;
Instr |= opc << 16;
Instr |= pg.Idx() << 10;
Instr |= zn.Idx() << 5;
Instr |= vd.Idx();
dc32(Instr);
}
// SVE floating-point round to integral value
void frintX(uint32_t opc, FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn) {
// opc = round mode
@@ -423,7 +423,7 @@ DEF_OP(VUMinV) {
const auto Pred = OpSize == 16 ? PRED_TMP_16B
: PRED_TMP_32B;
uminv(SubRegSize, Dst.Z(), Pred, Vector.Z());
uminv(SubRegSize, Dst, Pred, Vector.Z());
} else {
// Vector
uminv(SubRegSize, Dst.Q(), Vector.Q());
+82 -24
View File
@@ -512,11 +512,54 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer min/max/difference
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer multiply vectors (predicated)") {
// TODO: Implement in emitter.
TEST_SINGLE(mul(SubRegSize::i8Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"mul z30.b, p7/m, z30.b, z29.b");
TEST_SINGLE(mul(SubRegSize::i16Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"mul z30.h, p7/m, z30.h, z29.h");
TEST_SINGLE(mul(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"mul z30.s, p7/m, z30.s, z29.s");
TEST_SINGLE(mul(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"mul z30.d, p7/m, z30.d, z29.d");
TEST_SINGLE(smulh(SubRegSize::i8Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"smulh z30.b, p7/m, z30.b, z29.b");
TEST_SINGLE(smulh(SubRegSize::i16Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"smulh z30.h, p7/m, z30.h, z29.h");
TEST_SINGLE(smulh(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"smulh z30.s, p7/m, z30.s, z29.s");
TEST_SINGLE(smulh(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"smulh z30.d, p7/m, z30.d, z29.d");
TEST_SINGLE(umulh(SubRegSize::i8Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"umulh z30.b, p7/m, z30.b, z29.b");
TEST_SINGLE(umulh(SubRegSize::i16Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"umulh z30.h, p7/m, z30.h, z29.h");
TEST_SINGLE(umulh(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"umulh z30.s, p7/m, z30.s, z29.s");
TEST_SINGLE(umulh(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"umulh z30.d, p7/m, z30.d, z29.d");
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer divide vectors (predicated)") {
// TODO: Implement in emitter.
TEST_SINGLE(sdiv(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"sdiv z30.s, p7/m, z30.s, z29.s");
TEST_SINGLE(sdiv(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"sdiv z30.d, p7/m, z30.d, z29.d");
TEST_SINGLE(udiv(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"udiv z30.s, p7/m, z30.s, z29.s");
TEST_SINGLE(udiv(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"udiv z30.d, p7/m, z30.d, z29.d");
TEST_SINGLE(sdivr(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"sdivr z30.s, p7/m, z30.s, z29.s");
TEST_SINGLE(sdivr(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"sdivr z30.d, p7/m, z30.d, z29.d");
TEST_SINGLE(udivr(SubRegSize::i32Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"udivr z30.s, p7/m, z30.s, z29.s");
TEST_SINGLE(udivr(SubRegSize::i64Bit, ZReg::z30, PReg::p7.Merging(), ZReg::z30, ZReg::z29),
"udivr z30.d, p7/m, z30.d, z29.d");
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise logical operations (predicated)") {
@@ -546,32 +589,34 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise logical operations
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer add reduction (predicated)") {
// TODO: Implement in emitter.
TEST_SINGLE(saddv(SubRegSize::i8Bit, DReg::d30, PReg::p7, ZReg::z29), "saddv d30, p7, z29.b");
TEST_SINGLE(saddv(SubRegSize::i16Bit, DReg::d30, PReg::p7, ZReg::z29), "saddv d30, p7, z29.h");
TEST_SINGLE(saddv(SubRegSize::i32Bit, DReg::d30, PReg::p7, ZReg::z29), "saddv d30, p7, z29.s");
TEST_SINGLE(uaddv(SubRegSize::i8Bit, DReg::d30, PReg::p7, ZReg::z29), "uaddv d30, p7, z29.b");
TEST_SINGLE(uaddv(SubRegSize::i16Bit, DReg::d30, PReg::p7, ZReg::z29), "uaddv d30, p7, z29.h");
TEST_SINGLE(uaddv(SubRegSize::i32Bit, DReg::d30, PReg::p7, ZReg::z29), "uaddv d30, p7, z29.s");
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE integer min/max reduction (predicated)") {
TEST_SINGLE(smaxv(SubRegSize::i8Bit, ZReg::z30, PReg::p6, ZReg::z29), "smaxv b30, p6, z29.b");
TEST_SINGLE(smaxv(SubRegSize::i16Bit, ZReg::z30, PReg::p6, ZReg::z29), "smaxv h30, p6, z29.h");
TEST_SINGLE(smaxv(SubRegSize::i32Bit, ZReg::z30, PReg::p6, ZReg::z29), "smaxv s30, p6, z29.s");
//TEST_SINGLE(smaxv(SubRegSize::i64Bit, ZReg::z30, PReg::p6, ZReg::z29), "smaxv d30, p6, z29.d");
//TEST_SINGLE(smaxv(SubRegSize::i128Bit, ZReg::z30, PReg::p6, ZReg::z29), "smaxv q30, p6, z29.q");
TEST_SINGLE(smaxv(SubRegSize::i8Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv b30, p6, z29.b");
TEST_SINGLE(smaxv(SubRegSize::i16Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv h30, p6, z29.h");
TEST_SINGLE(smaxv(SubRegSize::i32Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv s30, p6, z29.s");
TEST_SINGLE(smaxv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "smaxv d30, p6, z29.d");
TEST_SINGLE(umaxv(SubRegSize::i8Bit, ZReg::z30, PReg::p6, ZReg::z29), "umaxv b30, p6, z29.b");
TEST_SINGLE(umaxv(SubRegSize::i16Bit, ZReg::z30, PReg::p6, ZReg::z29), "umaxv h30, p6, z29.h");
TEST_SINGLE(umaxv(SubRegSize::i32Bit, ZReg::z30, PReg::p6, ZReg::z29), "umaxv s30, p6, z29.s");
//TEST_SINGLE(umaxv(SubRegSize::i64Bit, ZReg::z30, PReg::p6, ZReg::z29), "umaxv d30, p6, z29.d");
//TEST_SINGLE(umaxv(SubRegSize::i128Bit, ZReg::z30, PReg::p6, ZReg::z29), "umaxv q30, p6, z29.q");
TEST_SINGLE(umaxv(SubRegSize::i8Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv b30, p6, z29.b");
TEST_SINGLE(umaxv(SubRegSize::i16Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv h30, p6, z29.h");
TEST_SINGLE(umaxv(SubRegSize::i32Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv s30, p6, z29.s");
TEST_SINGLE(umaxv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "umaxv d30, p6, z29.d");
TEST_SINGLE(sminv(SubRegSize::i8Bit, ZReg::z30, PReg::p6, ZReg::z29), "sminv b30, p6, z29.b");
TEST_SINGLE(sminv(SubRegSize::i16Bit, ZReg::z30, PReg::p6, ZReg::z29), "sminv h30, p6, z29.h");
TEST_SINGLE(sminv(SubRegSize::i32Bit, ZReg::z30, PReg::p6, ZReg::z29), "sminv s30, p6, z29.s");
//TEST_SINGLE(sminv(SubRegSize::i64Bit, ZReg::z30, PReg::p6, ZReg::z29), "sminv d30, p6, z29.d");
//TEST_SINGLE(sminv(SubRegSize::i128Bit, ZReg::z30, PReg::p6, ZReg::z29), "sminv q30, p6, z29.q");
TEST_SINGLE(sminv(SubRegSize::i8Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv b30, p6, z29.b");
TEST_SINGLE(sminv(SubRegSize::i16Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv h30, p6, z29.h");
TEST_SINGLE(sminv(SubRegSize::i32Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv s30, p6, z29.s");
TEST_SINGLE(sminv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "sminv d30, p6, z29.d");
TEST_SINGLE(uminv(SubRegSize::i8Bit, ZReg::z30, PReg::p6, ZReg::z29), "uminv b30, p6, z29.b");
TEST_SINGLE(uminv(SubRegSize::i16Bit, ZReg::z30, PReg::p6, ZReg::z29), "uminv h30, p6, z29.h");
TEST_SINGLE(uminv(SubRegSize::i32Bit, ZReg::z30, PReg::p6, ZReg::z29), "uminv s30, p6, z29.s");
//TEST_SINGLE(uminv(SubRegSize::i64Bit, ZReg::z30, PReg::p6, ZReg::z29), "uminv d30, p6, z29.d");
//TEST_SINGLE(uminv(SubRegSize::i128Bit, ZReg::z30, PReg::p6, ZReg::z29), "uminv q30, p6, z29.q");
TEST_SINGLE(uminv(SubRegSize::i8Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv b30, p6, z29.b");
TEST_SINGLE(uminv(SubRegSize::i16Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv h30, p6, z29.h");
TEST_SINGLE(uminv(SubRegSize::i32Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv s30, p6, z29.s");
TEST_SINGLE(uminv(SubRegSize::i64Bit, VReg::v30, PReg::p6, ZReg::z29), "uminv d30, p6, z29.d");
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE constructive prefix (predicated)") {
TEST_SINGLE(movprfx(SubRegSize::i8Bit, ZReg::z30, PReg::p6.Merging(), ZReg::z29), "movprfx z30.b, p6/m, z29.b");
@@ -586,7 +631,20 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE constructive prefix (predi
//TEST_SINGLE(movprfx(SubRegSize::i128Bit, ZReg::z30, PReg::p6.Zeroing(), ZReg::z29), "movprfx z30.q, p6/z, z29.q");
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise logical reduction (predicated)") {
// TODO: Implement in emitter.
TEST_SINGLE(orv(SubRegSize::i8Bit, VReg::v30, PReg::p7, ZReg::z29), "orv b30, p7, z29.b");
TEST_SINGLE(orv(SubRegSize::i16Bit, VReg::v30, PReg::p7, ZReg::z29), "orv h30, p7, z29.h");
TEST_SINGLE(orv(SubRegSize::i32Bit, VReg::v30, PReg::p7, ZReg::z29), "orv s30, p7, z29.s");
TEST_SINGLE(orv(SubRegSize::i64Bit, VReg::v30, PReg::p7, ZReg::z29), "orv d30, p7, z29.d");
TEST_SINGLE(eorv(SubRegSize::i8Bit, VReg::v30, PReg::p7, ZReg::z29), "eorv b30, p7, z29.b");
TEST_SINGLE(eorv(SubRegSize::i16Bit, VReg::v30, PReg::p7, ZReg::z29), "eorv h30, p7, z29.h");
TEST_SINGLE(eorv(SubRegSize::i32Bit, VReg::v30, PReg::p7, ZReg::z29), "eorv s30, p7, z29.s");
TEST_SINGLE(eorv(SubRegSize::i64Bit, VReg::v30, PReg::p7, ZReg::z29), "eorv d30, p7, z29.d");
TEST_SINGLE(andv(SubRegSize::i8Bit, VReg::v30, PReg::p7, ZReg::z29), "andv b30, p7, z29.b");
TEST_SINGLE(andv(SubRegSize::i16Bit, VReg::v30, PReg::p7, ZReg::z29), "andv h30, p7, z29.h");
TEST_SINGLE(andv(SubRegSize::i32Bit, VReg::v30, PReg::p7, ZReg::z29), "andv s30, p7, z29.s");
TEST_SINGLE(andv(SubRegSize::i64Bit, VReg::v30, PReg::p7, ZReg::z29), "andv d30, p7, z29.d");
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE bitwise shift by immediate (predicated)") {
TEST_SINGLE(asr(SubRegSize::i8Bit, ZReg::z30, PReg::p6.Merging(), ZReg::z30, 1), "asr z30.b, p6/m, z30.b, #1");