ARM: Use mask lookup table for condition codes
Vicki Pfau vi@endrift.com
Fri, 05 Mar 2021 23:38:44 -0800
1 files changed,
21 insertions(+),
47 deletions(-)
jump to
M
src/arm/arm.c
→
src/arm/arm.c
@@ -178,6 +178,25 @@ cpu->spsr = cpsr;
cpu->cpsr.i = 1; } +static const uint16_t conditionLut[16] = { + 0xF0F0, // EQ [-Z--] + 0x0F0F, // NE [-z--] + 0xCCCC, // CS [--C-] + 0x3333, // CC [--c-] + 0xFF00, // MI [N---] + 0x00FF, // PL [n---] + 0xAAAA, // VS [---V] + 0x5555, // VC [---v] + 0x0C0C, // HI [-zC-] + 0xF3F3, // LS [-Z--] || [--c-] + 0xAA55, // GE [N--V] || [n--v] + 0x55AA, // LT [N--v] || [n--V] + 0x0A05, // GT [Nz-V] || [nz-v] + 0xF5FA, // LE [-Z--] || [Nz-v] || [nz-V] + 0xFFFF, // AL [----] + 0x0000 // NV +}; + static inline void ARMStep(struct ARMCore* cpu) { uint32_t opcode = cpu->prefetch[0]; cpu->prefetch[0] = cpu->prefetch[1];@@ -186,53 +205,8 @@ LOAD_32(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion);
unsigned condition = opcode >> 28; if (condition != 0xE) { - bool conditionMet = false; - switch (condition) { - case 0x0: - conditionMet = ARM_COND_EQ; - break; - case 0x1: - conditionMet = ARM_COND_NE; - break; - case 0x2: - conditionMet = ARM_COND_CS; - break; - case 0x3: - conditionMet = ARM_COND_CC; - break; - case 0x4: - conditionMet = ARM_COND_MI; - break; - case 0x5: - conditionMet = ARM_COND_PL; - break; - case 0x6: - conditionMet = ARM_COND_VS; - break; - case 0x7: - conditionMet = ARM_COND_VC; - break; - case 0x8: - conditionMet = ARM_COND_HI; - break; - case 0x9: - conditionMet = ARM_COND_LS; - break; - case 0xA: - conditionMet = ARM_COND_GE; - break; - case 0xB: - conditionMet = ARM_COND_LT; - break; - case 0xC: - conditionMet = ARM_COND_GT; - break; - case 0xD: - conditionMet = ARM_COND_LE; - break; - default: - break; - } + unsigned flags = cpu->cpsr.flags >> 4; + bool conditionMet = conditionLut[condition] & (1 << flags); if (!conditionMet) { cpu->cycles += ARM_PREFETCH_CYCLES; return;