all repos — mgba @ 967215dcef72d77c5d111c258c9d5c5050dcf6ba

mGBA Game Boy Advance Emulator

ARM9: Implement BLX (2) Thumb
Jeffrey Pfau jeffrey@endrift.com
Tue, 03 Jan 2017 22:39:37 -0800
commit

967215dcef72d77c5d111c258c9d5c5050dcf6ba

parent

ac58636a9ebbbc345b2b4b896877af02027d6448

M include/mgba/internal/arm/emitter-thumb.hinclude/mgba/internal/arm/emitter-thumb.h

@@ -50,8 +50,8 @@ DECLARE_INSTRUCTION_WITH_HIGH_THUMB(EMITTER, CMP3), \

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)), \
M src/arm/decoder-thumb.csrc/arm/decoder-thumb.c

@@ -290,6 +290,12 @@ info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 |

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;
M src/arm/decoder.csrc/arm/decoder.c

@@ -393,6 +393,13 @@ case ARM_MN_BLX:

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:
M src/arm/isa-thumb.csrc/arm/isa-thumb.c

@@ -404,6 +404,21 @@ } else {

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] = {