aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorJens Bauer <jens@plustv.dk>2020-12-15 12:40:35 +0000
committerNick Clifton <nickc@redhat.com>2020-12-15 12:40:35 +0000
commit9f132af9e189a6c1e90b1ab7ed84c6613c8ac596 (patch)
tree052c3a3094e1ecbb08e2a7f1e0bb5d88825066ed /sim
parent77c8aaf716d9f93dc5850f8b2481da5eb7a53662 (diff)
downloadfsf-binutils-gdb-9f132af9e189a6c1e90b1ab7ed84c6613c8ac596.zip
fsf-binutils-gdb-9f132af9e189a6c1e90b1ab7ed84c6613c8ac596.tar.gz
fsf-binutils-gdb-9f132af9e189a6c1e90b1ab7ed84c6613c8ac596.tar.bz2
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.
Diffstat (limited to 'sim')
-rw-r--r--sim/arm/ChangeLog9
-rw-r--r--sim/arm/armemu.c63
-rw-r--r--sim/arm/thumbemu.c71
-rw-r--r--sim/arm/wrapper.c8
4 files changed, 132 insertions, 19 deletions
diff --git a/sim/arm/ChangeLog b/sim/arm/ChangeLog
index 92dfaba..64171d6 100644
--- a/sim/arm/ChangeLog
+++ b/sim/arm/ChangeLog
@@ -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.
diff --git a/sim/arm/armemu.c b/sim/arm/armemu.c
index 3a72277..922c2e4 100644
--- a/sim/arm/armemu.c
+++ b/sim/arm/armemu.c
@@ -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>. */
{
diff --git a/sim/arm/thumbemu.c b/sim/arm/thumbemu.c
index 72929c7..fa70d5b 100644
--- a/sim/arm/thumbemu.c
+++ b/sim/arm/thumbemu.c
@@ -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;
diff --git a/sim/arm/wrapper.c b/sim/arm/wrapper.c
index 68f8242..cc18498 100644
--- a/sim/arm/wrapper.c
+++ b/sim/arm/wrapper.c
@@ -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;