mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 17:00:19 +02:00
Merge pull request #2434 from lioncash/predmisc
ARMEmitter: Finish off SVE Predicate Misc group
This commit is contained in:
2 files changed
+52
-74
No files matched your search
+36
-67
@@ -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
@@ -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") {
|
||||
|
||||
Reference in new issue
Block a user