ARM_Disasm: Disassemble BLX

This commit is contained in:
MerryMage 2016-03-28 00:16:44 +01:00
parent 7aaef09f7d
commit 578e5881cc
2 changed files with 23 additions and 2 deletions

View File

@ -3,7 +3,9 @@
#include <string>
#include <unordered_set>
#include "common/assert.h"
#include "common/common_types.h"
#include "common/math_util.h"
#include "common/string_util.h"
#include "core/arm/disassembler/arm_disasm.h"
@ -252,8 +254,7 @@ std::string ARM_Disasm::Disassemble(u32 addr, u32 insn)
case OP_BKPT:
return DisassembleBKPT(insn);
case OP_BLX:
// not supported yet
break;
return DisassembleBLX(insn);
case OP_BX:
return DisassembleBX(insn);
case OP_CDP:
@ -513,6 +514,21 @@ std::string ARM_Disasm::DisassembleBX(u32 insn)
return Common::StringFromFormat("bx%s\tr%d", cond_to_str(cond), rn);
}
std::string ARM_Disasm::DisassembleBLX(u32 insn)
{
if ((insn & 0xFE000000) == 0xFA000000) {
u32 imm24 = insn & 0xFFFFFF;
u32 H = (insn >> 24) & 1;
s32 offset = MathUtil::SignExtend<26, s32>(imm24 << 2 + H << 1) + 8;
return Common::StringFromFormat("blx\t#+%d", offset);
} else if ((insn & 0x0FFFFFF0) == 0x012FFF30) {
u8 cond = (insn >> 28) & 0xf;
u8 rn = insn & 0xf;
return Common::StringFromFormat("blx%s\tr%d", cond_to_str(cond), rn);
}
UNREACHABLE();
}
std::string ARM_Disasm::DisassembleBKPT(u32 insn)
{
u8 cond = (insn >> 28) & 0xf;
@ -1062,6 +1078,10 @@ Opcode ARM_Disasm::Decode00(u32 insn) {
// Bx instruction
return OP_BX;
}
if ((insn & 0x0ffffff0) == 0x012fff30) {
// Blx instruction
return OP_BLX;
}
if ((insn & 0x0ff000f0) == 0x01600010) {
// Clz instruction
return OP_CLZ;

View File

@ -213,6 +213,7 @@ class ARM_Disasm {
static std::string DisassembleALU(Opcode opcode, u32 insn);
static std::string DisassembleBranch(u32 addr, Opcode opcode, u32 insn);
static std::string DisassembleBX(u32 insn);
static std::string DisassembleBLX(u32 insn);
static std::string DisassembleBKPT(u32 insn);
static std::string DisassembleCLZ(u32 insn);
static std::string DisassembleMediaMulDiv(Opcode opcode, u32 insn);