Update base address register after restoring register bank.
This commit is contained in:
parent
010ac81f2a
commit
dda308f5fd
@ -1,3 +1,10 @@
|
|||||||
|
2001-02-01 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* armemu.c (LoadSMult): Update base address register after
|
||||||
|
restoring register bank.
|
||||||
|
(StoreMult): Update base address register after restoring register
|
||||||
|
bank.
|
||||||
|
|
||||||
2001-01-31 Nick Clifton <nickc@redhat.com>
|
2001-01-31 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* armvirt.c (PutWord): Detect installation of SWI vector.
|
* armvirt.c (PutWord): Detect installation of SWI vector.
|
||||||
|
@ -2932,7 +2932,6 @@ ARMul_Emulate26 (register ARMul_State * state)
|
|||||||
LOADSMULT (instr, temp + 4L, temp);
|
LOADSMULT (instr, temp + 4L, temp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case 0x88: /* Store, No WriteBack, Post Inc */
|
case 0x88: /* Store, No WriteBack, Post Inc */
|
||||||
STOREMULT (instr, LSBase, 0L);
|
STOREMULT (instr, LSBase, 0L);
|
||||||
break;
|
break;
|
||||||
@ -2969,7 +2968,6 @@ ARMul_Emulate26 (register ARMul_State * state)
|
|||||||
LOADSMULT (instr, temp, temp + LSMNumRegs);
|
LOADSMULT (instr, temp, temp + LSMNumRegs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case 0x90: /* Store, No WriteBack, Pre Dec */
|
case 0x90: /* Store, No WriteBack, Pre Dec */
|
||||||
STOREMULT (instr, LSBase - LSMNumRegs, 0L);
|
STOREMULT (instr, LSBase - LSMNumRegs, 0L);
|
||||||
break;
|
break;
|
||||||
@ -3006,7 +3004,6 @@ ARMul_Emulate26 (register ARMul_State * state)
|
|||||||
LOADSMULT (instr, temp, temp);
|
LOADSMULT (instr, temp, temp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case 0x98: /* Store, No WriteBack, Pre Inc */
|
case 0x98: /* Store, No WriteBack, Pre Inc */
|
||||||
STOREMULT (instr, LSBase + 4L, 0L);
|
STOREMULT (instr, LSBase + 4L, 0L);
|
||||||
break;
|
break;
|
||||||
@ -4340,7 +4337,9 @@ LoadSMult (ARMul_State * state, ARMword instr,
|
|||||||
UNDEF_LSMNoRegs;
|
UNDEF_LSMNoRegs;
|
||||||
UNDEF_LSMPCBase;
|
UNDEF_LSMPCBase;
|
||||||
UNDEF_LSMBaseInListWb;
|
UNDEF_LSMBaseInListWb;
|
||||||
|
|
||||||
BUSUSEDINCPCS;
|
BUSUSEDINCPCS;
|
||||||
|
|
||||||
#ifndef MODE32
|
#ifndef MODE32
|
||||||
if (ADDREXCEPT (address))
|
if (ADDREXCEPT (address))
|
||||||
{
|
{
|
||||||
@ -4348,27 +4347,34 @@ LoadSMult (ARMul_State * state, ARMword instr,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!BIT (15) && state->Bank != USERBANK)
|
|
||||||
{
|
|
||||||
(void) ARMul_SwitchMode (state, state->Mode, USER26MODE); /* temporary reg bank switch */
|
|
||||||
UNDEF_LSMUserBankWb;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BIT (21) && LHSReg != 15)
|
if (BIT (21) && LHSReg != 15)
|
||||||
LSBase = WBBase;
|
LSBase = WBBase;
|
||||||
|
|
||||||
for (temp = 0; !BIT (temp); temp++); /* N cycle first */
|
if (!BIT (15) && state->Bank != USERBANK)
|
||||||
|
{
|
||||||
|
/* Temporary reg bank switch. */
|
||||||
|
(void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
|
||||||
|
UNDEF_LSMUserBankWb;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (temp = 0; !BIT (temp); temp ++)
|
||||||
|
; /* N cycle first. */
|
||||||
|
|
||||||
dest = ARMul_LoadWordN (state, address);
|
dest = ARMul_LoadWordN (state, address);
|
||||||
|
|
||||||
if (!state->abortSig)
|
if (!state->abortSig)
|
||||||
state->Reg[temp++] = dest;
|
state->Reg[temp++] = dest;
|
||||||
else if (!state->Aborted)
|
else if (!state->Aborted)
|
||||||
state->Aborted = ARMul_DataAbortV;
|
state->Aborted = ARMul_DataAbortV;
|
||||||
|
|
||||||
for (; temp < 16; temp++) /* S cycles from here on */
|
for (; temp < 16; temp++)
|
||||||
|
/* S cycles from here on. */
|
||||||
if (BIT (temp))
|
if (BIT (temp))
|
||||||
{ /* load this register */
|
{
|
||||||
|
/* Load this register. */
|
||||||
address += 4;
|
address += 4;
|
||||||
dest = ARMul_LoadWordS (state, address);
|
dest = ARMul_LoadWordS (state, address);
|
||||||
|
|
||||||
if (!state->abortSig && !state->Aborted)
|
if (!state->abortSig && !state->Aborted)
|
||||||
state->Reg[temp] = dest;
|
state->Reg[temp] = dest;
|
||||||
else if (!state->Aborted)
|
else if (!state->Aborted)
|
||||||
@ -4376,17 +4382,20 @@ LoadSMult (ARMul_State * state, ARMword instr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (BIT (15) && !state->Aborted)
|
if (BIT (15) && !state->Aborted)
|
||||||
{ /* PC is in the reg list */
|
{
|
||||||
|
/* PC is in the reg list. */
|
||||||
#ifdef MODE32
|
#ifdef MODE32
|
||||||
if (state->Mode != USER26MODE && state->Mode != USER32MODE)
|
if (state->Mode != USER26MODE && state->Mode != USER32MODE)
|
||||||
{
|
{
|
||||||
state->Cpsr = GETSPSR (state->Bank);
|
state->Cpsr = GETSPSR (state->Bank);
|
||||||
ARMul_CPSRAltered (state);
|
ARMul_CPSRAltered (state);
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteR15 (state, PC);
|
WriteR15 (state, PC);
|
||||||
#else
|
#else
|
||||||
if (state->Mode == USER26MODE || state->Mode == USER32MODE)
|
if (state->Mode == USER26MODE || state->Mode == USER32MODE)
|
||||||
{ /* protect bits in user mode */
|
{
|
||||||
|
/* Protect bits in user mode. */
|
||||||
ASSIGNN ((state->Reg[15] & NBIT) != 0);
|
ASSIGNN ((state->Reg[15] & NBIT) != 0);
|
||||||
ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
|
ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
|
||||||
ASSIGNC ((state->Reg[15] & CBIT) != 0);
|
ASSIGNC ((state->Reg[15] & CBIT) != 0);
|
||||||
@ -4399,9 +4408,11 @@ LoadSMult (ARMul_State * state, ARMword instr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!BIT (15) && state->Mode != USER26MODE && state->Mode != USER32MODE)
|
if (!BIT (15) && state->Mode != USER26MODE && state->Mode != USER32MODE)
|
||||||
(void) ARMul_SwitchMode (state, USER26MODE, state->Mode); /* restore the correct bank */
|
/* Restore the correct bank. */
|
||||||
|
(void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
|
||||||
|
|
||||||
ARMul_Icycles (state, 1, 0L); /* to write back the final register */
|
/* To write back the final register. */
|
||||||
|
ARMul_Icycles (state, 1, 0L);
|
||||||
|
|
||||||
if (state->Aborted)
|
if (state->Aborted)
|
||||||
{
|
{
|
||||||
@ -4409,7 +4420,6 @@ LoadSMult (ARMul_State * state, ARMword instr,
|
|||||||
LSBase = WBBase;
|
LSBase = WBBase;
|
||||||
TAKEABORT;
|
TAKEABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************\
|
/***************************************************************************\
|
||||||
@ -4491,68 +4501,89 @@ StoreMult (ARMul_State * state, ARMword instr,
|
|||||||
\***************************************************************************/
|
\***************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
StoreSMult (ARMul_State * state, ARMword instr,
|
StoreSMult (
|
||||||
ARMword address, ARMword WBBase)
|
ARMul_State * state,
|
||||||
|
ARMword instr,
|
||||||
|
ARMword address,
|
||||||
|
ARMword WBBase)
|
||||||
{
|
{
|
||||||
ARMword temp;
|
ARMword temp;
|
||||||
|
|
||||||
UNDEF_LSMNoRegs;
|
UNDEF_LSMNoRegs;
|
||||||
UNDEF_LSMPCBase;
|
UNDEF_LSMPCBase;
|
||||||
UNDEF_LSMBaseInListWb;
|
UNDEF_LSMBaseInListWb;
|
||||||
|
|
||||||
BUSUSEDINCPCN;
|
BUSUSEDINCPCN;
|
||||||
|
|
||||||
#ifndef MODE32
|
#ifndef MODE32
|
||||||
if (VECTORACCESS (address) || ADDREXCEPT (address))
|
if (VECTORACCESS (address) || ADDREXCEPT (address))
|
||||||
{
|
{
|
||||||
INTERNALABORT (address);
|
INTERNALABORT (address);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BIT (15))
|
if (BIT (15))
|
||||||
PATCHR15;
|
PATCHR15;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (state->Bank != USERBANK)
|
if (state->Bank != USERBANK)
|
||||||
{
|
{
|
||||||
(void) ARMul_SwitchMode (state, state->Mode, USER26MODE); /* Force User Bank */
|
/* Force User Bank. */
|
||||||
|
(void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
|
||||||
UNDEF_LSMUserBankWb;
|
UNDEF_LSMUserBankWb;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (temp = 0; !BIT (temp); temp++); /* N cycle first */
|
for (temp = 0; !BIT (temp); temp++)
|
||||||
|
; /* N cycle first. */
|
||||||
|
|
||||||
#ifdef MODE32
|
#ifdef MODE32
|
||||||
ARMul_StoreWordN (state, address, state->Reg[temp++]);
|
ARMul_StoreWordN (state, address, state->Reg[temp++]);
|
||||||
#else
|
#else
|
||||||
if (state->Aborted)
|
if (state->Aborted)
|
||||||
{
|
{
|
||||||
(void) ARMul_LoadWordN (state, address);
|
(void) ARMul_LoadWordN (state, address);
|
||||||
for (; temp < 16; temp++) /* Fake the Stores as Loads */
|
|
||||||
|
for (; temp < 16; temp++)
|
||||||
|
/* Fake the Stores as Loads. */
|
||||||
if (BIT (temp))
|
if (BIT (temp))
|
||||||
{ /* save this register */
|
{
|
||||||
|
/* Save this register. */
|
||||||
address += 4;
|
address += 4;
|
||||||
(void) ARMul_LoadWordS (state, address);
|
(void) ARMul_LoadWordS (state, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BIT (21) && LHSReg != 15)
|
if (BIT (21) && LHSReg != 15)
|
||||||
LSBase = WBBase;
|
LSBase = WBBase;
|
||||||
|
|
||||||
TAKEABORT;
|
TAKEABORT;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ARMul_StoreWordN (state, address, state->Reg[temp++]);
|
ARMul_StoreWordN (state, address, state->Reg[temp++]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (state->abortSig && !state->Aborted)
|
if (state->abortSig && !state->Aborted)
|
||||||
state->Aborted = ARMul_DataAbortV;
|
state->Aborted = ARMul_DataAbortV;
|
||||||
|
|
||||||
if (BIT (21) && LHSReg != 15)
|
for (; temp < 16; temp++)
|
||||||
LSBase = WBBase;
|
/* S cycles from here on. */
|
||||||
|
|
||||||
for (; temp < 16; temp++) /* S cycles from here on */
|
|
||||||
if (BIT (temp))
|
if (BIT (temp))
|
||||||
{ /* save this register */
|
{
|
||||||
|
/* Save this register. */
|
||||||
address += 4;
|
address += 4;
|
||||||
|
|
||||||
ARMul_StoreWordS (state, address, state->Reg[temp]);
|
ARMul_StoreWordS (state, address, state->Reg[temp]);
|
||||||
|
|
||||||
if (state->abortSig && !state->Aborted)
|
if (state->abortSig && !state->Aborted)
|
||||||
state->Aborted = ARMul_DataAbortV;
|
state->Aborted = ARMul_DataAbortV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->Mode != USER26MODE && state->Mode != USER32MODE)
|
if (state->Mode != USER26MODE && state->Mode != USER32MODE)
|
||||||
(void) ARMul_SwitchMode (state, USER26MODE, state->Mode); /* restore the correct bank */
|
/* Restore the correct bank. */
|
||||||
|
(void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
|
||||||
|
|
||||||
|
if (BIT (21) && LHSReg != 15)
|
||||||
|
LSBase = WBBase;
|
||||||
|
|
||||||
if (state->Aborted)
|
if (state->Aborted)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user