Add support for the SDIV and UDIV instructions to the ARM simulator.

* armemu.c (handle_v6_insn): Add support for SDIV and UDIV.
	* thumbemu.c (handle_T2_insn): Likewise.
This commit is contained in:
Jens Bauer 2020-12-15 12:40:35 +00:00 committed by Nick Clifton
parent 77c8aaf716
commit 9f132af9e1
4 changed files with 132 additions and 19 deletions

View File

@ -1,3 +1,12 @@
2020-12-15 Nick Clifton <nickc@redhat.com>
* wrapper.c (sim_create_inferior): Accept some more ARM machine numbers.
2020-12-15 Jens Bauer <jens@plustv.dk>
* armemu.c (handle_v6_insn): Add support for SDIV and UDIV.
* thumbemu.c (handle_T2_insn): Likewise.
2020-10-20 Dr. David Alan Gilbert <dgilbert@redhat.com>
* armos.c (SWIread): Fix printf format.

View File

@ -915,6 +915,68 @@ handle_v6_insn (ARMul_State * state, ARMword instr)
}
return 1;
case 0x71:
case 0x73:
{
ARMword valn, valm;
/* SDIV<c> <Rd>,<Rn>,<Rm>
UDIV<c> <Rd>,<Rn>,<Rm>
instr[31,28] = cond
instr[27,20] = 0111 0001 (SDIV), 0111 0011 (UDIV)
instr[21,21] = sign
instr[19,16] = Rn
instr[15,12] = 1111
instr[11, 8] = Rd
instr[ 7, 4] = 1111
instr[ 3, 0] = Rm */
/* These bit-positions are confusing!
instr[15,12] = Rd
instr[11, 8] = 1111 */
#if 0 /* This is what I would expect: */
Rn = BITS (16, 19);
Rd = BITS (8, 11);
Rm = BITS (0, 3);
#else /* This seem to work: */
Rd = BITS (16, 19);
Rm = BITS (8, 11);
Rn = BITS (0, 3);
#endif
if (Rn == 15 || Rd == 15 || Rm == 15
|| Rn == 13 || Rd == 13 || Rm == 13)
{
ARMul_UndefInstr (state, instr);
state->Emulate = FALSE;
break;
}
valn = state->Reg[Rn];
valm = state->Reg[Rm];
if (valm == 0)
{
#if 0
/* Exceptions: UsageFault, address 20
Note: UsageFault is for Cortex-M; I don't know what it would be on non-Cortex-M. */
ARMul_Abort (state, address);
#endif
printf ("Unhandled v6 insn: %cDIV divide by zero exception\n", "SU"[BIT(21)]);
}
else
{
if(BIT(21))
{
val = valn / valm;
}
else
{
val = ((ARMsword)valn / (ARMsword)valm);
}
state->Reg[Rd] = val;
}
return 1;
}
case 0x7c:
case 0x7d:
{
@ -963,7 +1025,6 @@ handle_v6_insn (ARMul_State * state, ARMword instr)
}
return 1;
}
case 0x7b:
case 0x7a: /* SBFX<c> <Rd>,<Rn>,#<lsb>,#<width>. */
{

View File

@ -1759,26 +1759,60 @@ handle_T2_insn (ARMul_State * state,
break;
}
case 0xDC: // SMULL
tASSERT (tBIT (4) == 0);
tASSERT (ntBITS (4, 7) == 0);
* ainstr = 0xE0C00090;
* ainstr |= (ntBITS (8, 11) << 16); // RdHi
* ainstr |= (ntBITS (12, 15) << 12); // RdLo
* ainstr |= (ntBITS (0, 3) << 8); // Rm
* ainstr |= tBITS (0, 3); // Rn
* pvalid = t_decoded;
case 0xDC:
if (tBIT (4) == 0 && ntBITS (4, 7) == 0)
{
// SMULL
* ainstr = 0xE0C00090;
* ainstr |= (ntBITS (8, 11) << 16); // RdHi
* ainstr |= (ntBITS (12, 15) << 12); // RdLo
* ainstr |= (ntBITS (0, 3) << 8); // Rm
* ainstr |= tBITS (0, 3); // Rn
* pvalid = t_decoded;
}
else if (tBIT (4) == 1 && ntBITS (4, 7) == 0xF)
{
// SDIV
* ainstr = 0xE710F010;
* ainstr |= (ntBITS (8, 11) << 16); // Rd
* ainstr |= (ntBITS (0, 3) << 8); // Rm
* ainstr |= tBITS (0, 3); // Rn
* pvalid = t_decoded;
}
else
{
fprintf (stderr, "(op = %x) ", tBITS (5,12));
tASSERT (0);
return;
}
break;
case 0xDD: // UMULL
tASSERT (tBIT (4) == 0);
tASSERT (ntBITS (4, 7) == 0);
* ainstr = 0xE0800090;
* ainstr |= (ntBITS (8, 11) << 16); // RdHi
* ainstr |= (ntBITS (12, 15) << 12); // RdLo
* ainstr |= (ntBITS (0, 3) << 8); // Rm
* ainstr |= tBITS (0, 3); // Rn
* pvalid = t_decoded;
case 0xDD:
if (tBIT (4) == 0 && ntBITS (4, 7) == 0)
{
// UMULL
* ainstr = 0xE0800090;
* ainstr |= (ntBITS (8, 11) << 16); // RdHi
* ainstr |= (ntBITS (12, 15) << 12); // RdLo
* ainstr |= (ntBITS (0, 3) << 8); // Rm
* ainstr |= tBITS (0, 3); // Rn
* pvalid = t_decoded;
}
else if (tBIT (4) == 1 && ntBITS (4, 7) == 0xF)
{
// UDIV
* ainstr = 0xE730F010;
* ainstr |= (ntBITS (8, 11) << 16); // Rd
* ainstr |= (ntBITS (0, 3) << 8); // Rm
* ainstr |= tBITS (0, 3); // Rn
* pvalid = t_decoded;
}
else
{
fprintf (stderr, "(op = %x) ", tBITS (5,12));
tASSERT (0);
return;
}
break;
case 0xDF: // UMLAL
@ -1896,6 +1930,7 @@ handle_v6_thumb_insn (ARMul_State * state,
case 0xEB80: // SUB
case 0xEBC0: // RSB
case 0xFA80: // UADD, SEL
case 0xFBC0: // UMULL, SMULL, SDIV, UDIV
handle_T2_insn (state, tinstr, next_instr, pc, ainstr, pvalid);
return;

View File

@ -241,6 +241,14 @@ sim_create_inferior (SIM_DESC sd ATTRIBUTE_UNUSED,
ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_v6_Prop);
break;
#if 1
case bfd_mach_arm_6T2:
case bfd_mach_arm_7:
case bfd_mach_arm_7EM:
ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_v6_Prop);
break;
#endif
case bfd_mach_arm_XScale:
ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop);
break;