all repos — mgba @ cd07dee7b17e6b15578f40a74eb2798e8996f835

mGBA Game Boy Advance Emulator

Implement immediate shifter
Jeffrey Pfau jeffrey@endrift.com
Fri, 05 Apr 2013 00:43:47 -0700
commit

cd07dee7b17e6b15578f40a74eb2798e8996f835

parent

c07df4a33749841108cf4501d69858e9f794a0c0

1 files changed, 18 insertions(+), 7 deletions(-)

jump to
M src/arm.csrc/arm.c

@@ -1,5 +1,8 @@

#include "arm.h" +#define ARM_SIGN(I) ((I) >> 31) +#define ARM_ROR(I, ROTATE) (((I) >> ROTATE) | (I << (32 - ROTATE))) + static inline void _ARMSetMode(struct ARMCore*, enum ExecutionMode); static ARMInstruction _ARMLoadInstructionARM(struct ARMMemory*, uint32_t address, uint32_t* opcodeOut); static ARMInstruction _ARMLoadInstructionThumb(struct ARMMemory*, uint32_t address, uint32_t* opcodeOut);

@@ -17,7 +20,15 @@ // TODO

} static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) { - // TODO + int rotate = (opcode & 0x00000F00) >> 7; + int immediate = opcode & 0x000000FF; + if (!rotate) { + cpu->shifterOperand = immediate; + cpu->shifterCarryOut = cpu->cpsr.c; + } else { + cpu->shifterOperand = ARM_ROR(immediate, rotate); + cpu->shifterCarryOut = ARM_SIGN(cpu->shifterOperand); + } } static const ARMInstruction armTable[0xF000];

@@ -89,10 +100,10 @@

// Instruction definitions // Beware pre-processor antics -#define ARM_CARRY_FROM(M, N, D) ((((M) | (N)) >> 31) && !((D) >> 31)) +#define ARM_CARRY_FROM(M, N, D) ((ARM_SIGN((M) | (N))) && !(ARM_SIGN(D))) #define ARM_BORROW_FROM(M, N, D) (((uint32_t) (M)) >= ((uint32_t) (N))) -#define ARM_V_ADDITION(M, N, D) (!(((M) ^ (N)) >> 31) && (((M) ^ (D)) >> 31) && (((N) ^ (D)) >> 31)) -#define ARM_V_SUBTRACTION(M, N, D) ((((M) ^ (N)) >> 31) && (((M) ^ (D)) >> 31)) +#define ARM_V_ADDITION(M, N, D) (!(ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D))) && (ARM_SIGN((N) ^ (D)))) +#define ARM_V_SUBTRACTION(M, N, D) ((ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D)))) #define ARM_COND_EQ (cpu->cpsr.z) #define ARM_COND_NE (!cpu->cpsr.z)

@@ -115,7 +126,7 @@ if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \

cpu->cpsr = cpu->spsr; \ _ARMReadCPSR(cpu); \ } else { \ - cpu->cpsr.n = (D) >> 31; \ + cpu->cpsr.n = ARM_SIGN(D); \ cpu->cpsr.z = !(D); \ cpu->cpsr.c = ARM_CARRY_FROM(M, N, D); \ cpu->cpsr.v = ARM_V_ADDITION(M, N, D); \

@@ -126,7 +137,7 @@ if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \

cpu->cpsr = cpu->spsr; \ _ARMReadCPSR(cpu); \ } else { \ - cpu->cpsr.n = (D) >> 31; \ + cpu->cpsr.n = ARM_SIGN(D); \ cpu->cpsr.z = !(D); \ cpu->cpsr.c = ARM_BORROW_FROM(M, N, D); \ cpu->cpsr.v = ARM_V_SUBTRACTION(M, N, D); \

@@ -137,7 +148,7 @@ if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \

cpu->cpsr = cpu->spsr; \ _ARMReadCPSR(cpu); \ } else { \ - cpu->cpsr.n = (D) >> 31; \ + cpu->cpsr.n = ARM_SIGN(D); \ cpu->cpsr.z = !(D); \ cpu->cpsr.c = cpu->shifterCarryOut; \ }