Implement BX
Jeffrey Pfau jeffrey@endrift.com
Thu, 11 Apr 2013 00:14:12 -0700
3 files changed,
20 insertions(+),
6 deletions(-)
M
src/arm.c
→
src/arm.c
@@ -1,6 +1,8 @@
#include "arm.h" +#include "isa-arm.h" #include "isa-inlines.h" +#include "isa-thumb.h" static inline enum RegisterBank _ARMSelectBank(enum PrivilegeMode);@@ -107,7 +109,7 @@ cpu->board->reset(cpu->board);
} void ARMRun(struct ARMCore* cpu) { - if (cpu->executionMode) { + if (cpu->executionMode == MODE_THUMB) { ThumbStep(cpu); } else { ARMStep(cpu);
M
src/isa-arm.c
→
src/isa-arm.c
@@ -126,10 +126,6 @@
// Instruction definitions // Beware pre-processor antics -#define ARM_WRITE_PC \ - cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM) + WORD_SIZE_ARM; \ - cpu->memory->setActiveRegion(cpu->memory, cpu->gprs[ARM_PC]); - #define ARM_ADDITION_S(M, N, D) \ if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \ cpu->cpsr = cpu->spsr; \@@ -412,7 +408,15 @@ cpu->gprs[ARM_PC] += offset; \
ARM_WRITE_PC;) DEFINE_INSTRUCTION_ARM(BL, ARM_STUB) -DEFINE_INSTRUCTION_ARM(BX, ARM_STUB) +DEFINE_INSTRUCTION_ARM(BX, \ + int rm = opcode & 0x0000000F; \ + _ARMSetMode(cpu, cpu->gprs[rm] & 0x00000001); \ + cpu->gprs[ARM_PC] = cpu->gprs[rm] & 0xFFFFFFFE; \ + if (cpu->executionMode == MODE_THUMB) { \ + THUMB_WRITE_PC; + } else { \ + ARM_WRITE_PC; \ + }) // End branch definitions
M
src/isa-inlines.h
→
src/isa-inlines.h
@@ -54,6 +54,14 @@ #define ARM_V_SUBTRACTION(M, N, D) ((ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D))))
#define ARM_STUB cpu->board->hitStub(cpu->board, opcode) +#define ARM_WRITE_PC \ + cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM) + WORD_SIZE_ARM; \ + cpu->memory->setActiveRegion(cpu->memory, cpu->gprs[ARM_PC]); + +#define THUMB_WRITE_PC \ + cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_THUMB) + WORD_SIZE_THUMB; \ + cpu->memory->setActiveRegion(cpu->memory, cpu->gprs[ARM_PC]); + static inline int _ARMModeHasSPSR(enum PrivilegeMode mode) { return mode != MODE_SYSTEM && mode != MODE_USER; }