Add iWMMXt support to ARM simulator

This commit is contained in:
Nick Clifton 2003-03-27 17:13:33 +00:00
parent 378bfd1b7a
commit 0f026fd00c
14 changed files with 4043 additions and 11 deletions

View File

@ -1,3 +1,7 @@
2003-03-27 Nick Clifton <nickc@redhat.com>
* sim-arm.h (sim_arm_regs): Add iWMMXt registers.
2003-03-20 Nick Clifton <nickc@redhat.com>
* sim-arm.h (sim_arm_regs): Add Maverick co-processor

View File

@ -72,7 +72,39 @@ enum sim_arm_regs
SIM_ARM_MAVERIC_COP0R13_REGNUM,
SIM_ARM_MAVERIC_COP0R14_REGNUM,
SIM_ARM_MAVERIC_COP0R15_REGNUM,
SIM_ARM_MAVERIC_DSPSC_REGNUM
SIM_ARM_MAVERIC_DSPSC_REGNUM,
SIM_ARM_IWMMXT_COP0R0_REGNUM,
SIM_ARM_IWMMXT_COP0R1_REGNUM,
SIM_ARM_IWMMXT_COP0R2_REGNUM,
SIM_ARM_IWMMXT_COP0R3_REGNUM,
SIM_ARM_IWMMXT_COP0R4_REGNUM,
SIM_ARM_IWMMXT_COP0R5_REGNUM,
SIM_ARM_IWMMXT_COP0R6_REGNUM,
SIM_ARM_IWMMXT_COP0R7_REGNUM,
SIM_ARM_IWMMXT_COP0R8_REGNUM,
SIM_ARM_IWMMXT_COP0R9_REGNUM,
SIM_ARM_IWMMXT_COP0R10_REGNUM,
SIM_ARM_IWMMXT_COP0R11_REGNUM,
SIM_ARM_IWMMXT_COP0R12_REGNUM,
SIM_ARM_IWMMXT_COP0R13_REGNUM,
SIM_ARM_IWMMXT_COP0R14_REGNUM,
SIM_ARM_IWMMXT_COP0R15_REGNUM,
SIM_ARM_IWMMXT_COP1R0_REGNUM,
SIM_ARM_IWMMXT_COP1R1_REGNUM,
SIM_ARM_IWMMXT_COP1R2_REGNUM,
SIM_ARM_IWMMXT_COP1R3_REGNUM,
SIM_ARM_IWMMXT_COP1R4_REGNUM,
SIM_ARM_IWMMXT_COP1R5_REGNUM,
SIM_ARM_IWMMXT_COP1R6_REGNUM,
SIM_ARM_IWMMXT_COP1R7_REGNUM,
SIM_ARM_IWMMXT_COP1R8_REGNUM,
SIM_ARM_IWMMXT_COP1R9_REGNUM,
SIM_ARM_IWMMXT_COP1R10_REGNUM,
SIM_ARM_IWMMXT_COP1R11_REGNUM,
SIM_ARM_IWMMXT_COP1R12_REGNUM,
SIM_ARM_IWMMXT_COP1R13_REGNUM,
SIM_ARM_IWMMXT_COP1R14_REGNUM,
SIM_ARM_IWMMXT_COP1R15_REGNUM
};
#ifdef __cplusplus

View File

@ -1,3 +1,28 @@
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.
(ARMul_OsHandleSWI): Catch SWIs for unhandled vectors.
* 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,

View File

@ -32,6 +32,11 @@ 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
CON_FLAGS=@CON_FLAGS@
ALL_CFLAGS += $(CON_FLAGS)
armemu26.o: armemu.c armdefs.h armemu.h
$(CC) -c $(srcdir)/armemu.c -o armemu26.o $(ALL_CFLAGS)

View File

@ -19,6 +19,9 @@
#include "armos.h"
#include "armemu.h"
#include "ansidecl.h"
#ifdef __IWMMXT__
#include "iwmmxt.h"
#endif
/* Dummy Co-processors. */
@ -1365,6 +1368,16 @@ ARMul_CoProInit (ARMul_State * state)
MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
}
#ifdef __IWMMXT__
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);
}
#endif
/* No handlers below here. */
/* Call all the initialisation routines. */

View File

@ -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 *

View File

