* 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:
Alexandre Oliva 2000-07-04 06:35:36 +00:00
parent cf52c765b0
commit 892c6b9d8f
3 changed files with 48 additions and 37 deletions

View File

@ -1,5 +1,13 @@
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().
* armsupp.c (ARMul_CPSRAltered): Zero out bits as they're
extracted from state->Cpsr, but preserve the unused bits.

View File

@ -24,6 +24,7 @@ static ARMword GetDPRegRHS (ARMul_State * state, ARMword instr);
static ARMword GetDPSRegRHS (ARMul_State * state, ARMword instr);
static void WriteR15 (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 GetLS7RHS (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
if (BITS (4, 27) == 0x12FFF1)
{ /* BX */
/* Branch to the address in RHSReg. If bit0 of
destination address is 1 then switch to Thumb mode: */
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;
}
WriteR15Branch (state, state->Reg[RHSReg]);
break;
}
#endif
if (DESTReg == 15)
@ -3128,11 +3102,14 @@ GetDPSRegRHS (ARMul_State * state, ARMword instr)
static void
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
state->Reg[15] = src & PCBITS & ~0x1;
state->Reg[15] = src & PCBITS;
#else
state->Reg[15] = (src & R15PCBITS & ~0x1) | ECC | ER15INT | EMODE;
state->Reg[15] = (src & R15PCBITS) | ECC | ER15INT | EMODE;
ARMul_R15Altered (state);
#endif
FLUSHPIPE;
@ -3145,6 +3122,7 @@ 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)
@ -3162,6 +3140,29 @@ WriteSR15 (ARMul_State * state, ARMword src)
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 *
* 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)
dest = ARMul_Align (state, address, dest);
WRITEDEST (dest);
WRITEDESTB (dest);
ARMul_Icycles (state, 1, 0L);
return (DESTReg != LHSReg);
@ -3471,10 +3472,7 @@ LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
if (BIT (15) && !state->Aborted)
{ /* PC is in the reg list */
#ifdef MODE32
state->Reg[15] = PC;
#endif
FLUSHPIPE;
WriteR15Branch(state, PC);
}
ARMul_Icycles (state, 1, 0L); /* to write back the final register */

View File

@ -332,6 +332,11 @@ extern ARMword isize;
ARMul_NegZero(state, d) ; \
}
#define WRITEDESTB(d) if (DESTReg == 15) \
WriteR15Branch(state, d) ; \
else \
DEST = d
#define BYTETOBUS(data) ((data & 0xff) | \
((data & 0xff) << 8) | \
((data & 0xff) << 16) | \