thumb32: Implement LDRD (literal)

This commit is contained in:
Lioncash 2021-03-13 14:47:17 -05:00
parent a74843ca17
commit 9757e2353f
3 changed files with 30 additions and 2 deletions

View file

@ -15,8 +15,8 @@ INST(thumb32_LDMDB, "LDMDB/LDMEA", "1110100100W1nnnniiiiii
//INST(thumb32_LDREX, "LDREX", "111010000101--------------------")
INST(thumb32_STRD_imm_1, "STRD (imm)", "11101000U110nnnnttttssssiiiiiiii")
INST(thumb32_STRD_imm_2, "STRD (imm)", "11101001U1W0nnnnttttssssiiiiiiii")
//INST(thumb32_LDRD_imm_1, "LDRD (lit)", "11101000-1111111----------------")
//INST(thumb32_LDRD_imm_2, "LDRD (lit)", "11101001-1-11111----------------")
INST(thumb32_LDRD_lit_1, "LDRD (lit)", "11101000U1111111ttttssssiiiiiiii")
INST(thumb32_LDRD_lit_2, "LDRD (lit)", "11101001U1W11111ttttssssiiiiiiii")
//INST(thumb32_LDRD_imm_1, "LDRD (imm)", "11101000-111--------------------")
//INST(thumb32_LDRD_imm_2, "LDRD (imm)", "11101001-1-1--------------------")
//INST(thumb32_STREXB, "STREXB", "111010001100------------0100----")

View file

@ -39,6 +39,24 @@ static bool TableBranch(ThumbTranslatorVisitor& v, Reg n, Reg m, bool half) {
return false;
}
static bool LoadDualLiteral(ThumbTranslatorVisitor& v, bool U, bool W, Reg t, Reg t2, Imm<8> imm8) {
if (t == Reg::PC || t2 == Reg::PC || t == t2) {
return v.UnpredictableInstruction();
}
if (W) {
return v.UnpredictableInstruction();
}
const auto imm = imm8.ZeroExtend() << 2;
const auto address_1 = U ? v.ir.Add(v.ir.Imm32(v.ir.AlignPC(4)), v.ir.Imm32(imm))
: v.ir.Sub(v.ir.Imm32(v.ir.AlignPC(4)), v.ir.Imm32(imm));
const auto address_2 = v.ir.Add(address_1, v.ir.Imm32(4));
v.ir.SetRegister(t, v.ir.ReadMemory32(address_1));
v.ir.SetRegister(t2, v.ir.ReadMemory32(address_2));
return true;
}
static bool StoreDual(ThumbTranslatorVisitor& v, bool P, bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8) {
if (W && (n == t || n == t2)) {
return v.UnpredictableInstruction();
@ -67,6 +85,14 @@ static bool StoreDual(ThumbTranslatorVisitor& v, bool P, bool U, bool W, Reg n,
return true;
}
bool ThumbTranslatorVisitor::thumb32_LDRD_lit_1(bool U, Reg t, Reg t2, Imm<8> imm8) {
return LoadDualLiteral(*this, U, true, t, t2, imm8);
}
bool ThumbTranslatorVisitor::thumb32_LDRD_lit_2(bool U, bool W, Reg t, Reg t2, Imm<8> imm8) {
return LoadDualLiteral(*this, U, W, t, t2, imm8);
}
bool ThumbTranslatorVisitor::thumb32_STRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8) {
return StoreDual(*this, false, U, true, n, t, t2, imm8);
}

View file

@ -180,6 +180,8 @@ struct ThumbTranslatorVisitor final {
bool thumb32_STMDB(bool W, Reg n, Imm<15> reg_list);
// thumb32 load/store dual, load/store exclusive, table branch instructions
bool thumb32_LDRD_lit_1(bool U, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_LDRD_lit_2(bool U, bool W, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_STRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_STRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_TBB(Reg n, Reg m);