diff options
Diffstat (limited to 'sim')
-rw-r--r-- | sim/arm/ChangeLog | 39 | ||||
-rw-r--r-- | sim/arm/Makefile.in | 1 | ||||
-rw-r--r-- | sim/arm/armcopro.c | 10 | ||||
-rw-r--r-- | sim/arm/armdefs.h | 2 | ||||
-rw-r--r-- | sim/arm/armemu.c | 23 | ||||
-rw-r--r-- | sim/arm/arminit.c | 23 | ||||
-rw-r--r-- | sim/arm/armos.c | 49 | ||||
-rwxr-xr-x | sim/arm/configure | 2 | ||||
-rw-r--r-- | sim/arm/configure.in | 2 | ||||
-rw-r--r-- | sim/arm/wrapper.c | 95 |
10 files changed, 232 insertions, 14 deletions
diff --git a/sim/arm/ChangeLog b/sim/arm/ChangeLog index c6597de..03c923e 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 017a983..7def0f9 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 b974789..aa75243 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 0f25222..a2ea405 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 44943c4..d12ad10 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 0439990..4588787 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 04916d6..613d07e 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 26fd5f5..a82b7c7 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 73fa0a0..44300ca 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 f13d329..bba6f7f 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; } |