Implement Thumb instructions: ADD (SP plus imm, T1), ADD (SP plus imm, T2), SUB (SP minus imm)

This commit is contained in:
MerryMage 2016-07-18 11:16:12 +01:00
parent c18a3eeab4
commit 9109b226af
4 changed files with 46 additions and 4 deletions

View file

@ -39,6 +39,7 @@ inline Reg operator+(Reg reg, int number) {
using Imm3 = u32;
using Imm4 = u32;
using Imm5 = u32;
using Imm7 = u32;
using Imm8 = u32;
using Imm11 = u32;
using Imm12 = u32;

View file

@ -113,13 +113,13 @@ boost::optional<const Thumb16Matcher<V>&> DecodeThumb16(u16 instruction) {
//INST(&V::thumb16_STR_sp, "STR (SP)", "10010dddvvvvvvvv"),
//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_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
//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_SXTB, "SXTB", "1011001001mmmddd"), // v6
INST(&V::thumb16_UXTH, "UXTH", "1011001010mmmddd"), // v6

View file

@ -249,6 +249,21 @@ public:
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) {
return Common::StringFromFormat("sxth %s, %s", RegStr(d), RegStr(m));
}

View file

@ -449,6 +449,32 @@ struct ThumbTranslatorVisitor final {
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) {
// SXTH <Rd>, <Rm>
// Rd cannot encode R15.