diff --git a/src/ARMInterpreter_LoadStore.cpp b/src/ARMInterpreter_LoadStore.cpp index cb646df5..a3bb1e6c 100644 --- a/src/ARMInterpreter_LoadStore.cpp +++ b/src/ARMInterpreter_LoadStore.cpp @@ -400,11 +400,7 @@ void A_LDM(ARM* cpu) if (!(cpu->CurInstr & (1<<23))) { - for (int i = 0; i < 16; i++) - { - if (cpu->CurInstr & (1<CurInstr & 0xFFFF); if (cpu->CurInstr & (1<<21)) { @@ -418,16 +414,17 @@ void A_LDM(ARM* cpu) if ((cpu->CurInstr & (1<<22)) && !(cpu->CurInstr & (1<<15))) cpu->UpdateMode(cpu->CPSR, (cpu->CPSR&~0x1F)|0x10, true); - for (int i = 0; i < 15; i++) + u16 reglist = cpu->CurInstr & 0x7FFF; + while (reglist) { - if (cpu->CurInstr & (1<DataRead32 (base, &cpu->R[i]); - else cpu->DataRead32S(base, &cpu->R[i]); - first = false; - if (!preinc) base += 4; - } + int i = __builtin_ctz(reglist); + reglist ^= 1<DataRead32 (base, &cpu->R[i]); + else cpu->DataRead32S(base, &cpu->R[i]); + first = false; + if (!preinc) base += 4; } if (cpu->CurInstr & (1<<15)) @@ -479,11 +476,7 @@ void A_STM(ARM* cpu) if (!(cpu->CurInstr & (1<<23))) { - for (u32 i = 0; i < 16; i++) - { - if (cpu->CurInstr & (1<CurInstr & 0xFFFF); if (cpu->CurInstr & (1<<21)) cpu->R[baseid] = base; @@ -503,26 +496,27 @@ void A_STM(ARM* cpu) cpu->UpdateMode(cpu->CPSR, (cpu->CPSR&~0x1F)|0x10, true); } - for (u32 i = 0; i < 16; i++) + u16 reglist = cpu->CurInstr & 0xFFFF; + while (reglist) { - if (cpu->CurInstr & (1<Num == 0) || (!(cpu->CurInstr & ((1<DataWrite32(base, oldbase) : cpu->DataWrite32S(base, oldbase); - else - first ? cpu->DataWrite32(base, base) : cpu->DataWrite32S(base, base); // checkme - } + if ((cpu->Num == 0) || (!(cpu->CurInstr & ((1<DataWrite32(base, oldbase) : cpu->DataWrite32S(base, oldbase); else - first ? cpu->DataWrite32(base, cpu->R[i]) : cpu->DataWrite32S(base, cpu->R[i]); - - first = false; - - if (!preinc) base += 4; + first ? cpu->DataWrite32(base, base) : cpu->DataWrite32S(base, base); // checkme } + else + first ? cpu->DataWrite32(base, cpu->R[i]) : cpu->DataWrite32S(base, cpu->R[i]); + + first = false; + + if (!preinc) base += 4; } if (cpu->CurInstr & (1<<22)) @@ -700,31 +694,23 @@ void T_LDR_SPREL(ARM* cpu) void T_PUSH(ARM* cpu) { - int nregs = 0; bool first = true; - for (int i = 0; i < 8; i++) - { - if (cpu->CurInstr & (1<CurInstr & (1<<8)) - nregs++; - u32 base = cpu->R[13]; - base -= (nregs<<2); + base -= 4 * __builtin_popcount(cpu->CurInstr & 0x1FF); + cpu->R[13] = base; - for (int i = 0; i < 8; i++) + u8 reglist = cpu->CurInstr & 0xFF; + while (reglist) { - if (cpu->CurInstr & (1<DataWrite32 (base, cpu->R[i]); - else cpu->DataWrite32S(base, cpu->R[i]); - first = false; - base += 4; - } + int i = __builtin_ctz(reglist); + reglist ^= 1<DataWrite32 (base, cpu->R[i]); + else cpu->DataWrite32S(base, cpu->R[i]); + first = false; + base += 4; } if (cpu->CurInstr & (1<<8)) @@ -741,15 +727,16 @@ void T_POP(ARM* cpu) u32 base = cpu->R[13]; bool first = true; - for (int i = 0; i < 8; i++) + u8 reglist = cpu->CurInstr & 0xFF; + while (reglist) { - if (cpu->CurInstr & (1<DataRead32 (base, &cpu->R[i]); - else cpu->DataRead32S(base, &cpu->R[i]); - first = false; - base += 4; - } + int i = __builtin_ctz(reglist); + reglist ^= 1<DataRead32 (base, &cpu->R[i]); + else cpu->DataRead32S(base, &cpu->R[i]); + first = false; + base += 4; } if (cpu->CurInstr & (1<<8)) @@ -771,15 +758,16 @@ void T_STMIA(ARM* cpu) u32 base = cpu->R[(cpu->CurInstr >> 8) & 0x7]; bool first = true; - for (int i = 0; i < 8; i++) + u8 reglist = cpu->CurInstr & 0xFF; + while (reglist) { - if (cpu->CurInstr & (1<DataWrite32 (base, cpu->R[i]); - else cpu->DataWrite32S(base, cpu->R[i]); - first = false; - base += 4; - } + int i = __builtin_ctz(reglist); + reglist ^= 1<DataWrite32 (base, cpu->R[i]); + else cpu->DataWrite32S(base, cpu->R[i]); + first = false; + base += 4; } // TODO: check "Rb included in Rlist" case @@ -792,15 +780,16 @@ void T_LDMIA(ARM* cpu) u32 base = cpu->R[(cpu->CurInstr >> 8) & 0x7]; bool first = true; - for (int i = 0; i < 8; i++) + u8 reglist = cpu->CurInstr & 0xFF; + while (reglist) { - if (cpu->CurInstr & (1<DataRead32 (base, &cpu->R[i]); - else cpu->DataRead32S(base, &cpu->R[i]); - first = false; - base += 4; - } + int i = __builtin_ctz(reglist); + reglist ^= 1<DataRead32 (base, &cpu->R[i]); + else cpu->DataRead32S(base, &cpu->R[i]); + first = false; + base += 4; } if (!(cpu->CurInstr & (1<<((cpu->CurInstr >> 8) & 0x7))))