@ -19,6 +19,9 @@
#include "armdefs.h"
#include "armemu.h"
#include "armos.h"
#ifdef __IWMMXT__
#include "iwmmxt.h"
#endif
static ARMword GetDPRegRHS (ARMul_State *, ARMword);
static ARMword GetDPSRegRHS (ARMul_State *, ARMword);
@ -379,6 +382,20 @@ ARMul_Emulate26 (ARMul_State * state)
fprintf (stderr, "pc: %x, instr: %x\n", pc & ~1, instr);
if (instr == 0)
abort ();
#endif
#ifdef __IWMMXT__
#if 0
{
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
#endif
if (state->Exception)
@ -492,6 +509,12 @@ ARMul_Emulate26 (ARMul_State * state)
else if ((instr & 0xFC70F000) == 0xF450F000)
/* The PLD instruction. Ignored. */
goto donext;
#ifdef __IWMMXT__
else if ( ((instr & 0xfe500f00) == 0xfc100100)
|| ((instr & 0xfe500f00) == 0xfc000100))
/* wldrw and wstrw are unconditional. */
goto mainswitch;
#endif
else
/* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2. */
ARMul_UndefInstr (state, instr);
@ -689,6 +712,10 @@ check_PMUintr:
goto donext;
}
}
#ifdef __IWMMXT__
if (ARMul_HandleIwmmxt (state, instr))
goto donext;
#endif
}
switch ((int) BITS (20, 27))

View File

@ -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;
}
}

View File

@ -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

9
sim/arm/configure vendored
View File

@ -3535,6 +3535,14 @@ done
COPRO="armcopro.o maverick.o"
CON_FLAGS=
case x$target_alias in
xxscale-*)
COPRO="armcopro.o maverick.o iwmmxt.o"
CON_FLAGS=-D__IWMMXT__
;;
esac
@ -3748,6 +3756,7 @@ s%@sim_stdio@%$sim_stdio%g
s%@sim_trace@%$sim_trace%g
s%@sim_profile@%$sim_profile%g
s%@EXEEXT@%$EXEEXT%g
s%@CON_FLAGS@%$CON_FLAGS%g
s%@COPRO@%$COPRO%g
CEOF

View File

@ -8,7 +8,15 @@ SIM_AC_COMMON
AC_CHECK_HEADERS(unistd.h)
COPRO="armcopro.o maverick.o"
CON_FLAGS=
case x$target_alias in
xxscale-*)
COPRO="armcopro.o maverick.o iwmmxt.o"
CON_FLAGS=-D__IWMMXT__
;;
esac
AC_SUBST(CON_FLAGS)
AC_SUBST(COPRO)
SIM_AC_OUTPUT

3730
sim/arm/iwmmxt.c Normal file

File diff suppressed because it is too large Load Diff

28
sim/arm/iwmmxt.h Normal file
View File

@ -0,0 +1,28 @@
/* iwmmxt.h -- Intel(r) Wireless MMX(tm) technology co-processor interface.
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by matthew green (mrg@redhat.com).
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
extern unsigned IwmmxtLDC (ARMul_State *, unsigned, ARMword, ARMword);
extern unsigned IwmmxtSTC (ARMul_State *, unsigned, ARMword, ARMword *);
extern unsigned IwmmxtMCR (ARMul_State *, unsigned, ARMword, ARMword);
extern unsigned IwmmxtMRC (ARMul_State *, unsigned, ARMword, ARMword *);
extern unsigned IwmmxtCDP (ARMul_State *, unsigned, ARMword);
extern int ARMul_HandleIwmmxt (ARMul_State *, ARMword);
extern int Fetch_Iwmmxt_Register (unsigned int, unsigned char *);
extern int Store_Iwmmxt_Register (unsigned int, unsigned char *);

View File

@ -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,41 @@ sim_store_register (sd, rn, memory, length)
memcpy (&DSPsc, memory, sizeof DSPsc);
return sizeof DSPsc;
#ifdef __IWMMXT__
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);
#endif
default:
return 0;
}
@ -560,6 +619,41 @@ sim_fetch_register (sd, rn, memory, length)
memcpy (memory, & DSPsc, sizeof DSPsc);
return sizeof DSPsc;
#ifdef __IWMMXT__
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);
#endif
default:
return 0;
}
@ -822,6 +916,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;
}