Add support for ARM's v5TE architecture and Intel's XScale extenstions

This commit is contained in:
Nick Clifton 2000-11-30 01:55:12 +00:00
parent 2a1aa0e97c
commit f1129fb8ff
12 changed files with 1772 additions and 251 deletions

View File

@ -1,3 +1,30 @@
2000-11-29 Nick Clifton <nickc@redhat.com>
* armdefs.h (State): Add 'v5e' and 'xscale' fields.
(ARM_v5e_Prop): Define.
(ARM_XScale_Prop): Define.
* wrapper.c (sim_create_inferior): Select processor based on
machine number.
(SWI_vector_installed): New boolean. Set to true if the SWI
vector address is written to by the executable.
* arminit.c (ARMul_NewState): Switch default to 32 bit mode.
(ARMul_SelectProcessor): Initialise v5e and xscale signals.
(ARMul_Abort): Fix calculation of LR address.
* armos.c (ARMul_OSHandleSWI): If a SWI vector has been installed
and a SWI is not handled by the simulator, pass the SWI off to the
vector, otherwise issue a warning message and continue.
* armsupp.c (ARMul_CPSRAltered): Set S bit aswell.
* thumbemu.c: Add v5 instruction simulation.
* armemu.c: Add v5, XScale and El Segundo instruction simulation.
* armcopro.c: Add XScale co-processor emulation.
* armemu.h: Add exported XScale co-processor functions.
2000-09-15 Nick Clifton <nickc@redhat.com>
* armdefs.h: Rename StrongARM property to v4_ARM and add v5 ARM
@ -189,7 +216,6 @@ Thu Sep 2 18:15:53 1999 Andrew Cagney <cagney@b1.cygnus.com>
* configure: Regenerated to track ../common/aclocal.m4 changes.
1999-05-08 Felix Lee <flee@cygnus.com>
* configure: Regenerated to track ../common/aclocal.m4 changes.

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,7 @@ typedef char *VoidStar;
#endif
typedef unsigned long ARMword; /* must be 32 bits wide */
typedef unsigned long long ARMdword; /* Must be at least 64 bits wide. */
typedef struct ARMul_State ARMul_State;
typedef unsigned ARMul_CPInits (ARMul_State * state);
@ -56,9 +57,13 @@ struct ARMul_State
unsigned ErrorCode; /* type of illegal instruction */
ARMword Reg[16]; /* the current register file */
ARMword RegBank[7][16]; /* all the registers */
/* 40 bit accumulator. We always keep this 64 bits wide,
and move only 40 bits out of it in an MRA insn. */
ARMdword Accumulator;
ARMword Cpsr; /* the current psr */
ARMword Spsr[7]; /* the exception psr's */
ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags; /* dummy flags for speed */
ARMword SFlag;
#ifdef MODET
ARMword TFlag; /* Thumb state */
#endif
@ -125,6 +130,8 @@ struct ARMul_State
unsigned is_v4; /* Are we emulating a v4 architecture (or higher) ? */
unsigned is_v5; /* Are we emulating a v5 architecture ? */
unsigned is_v5e; /* Are we emulating a v5e architecture ? */
unsigned is_XScale; /* Are we emulating an XScale architecture ? */
unsigned verbose; /* Print various messages like the banner */
};
@ -150,6 +157,8 @@ struct ARMul_State
#define ARM_Lock_Prop 0x20
#define ARM_v4_Prop 0x40
#define ARM_v5_Prop 0x80
#define ARM_v5e_Prop 0x100
#define ARM_XScale_Prop 0x200
/***************************************************************************\
* Macros to extract instruction fields *

View File

@ -459,6 +459,30 @@ ARMul_Emulate26 (register ARMul_State * state)
temp = TRUE;
break;
case NV:
if (state->is_v5)
{
if (BITS (25, 27) == 5) /* BLX(1) */
{
ARMword dest;
state->Reg[14] = pc + 4;
dest = pc + 8 + 1; /* Force entry into Thumb mode. */
if (BIT (23))
dest += (NEGBRANCH + (BIT (24) << 1));
else
dest += POSBRANCH + (BIT (24) << 1);
WriteR15Branch (state, dest);
goto donext;
}
else if ((instr & 0xFC70F000) == 0xF450F000)
/* The PLD instruction. Ignored. */
goto donext;
else
/* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2. */
ARMul_UndefInstr (state, instr);
}
temp = FALSE;
break;
case EQ:
@ -513,6 +537,63 @@ ARMul_Emulate26 (register ARMul_State * state)
{ /* if the condition codes don't match, stop here */
mainswitch:
if (state->is_XScale)
{
if (BIT (20) == 0 && BITS (25, 27) == 0)
{
if (BITS (4, 7) == 0xD)
{
/* XScale Load Consecutive insn. */
ARMword temp = GetLS7RHS (state, instr);
ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
ARMword addr = BIT (24) ? temp2 : temp;
if (BIT (12))
ARMul_UndefInstr (state, instr);
else if (addr & 7)
/* Alignment violation. */
ARMul_Abort (state, ARMul_DataAbortV);
else
{
int wb = BIT (24) && BIT (21);
state->Reg[BITS (12, 15)] =
ARMul_LoadWordN (state, addr);
state->Reg[BITS (12, 15) + 1] =
ARMul_LoadWordN (state, addr + 4);
if (wb)
LSBase = addr;
}
goto donext;
}
else if (BITS (4, 7) == 0xF)
{
/* XScale Store Consecutive insn. */
ARMword temp = GetLS7RHS (state, instr);
ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
ARMword addr = BIT (24) ? temp2 : temp;
if (BIT (12))
ARMul_UndefInstr (state, instr);
else if (addr & 7)
/* Alignment violation. */
ARMul_Abort (state, ARMul_DataAbortV);
else
{
ARMul_StoreWordN (state, addr,
state->Reg[BITS (12, 15)]);
ARMul_StoreWordN (state, addr + 4,
state->Reg[BITS (12, 15) + 1]);
if (BIT (21))
LSBase = addr;
}
goto donext;
}
}
}
switch ((int) BITS (20, 27))
{
@ -1000,6 +1081,48 @@ ARMul_Emulate26 (register ARMul_State * state)
break;
case 0x10: /* TST reg and MRS CPSR and SWP word */
if (state->is_v5e)
{
if (BIT (4) == 0 && BIT (7) == 1)
{
/* ElSegundo SMLAxy insn. */
ARMword op1 = state->Reg[BITS (0, 3)];
ARMword op2 = state->Reg[BITS (8, 11)];
ARMword Rn = state->Reg[BITS (12, 15)];
if (BIT (5))
op1 >>= 16;
if (BIT (6))
op2 >>= 16;
op1 &= 0xFFFF;
op2 &= 0xFFFF;
if (op1 & 0x8000)
op1 -= 65536;
if (op2 & 0x8000)
op2 -= 65536;
op1 *= op2;
if (AddOverflow (op1, Rn, op1 + Rn))
SETS;
state->Reg[BITS (16, 19)] = op1 + Rn;
break;
}
if (BITS (4, 11) == 5)
{
/* ElSegundo QADD insn. */
ARMword op1 = state->Reg[BITS (0, 3)];
ARMword op2 = state->Reg[BITS (16, 19)];
ARMword result = op1 + op2;
if (AddOverflow (op1, op2, result))
{
result = POS (result) ? 0x80000000 : 0x7fffffff;
SETS;
}
state->Reg[BITS (12, 15)] = result;
break;
}
}
#ifdef MODET
if (BITS (4, 11) == 0xB)
{
@ -1072,6 +1195,72 @@ ARMul_Emulate26 (register ARMul_State * state)
break;
case 0x12: /* TEQ reg and MSR reg to CPSR (ARM6) */
if (state->is_v5)
{
if (BITS (4, 7) == 3)
{
/* BLX(2) */
ARMword temp;
if (TFLAG)
temp = (pc + 2) | 1;
else
temp = pc + 4;
WriteR15Branch (state, state->Reg[RHSReg]);
state->Reg[14] = temp;
break;
}
}
if (state->is_v5e)
{
if (BIT (4) == 0 && BIT (7) == 1
&& (BIT (5) == 0 || BITS (12, 15) == 0))
{
/* ElSegundo SMLAWy/SMULWy insn. */
unsigned long long op1 = state->Reg[BITS (0, 3)];
unsigned long long op2 = state->Reg[BITS (8, 11)];
unsigned long long result;
if (BIT (6))
op2 >>= 16;
if (op1 & 0x80000000)
op1 -= 1ULL << 32;
op2 &= 0xFFFF;
if (op2 & 0x8000)
op2 -= 65536;
result = (op1 * op2) >> 16;
if (BIT (5) == 0)
{
ARMword Rn = state->Reg[BITS (12, 15)];
if (AddOverflow (result, Rn, result + Rn))
SETS;
result += Rn;
}
state->Reg[BITS (16, 19)] = result;
break;
}
if (BITS (4, 11) == 5)
{
/* ElSegundo QSUB insn. */
ARMword op1 = state->Reg[BITS (0, 3)];
ARMword op2 = state->Reg[BITS (16, 19)];
ARMword result = op1 - op2;
if (SubOverflow (op1, op2, result))
{
result = POS (result) ? 0x80000000 : 0x7fffffff;
SETS;
}
state->Reg[BITS (12, 15)] = result;
break;
}
}
#ifdef MODET
if (BITS (4, 11) == 0xB)
{
@ -1079,18 +1268,68 @@ ARMul_Emulate26 (register ARMul_State * state)
SHPREDOWNWB ();
break;
}
#endif
#ifdef MODET
if (BITS (4, 27) == 0x12FFF1)
{ /* BX */
{
/* BX */
WriteR15Branch (state, state->Reg[RHSReg]);
break;
}
#endif
if (state->is_v5)
{
if (BITS (4, 7) == 0x7)
{
ARMword value;
extern int SWI_vector_installed;
/* Hardware is allowed to optionally override this
instruction and treat it as a breakpoint. Since
this is a simulator not hardware, we take the position
that if a SWI vector was not installed, then an Abort
vector was probably not installed either, and so
normally this instruction would be ignored, even if an
Abort is generated. This is a bad thing, since GDB
uses this instruction for its breakpoints (at least in
Thumb mode it does). So intercept the instruction here
and generate a breakpoint SWI instead. */
if (! SWI_vector_installed)
ARMul_OSHandleSWI (state, SWI_Breakpoint);
else
/* BKPT - normally this will cause an abort, but for the
XScale if bit 31 in register 10 of coprocessor 14 is
clear, then this is treated as a no-op. */
if (state->is_XScale)
{
if (read_cp14_reg (10) & (1UL << 31))
{
ARMword value;
value = read_cp14_reg (10);
value &= ~0x1c;
value |= 0xc;
write_cp14_reg (10, value);
write_cp15_reg (5, 0, 0, 0x200); /* Set FSR. */
write_cp15_reg (6, 0, 0, pc); /* Set FAR. */
}
else
break;
}
ARMul_Abort (state, ARMul_PrefetchAbortV);
break;
}
}
if (DESTReg == 15)
{ /* MSR reg to CPSR */
{
/* MSR reg to CPSR */
UNDEF_MSRPC;
temp = DPRegRHS;
#ifdef MODET
/* Don't allow TBIT to be set by MSR. */
temp &= ~ TBIT;
#endif
ARMul_FixCPSR (state, instr, temp);
}
else
@ -1128,6 +1367,60 @@ ARMul_Emulate26 (register ARMul_State * state)
break;
case 0x14: /* CMP reg and MRS SPSR and SWP byte */
if (state->is_v5e)
{
if (BIT (4) == 0 && BIT (7) == 1)
{
/* ElSegundo SMLALxy insn. */
unsigned long long op1 = state->Reg[BITS (0, 3)];
unsigned long long op2 = state->Reg[BITS (8, 11)];
unsigned long long dest;
unsigned long long result;
if (BIT (5))
op1 >>= 16;
if (BIT (6))
op2 >>= 16;
op1 &= 0xFFFF;
if (op1 & 0x8000)
op1 -= 65536;
op2 &= 0xFFFF;
if (op2 & 0x8000)
op2 -= 65536;
dest = (unsigned long long) state->Reg[BITS (16, 19)] << 32;
dest |= state->Reg[BITS (12, 15)];
dest += op1 * op2;
state->Reg[BITS (12, 15)] = dest;
state->Reg[BITS (16, 19)] = dest >> 32;
break;
}
if (BITS (4, 11) == 5)
{
/* ElSegundo QDADD insn. */
ARMword op1 = state->Reg[BITS (0, 3)];
ARMword op2 = state->Reg[BITS (16, 19)];
ARMword op2d = op2 + op2;
ARMword result;
if (AddOverflow (op2, op2, op2d))
{
SETS;
op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
}
result = op1 + op2d;
if (AddOverflow (op1, op2d, result))
{
SETS;
result = POS (result) ? 0x80000000 : 0x7fffffff;
}
state->Reg[BITS (12, 15)] = result;
break;
}
}
#ifdef MODET
if (BITS (4, 7) == 0xB)
{
@ -1207,6 +1500,72 @@ ARMul_Emulate26 (register ARMul_State * state)
break;
case 0x16: /* CMN reg and MSR reg to SPSR */
if (state->is_v5e)
{
if (BIT (4) == 0 && BIT (7) == 1 && BITS (12, 15) == 0)
{
/* ElSegundo SMULxy insn. */
ARMword op1 = state->Reg[BITS (0, 3)];
ARMword op2 = state->Reg[BITS (8, 11)];
ARMword Rn = state->Reg[BITS (12, 15)];
if (BIT (5))
op1 >>= 16;
if (BIT (6))
op2 >>= 16;
op1 &= 0xFFFF;
op2 &= 0xFFFF;
if (op1 & 0x8000)
op1 -= 65536;
if (op2 & 0x8000)
op2 -= 65536;
state->Reg[BITS (16, 19)] = op1 * op2;
break;
}
if (BITS (4, 11) == 5)
{
/* ElSegundo QDSUB insn. */
ARMword op1 = state->Reg[BITS (0, 3)];
ARMword op2 = state->Reg[BITS (16, 19)];
ARMword op2d = op2 + op2;
ARMword result;
if (AddOverflow (op2, op2, op2d))
{
SETS;
op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
}
result = op1 - op2d;
if (SubOverflow (op1, op2d, result))
{
SETS;
result = POS (result) ? 0x80000000 : 0x7fffffff;
}
state->Reg[BITS (12, 15)] = result;
break;
}
}
if (state->is_v5)
{
if (BITS (4, 11) == 0xF1 && BITS (16, 19) == 0xF)
{
/* ARM5 CLZ insn. */
ARMword op1 = state->Reg[BITS (0, 3)];
int result = 32;
if (op1)
for (result = 0; (op1 & 0x80000000) == 0; op1 <<= 1)
result++;
state->Reg[BITS (12, 15)] = result;
break;
}
}
#ifdef MODET
if (BITS (4, 7) == 0xB)
{
@ -2393,7 +2752,7 @@ ARMul_Emulate26 (register ARMul_State * state)
{
/* Check for the special breakpoint opcode.
This value should correspond to the value defined
as ARM_BE_BREAKPOINT in gdb/arm-tdep.c. */
as ARM_BE_BREAKPOINT in gdb/arm/tm-arm.h. */
if (BITS (0, 19) == 0xfdefe)
{
if (!ARMul_OSHandleSWI (state, SWI_Breakpoint))
@ -2642,11 +3001,56 @@ ARMul_Emulate26 (register ARMul_State * state)
\***************************************************************************/
case 0xc4:
if (state->is_XScale)
{
if (BITS (4, 7) != 0x00)
ARMul_UndefInstr (state, instr);
if (BITS (8, 11) != 0x00)
ARMul_UndefInstr (state, instr); /* Not CP0. */
/* XScale MAR insn. Move two registers into accumulator. */
if (BITS (0, 3) == 0x00)
{
state->Accumulator = state->Reg[BITS (12, 15)];
state->Accumulator += (ARMdword) state->Reg[BITS (16, 19)] << 32;
break;
}
/* Access to any other acc is unpredicatable. */
break;
}
/* Drop through. */
case 0xc0: /* Store , No WriteBack , Post Dec */
ARMul_STC (state, instr, LHS);
break;
case 0xc5:
if (state->is_XScale)
{
if (BITS (4, 7) != 0x00)
ARMul_UndefInstr (state, instr);
if (BITS (8, 11) != 0x00)
ARMul_UndefInstr (state, instr); /* Not CP0. */
/* XScale MRA insn. Move accumulator into two registers. */
if (BITS (0, 3) == 0x00)
{
ARMword t1 = (state->Accumulator >> 32) & 255;
if (t1 & 128)
t1 -= 256;
state->Reg[BITS (12, 15)] = state->Accumulator;
state->Reg[BITS (16, 19)] = t1;
break;
}
/* Access to any other acc is unpredicatable. */
break;
}
/* Drop through. */
case 0xc1: /* Load , No WriteBack , Post Dec */
ARMul_LDC (state, instr, LHS);
break;
@ -2743,6 +3147,88 @@ ARMul_Emulate26 (register ARMul_State * state)
\***************************************************************************/
case 0xe2:
if (state->is_XScale)
switch (BITS (18, 19))
{
case 0x0:
{
/* XScale MIA instruction. Signed multiplication of two 32 bit
values and addition to 40 bit accumulator. */
long long Rm = state->Reg[MULLHSReg];
long long Rs = state->Reg[MULACCReg];
if (Rm & (1 << 31))
Rm -= 1ULL << 32;
if (Rs & (1 << 31))
Rs -= 1ULL << 32;
state->Accumulator += Rm * Rs;
}
goto donext;
case 0x2:
{
/* XScale MIAPH instruction. */
ARMword t1 = state->Reg[MULLHSReg] >> 16;
ARMword t2 = state->Reg[MULACCReg] >> 16;
ARMword t3 = state->Reg[MULLHSReg] & 0xffff;
ARMword t4 = state->Reg[MULACCReg] & 0xffff;
long long t5;
if (t1 & (1 << 15))
t1 -= 1 << 16;
if (t2 & (1 << 15))
t2 -= 1 << 16;
if (t3 & (1 << 15))
t3 -= 1 << 16;
if (t4 & (1 << 15))
t4 -= 1 << 16;
t1 *= t2;
t5 = t1;
if (t5 & (1 << 31))
t5 -= 1ULL << 32;
state->Accumulator += t5;
t3 *= t4;
t5 = t3;
if (t5 & (1 << 31))
t5 -= 1ULL << 32;
state->Accumulator += t5;
}
goto donext;
case 0x3:
{
/* XScale MIAxy instruction. */
ARMword t1;
ARMword t2;
long long t5;
if (BIT (17))
t1 = state->Reg[MULLHSReg] >> 16;
else
t1 = state->Reg[MULLHSReg] & 0xffff;
if (BIT (16))
t2 = state->Reg[MULACCReg] >> 16;
else
t2 = state->Reg[MULACCReg] & 0xffff;
if (t1 & (1 << 15))
t1 -= 1 << 16;
if (t2 & (1 << 15))
t2 -= 1 << 16;
t1 *= t2;
t5 = t1;
if (t5 & (1 << 31))
t5 -= 1ULL << 32;
state->Accumulator += t5;
}
goto donext;
default:
break;
}
/* Drop through. */
case 0xe0:
case 0xe4:
case 0xe6:

View File

@ -55,6 +55,7 @@ extern ARMword isize;
#define ZBIT (1L << 30)
#define CBIT (1L << 29)
#define VBIT (1L << 28)
#define SBIT (1L << 27)
#define IBIT (1L << 7)
#define FBIT (1L << 6)
#define IFBITS (3L << 6)
@ -98,6 +99,10 @@ extern ARMword isize;
#define CLEARV state->VFlag = 0
#define ASSIGNV(res) state->VFlag = res
#define SFLAG state->SFlag
#define SETS state->SFlag = 1
#define CLEARS state->SFlag = 0
#define ASSIGNS(res) state->SFlag = res
#define IFLAG (state->IFFlags >> 1)
#define FFLAG (state->IFFlags & 1)
@ -110,7 +115,12 @@ extern ARMword isize;
#define PSR_XBITS (0x0000ff00L)
#define PSR_CBITS (0x000000ffL)
#if defined MODE32 || defined MODET
#define CCBITS (0xf8000000L)
#else
#define CCBITS (0xf0000000L)
#endif
#define INTBITS (0xc0L)
#if defined MODET && defined MODE32
@ -149,7 +159,7 @@ extern ARMword isize;
#define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS))
#define R15MODE (state->Reg[15] & R15MODEBITS)
#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28))
#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (SFLAG << 27))
#define EINT (IFFLAGS << 6)
#define ER15INT (IFFLAGS << 26)
#define EMODE (state->Mode)
@ -472,3 +482,14 @@ extern tdstate ARMul_ThumbDecode (ARMul_State * state, ARMword pc,
#define UNDEF_IllegalMode
#define UNDEF_Prog32SigChange
#define UNDEF_Data32SigChange
/* Coprocessor support functions. */
extern unsigned ARMul_CoProInit (ARMul_State *);
extern void ARMul_CoProExit (ARMul_State *);
extern void ARMul_CoProAttach (ARMul_State *, unsigned, ARMul_CPInits *, ARMul_CPExits *,
ARMul_LDCs *, ARMul_STCs *, ARMul_MRCs *, ARMul_MCRs *,
ARMul_CDPs *, ARMul_CPReads *, ARMul_CPWrites *);
extern void ARMul_CoProDetach (ARMul_State *, unsigned);
extern void write_cp15_reg (unsigned, unsigned, unsigned, ARMword);
extern void write_cp14_reg (unsigned, ARMword);
extern ARMword read_cp14_reg (unsigned);

View File

@ -86,7 +86,8 @@ ARMul_NewState (void)
for (i = 0; i < 7; i++)
state->Spsr[i] = 0;
state->Mode = USER26MODE;
/* state->Mode = USER26MODE; */
state->Mode = USER32MODE;
state->CallDebug = FALSE;
state->Debug = FALSE;
@ -113,19 +114,16 @@ ARMul_NewState (void)
for (i = 0; i < EVENTLISTSIZE; i++)
*(state->EventPtr + i) = NULL;
#ifdef ARM61
state->prog32Sig = LOW;
state->data32Sig = LOW;
#else
state->prog32Sig = HIGH;
state->data32Sig = HIGH;
#endif
state->lateabtSig = LOW;
state->bigendSig = LOW;
state->is_v4 = LOW;
state->is_v5 = LOW;
state->is_v5e = LOW;
state->is_XScale = LOW;
ARMul_Reset (state);
@ -154,6 +152,8 @@ ARMul_SelectProcessor (ARMul_State * state, unsigned properties)
state->is_v4 = (properties & (ARM_v4_Prop | ARM_v5_Prop)) ? HIGH : LOW;
state->is_v5 = (properties & ARM_v5_Prop) ? HIGH : LOW;
state->is_v5e = (properties & ARM_v5e_Prop) ? HIGH : LOW;
state->is_XScale = (properties & ARM_XScale_Prop) ? HIGH : LOW;
}
/***************************************************************************\
@ -261,6 +261,8 @@ ARMul_Abort (ARMul_State * state, ARMword vector)
{
ARMword temp;
int isize = INSN_SIZE;
int esize = (TFLAG ? 0 : 4);
int e2size = (TFLAG ? -4 : 0);
state->Aborted = FALSE;
@ -288,19 +290,19 @@ ARMul_Abort (ARMul_State * state, ARMword vector)
break;
case ARMul_PrefetchAbortV: /* Prefetch Abort */
state->AbortAddr = 1;
SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, isize);
SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, esize);
break;
case ARMul_DataAbortV: /* Data Abort */
SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, isize);
SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, e2size);
break;
case ARMul_AddrExceptnV: /* Address Exception */
SETABORT (IBIT, SVC26MODE, isize);
break;
case ARMul_IRQV: /* IRQ */
SETABORT (IBIT, state->prog32Sig ? IRQ32MODE : IRQ26MODE, isize);
SETABORT (IBIT, state->prog32Sig ? IRQ32MODE : IRQ26MODE, esize);
break;
case ARMul_FIQV: /* FIQ */
SETABORT (INTBITS, state->prog32Sig ? FIQ32MODE : FIQ26MODE, isize);
SETABORT (INTBITS, state->prog32Sig ? FIQ32MODE : FIQ26MODE, esize);
break;
}
if (ARMul_MODE32BIT)

View File

@ -70,6 +70,8 @@ extern int _fisatty (FILE *);
#include "armdefs.h"
#include "armos.h"
#include "armemu.h"
#ifndef NOOS
#ifndef VALIDATE
/* #ifndef ASIM */
@ -445,11 +447,6 @@ ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
state->Reg[0] = OSptr->ErrorNo;
return (TRUE);
case SWI_Breakpoint:
state->EndCondition = RDIError_BreakpointReached;
state->Emulate = FALSE;
return (TRUE);
case SWI_GetEnv:
state->Reg[0] = ADDRCMDLINE;
if (state->MemSize)
@ -459,6 +456,11 @@ ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
WriteCommandLineTo (state, state->Reg[0]);
return (TRUE);
case SWI_Breakpoint:
state->EndCondition = RDIError_BreakpointReached;
state->Emulate = FALSE;
return (TRUE);
/* Handle Angel SWIs as well as Demon ones */
case AngelSWI_ARM:
@ -587,29 +589,58 @@ ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
return TRUE;
}
case 0x90:
case 0x92:
/* These are used by the FPE code. */
return TRUE;
default:
state->Emulate = FALSE;
return (FALSE);
{
/* If there is a SWI vector installed use it. */
extern int SWI_vector_installed;
if (SWI_vector_installed && number != SWI_Breakpoint)
{
ARMword cpsr;
ARMword i_size;
cpsr = ARMul_GetCPSR (state);
i_size = INSN_SIZE;
ARMul_SetSPSR (state, SVC32MODE, cpsr);
cpsr &= ~0xbf;
cpsr |= SVC32MODE | 0x80;
ARMul_SetCPSR (state, cpsr);
state->RegBank[SVCBANK][14] = state->Reg[14] = state->Reg[15] - i_size;
state->NextInstr = RESUME;
state->Reg[15] = state->pc = ARMSWIV;
FLUSHPIPE;
}
else
fprintf (stderr, "unknown SWI encountered - %x - ignoring\n", number);
return TRUE;
}
}
}
#ifndef NOOS
#ifndef ASIM
/***************************************************************************\
* The emulator calls this routine when an Exception occurs. The second *
* parameter is the address of the relevant exception vector. Returning *
* FALSE from this routine causes the trap to be taken, TRUE causes it to *
* be ignored (so set state->Emulate to FALSE!). *
\***************************************************************************/
/* The emulator calls this routine when an Exception occurs. The second
parameter is the address of the relevant exception vector. Returning
FALSE from this routine causes the trap to be taken, TRUE causes it to
be ignored (so set state->Emulate to FALSE!). */
unsigned
ARMul_OSException (ARMul_State * state ATTRIBUTE_UNUSED, ARMword vector ATTRIBUTE_UNUSED, ARMword pc ATTRIBUTE_UNUSED)
{ /* don't use this here */
return (FALSE);
ARMul_OSException (
ARMul_State * state ATTRIBUTE_UNUSED,
ARMword vector ATTRIBUTE_UNUSED,
ARMword pc ATTRIBUTE_UNUSED)
{
return FALSE;
}
#endif
#endif /* NOOS */

View File

@ -302,6 +302,8 @@ ARMul_CPSRAltered (ARMul_State * state)
state->Cpsr &= ~CBIT;
ASSIGNV ((state->Cpsr & VBIT) != 0);
state->Cpsr &= ~VBIT;
ASSIGNS ((state->Cpsr & SBIT) != 0);
state->Cpsr &= ~SBIT;
#ifdef MODET
ASSIGNT ((state->Cpsr & TBIT) != 0);
state->Cpsr &= ~TBIT;

View File

@ -209,11 +209,19 @@ tdstate ARMul_ThumbDecode (state, pc, tinstr, ainstr)
*ainstr = 0xE12FFF10 /* base */
| ((tinstr & 0x0078) >> 3); /* Rd */
break;
case 0xE: /* UNDEFINED */
case 0xF: /* UNDEFINED */
if (state->is_v5)
{
/* BLX Rs; BLX Hs */
*ainstr = 0xE12FFF30 /* base */
| ((tinstr & 0x0078) >> 3); /* Rd */
break;
}
/* Drop through. */
case 0x0: /* UNDEFINED */
case 0x4: /* UNDEFINED */
case 0x8: /* UNDEFINED */
case 0xE: /* UNDEFINED */
case 0xF: /* UNDEFINED */
valid = t_undefined;
break;
}
@ -322,30 +330,48 @@ tdstate ARMul_ThumbDecode (state, pc, tinstr, ainstr)
break;
case 22:
case 23:
if ((tinstr & 0x0F00) == 0x0000)
switch (tinstr & 0x0F00)
{
case 0x0000:
/* Format 13 */
/* NOTE: The instruction contains a shift left of 2
equivalent (implemented as ROR #30): */
equivalent (implemented as ROR #30): */
*ainstr = ((tinstr & (1 << 7)) /* base */
? 0xE24DDF00 /* SUB */
: 0xE28DDF00) /* ADD */
| (tinstr & 0x007F); /* off7 */
}
else if ((tinstr & 0x0F00) == 0x0e00)
*ainstr = 0xEF000000 | SWI_Breakpoint;
else
{
/* Format 14 */
ARMword subset[4] = {
0xE92D0000, /* STMDB sp!,{rlist} */
0xE92D4000, /* STMDB sp!,{rlist,lr} */
0xE8BD0000, /* LDMIA sp!,{rlist} */
0xE8BD8000 /* LDMIA sp!,{rlist,pc} */
};
*ainstr = subset[((tinstr & (1 << 11)) >> 10)
| ((tinstr & (1 << 8)) >> 8)] /* base */
| (tinstr & 0x00FF); /* mask8 */
break;
case 0x0400:
/* Format 14 - Push */
* ainstr = 0xE92D0000 | (tinstr & 0x00FF);
break;
case 0x0500:
/* Format 14 - Push + LR */
* ainstr = 0xE92D4000 | (tinstr & 0x00FF);
break;
case 0x0c00:
/* Format 14 - Pop */
* ainstr = 0xE8BD0000 | (tinstr & 0x00FF);
break;
case 0x0d00:
/* Format 14 - Pop + PC */
* ainstr = 0xE8BD8000 | (tinstr & 0x00FF);
break;
case 0x0e00:
if (state->is_v5)
{
/* This is normally an undefined instruction. The v5t architecture
defines this particular pattern as a BKPT instruction, for
hardware assisted debugging. We map onto the arm BKPT
instruction. */
* ainstr = 0xE1200070 | ((tinstr & 0xf0) << 4) | (tinstr & 0xf);
break;
}
/* Drop through. */
default:
/* Everything else is an undefined instruction. */
valid = t_undefined;
break;
}
break;
case 24: /* STMIA */
@ -446,6 +472,34 @@ tdstate ARMul_ThumbDecode (state, pc, tinstr, ainstr)
valid = t_branch;
break;
case 29: /* UNDEFINED */
if (state->is_v5)
{
if (tinstr & 1)
{
valid = t_undefined;
break;
}
/* Drop through. */
do_blx2: /* BLX instruction 2 */
/* Format 19 */
/* There is no single ARM instruction equivalent for this
instruction. Also, it should only ever be matched with the
fmt19 "BL/BLX instruction 1" instruction. However, we do
allow the simulation of it on its own, with undefined results
if r14 is not suitably initialised. */
{
ARMword tmp = (pc + 2);
state->Reg[15] = ((state->Reg[14] + ((tinstr & 0x07FF) << 1))
& 0xFFFFFFFC);
CLEART;
state->Reg[14] = (tmp | 1);
valid = t_branch;
FLUSHPIPE;
break;
}
}
valid = t_undefined;
break;
case 30: /* BL instruction 1 */
@ -461,7 +515,14 @@ tdstate ARMul_ThumbDecode (state, pc, tinstr, ainstr)
valid = t_branch; /* in-case we don't have the 2nd half */
tinstr = next_instr; /* move the instruction down */
if (((tinstr & 0xF800) >> 11) != 31)
break; /* exit, since not correct instruction */
{
if (((tinstr & 0xF800) >> 11) == 29)
{
pc += 2;
goto do_blx2;
}
break; /* exit, since not correct instruction */
}
/* else we fall through to process the second half of the BL */
pc += 2; /* point the pc at the 2nd half */
case 31: /* BL instruction 2 */

View File

@ -114,6 +114,8 @@ ARMul_Debug (ARMul_State * state ATTRIBUTE_UNUSED, ARMword pc ATTRIBUTE_UNUSED,
return 0;
}
int SWI_vector_installed = FALSE;
int
sim_write (sd, addr, buffer, size)
SIM_DESC sd ATTRIBUTE_UNUSED;
@ -125,6 +127,9 @@ sim_write (sd, addr, buffer, size)
init ();
if ((addr <= 0x8) && ((addr + size) >= 0x8))
SWI_vector_installed = TRUE;
for (i = 0; i < size; i++)
ARMul_WriteByte (state, addr + i, buffer[i]);
@ -216,37 +221,47 @@ sim_create_inferior (sd, abfd, argv, env)
"Unknown machine type; please update sim_create_inferior.\n");
/* fall through */
case 0: /* arm */
case 0:
/* We wouldn't set the machine type with earlier toolchains, so we
explicitly select a processor capable of supporting all ARM
32bit mode. */
/* fall through */
case 5: /* armv4 */
case 6: /* armv4t */
case 7: /* armv5 */
case 8: /* armv5t */
if (mach == 7 || mach == 8)
ARMul_SelectProcessor (state, ARM_v5_Prop);
else
ARMul_SelectProcessor (state, ARM_v4_Prop);
/* Reset mode to ARM. A gdb user may rerun a program that had entered
THUMB mode from the start and cause the ARM-mode startup code to be
executed in THUMB mode. */
ARMul_SetCPSR (state, USER32MODE);
explicitly select a processor capable of supporting all ARMs in
32bit mode. */
case bfd_mach_arm_5:
case bfd_mach_arm_5T:
ARMul_SelectProcessor (state, ARM_v5_Prop);
break;
case 3: /* armv3 */
case 4: /* armv3m */
case bfd_mach_arm_5TE:
ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop);
break;
case bfd_mach_arm_XScale:
ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
break;
case bfd_mach_arm_4:
case bfd_mach_arm_4T:
ARMul_SelectProcessor (state, ARM_v4_Prop);
break;
case bfd_mach_arm_3:
case bfd_mach_arm_3M:
ARMul_SelectProcessor (state, ARM_Lock_Prop);
break;
case 1: /* armv2 */
case 2: /* armv2a */
case bfd_mach_arm_2:
case bfd_mach_arm_2a:
ARMul_SelectProcessor (state, ARM_Fix26_Prop);
break;
}
if (mach > 3)
{
/* Reset mode to ARM. A gdb user may rerun a program that had entered
THUMB mode from the start and cause the ARM-mode startup code to be
executed in THUMB mode. */
ARMul_SetCPSR (state, USER32MODE);
}
if (argv != NULL)
{
/*
@ -354,6 +369,7 @@ sim_store_register (sd, rn, memory, length)
int length ATTRIBUTE_UNUSED;
{
init ();
if (rn == 25)
{
state->Cpsr = frommem (state, memory);
@ -374,6 +390,7 @@ sim_fetch_register (sd, rn, memory, length)
ARMword regval;
init ();
if (rn < 16)
regval = ARMul_GetReg (state, state->Mode, rn);
else if (rn == 25) /* FIXME: use PS_REGNUM from gdb/config/arm/tm-arm.h */

4
sim/configure vendored
View File

@ -1415,6 +1415,10 @@ case "${target}" in
sim_target=arm
extra_subdirs="${extra_subdirs} testsuite"
;;
xscale-*-*)
sim_target=arm
extra_subdirs="${extra_subdirs} testsuite"
;;
d10v-*-*) sim_target=d10v ;;
d30v-*-*)
sim_target=d30v

View File

@ -54,6 +54,10 @@ case "${target}" in
sim_target=arm
extra_subdirs="${extra_subdirs} testsuite"
;;
xscale-*-*)
sim_target=arm
extra_subdirs="${extra_subdirs} testsuite"
;;
d10v-*-*) sim_target=d10v ;;
d30v-*-*)
sim_target=d30v