ARM9: Implement BLX (2) Thumb

This commit is contained in:
Jeffrey Pfau 2017-01-03 22:39:37 -08:00
parent ac58636a9e
commit 967215dcef
4 changed files with 30 additions and 2 deletions

View File

@ -50,8 +50,8 @@
DECLARE_INSTRUCTION_WITH_HIGH_THUMB(EMITTER, MOV3), \
DECLARE_INSTRUCTION_THUMB(EMITTER, BX), \
DECLARE_INSTRUCTION_THUMB(EMITTER, BX), \
DECLARE_INSTRUCTION_THUMB(EMITTER, ILL), \
DECLARE_INSTRUCTION_THUMB(EMITTER, ILL), \
MIN_V(DECLARE_INSTRUCTION_THUMB(EMITTER, BLX2), DECLARE_INSTRUCTION_THUMB(EMITTER, ILL), V >= 5), \
MIN_V(DECLARE_INSTRUCTION_THUMB(EMITTER, BLX2), DECLARE_INSTRUCTION_THUMB(EMITTER, ILL), V >= 5), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, LDR3))), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, STR2)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, STRH2)), \

View File

@ -290,6 +290,12 @@ DEFINE_THUMB_DECODER(BLX1, BLX,
ARM_OPERAND_REGISTER_2 | ARM_OPERAND_IMMEDIATE_3;
info->branchType = ARM_BRANCH_LINKED;)
DEFINE_THUMB_DECODER(BLX2, BLX,
info->op1.reg = (opcode >> 3) & 0xF;
info->op2.reg = ARM_LR;
info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_REGISTER_2 | ARM_OPERAND_AFFECTED_2;
info->branchType = ARM_BRANCH_INDIRECT;)
DEFINE_THUMB_DECODER(BX, BX,
info->op1.reg = (opcode >> 3) & 0xF;
info->operandFormat = ARM_OPERAND_REGISTER_1;

View File

@ -393,6 +393,13 @@ int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, i
if (info->operandFormat & ARM_OPERAND_IMMEDIATE_1) {
written = _decodePCRelative(info->op1.immediate, pc, buffer, blen);
ADVANCE(written);
} else if (info->operandFormat & ARM_OPERAND_REGISTER_1) {
written = _decodeRegister(info->op1.reg, buffer, blen);
ADVANCE(written);
if (info->op1.reg > ARM_PC) {
written = _decodePSR(info->op1.psrBits, buffer, blen);
ADVANCE(written);
}
}
break;
default:

View File

@ -404,6 +404,21 @@ DEFINE_INSTRUCTION_THUMB(BX,
ARM_WRITE_PC;
})
DEFINE_INSTRUCTION_THUMB(BLX2,
int rm = (opcode >> 3) & 0xF;
_ARMSetMode(cpu, cpu->gprs[rm] & 0x00000001);
int misalign = 0;
if (rm == ARM_PC) {
misalign = cpu->gprs[rm] & 0x00000002;
}
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - 1;
cpu->gprs[ARM_PC] = (cpu->gprs[rm] & 0xFFFFFFFE) - misalign;
if (cpu->executionMode == MODE_THUMB) {
THUMB_WRITE_PC;
} else {
ARM_WRITE_PC;
})
DEFINE_INSTRUCTION_THUMB(SWI, cpu->irqh.swi16(cpu, opcode & 0xFF))
const ThumbInstruction _thumbv4Table[0x400] = {