sim: replace custom attributes with ansidecl.h
[binutils-gdb.git] / sim / arm / armemu.c
index 3826c78aa9e9f62e2c09ee48d24e7dcc9e579a56..f93ad0cee254bab55602fe515b1e01c94734ac35 100644 (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>.  */
       {
@@ -1140,10 +1201,6 @@ handle_VFP_move (ARMul_State * state, ARMword instr)
 
 /* EMULATION of ARM6.  */
 
-/* The PC pipeline value depends on whether ARM
-   or Thumb instructions are being executed.  */
-ARMword isize;
-
 ARMword
 #ifdef MODE32
 ARMul_Emulate32 (ARMul_State * state)
@@ -1293,7 +1350,6 @@ ARMul_Emulate26 (ARMul_State * state)
 
       if (state->CallDebug > 0)
        {
-         instr = ARMul_Debug (state, pc, instr);
          if (state->Emulate < ONCE)
            {
              state->NextInstr = RESUME;
@@ -5401,7 +5457,10 @@ Handle_Store_Double (ARMul_State * state, ARMword instr)
     addr = base;
 
   /* The address must be aligned on a 8 byte boundary.  */
-  if (addr & 0x7)
+  if (state->is_v6 && (addr & 0x3) == 0)
+    /* Word alignment is enough for v6.  */
+    ;
+  else if (addr & 0x7)
     {
 #ifdef ABORTS
       ARMul_DATAABORT (addr);
@@ -5951,10 +6010,10 @@ Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
        ;
       else
 #endif
-       if (nRdHi == nRm || nRdLo == nRm)
+       /* BAD code can trigger this result.  So only complain if debugging.  */
+       if (state->Debug && (nRdHi == nRm || nRdLo == nRm))
          fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS: %d %d %d\n",
                   nRdHi, nRdLo, nRm);
-
       if (msigned)
        {
          /* Compute sign of result and adjust operands if necessary.  */
@@ -5999,7 +6058,7 @@ Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
       state->Reg[nRdLo] = RdLo;
       state->Reg[nRdHi] = RdHi;
     }
-  else
+  else if (state->Debug)
     fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS\n");
 
   if (scc)