aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
Diffstat (limited to 'sim')
-rw-r--r--sim/arm/ChangeLog7
-rw-r--r--sim/arm/armemu.c83
2 files changed, 64 insertions, 26 deletions
diff --git a/sim/arm/ChangeLog b/sim/arm/ChangeLog
index b4ffb90..0bd88b5 100644
--- a/sim/arm/ChangeLog
+++ b/sim/arm/ChangeLog
@@ -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>
* armvirt.c (PutWord): Detect installation of SWI vector.
diff --git a/sim/arm/armemu.c b/sim/arm/armemu.c
index 47dc1b8..a7923d4 100644
--- a/sim/arm/armemu.c
+++ b/sim/arm/armemu.c
@@ -2932,7 +2932,6 @@ ARMul_Emulate26 (register ARMul_State * state)
LOADSMULT (instr, temp + 4L, temp);
break;
-
case 0x88: /* Store, No WriteBack, Post Inc */
STOREMULT (instr, LSBase, 0L);
break;
@@ -2969,7 +2968,6 @@ ARMul_Emulate26 (register ARMul_State * state)
LOADSMULT (instr, temp, temp + LSMNumRegs);
break;
-
case 0x90: /* Store, No WriteBack, Pre Dec */
STOREMULT (instr, LSBase - LSMNumRegs, 0L);
break;
@@ -3006,7 +3004,6 @@ ARMul_Emulate26 (register ARMul_State * state)
LOADSMULT (instr, temp, temp);
break;
-
case 0x98: /* Store, No WriteBack, Pre Inc */
STOREMULT (instr, LSBase + 4L, 0L);
break;
@@ -4340,7 +4337,9 @@ LoadSMult (ARMul_State * state, ARMword instr,
UNDEF_LSMNoRegs;
UNDEF_LSMPCBase;
UNDEF_LSMBaseInListWb;
+
BUSUSEDINCPCS;
+
#ifndef MODE32
if (ADDREXCEPT (address))
{
@@ -4348,27 +4347,34 @@ LoadSMult (ARMul_State * state, ARMword instr,
}
#endif
+ if (BIT (21) && LHSReg != 15)
+ LSBase = WBBase;
+
if (!BIT (15) && state->Bank != USERBANK)
{
- (void) ARMul_SwitchMode (state, state->Mode, USER26MODE); /* temporary reg bank switch */
+ /* Temporary reg bank switch. */
+ (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
UNDEF_LSMUserBankWb;
}
- if (BIT (21) && LHSReg != 15)
- LSBase = WBBase;
+ for (temp = 0; !BIT (temp); temp ++)
+ ; /* N cycle first. */
- for (temp = 0; !BIT (temp); temp++); /* N cycle first */
dest = ARMul_LoadWordN (state, address);
+
if (!state->abortSig)
state->Reg[temp++] = dest;
else if (!state->Aborted)
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))
- { /* load this register */
+ {
+ /* Load this register. */
address += 4;
dest = ARMul_LoadWordS (state, address);
+
if (!state->abortSig && !state->Aborted)
state->Reg[temp] = dest;
else if (!state->Aborted)
@@ -4376,17 +4382,20 @@ LoadSMult (ARMul_State * state, ARMword instr,
}
if (BIT (15) && !state->Aborted)
- { /* PC is in the reg list */
+ {
+ /* PC is in the reg list. */
#ifdef MODE32
if (state->Mode != USER26MODE && state->Mode != USER32MODE)
{
state->Cpsr = GETSPSR (state->Bank);
ARMul_CPSRAltered (state);
}
+
WriteR15 (state, PC);
#else
if (state->Mode == USER26MODE || state->Mode == USER32MODE)
- { /* protect bits in user mode */
+ {
+ /* Protect bits in user mode. */
ASSIGNN ((state->Reg[15] & NBIT) != 0);
ASSIGNZ ((state->Reg[15] & ZBIT) != 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)
- (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)
{
@@ -4409,7 +4420,6 @@ LoadSMult (ARMul_State * state, ARMword instr,
LSBase = WBBase;
TAKEABORT;
}
-
}
/***************************************************************************\
@@ -4491,68 +4501,89 @@ StoreMult (ARMul_State * state, ARMword instr,
\***************************************************************************/
static void
-StoreSMult (ARMul_State * state, ARMword instr,
- ARMword address, ARMword WBBase)
+StoreSMult (
+ ARMul_State * state,
+ ARMword instr,
+ ARMword address,
+ ARMword WBBase)
{
ARMword temp;
UNDEF_LSMNoRegs;
UNDEF_LSMPCBase;
UNDEF_LSMBaseInListWb;
+
BUSUSEDINCPCN;
+
#ifndef MODE32
if (VECTORACCESS (address) || ADDREXCEPT (address))
{
INTERNALABORT (address);
}
+
if (BIT (15))
PATCHR15;
#endif
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;
}
- for (temp = 0; !BIT (temp); temp++); /* N cycle first */
+ for (temp = 0; !BIT (temp); temp++)
+ ; /* N cycle first. */
+
#ifdef MODE32
ARMul_StoreWordN (state, address, state->Reg[temp++]);
#else
if (state->Aborted)
{
(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))
- { /* save this register */
+ {
+ /* Save this register. */
address += 4;
(void) ARMul_LoadWordS (state, address);
}
+
if (BIT (21) && LHSReg != 15)
LSBase = WBBase;
+
TAKEABORT;
+
return;
}
else
ARMul_StoreWordN (state, address, state->Reg[temp++]);
#endif
+
if (state->abortSig && !state->Aborted)
state->Aborted = ARMul_DataAbortV;
- if (BIT (21) && LHSReg != 15)
- LSBase = WBBase;
-
- for (; temp < 16; temp++) /* S cycles from here on */
+ for (; temp < 16; temp++)
+ /* S cycles from here on. */
if (BIT (temp))
- { /* save this register */
+ {
+ /* Save this register. */
address += 4;
+
ARMul_StoreWordS (state, address, state->Reg[temp]);
+
if (state->abortSig && !state->Aborted)
state->Aborted = ARMul_DataAbortV;
}
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)
{