thumb32: Implement LDRD (immediate)
This commit is contained in:
parent
9757e2353f
commit
5873e6b955
3 changed files with 38 additions and 2 deletions
|
@ -17,8 +17,8 @@ INST(thumb32_STRD_imm_1, "STRD (imm)", "11101000U110nnnnttttss
|
||||||
INST(thumb32_STRD_imm_2, "STRD (imm)", "11101001U1W0nnnnttttssssiiiiiiii")
|
INST(thumb32_STRD_imm_2, "STRD (imm)", "11101001U1W0nnnnttttssssiiiiiiii")
|
||||||
INST(thumb32_LDRD_lit_1, "LDRD (lit)", "11101000U1111111ttttssssiiiiiiii")
|
INST(thumb32_LDRD_lit_1, "LDRD (lit)", "11101000U1111111ttttssssiiiiiiii")
|
||||||
INST(thumb32_LDRD_lit_2, "LDRD (lit)", "11101001U1W11111ttttssssiiiiiiii")
|
INST(thumb32_LDRD_lit_2, "LDRD (lit)", "11101001U1W11111ttttssssiiiiiiii")
|
||||||
//INST(thumb32_LDRD_imm_1, "LDRD (imm)", "11101000-111--------------------")
|
INST(thumb32_LDRD_imm_1, "LDRD (imm)", "11101000U111nnnnttttssssiiiiiiii")
|
||||||
//INST(thumb32_LDRD_imm_2, "LDRD (imm)", "11101001-1-1--------------------")
|
INST(thumb32_LDRD_imm_2, "LDRD (imm)", "11101001U1W1nnnnttttssssiiiiiiii")
|
||||||
//INST(thumb32_STREXB, "STREXB", "111010001100------------0100----")
|
//INST(thumb32_STREXB, "STREXB", "111010001100------------0100----")
|
||||||
//INST(thumb32_STREXH, "STREXH", "111010001100------------0101----")
|
//INST(thumb32_STREXH, "STREXH", "111010001100------------0101----")
|
||||||
//INST(thumb32_STREXD, "STREXD", "111010001100------------0111----")
|
//INST(thumb32_STREXD, "STREXD", "111010001100------------0111----")
|
||||||
|
|
|
@ -39,6 +39,32 @@ static bool TableBranch(ThumbTranslatorVisitor& v, Reg n, Reg m, bool half) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool LoadDualImmediate(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();
|
||||||
|
}
|
||||||
|
if (t == Reg::PC || t2 == Reg::PC || t == t2) {
|
||||||
|
return v.UnpredictableInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
const u32 imm = imm8.ZeroExtend() << 2;
|
||||||
|
const IR::U32 reg_n = v.ir.GetRegister(n);
|
||||||
|
const IR::U32 offset_address = U ? v.ir.Add(reg_n, v.ir.Imm32(imm))
|
||||||
|
: v.ir.Sub(reg_n, v.ir.Imm32(imm));
|
||||||
|
const IR::U32 address_1 = P ? offset_address
|
||||||
|
: reg_n;
|
||||||
|
const IR::U32 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));
|
||||||
|
|
||||||
|
if (W) {
|
||||||
|
v.ir.SetRegister(n, offset_address);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool LoadDualLiteral(ThumbTranslatorVisitor& v, bool U, bool W, Reg t, Reg t2, Imm<8> imm8) {
|
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) {
|
if (t == Reg::PC || t2 == Reg::PC || t == t2) {
|
||||||
return v.UnpredictableInstruction();
|
return v.UnpredictableInstruction();
|
||||||
|
@ -85,6 +111,14 @@ static bool StoreDual(ThumbTranslatorVisitor& v, bool P, bool U, bool W, Reg n,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ThumbTranslatorVisitor::thumb32_LDRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8) {
|
||||||
|
return LoadDualImmediate(*this, false, U, true, n, t, t2, imm8);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThumbTranslatorVisitor::thumb32_LDRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8) {
|
||||||
|
return LoadDualImmediate(*this, true, U, W, n, t, t2, imm8);
|
||||||
|
}
|
||||||
|
|
||||||
bool ThumbTranslatorVisitor::thumb32_LDRD_lit_1(bool U, Reg t, Reg t2, Imm<8> imm8) {
|
bool ThumbTranslatorVisitor::thumb32_LDRD_lit_1(bool U, Reg t, Reg t2, Imm<8> imm8) {
|
||||||
return LoadDualLiteral(*this, U, true, t, t2, imm8);
|
return LoadDualLiteral(*this, U, true, t, t2, imm8);
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,6 +180,8 @@ struct ThumbTranslatorVisitor final {
|
||||||
bool thumb32_STMDB(bool W, Reg n, Imm<15> reg_list);
|
bool thumb32_STMDB(bool W, Reg n, Imm<15> reg_list);
|
||||||
|
|
||||||
// thumb32 load/store dual, load/store exclusive, table branch instructions
|
// thumb32 load/store dual, load/store exclusive, table branch instructions
|
||||||
|
bool thumb32_LDRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8);
|
||||||
|
bool thumb32_LDRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8);
|
||||||
bool thumb32_LDRD_lit_1(bool U, Reg t, Reg t2, Imm<8> imm8);
|
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_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_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8);
|
||||||
|
|
Loading…
Reference in a new issue