* armemu.h (INSN_SIZE): New macro.
(SET_ABORT): Save CPSR in SPSR and set LR. * armemu.c (ARMul_Emulate, isize): Set to INSN_SIZE. (WriteR15, WriteSR15): Do not discard bit 1 in Thumb mode. * arminit.c (ARMul_Abort): Use new SETABORT and INSN_SIZE.
This commit is contained in:
parent
13b6dd6f68
commit
e063aa3bd8
@ -1,5 +1,11 @@
|
||||
2000-07-04 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* armemu.h (INSN_SIZE): New macro.
|
||||
(SET_ABORT): Save CPSR in SPSR and set LR.
|
||||
* armemu.c (ARMul_Emulate, isize): Set to INSN_SIZE.
|
||||
(WriteR15, WriteSR15): Do not discard bit 1 in Thumb mode.
|
||||
* arminit.c (ARMul_Abort): Use new SETABORT and INSN_SIZE.
|
||||
|
||||
* armemu.c (LoadSMult): Use WriteR15() to discard the least
|
||||
significant bits of PC.
|
||||
|
||||
|
@ -299,14 +299,7 @@ ARMul_Emulate26 (register ARMul_State * state)
|
||||
|
||||
do
|
||||
{ /* just keep going */
|
||||
#ifdef MODET
|
||||
if (TFLAG)
|
||||
{
|
||||
isize = 2;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
isize = 4;
|
||||
isize = INSN_SIZE;
|
||||
switch (state->NextInstr)
|
||||
{
|
||||
case SEQ:
|
||||
@ -3104,8 +3097,15 @@ WriteR15 (ARMul_State * state, ARMword src)
|
||||
{
|
||||
/* The ARM documentation states that the two least significant bits
|
||||
are discarded when setting PC, except in the cases handled by
|
||||
WriteR15Branch() below. */
|
||||
src &= 0xfffffffc;
|
||||
WriteR15Branch() below. It's probably an oversight: in THUMB
|
||||
mode, the second least significant bit should probably not be
|
||||
discarded. */
|
||||
#ifdef MODET
|
||||
if (TFLAG)
|
||||
src &= 0xfffffffe;
|
||||
else
|
||||
#endif
|
||||
src &= 0xfffffffc;
|
||||
#ifdef MODE32
|
||||
state->Reg[15] = src & PCBITS;
|
||||
#else
|
||||
@ -3122,15 +3122,26 @@ WriteR15 (ARMul_State * state, ARMword src)
|
||||
static void
|
||||
WriteSR15 (ARMul_State * state, ARMword src)
|
||||
{
|
||||
src &= 0xfffffffc;
|
||||
#ifdef MODE32
|
||||
state->Reg[15] = src & PCBITS;
|
||||
if (state->Bank > 0)
|
||||
{
|
||||
state->Cpsr = state->Spsr[state->Bank];
|
||||
ARMul_CPSRAltered (state);
|
||||
}
|
||||
#ifdef MODET
|
||||
if (TFLAG)
|
||||
src &= 0xfffffffe;
|
||||
else
|
||||
#endif
|
||||
src &= 0xfffffffc;
|
||||
state->Reg[15] = src & PCBITS;
|
||||
#else
|
||||
#ifdef MODET
|
||||
if (TFLAG)
|
||||
abort (); /* ARMul_R15Altered would have to support it. */
|
||||
else
|
||||
#endif
|
||||
src &= 0xfffffffc;
|
||||
if (state->Bank == USERBANK)
|
||||
state->Reg[15] = (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE;
|
||||
else
|
||||
|
@ -73,6 +73,9 @@ extern ARMword isize;
|
||||
#define SETT state->TFlag = 1
|
||||
#define CLEART state->TFlag = 0
|
||||
#define ASSIGNT(res) state->TFlag = res
|
||||
#define INSN_SIZE (TFLAG ? 2 : 4)
|
||||
#else
|
||||
#define INSN_SIZE 4
|
||||
#endif
|
||||
|
||||
#define NFLAG state->NFlag
|
||||
@ -179,7 +182,13 @@ extern ARMword isize;
|
||||
state->Reg[15] = R15PC | ((s) & (CCBITS | R15INTBITS | R15MODEBITS)) ; \
|
||||
ARMul_R15Altered (state) ; \
|
||||
}
|
||||
#define SETABORT(i,m) state->Cpsr = ECC | EINT | (i) | (m)
|
||||
#define SETABORT(i,m,d) do { \
|
||||
int SETABORT_mode = (m); \
|
||||
ARMul_SetSPSR (state, SETABORT_mode, ARMul_GetCPSR (state)); \
|
||||
ARMul_SetCPSR (state, ((ARMul_GetCPSR (state) & ~(EMODE | TBIT)) \
|
||||
| (i) | SETABORT_mode)); \
|
||||
state->Reg[14] = temp - (d); \
|
||||
} while (0)
|
||||
|
||||
#ifndef MODE32
|
||||
#define VECTORS 0x20
|
||||
|
@ -253,6 +253,7 @@ void
|
||||
ARMul_Abort (ARMul_State * state, ARMword vector)
|
||||
{
|
||||
ARMword temp;
|
||||
int isize = INSN_SIZE;
|
||||
|
||||
state->Aborted = FALSE;
|
||||
|
||||
@ -270,53 +271,29 @@ ARMul_Abort (ARMul_State * state, ARMword vector)
|
||||
switch (vector)
|
||||
{
|
||||
case ARMul_ResetV: /* RESET */
|
||||
state->Spsr[SVCBANK] = CPSR;
|
||||
SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp;
|
||||
SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE, 0);
|
||||
break;
|
||||
case ARMul_UndefinedInstrV: /* Undefined Instruction */
|
||||
state->Spsr[state->prog32Sig ? UNDEFBANK : SVCBANK] = CPSR;
|
||||
SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4;
|
||||
SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE, isize);
|
||||
break;
|
||||
case ARMul_SWIV: /* Software Interrupt */
|
||||
state->Spsr[SVCBANK] = CPSR;
|
||||
SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4;
|
||||
SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE, isize);
|
||||
break;
|
||||
case ARMul_PrefetchAbortV: /* Prefetch Abort */
|
||||
state->AbortAddr = 1;
|
||||
state->Spsr[state->prog32Sig ? ABORTBANK : SVCBANK] = CPSR;
|
||||
SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4;
|
||||
SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, isize);
|
||||
break;
|
||||
case ARMul_DataAbortV: /* Data Abort */
|
||||
state->Spsr[state->prog32Sig ? ABORTBANK : SVCBANK] = CPSR;
|
||||
SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4; /* the PC must have been incremented */
|
||||
SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, isize);
|
||||
break;
|
||||
case ARMul_AddrExceptnV: /* Address Exception */
|
||||
state->Spsr[SVCBANK] = CPSR;
|
||||
SETABORT (IBIT, SVC26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4;
|
||||
SETABORT (IBIT, SVC26MODE, isize);
|
||||
break;
|
||||
case ARMul_IRQV: /* IRQ */
|
||||
state->Spsr[IRQBANK] = CPSR;
|
||||
SETABORT (IBIT, state->prog32Sig ? IRQ32MODE : IRQ26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4;
|
||||
SETABORT (IBIT, state->prog32Sig ? IRQ32MODE : IRQ26MODE, isize);
|
||||
break;
|
||||
case ARMul_FIQV: /* FIQ */
|
||||
state->Spsr[FIQBANK] = CPSR;
|
||||
SETABORT (INTBITS, state->prog32Sig ? FIQ32MODE : FIQ26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4;
|
||||
SETABORT (INTBITS, state->prog32Sig ? FIQ32MODE : FIQ26MODE, isize);
|
||||
break;
|
||||
}
|
||||
if (ARMul_MODE32BIT)
|
||||
|
Loading…
Reference in New Issue
Block a user