* armemu.c (handle_v6_insn): New function - emulate a few of the v6 instructions - the ones now generated by GCC.

(ARMulEmulate32): Call handle_v6_insn when a possible v6 insn is found.
* armdefs.h (struct ARMul_State): Add new field: is_v6.#
  (ARM_v6_Prop): Define.
* arminit.c (ARMul_NewState): Initialise the v6 flag.
  (ARMul_SelectProcessor): Determine if the v6 flag should be set.
* wrapper.c (sim_create_inferior): For unknown architectures, default to allowing the v6 instructions.
This commit is contained in:
Nick Clifton 2005-04-25 07:48:59 +00:00
parent 02ddf15681
commit 8207e0f24e
5 changed files with 314 additions and 1 deletions

View file

@ -1,3 +1,17 @@
2005-04-20 Nick Clifton <nickc@redhat.com>
* armemu.c (handle_v6_insn): New function - emulate a few of the
v6 instructions - the ones now generated by GCC.
(ARMulEmulate32): Call handle_v6_insn when a possible v6 insn is
found.
* armdefs.h (struct ARMul_State): Add new field: is_v6.
(ARM_v6_Prop): Define.
* arminit.c (ARMul_NewState): Initialise the v6 flag.
(ARMul_SelectProcessor): Determine if the v6 flag should be
set.
* wrapper.c (sim_create_inferior): For unknown architectures,
default to allowing the v6 instructions.
2005-04-18 Nick Clifton <nickc@redhat.com>
* iwmmxt.c (WMAC, WMADD): Move casts from the LHS of an assignment

View file

