use bit manip instead of loops for ldm/stm
This commit is contained in:
parent
56638c89bc
commit
f6b73decc7
|
@ -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<<i))
|
||||
base -= 4;
|
||||
}
|
||||
base -= 4 * __builtin_popcount(cpu->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<<i))
|
||||
{
|
||||
if (preinc) base += 4;
|
||||
if (first) cpu->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<<i;
|
||||
|
||||
if (preinc) base += 4;
|
||||
if (first) cpu->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<<i))
|
||||
base -= 4;
|
||||
}
|
||||
base -= 4 * __builtin_popcount(cpu->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<<i))
|
||||
int i = __builtin_ctz(reglist);
|
||||
reglist ^= 1<<i;
|
||||
|
||||
if (preinc) base += 4;
|
||||
|
||||
if (i == baseid && !isbanked)
|
||||
{
|
||||
if (preinc) base += 4;
|
||||
|
||||
if (i == baseid && !isbanked)
|
||||
{
|
||||
if ((cpu->Num == 0) || (!(cpu->CurInstr & ((1<<i)-1))))
|
||||
first ? cpu->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<<i)-1))))
|
||||
first ? cpu->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<<i))
|
||||
nregs++;
|
||||
}
|
||||
|
||||
if (cpu->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<<i))
|
||||
{
|
||||
if (first) cpu->DataWrite32 (base, cpu->R[i]);
|
||||
else cpu->DataWrite32S(base, cpu->R[i]);
|
||||
first = false;
|
||||
base += 4;
|
||||
}
|
||||
int i = __builtin_ctz(reglist);
|
||||
reglist ^= 1<<i;
|
||||
|
||||
if (first) cpu->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<<i))
|
||||
{
|
||||
if (first) cpu->DataRead32 (base, &cpu->R[i]);
|
||||
else cpu->DataRead32S(base, &cpu->R[i]);
|
||||
first = false;
|
||||
base += 4;
|
||||
}
|
||||
int i = __builtin_ctz(reglist);
|
||||
reglist ^= 1<<i;
|
||||
|
||||
if (first) cpu->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<<i))
|
||||
{
|
||||
if (first) cpu->DataWrite32 (base, cpu->R[i]);
|
||||
else cpu->DataWrite32S(base, cpu->R[i]);
|
||||
first = false;
|
||||
base += 4;
|
||||
}
|
||||
int i = __builtin_ctz(reglist);
|
||||
reglist ^= 1<<i;
|
||||
|
||||
if (first) cpu->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<<i))
|
||||
{
|
||||
if (first) cpu->DataRead32 (base, &cpu->R[i]);
|
||||
else cpu->DataRead32S(base, &cpu->R[i]);
|
||||
first = false;
|
||||
base += 4;
|
||||
}
|
||||
int i = __builtin_ctz(reglist);
|
||||
reglist ^= 1<<i;
|
||||
|
||||
if (first) cpu->DataRead32 (base, &cpu->R[i]);
|
||||
else cpu->DataRead32S(base, &cpu->R[i]);
|
||||
first = false;
|
||||
base += 4;
|
||||
}
|
||||
|
||||
if (!(cpu->CurInstr & (1<<((cpu->CurInstr >> 8) & 0x7))))
|
||||
|
|
Loading…
Reference in New Issue