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:
parent
77c8aaf716
commit
9f132af9e1
@ -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.
|
||||
|
@ -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>. */
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user