* armemu.h (WRITEDESTB): New macro.
* armemu.c (ARMul_Emulate26, bl): Use WriteR15Branch() to modify PC. Moved the existing logic... (WriteR15Branch): ... here. New function. (WriteR15, WriteSR15): Drop the two least significant bits. (LoadSMult): Use WriteR15Branch() to modify PC. (LoadMult): Use WRITEDESTB() instead of WRITEDEST().
This commit is contained in:
parent
cf52c765b0
commit
892c6b9d8f
3 changed files with 48 additions and 37 deletions
|
@ -1,5 +1,13 @@
|
||||||
2000-07-04 Alexandre Oliva <aoliva@redhat.com>
|
2000-07-04 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
|
* armemu.h (WRITEDESTB): New macro.
|
||||||
|
* armemu.c (ARMul_Emulate26, bl): Use WriteR15Branch() to
|
||||||
|
modify PC. Moved the existing logic...
|
||||||
|
(WriteR15Branch): ... here. New function.
|
||||||
|
(WriteR15, WriteSR15): Drop the two least significant bits.
|
||||||
|
(LoadSMult): Use WriteR15Branch() to modify PC.
|
||||||
|
(LoadMult): Use WRITEDESTB() instead of WRITEDEST().
|
||||||
|
|
||||||
* armemu.h (GETSPSR): Call ARMul_GetSPSR().
|
* armemu.h (GETSPSR): Call ARMul_GetSPSR().
|
||||||
* armsupp.c (ARMul_CPSRAltered): Zero out bits as they're
|
* armsupp.c (ARMul_CPSRAltered): Zero out bits as they're
|
||||||
extracted from state->Cpsr, but preserve the unused bits.
|
extracted from state->Cpsr, but preserve the unused bits.
|
||||||
|
|
|
@ -24,6 +24,7 @@ static ARMword GetDPRegRHS (ARMul_State * state, ARMword instr);
|
||||||
static ARMword GetDPSRegRHS (ARMul_State * state, ARMword instr);
|
static ARMword GetDPSRegRHS (ARMul_State * state, ARMword instr);
|
||||||
static void WriteR15 (ARMul_State * state, ARMword src);
|
static void WriteR15 (ARMul_State * state, ARMword src);
|
||||||
static void WriteSR15 (ARMul_State * state, ARMword src);
|
static void WriteSR15 (ARMul_State * state, ARMword src);
|
||||||
|
static void WriteR15Branch (ARMul_State * state, ARMword src);
|
||||||
static ARMword GetLSRegRHS (ARMul_State * state, ARMword instr);
|
static ARMword GetLSRegRHS (ARMul_State * state, ARMword instr);
|
||||||
static ARMword GetLS7RHS (ARMul_State * state, ARMword instr);
|
static ARMword GetLS7RHS (ARMul_State * state, ARMword instr);
|
||||||
static unsigned LoadWord (ARMul_State * state, ARMword instr,
|
static unsigned LoadWord (ARMul_State * state, ARMword instr,
|
||||||
|
@ -1082,35 +1083,8 @@ ARMul_Emulate26 (register ARMul_State * state)
|
||||||
#ifdef MODET
|
#ifdef MODET
|
||||||
if (BITS (4, 27) == 0x12FFF1)
|
if (BITS (4, 27) == 0x12FFF1)
|
||||||
{ /* BX */
|
{ /* BX */
|
||||||
/* Branch to the address in RHSReg. If bit0 of
|
WriteR15Branch (state, state->Reg[RHSReg]);
|
||||||
destination address is 1 then switch to Thumb mode: */
|
break;
|
||||||
ARMword addr = state->Reg[RHSReg];
|
|
||||||
|
|
||||||
/* If we read the PC then the bottom bit is clear */
|
|
||||||
if (RHSReg == 15)
|
|
||||||
addr &= ~1;
|
|
||||||
|
|
||||||
/* Enable this for a helpful bit of debugging when
|
|
||||||
GDB is not yet fully working...
|
|
||||||
fprintf (stderr, "BX at %x to %x (go %s)\n",
|
|
||||||
state->Reg[15], addr, (addr & 1) ? "thumb": "arm" ); */
|
|
||||||
|
|
||||||
if (addr & (1 << 0))
|
|
||||||
{ /* Thumb bit */
|
|
||||||
SETT;
|
|
||||||
state->Reg[15] = addr & 0xfffffffe;
|
|
||||||
/* NOTE: The other CPSR flag setting blocks do not
|
|
||||||
seem to update the state->Cpsr state, but just do
|
|
||||||
the explicit flag. The copy from the seperate
|
|
||||||
flags to the register must happen later. */
|
|
||||||
FLUSHPIPE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CLEART;
|
|
||||||
state->Reg[15] = addr & 0xfffffffc;
|
|
||||||
FLUSHPIPE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (DESTReg == 15)
|
if (DESTReg == 15)
|
||||||
|
@ -3128,11 +3102,14 @@ GetDPSRegRHS (ARMul_State * state, ARMword instr)
|
||||||
static void
|
static void
|
||||||
WriteR15 (ARMul_State * state, ARMword src)
|
WriteR15 (ARMul_State * state, ARMword src)
|
||||||
{
|
{
|
||||||
/* The ARM documentation implies (but doe snot state) that the bottom bit of the PC is never set */
|
/* 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;
|
||||||
#ifdef MODE32
|
#ifdef MODE32
|
||||||
state->Reg[15] = src & PCBITS & ~0x1;
|
state->Reg[15] = src & PCBITS;
|
||||||
#else
|
#else
|
||||||
state->Reg[15] = (src & R15PCBITS & ~0x1) | ECC | ER15INT | EMODE;
|
state->Reg[15] = (src & R15PCBITS) | ECC | ER15INT | EMODE;
|
||||||
ARMul_R15Altered (state);
|
ARMul_R15Altered (state);
|
||||||
#endif
|
#endif
|
||||||
FLUSHPIPE;
|
FLUSHPIPE;
|
||||||
|
@ -3145,6 +3122,7 @@ WriteR15 (ARMul_State * state, ARMword src)
|
||||||
static void
|
static void
|
||||||
WriteSR15 (ARMul_State * state, ARMword src)
|
WriteSR15 (ARMul_State * state, ARMword src)
|
||||||
{
|
{
|
||||||
|
src &= 0xfffffffc;
|
||||||
#ifdef MODE32
|
#ifdef MODE32
|
||||||
state->Reg[15] = src & PCBITS;
|
state->Reg[15] = src & PCBITS;
|
||||||
if (state->Bank > 0)
|
if (state->Bank > 0)
|
||||||
|
@ -3162,6 +3140,29 @@ WriteSR15 (ARMul_State * state, ARMword src)
|
||||||
FLUSHPIPE;
|
FLUSHPIPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM
|
||||||
|
will switch to Thumb mode if the least significant bit is set. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
WriteR15Branch (ARMul_State * state, ARMword src)
|
||||||
|
{
|
||||||
|
#ifdef MODET
|
||||||
|
if (src & 1)
|
||||||
|
{ /* Thumb bit */
|
||||||
|
SETT;
|
||||||
|
state->Reg[15] = src & 0xfffffffe;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CLEART;
|
||||||
|
state->Reg[15] = src & 0xfffffffc;
|
||||||
|
}
|
||||||
|
FLUSHPIPE;
|
||||||
|
#else
|
||||||
|
WriteR15 (state, src);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************\
|
/***************************************************************************\
|
||||||
* This routine evaluates most Load and Store register RHS's. It is *
|
* This routine evaluates most Load and Store register RHS's. It is *
|
||||||
* intended to be called from the macro LSRegRHS, which filters the *
|
* intended to be called from the macro LSRegRHS, which filters the *
|
||||||
|
@ -3249,7 +3250,7 @@ LoadWord (ARMul_State * state, ARMword instr, ARMword address)
|
||||||
}
|
}
|
||||||
if (address & 3)
|
if (address & 3)
|
||||||
dest = ARMul_Align (state, address, dest);
|
dest = ARMul_Align (state, address, dest);
|
||||||
WRITEDEST (dest);
|
WRITEDESTB (dest);
|
||||||
ARMul_Icycles (state, 1, 0L);
|
ARMul_Icycles (state, 1, 0L);
|
||||||
|
|
||||||
return (DESTReg != LHSReg);
|
return (DESTReg != LHSReg);
|
||||||
|
@ -3471,10 +3472,7 @@ LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
|
||||||
|
|
||||||
if (BIT (15) && !state->Aborted)
|
if (BIT (15) && !state->Aborted)
|
||||||
{ /* PC is in the reg list */
|
{ /* PC is in the reg list */
|
||||||
#ifdef MODE32
|
WriteR15Branch(state, PC);
|
||||||
state->Reg[15] = PC;
|
|
||||||
#endif
|
|
||||||
FLUSHPIPE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ARMul_Icycles (state, 1, 0L); /* to write back the final register */
|
ARMul_Icycles (state, 1, 0L); /* to write back the final register */
|
||||||
|
|
|
@ -332,6 +332,11 @@ extern ARMword isize;
|
||||||
ARMul_NegZero(state, d) ; \
|
ARMul_NegZero(state, d) ; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define WRITEDESTB(d) if (DESTReg == 15) \
|
||||||
|
WriteR15Branch(state, d) ; \
|
||||||
|
else \
|
||||||
|
DEST = d
|
||||||
|
|
||||||
#define BYTETOBUS(data) ((data & 0xff) | \
|
#define BYTETOBUS(data) ((data & 0xff) | \
|
||||||
((data & 0xff) << 8) | \
|
((data & 0xff) << 8) | \
|
||||||
((data & 0xff) << 16) | \
|
((data & 0xff) << 16) | \
|
||||||
|
|
Loading…
Reference in a new issue