Implement Thumb PUSH instruction

This commit is contained in:
MerryMage
2016-07-18 15:11:16 +01:00
parent 9109b226af
commit f7e3d7b8d2
10 changed files with 191 additions and 54 deletions

View File

@@ -7,6 +7,7 @@
#include <tuple>
#include "common/assert.h"
#include "common/bit_util.h"
#include "frontend/arm_types.h"
#include "frontend/decoder/thumb16.h"
#include "frontend/ir/ir_emitter.h"
@@ -507,6 +508,28 @@ struct ThumbTranslatorVisitor final {
return true;
}
bool thumb16_PUSH(bool M, RegList reg_list) {
if (M) reg_list |= 1 << 14;
if (Common::BitCount(reg_list) < 1) {
return UnpredictableInstruction();
}
// PUSH <reg_list>
// reg_list cannot encode for R15.
u32 num_bytes_to_push = static_cast<u32>(4 * Common::BitCount(reg_list));
const auto final_address = ir.Sub(ir.GetRegister(Reg::SP), ir.Imm32(num_bytes_to_push));
auto address = final_address;
for (size_t i = 0; i < 16; i++) {
if (Common::Bit(i, reg_list)) {
auto Ri = ir.GetRegister(static_cast<Reg>(i));
ir.WriteMemory32(address, Ri);
address = ir.Add(address, ir.Imm32(4));
}
}
ir.SetRegister(Reg::SP, final_address);
// TODO(optimization): Possible location for an RSB push.
return true;
}
bool thumb16_REV(Reg m, Reg d) {
// REV <Rd>, <Rm>
// Rd cannot encode R15.