Update base address register after restoring register bank.

This commit is contained in:
Nick Clifton 2001-02-01 20:39:51 +00:00
parent 010ac81f2a
commit dda308f5fd
2 changed files with 67 additions and 29 deletions

View File

@ -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.

View File

@ -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)
{ {