ARM: Use mask lookup table for condition codes

This commit is contained in:
Vicki Pfau 2021-03-05 23:38:44 -08:00
parent cc739bb369
commit 74fd2c3c0b
1 changed files with 21 additions and 47 deletions

View File

@ -178,6 +178,25 @@ void ARMRaiseUndefined(struct ARMCore* cpu) {
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 @@ static inline void ARMStep(struct ARMCore* cpu) {
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;