Implement Thumb instructions: ADD (SP plus imm, T1), ADD (SP plus imm, T2), SUB (SP minus imm)
This commit is contained in:
parent
c18a3eeab4
commit
9109b226af
4 changed files with 46 additions and 4 deletions
|
@ -39,6 +39,7 @@ inline Reg operator+(Reg reg, int number) {
|
||||||
using Imm3 = u32;
|
using Imm3 = u32;
|
||||||
using Imm4 = u32;
|
using Imm4 = u32;
|
||||||
using Imm5 = u32;
|
using Imm5 = u32;
|
||||||
|
using Imm7 = u32;
|
||||||
using Imm8 = u32;
|
using Imm8 = u32;
|
||||||
using Imm11 = u32;
|
using Imm11 = u32;
|
||||||
using Imm12 = u32;
|
using Imm12 = u32;
|
||||||
|
|
|
@ -113,13 +113,13 @@ boost::optional<const Thumb16Matcher<V>&> DecodeThumb16(u16 instruction) {
|
||||||
//INST(&V::thumb16_STR_sp, "STR (SP)", "10010dddvvvvvvvv"),
|
//INST(&V::thumb16_STR_sp, "STR (SP)", "10010dddvvvvvvvv"),
|
||||||
//INST(&V::thumb16_LDR_sp, "LDR (SP)", "10011dddvvvvvvvv"),
|
//INST(&V::thumb16_LDR_sp, "LDR (SP)", "10011dddvvvvvvvv"),
|
||||||
|
|
||||||
// Generate relative address instruction
|
// Generate relative address instructions
|
||||||
INST(&V::thumb16_ADR, "ADR", "10100dddvvvvvvvv"),
|
INST(&V::thumb16_ADR, "ADR", "10100dddvvvvvvvv"),
|
||||||
//INST(&V::thumb16_ADD_sp, "ADD (relative to SP)", "10101dddvvvvvvvv"),
|
INST(&V::thumb16_ADD_sp_t1, "ADD (SP plus imm, T1)", "10101dddvvvvvvvv"),
|
||||||
|
INST(&V::thumb16_ADD_sp_t2, "ADD (SP plus imm, T2)", "101100000vvvvvvv"), // v4T
|
||||||
|
INST(&V::thumb16_SUB_sp, "SUB (SP minus imm)", "101100001vvvvvvv"), // v4T
|
||||||
|
|
||||||
// Miscellaneous 16-bit instructions
|
// Miscellaneous 16-bit instructions
|
||||||
//INST(&V::thumb16_ADD_spsp, "ADD (imm to SP)", "101100000vvvvvvv"), // v4T
|
|
||||||
//INST(&V::thumb16_SUB_spsp, "SUB (imm from SP)", "101100001vvvvvvv"), // v4T
|
|
||||||
INST(&V::thumb16_SXTH, "SXTH", "1011001000mmmddd"), // v6
|
INST(&V::thumb16_SXTH, "SXTH", "1011001000mmmddd"), // v6
|
||||||
INST(&V::thumb16_SXTB, "SXTB", "1011001001mmmddd"), // v6
|
INST(&V::thumb16_SXTB, "SXTB", "1011001001mmmddd"), // v6
|
||||||
INST(&V::thumb16_UXTH, "UXTH", "1011001010mmmddd"), // v6
|
INST(&V::thumb16_UXTH, "UXTH", "1011001010mmmddd"), // v6
|
||||||
|
|
|
@ -249,6 +249,21 @@ public:
|
||||||
return Common::StringFromFormat("adr %s, +#%u", RegStr(d), imm32);
|
return Common::StringFromFormat("adr %s, +#%u", RegStr(d), imm32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string thumb16_ADD_sp_t1(Reg d, Imm8 imm8) {
|
||||||
|
u32 imm32 = imm8 << 2;
|
||||||
|
return Common::StringFromFormat("add %s, sp, #%u", RegStr(d), imm32);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string thumb16_ADD_sp_t2(Imm7 imm7) {
|
||||||
|
u32 imm32 = imm7 << 2;
|
||||||
|
return Common::StringFromFormat("add sp, sp, #%u", imm32);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string thumb16_SUB_sp(Imm7 imm7) {
|
||||||
|
u32 imm32 = imm7 << 2;
|
||||||
|
return Common::StringFromFormat("sub sp, sp, #%u", imm32);
|
||||||
|
}
|
||||||
|
|
||||||
std::string thumb16_SXTH(Reg m, Reg d) {
|
std::string thumb16_SXTH(Reg m, Reg d) {
|
||||||
return Common::StringFromFormat("sxth %s, %s", RegStr(d), RegStr(m));
|
return Common::StringFromFormat("sxth %s, %s", RegStr(d), RegStr(m));
|
||||||
}
|
}
|
||||||
|
|
|
@ -449,6 +449,32 @@ struct ThumbTranslatorVisitor final {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool thumb16_ADD_sp_t1(Reg d, Imm8 imm8) {
|
||||||
|
u32 imm32 = imm8 << 2;
|
||||||
|
// ADD <Rd>, SP, #<imm>
|
||||||
|
auto result = ir.AddWithCarry(ir.GetRegister(Reg::SP), ir.Imm32(imm32), ir.Imm1(0));
|
||||||
|
ir.SetRegister(d, result.result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool thumb16_ADD_sp_t2(Imm7 imm7) {
|
||||||
|
u32 imm32 = imm7 << 2;
|
||||||
|
Reg d = Reg::SP;
|
||||||
|
// ADD SP, SP, #<imm>
|
||||||
|
auto result = ir.AddWithCarry(ir.GetRegister(Reg::SP), ir.Imm32(imm32), ir.Imm1(0));
|
||||||
|
ir.SetRegister(d, result.result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool thumb16_SUB_sp(Imm7 imm7) {
|
||||||
|
u32 imm32 = imm7 << 2;
|
||||||
|
Reg d = Reg::SP;
|
||||||
|
// SUB SP, SP, #<imm>
|
||||||
|
auto result = ir.SubWithCarry(ir.GetRegister(Reg::SP), ir.Imm32(imm32), ir.Imm1(1));
|
||||||
|
ir.SetRegister(d, result.result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool thumb16_SXTH(Reg m, Reg d) {
|
bool thumb16_SXTH(Reg m, Reg d) {
|
||||||
// SXTH <Rd>, <Rm>
|
// SXTH <Rd>, <Rm>
|
||||||
// Rd cannot encode R15.
|
// Rd cannot encode R15.
|
||||||
|
|
Loading…
Reference in a new issue