Implemented Thumb Instructions: STR (imm, T1), STRB (imm), LDRB (imm), STR (imm, T2), LDR (imm, T2)
This commit is contained in:
parent
a605a43ef9
commit
14dcb18bbe
3 changed files with 83 additions and 3 deletions
|
@ -107,11 +107,14 @@ boost::optional<const Thumb16Matcher<V>&> DecodeThumb16(u16 instruction) {
|
||||||
INST(&V::thumb16_LDRH_reg, "LDRH (reg)", "0101101mmmnnnttt"),
|
INST(&V::thumb16_LDRH_reg, "LDRH (reg)", "0101101mmmnnnttt"),
|
||||||
INST(&V::thumb16_LDRB_reg, "LDRB (reg)", "0101110mmmnnnttt"),
|
INST(&V::thumb16_LDRB_reg, "LDRB (reg)", "0101110mmmnnnttt"),
|
||||||
INST(&V::thumb16_LDRSH_reg, "LDRSH (reg)", "0101111mmmnnnttt"),
|
INST(&V::thumb16_LDRSH_reg, "LDRSH (reg)", "0101111mmmnnnttt"),
|
||||||
|
INST(&V::thumb16_STR_imm_t1, "STR (imm, T1)", "01100vvvvvnnnttt"),
|
||||||
INST(&V::thumb16_LDR_imm_t1, "LDR (imm, T1)", "01101vvvvvnnnttt"),
|
INST(&V::thumb16_LDR_imm_t1, "LDR (imm, T1)", "01101vvvvvnnnttt"),
|
||||||
|
INST(&V::thumb16_STRB_imm, "STRB (imm)", "01110vvvvvnnnttt"),
|
||||||
|
INST(&V::thumb16_LDRB_imm, "LDRB (imm)", "01111vvvvvnnnttt"),
|
||||||
INST(&V::thumb16_STRH_imm, "STRH (imm)", "10000vvvvvnnnttt"),
|
INST(&V::thumb16_STRH_imm, "STRH (imm)", "10000vvvvvnnnttt"),
|
||||||
INST(&V::thumb16_LDRH_imm, "LDRH (imm)", "10001vvvvvnnnttt"),
|
INST(&V::thumb16_LDRH_imm, "LDRH (imm)", "10001vvvvvnnnttt"),
|
||||||
//INST(&V::thumb16_STR_sp, "STR (SP)", "10010dddvvvvvvvv"),
|
INST(&V::thumb16_STR_imm_t2, "STR (imm, T2)", "10010tttvvvvvvvv"),
|
||||||
//INST(&V::thumb16_LDR_sp, "LDR (SP)", "10011dddvvvvvvvv"),
|
INST(&V::thumb16_LDR_imm_t2, "LDR (imm, T2)", "10011tttvvvvvvvv"),
|
||||||
|
|
||||||
// Generate relative address instructions
|
// Generate relative address instructions
|
||||||
INST(&V::thumb16_ADR, "ADR", "10100dddvvvvvvvv"),
|
INST(&V::thumb16_ADR, "ADR", "10100dddvvvvvvvv"),
|
||||||
|
|
|
@ -259,11 +259,26 @@ public:
|
||||||
return Common::StringFromFormat("ldrsh %s, [%s, %s]", RegStr(t), RegStr(n), RegStr(m));
|
return Common::StringFromFormat("ldrsh %s, [%s, %s]", RegStr(t), RegStr(n), RegStr(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string thumb16_STR_imm_t1(Imm5 imm5, Reg n, Reg t) {
|
||||||
|
u32 imm32 = imm5 << 2;
|
||||||
|
return Common::StringFromFormat("str %s, [%s, #%u]", RegStr(t), RegStr(n), imm32);
|
||||||
|
}
|
||||||
|
|
||||||
std::string thumb16_LDR_imm_t1(Imm5 imm5, Reg n, Reg t) {
|
std::string thumb16_LDR_imm_t1(Imm5 imm5, Reg n, Reg t) {
|
||||||
u32 imm32 = imm5 << 2;
|
u32 imm32 = imm5 << 2;
|
||||||
return Common::StringFromFormat("ldr %s, [%s, #%u]", RegStr(t), RegStr(n), imm32);
|
return Common::StringFromFormat("ldr %s, [%s, #%u]", RegStr(t), RegStr(n), imm32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string thumb16_STRB_imm(Imm5 imm5, Reg n, Reg t) {
|
||||||
|
u32 imm32 = imm5;
|
||||||
|
return Common::StringFromFormat("strb %s, [%s, #%u]", RegStr(t), RegStr(n), imm32);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string thumb16_LDRB_imm(Imm5 imm5, Reg n, Reg t) {
|
||||||
|
u32 imm32 = imm5;
|
||||||
|
return Common::StringFromFormat("ldrb %s, [%s, #%u]", RegStr(t), RegStr(n), imm32);
|
||||||
|
}
|
||||||
|
|
||||||
std::string thumb16_STRH_imm(Imm5 imm5, Reg n, Reg t) {
|
std::string thumb16_STRH_imm(Imm5 imm5, Reg n, Reg t) {
|
||||||
u32 imm32 = imm5 << 1;
|
u32 imm32 = imm5 << 1;
|
||||||
return Common::StringFromFormat("strh %s, [%s, #%u]", RegStr(t), RegStr(n), imm32);
|
return Common::StringFromFormat("strh %s, [%s, #%u]", RegStr(t), RegStr(n), imm32);
|
||||||
|
@ -274,6 +289,16 @@ public:
|
||||||
return Common::StringFromFormat("ldrh %s, [%s, #%u]", RegStr(t), RegStr(n), imm32);
|
return Common::StringFromFormat("ldrh %s, [%s, #%u]", RegStr(t), RegStr(n), imm32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string thumb16_STR_imm_t2(Reg t, Imm5 imm5) {
|
||||||
|
u32 imm32 = imm5 << 2;
|
||||||
|
return Common::StringFromFormat("str %s, [sp, #%u]", RegStr(t), imm32);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string thumb16_LDR_imm_t2(Reg t, Imm5 imm5) {
|
||||||
|
u32 imm32 = imm5 << 2;
|
||||||
|
return Common::StringFromFormat("ldr %s, [sp, #%u]", RegStr(t), imm32);
|
||||||
|
}
|
||||||
|
|
||||||
std::string thumb16_ADR(Reg d, Imm8 imm8) {
|
std::string thumb16_ADR(Reg d, Imm8 imm8) {
|
||||||
u32 imm32 = imm8 << 2;
|
u32 imm32 = imm8 << 2;
|
||||||
return Common::StringFromFormat("adr %s, +#%u", RegStr(d), imm32);
|
return Common::StringFromFormat("adr %s, +#%u", RegStr(d), imm32);
|
||||||
|
|
|
@ -476,9 +476,19 @@ struct ThumbTranslatorVisitor final {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool thumb16_STR_imm_t1(Imm5 imm5, Reg n, Reg t) {
|
||||||
|
u32 imm32 = imm5 << 2;
|
||||||
|
// STR <Rt>, [<Rn>, #<imm>]
|
||||||
|
// Rt cannot encode R15.
|
||||||
|
auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
|
||||||
|
auto data = ir.GetRegister(t);
|
||||||
|
ir.WriteMemory32(address, data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool thumb16_LDR_imm_t1(Imm5 imm5, Reg n, Reg t) {
|
bool thumb16_LDR_imm_t1(Imm5 imm5, Reg n, Reg t) {
|
||||||
u32 imm32 = imm5 << 2;
|
u32 imm32 = imm5 << 2;
|
||||||
// LDR <Rt>, [<Rn>, #<imm>}
|
// LDR <Rt>, [<Rn>, #<imm>]
|
||||||
// Rt cannot encode R15.
|
// Rt cannot encode R15.
|
||||||
auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
|
auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
|
||||||
auto data = ir.ReadMemory32(address);
|
auto data = ir.ReadMemory32(address);
|
||||||
|
@ -486,6 +496,26 @@ struct ThumbTranslatorVisitor final {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool thumb16_STRB_imm(Imm5 imm5, Reg n, Reg t) {
|
||||||
|
u32 imm32 = imm5;
|
||||||
|
// STRB <Rt>, [<Rn>, #<imm>]
|
||||||
|
// Rt cannot encode R15.
|
||||||
|
auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
|
||||||
|
auto data = ir.LeastSignificantByte(ir.GetRegister(t));
|
||||||
|
ir.WriteMemory8(address, data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool thumb16_LDRB_imm(Imm5 imm5, Reg n, Reg t) {
|
||||||
|
u32 imm32 = imm5;
|
||||||
|
// LDRB <Rt>, [<Rn>, #<imm>]
|
||||||
|
// Rt cannot encode R15.
|
||||||
|
auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
|
||||||
|
auto data = ir.ZeroExtendByteToWord(ir.ReadMemory8(address));
|
||||||
|
ir.SetRegister(t, data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool thumb16_STRH_imm(Imm5 imm5, Reg n, Reg t) {
|
bool thumb16_STRH_imm(Imm5 imm5, Reg n, Reg t) {
|
||||||
u32 imm32 = imm5 << 1;
|
u32 imm32 = imm5 << 1;
|
||||||
// STRH <Rt>, [<Rn>, #<imm5>]
|
// STRH <Rt>, [<Rn>, #<imm5>]
|
||||||
|
@ -504,6 +534,28 @@ struct ThumbTranslatorVisitor final {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool thumb16_STR_imm_t2(Reg t, Imm5 imm5) {
|
||||||
|
u32 imm32 = imm5 << 2;
|
||||||
|
Reg n = Reg::SP;
|
||||||
|
// STR <Rt>, [<Rn>, #<imm>]
|
||||||
|
// Rt cannot encode R15.
|
||||||
|
auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
|
||||||
|
auto data = ir.GetRegister(t);
|
||||||
|
ir.WriteMemory32(address, data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool thumb16_LDR_imm_t2(Reg t, Imm5 imm5) {
|
||||||
|
u32 imm32 = imm5 << 2;
|
||||||
|
Reg n = Reg::SP;
|
||||||
|
// LDR <Rt>, [<Rn>, #<imm>]
|
||||||
|
// Rt cannot encode R15.
|
||||||
|
auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm32));
|
||||||
|
auto data = ir.ReadMemory32(address);
|
||||||
|
ir.SetRegister(t, data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool thumb16_ADR(Reg d, Imm8 imm8) {
|
bool thumb16_ADR(Reg d, Imm8 imm8) {
|
||||||
u32 imm32 = imm8 << 2;
|
u32 imm32 = imm8 << 2;
|
||||||
// ADR <Rd>, <label>
|
// ADR <Rd>, <label>
|
||||||
|
|
Loading…
Reference in a new issue