TranslateArm: Implement STM, STMDA, STMDB, STMIB
This commit is contained in:
parent
5d26899ac9
commit
d0d51ba346
4 changed files with 83 additions and 6 deletions
|
@ -229,7 +229,10 @@ std::vector<ArmMatcher<V>> GetArmDecodeTable() {
|
||||||
INST(&V::arm_LDMIB, "LDMIB", "cccc100110w1nnnnxxxxxxxxxxxxxxxx"), // all
|
INST(&V::arm_LDMIB, "LDMIB", "cccc100110w1nnnnxxxxxxxxxxxxxxxx"), // all
|
||||||
INST(&V::arm_LDM_usr, "LDM (usr reg)", "----100--101--------------------"), // all
|
INST(&V::arm_LDM_usr, "LDM (usr reg)", "----100--101--------------------"), // all
|
||||||
INST(&V::arm_LDM_eret, "LDM (exce ret)", "----100--1-1----1---------------"), // all
|
INST(&V::arm_LDM_eret, "LDM (exce ret)", "----100--1-1----1---------------"), // all
|
||||||
INST(&V::arm_STM, "STM", "cccc100pu0w0nnnnxxxxxxxxxxxxxxxx"), // all
|
INST(&V::arm_STM, "STM", "cccc100010w0nnnnxxxxxxxxxxxxxxxx"), // all
|
||||||
|
INST(&V::arm_STMDA, "STMDA", "cccc100000w0nnnnxxxxxxxxxxxxxxxx"), // all
|
||||||
|
INST(&V::arm_STMDB, "STMDB", "cccc100100w0nnnnxxxxxxxxxxxxxxxx"), // all
|
||||||
|
INST(&V::arm_STMIB, "STMIB", "cccc100110w0nnnnxxxxxxxxxxxxxxxx"), // all
|
||||||
INST(&V::arm_STM_usr, "STM (usr reg)", "----100--100--------------------"), // all
|
INST(&V::arm_STM_usr, "STM (usr reg)", "----100--100--------------------"), // all
|
||||||
|
|
||||||
// Miscellaneous instructions
|
// Miscellaneous instructions
|
||||||
|
|
|
@ -381,7 +381,18 @@ public:
|
||||||
}
|
}
|
||||||
std::string arm_LDM_usr() { return "ice"; }
|
std::string arm_LDM_usr() { return "ice"; }
|
||||||
std::string arm_LDM_eret() { return "ice"; }
|
std::string arm_LDM_eret() { return "ice"; }
|
||||||
std::string arm_STM(Cond cond, bool P, bool U, bool W, Reg n, RegList list) { return "ice"; }
|
std::string arm_STM(Cond cond, bool W, Reg n, RegList list) {
|
||||||
|
return Common::StringFromFormat("stm%s %s%s, {%s}", CondToString(cond), RegToString(n), W ? "!" : "", RegListToString(list).c_str());
|
||||||
|
}
|
||||||
|
std::string arm_STMDA(Cond cond, bool W, Reg n, RegList list) {
|
||||||
|
return Common::StringFromFormat("stmda%s %s%s, {%s}", CondToString(cond), RegToString(n), W ? "!" : "", RegListToString(list).c_str());
|
||||||
|
}
|
||||||
|
std::string arm_STMDB(Cond cond, bool W, Reg n, RegList list) {
|
||||||
|
return Common::StringFromFormat("stmdb%s %s%s, {%s}", CondToString(cond), RegToString(n), W ? "!" : "", RegListToString(list).c_str());
|
||||||
|
}
|
||||||
|
std::string arm_STMIB(Cond cond, bool W, Reg n, RegList list) {
|
||||||
|
return Common::StringFromFormat("stmib%s %s%s, {%s}", CondToString(cond), RegToString(n), W ? "!" : "", RegListToString(list).c_str());
|
||||||
|
}
|
||||||
std::string arm_STM_usr() { return "ice"; }
|
std::string arm_STM_usr() { return "ice"; }
|
||||||
|
|
||||||
// Miscellaneous instructions
|
// Miscellaneous instructions
|
||||||
|
|
|
@ -371,7 +371,6 @@ static bool LDMHelper(IREmitter& ir, bool W, Reg n, RegList list, IR::Value star
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_LDM(Cond cond, bool W, Reg n, RegList list) {
|
bool ArmTranslatorVisitor::arm_LDM(Cond cond, bool W, Reg n, RegList list) {
|
||||||
if (n == Reg::PC || Common::BitCount(list) < 1)
|
if (n == Reg::PC || Common::BitCount(list) < 1)
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
|
@ -428,8 +427,69 @@ bool ArmTranslatorVisitor::arm_LDM_eret() {
|
||||||
return InterpretThisInstruction();
|
return InterpretThisInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_STM(Cond cond, bool P, bool U, bool W, Reg n, RegList list) {
|
static bool STMHelper(IREmitter& ir, bool W, Reg n, RegList list, IR::Value start_address, IR::Value writeback_address) {
|
||||||
return InterpretThisInstruction();
|
auto address = start_address;
|
||||||
|
for (size_t i = 0; i <= 14; i++) {
|
||||||
|
if (Common::Bit(i, list)) {
|
||||||
|
ir.WriteMemory32(address, ir.GetRegister(static_cast<Reg>(i)));
|
||||||
|
address = ir.Add(address, ir.Imm32(4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (W) {
|
||||||
|
ir.SetRegister(n, writeback_address);
|
||||||
|
}
|
||||||
|
if (Common::Bit<15>(list)) {
|
||||||
|
ir.WriteMemory32(address, ir.Imm32(ir.PC()));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_STM(Cond cond, bool W, Reg n, RegList list) {
|
||||||
|
if (n == Reg::PC || Common::BitCount(list) < 1)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
// STM <Rn>{!}, <reg_list>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto start_address = ir.GetRegister(n);
|
||||||
|
auto writeback_address = ir.Add(start_address, ir.Imm32(u32(Common::BitCount(list) * 4)));
|
||||||
|
return STMHelper(ir, W, n, list, start_address, writeback_address);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_STMDA(Cond cond, bool W, Reg n, RegList list) {
|
||||||
|
if (n == Reg::PC || Common::BitCount(list) < 1)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
// STMDA <Rn>{!}, <reg_list>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto start_address = ir.Sub(ir.GetRegister(n), ir.Imm32(u32(4 * Common::BitCount(list) - 4)));
|
||||||
|
auto writeback_address = ir.Add(start_address, ir.Imm32(4));
|
||||||
|
return STMHelper(ir, W, n, list, start_address, writeback_address);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_STMDB(Cond cond, bool W, Reg n, RegList list) {
|
||||||
|
if (n == Reg::PC || Common::BitCount(list) < 1)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
// STMDB <Rn>{!}, <reg_list>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto start_address = ir.Sub(ir.GetRegister(n), ir.Imm32(u32(4 * Common::BitCount(list))));
|
||||||
|
auto writeback_address = start_address;
|
||||||
|
return STMHelper(ir, W, n, list, start_address, writeback_address);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::arm_STMIB(Cond cond, bool W, Reg n, RegList list) {
|
||||||
|
if (n == Reg::PC || Common::BitCount(list) < 1)
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
// STMIB <Rn>{!}, <reg_list>
|
||||||
|
if (ConditionPassed(cond)) {
|
||||||
|
auto start_address = ir.Add(ir.GetRegister(n), ir.Imm32(4));
|
||||||
|
auto writeback_address = ir.Add(ir.GetRegister(n), ir.Imm32(u32(4 * Common::BitCount(list))));
|
||||||
|
return STMHelper(ir, W, n, list, start_address, writeback_address);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_STM_usr() {
|
bool ArmTranslatorVisitor::arm_STM_usr() {
|
||||||
|
|
|
@ -192,7 +192,10 @@ struct ArmTranslatorVisitor final {
|
||||||
bool arm_LDMIB(Cond cond, bool W, Reg n, RegList list);
|
bool arm_LDMIB(Cond cond, bool W, Reg n, RegList list);
|
||||||
bool arm_LDM_usr();
|
bool arm_LDM_usr();
|
||||||
bool arm_LDM_eret();
|
bool arm_LDM_eret();
|
||||||
bool arm_STM(Cond cond, bool P, bool U, bool W, Reg n, RegList list);
|
bool arm_STM(Cond cond, bool W, Reg n, RegList list);
|
||||||
|
bool arm_STMDA(Cond cond, bool W, Reg n, RegList list);
|
||||||
|
bool arm_STMDB(Cond cond, bool W, Reg n, RegList list);
|
||||||
|
bool arm_STMIB(Cond cond, bool W, Reg n, RegList list);
|
||||||
bool arm_STM_usr();
|
bool arm_STM_usr();
|
||||||
|
|
||||||
// Miscellaneous instructions
|
// Miscellaneous instructions
|
||||||
|
|
Loading…
Reference in a new issue