@ -134,6 +134,7 @@ 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_v6; /* Are we emulating a v6 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 ? */
@ -166,6 +167,7 @@ struct ARMul_State
#define ARM_XScale_Prop 0x200
#define ARM_ep9312_Prop 0x400
#define ARM_iWMMXt_Prop 0x800
#define ARM_v6_Prop 0x1000
/***************************************************************************\
* Macros to extract instruction fields *

View file

@ -269,6 +269,211 @@ extern int stop_simulator;
break; \
}
/* Attempt to emulate an ARMv6 instruction.
Returns non-zero upon success. */
static int
handle_v6_insn (ARMul_State * state, ARMword instr)
{
switch (BITS (20, 27))
{
#if 0
case 0x03: printf ("Unhandled v6 insn: ldr\n"); break;
case 0x04: printf ("Unhandled v6 insn: umaal\n"); break;
case 0x06: printf ("Unhandled v6 insn: mls/str\n"); break;
case 0x16: printf ("Unhandled v6 insn: smi\n"); break;
case 0x18: printf ("Unhandled v6 insn: strex\n"); break;
case 0x19: printf ("Unhandled v6 insn: ldrex\n"); break;
case 0x1a: printf ("Unhandled v6 insn: strexd\n"); break;
case 0x1b: printf ("Unhandled v6 insn: ldrexd\n"); break;
case 0x1c: printf ("Unhandled v6 insn: strexb\n"); break;
case 0x1d: printf ("Unhandled v6 insn: ldrexb\n"); break;
case 0x1e: printf ("Unhandled v6 insn: strexh\n"); break;
case 0x1f: printf ("Unhandled v6 insn: ldrexh\n"); break;
case 0x30: printf ("Unhandled v6 insn: movw\n"); break;
case 0x32: printf ("Unhandled v6 insn: nop/sev/wfe/wfi/yield\n"); break;
case 0x34: printf ("Unhandled v6 insn: movt\n"); break;
case 0x3f: printf ("Unhandled v6 insn: rbit\n"); break;
#endif
case 0x61: printf ("Unhandled v6 insn: sadd/ssub\n"); break;
case 0x62: printf ("Unhandled v6 insn: qadd/qsub\n"); break;
case 0x63: printf ("Unhandled v6 insn: shadd/shsub\n"); break;
case 0x65: printf ("Unhandled v6 insn: uadd/usub\n"); break;
case 0x66: printf ("Unhandled v6 insn: uqadd/uqsub\n"); break;
case 0x67: printf ("Unhandled v6 insn: uhadd/uhsub\n"); break;
case 0x68: printf ("Unhandled v6 insn: pkh/sxtab/selsxtb\n"); break;
case 0x6c: printf ("Unhandled v6 insn: uxtb16/uxtab16\n"); break;
case 0x70: printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); break;
case 0x74: printf ("Unhandled v6 insn: smlald/smlsld\n"); break;
case 0x75: printf ("Unhandled v6 insn: smmla/smmls/smmul\n"); break;
case 0x78: printf ("Unhandled v6 insn: usad/usada8\n"); break;
case 0x7a: printf ("Unhandled v6 insn: usbfx\n"); break;
case 0x7c: printf ("Unhandled v6 insn: bfc/bfi\n"); break;
case 0x6a:
{
ARMword Rm;
int ror = -1;
switch (BITS (4, 11))
{
case 0x07: ror = 0; break;
case 0x47: ror = 8; break;
case 0x87: ror = 16; break;
case 0xc7: ror = 24; break;
case 0x01:
case 0xf3:
printf ("Unhandled v6 insn: ssat\n");
return 0;
default:
break;
}
if (ror == -1)
{
if (BITS (4, 6) == 0x7)
{
printf ("Unhandled v6 insn: ssat\n");
return 0;
}
break;
}
Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF);
if (Rm & 0x80)
Rm |= 0xffffff00;
if (BITS (16, 19) == 0xf)
/* SXTB */
state->Reg[BITS (12, 15)] = Rm;
else
/* SXTAB */
state->Reg[BITS (12, 15)] += Rm;
}
return 1;
case 0x6b:
{
ARMword Rm;
int ror = -1;
switch (BITS (4, 11))
{
case 0x07: ror = 0; break;
case 0x47: ror = 8; break;
case 0x87: ror = 16; break;
case 0xc7: ror = 24; break;
case 0xfb:
printf ("Unhandled v6 insn: rev\n");
return 0;
default:
break;
}
if (ror == -1)
break;
Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF);
if (Rm & 8000)
Rm |= 0xffff0000;
if (BITS (16, 19) == 0xf)
/* SXTH */
state->Reg[BITS (12, 15)] = Rm;
else
/* SXTAH */
state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm;
}
return 1;
case 0x6e:
{
ARMword Rm;
int ror = -1;
switch (BITS (4, 11))
{
case 0x07: ror = 0; break;
case 0x47: ror = 8; break;
case 0x87: ror = 16; break;
case 0xc7: ror = 24; break;
case 0x01:
case 0xf3:
printf ("Unhandled v6 insn: usat\n");
return 0;
default:
break;
}
if (ror == -1)
{
if (BITS (4, 6) == 0x7)
{
printf ("Unhandled v6 insn: usat\n");
return 0;
}
break;
}
Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF);
if (BITS (16, 19) == 0xf)
/* UXTB */
state->Reg[BITS (12, 15)] = Rm;
else
/* UXTAB */
state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm;
}
return 1;
case 0x6f:
{
ARMword Rm;
int ror = -1;
switch (BITS (4, 11))
{
case 0x07: ror = 0; break;
case 0x47: ror = 8; break;
case 0x87: ror = 16; break;
case 0xc7: ror = 24; break;
case 0xfb:
printf ("Unhandled v6 insn: revsh\n");
return 0;
default:
break;
}
if (ror == -1)
break;
Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF);
if (BITS (16, 19) == 0xf)
/* UXT */
state->Reg[BITS (12, 15)] = Rm;
else
{
/* UXTAH */
state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm;
}
}
return 1;
#if 0
case 0x84: printf ("Unhandled v6 insn: srs\n"); break;
#endif
default:
break;
}
printf ("Unhandled v6 insn: UNKNOWN: %08x\n", instr);
return 0;
}
/* EMULATION of ARM6. */
/* The PC pipeline value depends on whether ARM
@ -2537,6 +2742,11 @@ check_PMUintr:
case 0x61: /* Load Word, No WriteBack, Post Dec, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2553,6 +2763,11 @@ check_PMUintr:
case 0x62: /* Store Word, WriteBack, Post Dec, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2570,6 +2785,11 @@ check_PMUintr:
case 0x63: /* Load Word, WriteBack, Post Dec, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2603,6 +2823,11 @@ check_PMUintr:
case 0x65: /* Load Byte, No WriteBack, Post Dec, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2619,6 +2844,11 @@ check_PMUintr:
case 0x66: /* Store Byte, WriteBack, Post Dec, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2636,6 +2866,11 @@ check_PMUintr:
case 0x67: /* Load Byte, WriteBack, Post Dec, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2654,6 +2889,11 @@ check_PMUintr:
case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2685,6 +2925,11 @@ check_PMUintr:
case 0x6a: /* Store Word, WriteBack, Post Inc, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2702,6 +2947,11 @@ check_PMUintr:
case 0x6b: /* Load Word, WriteBack, Post Inc, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2720,6 +2970,11 @@ check_PMUintr:
case 0x6c: /* Store Byte, No WriteBack, Post Inc, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2751,6 +3006,11 @@ check_PMUintr:
case 0x6e: /* Store Byte, WriteBack, Post Inc, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2768,6 +3028,11 @@ check_PMUintr:
case 0x6f: /* Load Byte, WriteBack, Post Inc, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2787,6 +3052,11 @@ check_PMUintr:
case 0x70: /* Store Word, No WriteBack, Pre Dec, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2835,6 +3105,11 @@ check_PMUintr:
case 0x74: /* Store Byte, No WriteBack, Pre Dec, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2844,6 +3119,11 @@ check_PMUintr:
case 0x75: /* Load Byte, No WriteBack, Pre Dec, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2883,6 +3163,11 @@ check_PMUintr:
case 0x78: /* Store Word, No WriteBack, Pre Inc, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2901,6 +3186,11 @@ check_PMUintr:
case 0x7a: /* Store Word, WriteBack, Pre Inc, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}
@ -2931,6 +3221,11 @@ check_PMUintr:
case 0x7c: /* Store Byte, No WriteBack, Pre Inc, Reg. */
if (BIT (4))
{
#ifdef MODE32
if (state->is_v6
&& handle_v6_insn (state, instr))
break;
#endif
ARMul_UndefInstr (state, instr);
break;
}

View file

@ -129,6 +129,7 @@ ARMul_NewState (void)
state->is_v5e = LOW;
state->is_XScale = LOW;
state->is_iWMMXt = LOW;
state->is_v6 = LOW;
ARMul_Reset (state);
@ -161,6 +162,7 @@ ARMul_SelectProcessor (ARMul_State * state, unsigned properties)
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;
state->is_v6 = (properties & ARM_v6_Prop) ? HIGH : LOW;
/* Only initialse the coprocessor support once we
know what kind of chip we are dealing with. */

View file

@ -275,7 +275,7 @@ sim_create_inferior (sd, abfd, argv, env)
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);
ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop);
break;
case bfd_mach_arm_iWMMXt: