Merge pull request #2434 from lioncash/predmisc

ARMEmitter: Finish off SVE Predicate Misc group
This commit is contained in:
Ryan Houdek authored and GitHub committed 2023-02-23 12:20:03 -08:00
commit 165db37c8d
2 files changed
+52 -74

No files matched your search

@@ -1372,54 +1372,49 @@ public:
}
// SVE Predicate Misc
// XXX:
// XXX: PNEXT
void pnext(SubRegSize size, PRegister pd, PRegister pv, PRegister pn) {
LOGMAN_THROW_A_FMT(pd == pn, "pd and pn need to be the same");
SVEPredicateMisc(0b1001, 0b00010, pv.Idx(), size, pd);
}
// SVE predicate test
void ptest(FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::PRegister pn) {
constexpr uint32_t Op = 0b0010'0101'0001'0000'11 << 14;
SVEPredicateTest(Op, 0, 1, 0b0000, pg, pn);
void ptest(PRegister pg, PRegister pn) {
SVEPredicateMisc(0b0000, pg.Idx() << 1, pn.Idx(), SubRegSize::i16Bit, PReg::p0);
}
// SVE predicate first active
void pfirst(FEXCore::ARMEmitter::PRegister pd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::PRegister pn) {
void pfirst(PRegister pd, PRegister pg, PRegister pn) {
LOGMAN_THROW_A_FMT(pd == pn, "pd and pn need to be the same");
constexpr uint32_t Op = 0b0010'0101'0001'1000'1100 << 12;
SVEPredicateReadFFRPredicated(Op, 0, 1, pg, pd);
SVEPredicateMisc(0b1000, 0b00000, pg.Idx(), SubRegSize::i16Bit, pd);
}
// SVE predicate zero
void pfalse(FEXCore::ARMEmitter::PRegister pd) {
constexpr uint32_t Op = 0b0010'0101'0001'1000'1110'01 << 10;
SVEPredicateReadFFR(Op, 0, 0, pd);
void pfalse(PRegister pd) {
SVEPredicateMisc(0b1000, 0b10010, 0b0000, SubRegSize::i8Bit, pd);
}
// SVE predicate read from FFR (predicated)
void rdffr(FEXCore::ARMEmitter::PRegister pd, FEXCore::ARMEmitter::PRegister pg) {
constexpr uint32_t Op = 0b0010'0101'0001'1000'1111 << 12;
SVEPredicateReadFFRPredicated(Op, 0, 0, pg, pd);
void rdffr(PRegister pd, PRegisterZero pg) {
SVEPredicateMisc(0b1000, 0b11000, pg.Idx(), SubRegSize::i8Bit, pd);
}
void rdffrs(FEXCore::ARMEmitter::PRegister pd, FEXCore::ARMEmitter::PRegister pg) {
constexpr uint32_t Op = 0b0010'0101'0001'1000'1111 << 12;
SVEPredicateReadFFRPredicated(Op, 0, 1, pg, pd);
void rdffrs(PRegister pd, PRegisterZero pg) {
SVEPredicateMisc(0b1000, 0b11000, pg.Idx(), SubRegSize::i16Bit, pd);
}
// SVE predicate read from FFR (unpredicated)
void rdffr(FEXCore::ARMEmitter::PRegister pd) {
constexpr uint32_t Op = 0b0010'0101'0001'1001'1111 << 12;
SVEPredicateReadFFR(Op, 0, 0, pd);
void rdffr(PRegister pd) {
SVEPredicateMisc(0b1001, 0b11000, 0b0000, SubRegSize::i8Bit, pd);
}
// SVE predicate initialize
template<FEXCore::ARMEmitter::SubRegSize size>
void ptrue(FEXCore::ARMEmitter::PRegister pd, FEXCore::ARMEmitter::PredicatePattern pattern) {
constexpr uint32_t Op = 0b0010'0101'0001'1000'1110 << 12;
SVEPredicateInit(Op, size, 0, pattern, pd);
template <SubRegSize size>
void ptrue(PRegister pd, PredicatePattern pattern) {
SVEPredicateMisc(0b1000, 0b10000, FEXCore::ToUnderlying(pattern), size, pd);
}
template<FEXCore::ARMEmitter::SubRegSize size>
void ptrues(FEXCore::ARMEmitter::PRegister pd, FEXCore::ARMEmitter::PredicatePattern pattern) {
constexpr uint32_t Op = 0b0010'0101'0001'1000'1110 << 12;
SVEPredicateInit(Op, size, 1, pattern, pd);
template <SubRegSize size>
void ptrues(PRegister pd, PredicatePattern pattern) {
SVEPredicateMisc(0b1001, 0b10000, FEXCore::ToUnderlying(pattern), size, pd);
}
// SVE Integer Compare - Scalars
@@ -3705,45 +3700,6 @@ private:
Instr |= zt.Idx();
dc32(Instr);
}
void SVEPredicateTest(uint32_t Op, uint32_t op, uint32_t S, uint32_t opc2, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::PRegister pn) {
uint32_t Instr = Op;
Instr |= op << 23;
Instr |= S << 22;
Instr |= pg.Idx() << 10;
Instr |= pn.Idx() << 5;
Instr |= opc2;
dc32(Instr);
}
void SVEPredicateReadFFRPredicated(uint32_t Op, uint32_t op, uint32_t S, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::PRegister pd) {
uint32_t Instr = Op;
Instr |= op << 23;
Instr |= S << 22;
Instr |= pg.Idx() << 5;
Instr |= pd.Idx();
dc32(Instr);
}
void SVEPredicateReadFFR(uint32_t Op, uint32_t op, uint32_t S, FEXCore::ARMEmitter::PRegister pd) {
uint32_t Instr = Op;
Instr |= op << 23;
Instr |= S << 16;
Instr |= pd.Idx();
dc32(Instr);
}
void SVEPredicateInit(uint32_t Op, FEXCore::ARMEmitter::SubRegSize size, uint32_t S, FEXCore::ARMEmitter::PredicatePattern pattern, FEXCore::ARMEmitter::PRegister pd) {
uint32_t Instr = Op;
Instr |= FEXCore::ToUnderlying(size) << 22;
Instr |= S << 16;
Instr |= FEXCore::ToUnderlying(pattern) << 5;
Instr |= pd.Idx();
dc32(Instr);
}
void SVEIndexGeneration(uint32_t op, SubRegSize size, ZRegister zd, int32_t imm5, int32_t imm5b) {
LOGMAN_THROW_A_FMT(size != SubRegSize::i128Bit, "INDEX cannot use 128-bit element sizes");
@@ -4112,3 +4068,16 @@ private:
Instr |= pd.Idx();
dc32(Instr);
}
void SVEPredicateMisc(uint32_t op0, uint32_t op2, uint32_t op3, SubRegSize size, PRegister pd) {
// Note: op2 combines op1 like [op1:op2], since they're adjacent.
LOGMAN_THROW_A_FMT(size != SubRegSize::i128Bit, "Can't use 128-bit size");
uint32_t Instr = 0b0010'0101'0001'0000'1100'0000'0000'0000;
Instr |= FEXCore::ToUnderlying(size) << 22;
Instr |= op0 << 16;
Instr |= op2 << 9;
Instr |= op3 << 5;
Instr |= pd.Idx();
dc32(Instr);
}
+16 -7
View File
@@ -1395,28 +1395,37 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE partition break condition"
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE Predicate Misc") {
// TODO: Implement in emitter.
TEST_SINGLE(pnext(SubRegSize::i8Bit, PReg::p15, PReg::p14, PReg::p15), "pnext p15.b, p14, p15.b");
TEST_SINGLE(pnext(SubRegSize::i16Bit, PReg::p15, PReg::p14, PReg::p15), "pnext p15.h, p14, p15.h");
TEST_SINGLE(pnext(SubRegSize::i32Bit, PReg::p15, PReg::p14, PReg::p15), "pnext p15.s, p14, p15.s");
TEST_SINGLE(pnext(SubRegSize::i64Bit, PReg::p15, PReg::p14, PReg::p15), "pnext p15.d, p14, p15.d");
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE predicate test") {
TEST_SINGLE(ptest(PReg::p6, PReg::p5), "ptest p6, p5.b");
TEST_SINGLE(ptest(PReg::p6, PReg::p5), "ptest p6, p5.b");
TEST_SINGLE(ptest(PReg::p15, PReg::p14), "ptest p15, p14.b");
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE predicate first active") {
TEST_SINGLE(pfirst(PReg::p6, PReg::p5, PReg::p6), "pfirst p6.b, p5, p6.b");
TEST_SINGLE(pfirst(PReg::p6, PReg::p5, PReg::p6), "pfirst p6.b, p5, p6.b");
TEST_SINGLE(pfirst(PReg::p15, PReg::p14, PReg::p15), "pfirst p15.b, p14, p15.b");
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE predicate zero") {
TEST_SINGLE(pfalse(PReg::p6), "pfalse p6.b");
TEST_SINGLE(pfalse(PReg::p6), "pfalse p6.b");
TEST_SINGLE(pfalse(PReg::p15), "pfalse p15.b");
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE predicate read from FFR (predicated)") {
TEST_SINGLE(rdffr(PReg::p6, PReg::p5), "rdffr p6.b, p5/z");
TEST_SINGLE(rdffrs(PReg::p6, PReg::p5), "rdffrs p6.b, p5/z");
TEST_SINGLE(rdffr(PReg::p6, PReg::p5.Zeroing()), "rdffr p6.b, p5/z");
TEST_SINGLE(rdffr(PReg::p15, PReg::p14.Zeroing()), "rdffr p15.b, p14/z");
TEST_SINGLE(rdffrs(PReg::p6, PReg::p5.Zeroing()), "rdffrs p6.b, p5/z");
TEST_SINGLE(rdffrs(PReg::p15, PReg::p14.Zeroing()), "rdffrs p15.b, p14/z");
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE predicate read from FFR (unpredicated)") {
TEST_SINGLE(rdffr(PReg::p6), "rdffr p6.b");
TEST_SINGLE(rdffr(PReg::p6), "rdffr p6.b");
TEST_SINGLE(rdffr(PReg::p15), "rdffr p15.b");
}
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE predicate initialize") {