summaryrefslogtreecommitdiff
path: root/sim/arm
diff options
context:
space:
mode:
Diffstat (limited to 'sim/arm')
-rw-r--r--sim/arm/ChangeLog39
-rw-r--r--sim/arm/Makefile.in1
-rw-r--r--sim/arm/armcopro.c10
-rw-r--r--sim/arm/armdefs.h2
-rw-r--r--sim/arm/armemu.c23
-rw-r--r--sim/arm/arminit.c23
-rw-r--r--sim/arm/armos.c49
-rwxr-xr-xsim/arm/configure2
-rw-r--r--sim/arm/configure.in2
-rw-r--r--sim/arm/wrapper.c95
10 files changed, 232 insertions, 14 deletions
diff --git a/sim/arm/ChangeLog b/sim/arm/ChangeLog
index c6597defef5..03c923ee0d6 100644
--- a/sim/arm/ChangeLog
+++ b/sim/arm/ChangeLog
@@ -1,3 +1,42 @@
+2003-03-30 Nick Clifton <nickc@redhat.com>
+
+ * configure.in (CON_FLAGS): Remove.
+ (COPRO): Unconditionally include iwmmxt.o.
+ * configure: Regenerate.
+ * Makefile.in (CON_FLAGS): Remove.
+ * armcopro.c: Remove use of __IWMMXT__ flag.
+ * wrapper.c: Likewise.
+ * armemu.c: Likewise.
+ Add explanatory comment for suppressed code.
+
+2003-03-27 Nick Clifton <nickc@redhat.com>
+
+ * armos.c (ARMul_OsHandleSWI): Catch SWIs for unhandled vectors.
+
+2003-03-27 Nick Clifton <nickc@redhat.com>
+
+ * configure.in: (CON_FLAGS): Define and intialise.
+ (COPRO): Add iwmmxt.o if configuring for XScale.
+ * configure: Regenerate.
+ * Makefile.in (iwmmxt.o): Add rule to build.
+ (COM_FLAGS): Define.
+ (ALL_FLAGS): Add CON_FLAGS.
+ * armcopro.c (ARMul_CoProInit): Initialise iWMMXt coprocessors.
+ * armdefs.h (struct ARMul_State): Add 'is_iWMMXt' field.
+ (ARM_iWMMXt_Prop): Define.
+ * armemu.c (ARMul_Emulate16): Intercept iWMMXt instructions and
+ pass to coprocessor.
+ * arminit.c (ARMul_NewState): Initialise 'is_iWMMXt'.
+ (ARMul_Abort): Catch branches through uninitialised vectors.
+ * armos.c (softevtorcode): Update comment.
+ (ARMul_OsInit): Use ARMUndefinedInstrV.
+ * wrapper.c (sim_create_inferior): Handle iWMMXt processor type.
+ (sim_store_register): Handle iWMMXt registers.
+ (sim_fetch_register): Handle iWMMXt registers.
+ * iwmmxt.h: New file. Exported iWMMXt coprocessor emulator
+ functions.
+ * iwmmxt.c: New file: iWMMXt emulator.
+
2003-03-20 Nick Clifton <nickc@redhat.com>
* Contribute support for Cirrus Maverick ARM co-processor,
diff --git a/sim/arm/Makefile.in b/sim/arm/Makefile.in
index 017a983289d..7def0f967bb 100644
--- a/sim/arm/Makefile.in
+++ b/sim/arm/Makefile.in
@@ -32,6 +32,7 @@ armos.o: armos.c armdefs.h armos.h armfpe.h
armcopro.o: armcopro.c armdefs.h
maverick.o: maverick.c armdefs.h
+iwmmxt.o: iwmmxt.c iwmmxt.h armdefs.h
armemu26.o: armemu.c armdefs.h armemu.h
$(CC) -c $(srcdir)/armemu.c -o armemu26.o $(ALL_CFLAGS)
diff --git a/sim/arm/armcopro.c b/sim/arm/armcopro.c
index b9747894869..aa75243dc33 100644
--- a/sim/arm/armcopro.c
+++ b/sim/arm/armcopro.c
@@ -19,6 +19,7 @@
#include "armos.h"
#include "armemu.h"
#include "ansidecl.h"
+#include "iwmmxt.h"
/* Dummy Co-processors. */
@@ -1365,6 +1366,15 @@ ARMul_CoProInit (ARMul_State * state)
MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
}
+ if (state->is_iWMMXt)
+ {
+ ARMul_CoProAttach (state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC,
+ NULL, NULL, IwmmxtCDP, NULL, NULL);
+
+ ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL,
+ IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL, NULL);
+ }
+
/* No handlers below here. */
/* Call all the initialisation routines. */
diff --git a/sim/arm/armdefs.h b/sim/arm/armdefs.h
index 0f252226dd9..a2ea4059037 100644
--- a/sim/arm/armdefs.h
+++ b/sim/arm/armdefs.h
@@ -135,6 +135,7 @@ struct ARMul_State
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 is_iWMMXt; /* Are we emulating an iWMMXt co-processor ? */
unsigned is_ep9312; /* Are we emulating a Cirrus Maverick co-processor ? */
unsigned verbose; /* Print various messages like the banner */
};
@@ -164,6 +165,7 @@ struct ARMul_State
#define ARM_v5e_Prop 0x100
#define ARM_XScale_Prop 0x200
#define ARM_ep9312_Prop 0x400
+#define ARM_iWMMXt_Prop 0x800
/***************************************************************************\
* Macros to extract instruction fields *
diff --git a/sim/arm/armemu.c b/sim/arm/armemu.c
index 44943c4ecde..d12ad10e41c 100644
--- a/sim/arm/armemu.c
+++ b/sim/arm/armemu.c
@@ -19,6 +19,7 @@
#include "armdefs.h"
#include "armemu.h"
#include "armos.h"
+#include "iwmmxt.h"
static ARMword GetDPRegRHS (ARMul_State *, ARMword);
static ARMword GetDPSRegRHS (ARMul_State *, ARMword);
@@ -374,12 +375,23 @@ ARMul_Emulate26 (ARMul_State * state)
if (state->EventSet)
ARMul_EnvokeEvent (state);
-#if 0
- /* Enable this for a helpful bit of debugging when tracing is needed. */
+#if 0 /* Enable this for a helpful bit of debugging when tracing is needed. */
fprintf (stderr, "pc: %x, instr: %x\n", pc & ~1, instr);
if (instr == 0)
abort ();
#endif
+#if 0 /* Enable this code to help track down stack alignment bugs. */
+ {
+ static ARMword old_sp = -1;
+
+ if (old_sp != state->Reg[13])
+ {
+ old_sp = state->Reg[13];
+ fprintf (stderr, "pc: %08x: SP set to %08x%s\n",
+ pc & ~1, old_sp, (old_sp % 8) ? " [UNALIGNED!]" : "");
+ }
+ }
+#endif
if (state->Exception)
{
@@ -492,6 +504,10 @@ ARMul_Emulate26 (ARMul_State * state)
else if ((instr & 0xFC70F000) == 0xF450F000)
/* The PLD instruction. Ignored. */
goto donext;
+ else if ( ((instr & 0xfe500f00) == 0xfc100100)
+ || ((instr & 0xfe500f00) == 0xfc000100))
+ /* wldrw and wstrw are unconditional. */
+ goto mainswitch;
else
/* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2. */
ARMul_UndefInstr (state, instr);
@@ -689,6 +705,9 @@ check_PMUintr:
goto donext;
}
}
+
+ if (ARMul_HandleIwmmxt (state, instr))
+ goto donext;
}
switch ((int) BITS (20, 27))
diff --git a/sim/arm/arminit.c b/sim/arm/arminit.c
index 04399900c95..45887879c31 100644
--- a/sim/arm/arminit.c
+++ b/sim/arm/arminit.c
@@ -17,6 +17,7 @@
#include "armdefs.h"
#include "armemu.h"
+#include "dbg_rdi.h"
/***************************************************************************\
* Definitions for the emulator architecture *
@@ -127,6 +128,7 @@ ARMul_NewState (void)
state->is_v5 = LOW;
state->is_v5e = LOW;
state->is_XScale = LOW;
+ state->is_iWMMXt = LOW;
ARMul_Reset (state);
@@ -157,6 +159,7 @@ ARMul_SelectProcessor (ARMul_State * state, unsigned properties)
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;
+ state->is_iWMMXt = (properties & ARM_iWMMXt_Prop) ? HIGH : LOW;
state->is_ep9312 = (properties & ARM_ep9312_Prop) ? HIGH : LOW;
/* Only initialse the coprocessor support once we
@@ -323,4 +326,24 @@ ARMul_Abort (ARMul_State * state, ARMword vector)
ARMul_SetR15 (state, vector);
else
ARMul_SetR15 (state, R15CCINTMODE | vector);
+
+ if (ARMul_ReadWord (state, ARMul_GetPC (state)) == 0)
+ {
+ /* No vector has been installed. Rather than simulating whatever
+ random bits might happen to be at address 0x20 onwards we elect
+ to stop. */
+ switch (vector)
+ {
+ case ARMul_ResetV: state->EndCondition = RDIError_Reset; break;
+ case ARMul_UndefinedInstrV: state->EndCondition = RDIError_UndefinedInstruction; break;
+ case ARMul_SWIV: state->EndCondition = RDIError_SoftwareInterrupt; break;
+ case ARMul_PrefetchAbortV: state->EndCondition = RDIError_PrefetchAbort; break;
+ case ARMul_DataAbortV: state->EndCondition = RDIError_DataAbort; break;
+ case ARMul_AddrExceptnV: state->EndCondition = RDIError_AddressException; break;
+ case ARMul_IRQV: state->EndCondition = RDIError_IRQ; break;
+ case ARMul_FIQV: state->EndCondition = RDIError_FIQ; break;
+ default: break;
+ }
+ state->Emulate = FALSE;
+ }
}
diff --git a/sim/arm/armos.c b/sim/arm/armos.c
index 04916d6ad72..613d07eda17 100644
--- a/sim/arm/armos.c
+++ b/sim/arm/armos.c
@@ -131,8 +131,11 @@ unsigned int swi_mask = -1;
static ARMword softvectorcode[] =
{
- /* Basic: swi tidyexception + event; mov pc, lr;
- ldmia r11,{r11,pc}; swi generateexception + event. */
+ /* Installed instructions:
+ swi tidyexception + event;
+ mov lr, pc;
+ ldmia fp, {fp, pc};
+ swi generateexception + event. */
0xef000090, 0xe1a0e00f, 0xe89b8800, 0xef000080, /* Reset */
0xef000091, 0xe1a0e00f, 0xe89b8800, 0xef000081, /* Undef */
0xef000092, 0xe1a0e00f, 0xe89b8800, 0xef000082, /* SWI */
@@ -205,11 +208,15 @@ ARMul_OSInit (ARMul_State * state)
/* Copy the code. */
ARMul_WriteWord (state, FPESTART + i, fpecode[i >> 2]);
+ /* Scan backwards from the end of the code. */
for (i = FPESTART + fpesize;; i -= 4)
{
- /* Reverse the error strings. */
+ /* When we reach the marker value, break out of
+ the loop, leaving i pointing at the maker. */
if ((j = ARMul_ReadWord (state, i)) == 0xffffffff)
break;
+
+ /* If necessary, reverse the error strings. */
if (state->bigendSig && j < 0x80000000)
{
/* It's part of the string so swap it. */
@@ -221,9 +228,9 @@ ARMul_OSInit (ARMul_State * state)
}
/* Copy old illegal instr vector. */
- ARMul_WriteWord (state, FPEOLDVECT, ARMul_ReadWord (state, 4));
+ ARMul_WriteWord (state, FPEOLDVECT, ARMul_ReadWord (state, ARMUndefinedInstrV));
/* Install new vector. */
- ARMul_WriteWord (state, 4, FPENEWVECT (ARMul_ReadWord (state, i - 4)));
+ ARMul_WriteWord (state, ARMUndefinedInstrV, FPENEWVECT (ARMul_ReadWord (state, i - 4)));
ARMul_ConsolePrint (state, ", FPE");
/* #endif ASIM */
@@ -692,12 +699,34 @@ ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
unhandled = TRUE;
break;
- case 0x90:
- case 0x91:
- case 0x92:
- /* These are used by the FPE code. */
+ /* The following SWIs are generated by the softvectorcode[]
+ installed by default by the simulator. */
+ case 0x91: /* Undefined Instruction. */
+ {
+ ARMword addr = state->RegBank[UNDEFBANK][14] - 4;
+
+ sim_callback->printf_filtered
+ (sim_callback, "sim: exception: Unhandled Instruction '0x%08x' at 0x%08x. Stopping.\n",
+ ARMul_ReadWord (state, addr), addr);
+ state->EndCondition = RDIError_SoftwareInterrupt;
+ state->Emulate = FALSE;
+ return FALSE;
+ }
+
+ case 0x90: /* Reset. */
+ case 0x92: /* SWI. */
+ /* These two can be safely ignored. */
break;
-
+
+ case 0x93: /* Prefetch Abort. */
+ case 0x94: /* Data Abort. */
+ case 0x95: /* Address Exception. */
+ case 0x96: /* IRQ. */
+ case 0x97: /* FIQ. */
+ case 0x98: /* Error. */
+ unhandled = TRUE;
+ break;
+
case -1:
/* This can happen when a SWI is interrupted (eg receiving a
ctrl-C whilst processing SWIRead()). The SWI will complete
diff --git a/sim/arm/configure b/sim/arm/configure
index 26fd5f5d6d1..a82b7c7119e 100755
--- a/sim/arm/configure
+++ b/sim/arm/configure
@@ -3534,7 +3534,7 @@ fi
done
-COPRO="armcopro.o maverick.o"
+COPRO="armcopro.o maverick.o iwmmxt.o"
diff --git a/sim/arm/configure.in b/sim/arm/configure.in
index 73fa0a0a643..44300ca8ca7 100644
--- a/sim/arm/configure.in
+++ b/sim/arm/configure.in
@@ -7,7 +7,7 @@ SIM_AC_COMMON
AC_CHECK_HEADERS(unistd.h)
-COPRO="armcopro.o maverick.o"
+COPRO="armcopro.o maverick.o iwmmxt.o"
AC_SUBST(COPRO)
diff --git a/sim/arm/wrapper.c b/sim/arm/wrapper.c
index f13d32928b0..bba6f7fd444 100644
--- a/sim/arm/wrapper.c
+++ b/sim/arm/wrapper.c
@@ -263,10 +263,34 @@ sim_create_inferior (sd, abfd, argv, env)
/* We wouldn't set the machine type with earlier toolchains, so we
explicitly select a processor capable of supporting all ARMs in
32bit mode. */
+ /* We choose the XScale rather than the iWMMXt, because the iWMMXt
+ removes the FPE emulator, since it conflicts with its coprocessors.
+ For the most generic ARM support, we want the FPE emulator in place. */
case bfd_mach_arm_XScale:
ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
break;
+ case bfd_mach_arm_iWMMXt:
+ {
+ extern int SWI_vector_installed;
+ ARMword i;
+
+ if (! SWI_vector_installed)
+ {
+ /* Intialise the hardware vectors to zero. */
+ if (! SWI_vector_installed)
+ for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
+ ARMul_WriteWord (state, i, 0);
+
+ /* ARM_WriteWord will have detected the write to the SWI vector,
+ but we want SWI_vector_installed to remain at 0 so that thumb
+ mode breakpoints will work. */
+ SWI_vector_installed = 0;
+ }
+ }
+ ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_iWMMXt_Prop);
+ break;
+
case bfd_mach_arm_ep9312:
ARMul_SelectProcessor (state, ARM_v4_Prop | ARM_ep9312_Prop);
break;
@@ -481,6 +505,40 @@ sim_store_register (sd, rn, memory, length)
memcpy (&DSPsc, memory, sizeof DSPsc);
return sizeof DSPsc;
+ case SIM_ARM_IWMMXT_COP0R0_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R1_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R2_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R3_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R4_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R5_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R6_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R7_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R8_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R9_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R10_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R11_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R12_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R13_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R14_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R15_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R0_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R1_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R2_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R3_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R4_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R5_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R6_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R7_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R8_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R9_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R10_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R11_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R12_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R13_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R14_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R15_REGNUM:
+ return Store_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
+
default:
return 0;
}
@@ -560,6 +618,40 @@ sim_fetch_register (sd, rn, memory, length)
memcpy (memory, & DSPsc, sizeof DSPsc);
return sizeof DSPsc;
+ case SIM_ARM_IWMMXT_COP0R0_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R1_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R2_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R3_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R4_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R5_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R6_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R7_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R8_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R9_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R10_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R11_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R12_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R13_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R14_REGNUM:
+ case SIM_ARM_IWMMXT_COP0R15_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R0_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R1_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R2_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R3_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R4_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R5_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R6_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R7_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R8_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R9_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R10_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R11_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R12_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R13_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R14_REGNUM:
+ case SIM_ARM_IWMMXT_COP1R15_REGNUM:
+ return Fetch_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
+
default:
return 0;
}
@@ -822,6 +914,9 @@ sim_stop_reason (sd, reason, sigrc)
*reason = sim_stopped;
if (state->EndCondition == RDIError_BreakpointReached)
*sigrc = SIGTRAP;
+ else if ( state->EndCondition == RDIError_DataAbort
+ || state->EndCondition == RDIError_AddressException)
+ *sigrc = SIGBUS;
else
*sigrc = 0;
}