mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 18:00:17 +02:00
CodeEmitter/LoadstoreOps: Add Load/store register (PAC) group
Eh, what the heck. Gets rid of the last TODO marker in the base load-stores.
This commit is contained in:
1 parent
c8371087e6
commit
4e6f183f77
2 files changed
+49
-2
No files matched your search
@@ -4182,7 +4182,12 @@ public:
|
||||
}
|
||||
|
||||
// Loadstore PAC
|
||||
// TODO
|
||||
void ldraa(XRegister rt, XRegister rn, IndexType type, int32_t offset = 0) {
|
||||
LoadStorePAC(0b11, 0, 0, offset, type, rn, rt);
|
||||
}
|
||||
void ldrab(XRegister rt, XRegister rn, IndexType type, int32_t offset = 0) {
|
||||
LoadStorePAC(0b11, 0, 1, offset, type, rn, rt);
|
||||
}
|
||||
|
||||
// Loadstore unsigned immediate
|
||||
// Maximum values of unsigned immediate offsets for particular data sizes.
|
||||
@@ -4411,6 +4416,30 @@ private:
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
void LoadStorePAC(uint32_t size, uint32_t VR, uint32_t M, int32_t imm, IndexType type, Register rn, Register rt) {
|
||||
LOGMAN_THROW_A_FMT((imm % 8) == 0, "Immediate ({}) must be divisible by 8", imm);
|
||||
LOGMAN_THROW_A_FMT(imm >= -4096 && imm <= 4088, "Immediate ({}) must be within [-4096, 4088]", imm);
|
||||
LOGMAN_THROW_A_FMT(type == IndexType::OFFSET || type == IndexType::PRE, "PAC may only use offset or pre-indexed values");
|
||||
|
||||
// The immediate is scaled down in order to fit within the available 10 immediate bits.
|
||||
const auto scaled_imm = static_cast<uint32_t>(imm / 8);
|
||||
const auto imm9 = scaled_imm & 0b1'1111'1111;
|
||||
const auto S = (scaled_imm >> 9) & 1;
|
||||
|
||||
const auto W = type == IndexType::OFFSET ? 0U : 1U;
|
||||
|
||||
uint32_t Instr = 0b0011'1000'0010'0000'0000'0100'0000'0000;
|
||||
Instr |= size << 30;
|
||||
Instr |= VR << 26;
|
||||
Instr |= M << 23;
|
||||
Instr |= S << 22;
|
||||
Instr |= imm9 << 12;
|
||||
Instr |= W << 11;
|
||||
Instr |= rn.Idx() << 5;
|
||||
Instr |= rt.Idx();
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// Loadstore unsigned immediate
|
||||
template<typename T>
|
||||
void LoadStoreUnsigned(uint32_t size, uint32_t V, uint32_t opc, T rt, Register rn, uint32_t Imm) {
|
||||
|
||||
@@ -2906,7 +2906,25 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: Loadstore: Loadstore register-regis
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(TestDisassembler, "Emitter: Loadstore: Loadstore PAC") {
|
||||
// TODO: Implement in emitter.
|
||||
TEST_SINGLE(ldraa(XReg::x30, XReg::x29, ARMEmitter::IndexType::OFFSET, 0), "ldraa x30, [x29]");
|
||||
TEST_SINGLE(ldraa(XReg::x30, XReg::x29, ARMEmitter::IndexType::OFFSET, -4096), "ldraa x30, [x29, #-4096]");
|
||||
TEST_SINGLE(ldraa(XReg::x30, XReg::x29, ARMEmitter::IndexType::OFFSET, 512), "ldraa x30, [x29, #512]");
|
||||
TEST_SINGLE(ldraa(XReg::x30, XReg::x29, ARMEmitter::IndexType::OFFSET, 4088), "ldraa x30, [x29, #4088]");
|
||||
|
||||
TEST_SINGLE(ldraa(XReg::x30, XReg::x29, ARMEmitter::IndexType::PRE, 0), "ldraa x30, [x29]!");
|
||||
TEST_SINGLE(ldraa(XReg::x30, XReg::x29, ARMEmitter::IndexType::PRE, -4096), "ldraa x30, [x29, #-4096]!");
|
||||
TEST_SINGLE(ldraa(XReg::x30, XReg::x29, ARMEmitter::IndexType::PRE, 512), "ldraa x30, [x29, #512]!");
|
||||
TEST_SINGLE(ldraa(XReg::x30, XReg::x29, ARMEmitter::IndexType::PRE, 4088), "ldraa x30, [x29, #4088]!");
|
||||
|
||||
TEST_SINGLE(ldrab(XReg::x30, XReg::x29, ARMEmitter::IndexType::OFFSET, 0), "ldrab x30, [x29]");
|
||||
TEST_SINGLE(ldrab(XReg::x30, XReg::x29, ARMEmitter::IndexType::OFFSET, -4096), "ldrab x30, [x29, #-4096]");
|
||||
TEST_SINGLE(ldrab(XReg::x30, XReg::x29, ARMEmitter::IndexType::OFFSET, 512), "ldrab x30, [x29, #512]");
|
||||
TEST_SINGLE(ldrab(XReg::x30, XReg::x29, ARMEmitter::IndexType::OFFSET, 4088), "ldrab x30, [x29, #4088]");
|
||||
|
||||
TEST_SINGLE(ldrab(XReg::x30, XReg::x29, ARMEmitter::IndexType::PRE, 0), "ldrab x30, [x29]!");
|
||||
TEST_SINGLE(ldrab(XReg::x30, XReg::x29, ARMEmitter::IndexType::PRE, -4096), "ldrab x30, [x29, #-4096]!");
|
||||
TEST_SINGLE(ldrab(XReg::x30, XReg::x29, ARMEmitter::IndexType::PRE, 512), "ldrab x30, [x29, #512]!");
|
||||
TEST_SINGLE(ldrab(XReg::x30, XReg::x29, ARMEmitter::IndexType::PRE, 4088), "ldrab x30, [x29, #4088]!");
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(TestDisassembler, "Emitter: Loadstore: Loadstore unsigned immediate") {
|
||||
|
||||
Reference in new issue
Block a user