sim: replace custom attributes with ansidecl.h
[binutils-gdb.git] / sim / arm / armemu.c
index ebc6aed1f6da38b5ebdc3e3c07903eb5518f5bcb..f93ad0cee254bab55602fe515b1e01c94734ac35 100644 (file)
@@ -1,30 +1,31 @@
 /*  armemu.c -- Main instruction emulation:  ARM7 Instruction Emulator.
     Copyright (C) 1994 Advanced RISC Machines Ltd.
     Modifications to add arch. v4 support by <jsmith@cygnus.com>.
+
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
+    the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
+
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
+
     You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+    along with this program; if not, see <http://www.gnu.org/licenses/>.  */
 
 #include "armdefs.h"
 #include "armemu.h"
 #include "armos.h"
+#include "iwmmxt.h"
 
 static ARMword  GetDPRegRHS         (ARMul_State *, ARMword);
 static ARMword  GetDPSRegRHS        (ARMul_State *, ARMword);
 static void     WriteR15            (ARMul_State *, ARMword);
 static void     WriteSR15           (ARMul_State *, ARMword);
 static void     WriteR15Branch      (ARMul_State *, ARMword);
+static void     WriteR15Load        (ARMul_State *, ARMword);
 static ARMword  GetLSRegRHS         (ARMul_State *, ARMword);
 static ARMword  GetLS7RHS           (ARMul_State *, ARMword);
 static unsigned LoadWord            (ARMul_State *, ARMword, ARMword);
@@ -47,17 +48,6 @@ static void     Handle_Store_Double (ARMul_State *, ARMword);
 #define LDEFAULT  (0)          /* default : do nothing */
 #define LSCC      (1)          /* set condition codes on result */
 
-#ifdef NEED_UI_LOOP_HOOK
-/* How often to run the ui_loop update, when in use.  */
-#define UI_LOOP_POLL_INTERVAL 0x32000
-
-/* Counter for the ui_loop_hook update.  */
-static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
-
-/* Actual hook to call to run through gdb's gui event loop.  */
-extern int (*ui_loop_hook) (int);
-#endif /* NEED_UI_LOOP_HOOK */
-
 extern int stop_simulator;
 
 /* Short-hand macros for LDR/STR.  */
@@ -268,11 +258,948 @@ extern int stop_simulator;
      break;                                                            \
 }
 
-/* EMULATION of ARM6.  */
+/* Attempt to emulate an ARMv6 instruction.
+   Returns non-zero upon success.  */
+
+#ifdef MODE32
+static int
+handle_v6_insn (ARMul_State * state, ARMword instr)
+{
+  ARMword val;
+  ARMword Rd;
+  ARMword Rm;
+  ARMword Rn;
+
+  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 0x32: printf ("Unhandled v6 insn: nop/sev/wfe/wfi/yield\n"); break;
+    case 0x3f: printf ("Unhandled v6 insn: rbit\n"); break;
+#endif
+    case 0x61: printf ("Unhandled v6 insn: sadd/ssub\n"); break;
+    case 0x63: printf ("Unhandled v6 insn: shadd/shsub\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 0x30:
+      {
+       /* MOVW<c> <Rd>,#<imm16>
+          instr[31,28] = cond
+          instr[27,20] = 0011 0000
+          instr[19,16] = imm4
+          instr[15,12] = Rd
+          instr[11, 0] = imm12.  */
+       Rd = BITS (12, 15);
+       val = (BITS (16, 19) << 12) | BITS (0, 11);
+       state->Reg[Rd] = val;
+       return 1;
+      }
+
+    case 0x34:
+      {
+       /* MOVT<c> <Rd>,#<imm16>
+          instr[31,28] = cond
+          instr[27,20] = 0011 0100
+          instr[19,16] = imm4
+          instr[15,12] = Rd
+          instr[11, 0] = imm12.  */
+       Rd = BITS (12, 15);
+       val = (BITS (16, 19) << 12) | BITS (0, 11);
+       state->Reg[Rd] &= 0xFFFF;
+       state->Reg[Rd] |= val << 16;
+       return 1;
+      }
+
+    case 0x62:
+      {
+       ARMword val1;
+       ARMword val2;
+       ARMsword n, m, r;
+       int i;
+
+       Rd = BITS (12, 15);
+       Rn = BITS (16, 19);
+       Rm = BITS (0, 3);
+
+       if (Rd == 15 || Rn == 15 || Rm == 15)
+         break;
+
+       val1 = state->Reg[Rn];
+       val2 = state->Reg[Rm];
+
+       switch (BITS (4, 11))
+         {
+         case 0xF1: /* QADD16<c> <Rd>,<Rn>,<Rm>.  */
+           state->Reg[Rd] = 0;
+
+           for (i = 0; i < 32; i+= 16)
+             {
+               n = (val1 >> i) & 0xFFFF;
+               if (n & 0x8000)
+                 n |= -(1 << 16);
+
+               m = (val2 >> i) & 0xFFFF;
+               if (m & 0x8000)
+                 m |= -(1 << 16);
+
+               r = n + m;
+
+               if (r > 0x7FFF)
+                 r = 0x7FFF;
+               else if (r < -(0x8000))
+                 r = - 0x8000;
+
+               state->Reg[Rd] |= (r & 0xFFFF) << i;
+             } 
+           return 1;
+
+         case 0xF3: /* QASX<c> <Rd>,<Rn>,<Rm>.  */
+           n = val1 & 0xFFFF;
+           if (n & 0x8000)
+             n |= -(1 << 16);
+
+           m = (val2 >> 16) & 0xFFFF;
+           if (m & 0x8000)
+             m |= -(1 << 16);
+
+           r = n - m;
+
+           if (r > 0x7FFF)
+             r = 0x7FFF;
+           else if (r < -(0x8000))
+             r = - 0x8000;
+
+           state->Reg[Rd] = (r & 0xFFFF);
+
+           n = (val1 >> 16) & 0xFFFF;
+           if (n & 0x8000)
+             n |= -(1 << 16);
+
+           m = val2 & 0xFFFF;
+           if (m & 0x8000)
+             m |= -(1 << 16);
+
+           r = n + m;
+
+           if (r > 0x7FFF)
+             r = 0x7FFF;
+           else if (r < -(0x8000))
+             r = - 0x8000;
+
+           state->Reg[Rd] |= (r & 0xFFFF) << 16;
+           return 1;
+
+         case 0xF5: /* QSAX<c> <Rd>,<Rn>,<Rm>.  */
+           n = val1 & 0xFFFF;
+           if (n & 0x8000)
+             n |= -(1 << 16);
+
+           m = (val2 >> 16) & 0xFFFF;
+           if (m & 0x8000)
+             m |= -(1 << 16);
+
+           r = n + m;
+
+           if (r > 0x7FFF)
+             r = 0x7FFF;
+           else if (r < -(0x8000))
+             r = - 0x8000;
+
+           state->Reg[Rd] = (r & 0xFFFF);
+
+           n = (val1 >> 16) & 0xFFFF;
+           if (n & 0x8000)
+             n |= -(1 << 16);
+
+           m = val2 & 0xFFFF;
+           if (m & 0x8000)
+             m |= -(1 << 16);
+
+           r = n - m;
+
+           if (r > 0x7FFF)
+             r = 0x7FFF;
+           else if (r < -(0x8000))
+             r = - 0x8000;
+
+           state->Reg[Rd] |= (r & 0xFFFF) << 16;
+           return 1;
+
+         case 0xF7: /* QSUB16<c> <Rd>,<Rn>,<Rm>.  */
+           state->Reg[Rd] = 0;
+
+           for (i = 0; i < 32; i+= 16)
+             {
+               n = (val1 >> i) & 0xFFFF;
+               if (n & 0x8000)
+                 n |= -(1 << 16);
+
+               m = (val2 >> i) & 0xFFFF;
+               if (m & 0x8000)
+                 m |= -(1 << 16);
+
+               r = n - m;
+
+               if (r > 0x7FFF)
+                 r = 0x7FFF;
+               else if (r < -(0x8000))
+                 r = - 0x8000;
+
+               state->Reg[Rd] |= (r & 0xFFFF) << i;
+             } 
+           return 1;
+
+         case 0xF9: /* QADD8<c> <Rd>,<Rn>,<Rm>.  */
+           state->Reg[Rd] = 0;
+
+           for (i = 0; i < 32; i+= 8)
+             {
+               n = (val1 >> i) & 0xFF;
+               if (n & 0x80)
+                 n |= - (1 << 8);
+
+               m = (val2 >> i) & 0xFF;
+               if (m & 0x80)
+                 m |= - (1 << 8);
+
+               r = n + m;
+
+               if (r > 127)
+                 r = 127;
+               else if (r < -128)
+                 r = -128;
+
+               state->Reg[Rd] |= (r & 0xFF) << i;
+             } 
+           return 1;
+
+         case 0xFF: /* QSUB8<c> <Rd>,<Rn>,<Rm>.  */
+           state->Reg[Rd] = 0;
+
+           for (i = 0; i < 32; i+= 8)
+             {
+               n = (val1 >> i) & 0xFF;
+               if (n & 0x80)
+                 n |= - (1 << 8);
+
+               m = (val2 >> i) & 0xFF;
+               if (m & 0x80)
+                 m |= - (1 << 8);
+
+               r = n - m;
+
+               if (r > 127)
+                 r = 127;
+               else if (r < -128)
+                 r = -128;
+
+               state->Reg[Rd] |= (r & 0xFF) << i;
+             } 
+           return 1;
+
+         default:
+           break;
+         }
+       break;
+      }
+
+    case 0x65:
+      {
+       ARMword valn;
+       ARMword valm;
+       ARMword res1, res2, res3, res4;
+
+       /* U{ADD|SUB}{8|16}<c> <Rd>, <Rn>, <Rm>
+          instr[31,28] = cond
+          instr[27,20] = 0110 0101
+          instr[19,16] = Rn
+          instr[15,12] = Rd
+          instr[11, 8] = 1111
+          instr[ 7, 4] = opcode: UADD8 (1001), UADD16 (0001), USUB8 (1111), USUB16 (0111)
+          instr[ 3, 0] = Rm.  */
+       if (BITS (8, 11) != 0xF)
+         break;
+
+       Rn = BITS (16, 19);
+       Rd = BITS (12, 15);
+       Rm = BITS (0, 3);
+
+       if (Rn == 15 || Rd == 15 || Rm == 15)
+         {
+           ARMul_UndefInstr (state, instr);
+           state->Emulate = FALSE;
+           break;
+         }
+
+       valn = state->Reg[Rn];
+       valm = state->Reg[Rm];
+       
+       switch (BITS (4, 7))
+         {
+         case 1:  /* UADD16.  */
+           res1 = (valn & 0xFFFF) + (valm & 0xFFFF);
+           if (res1 > 0xFFFF)
+             state->Cpsr |= (GE0 | GE1);
+           else
+             state->Cpsr &= ~ (GE0 | GE1);
+
+           res2 = (valn >> 16) + (valm >> 16);
+           if (res2 > 0xFFFF)
+             state->Cpsr |= (GE2 | GE3);
+           else
+             state->Cpsr &= ~ (GE2 | GE3);
+
+           state->Reg[Rd] = (res1 & 0xFFFF) | (res2 << 16);
+           return 1;
+
+         case 7:  /* USUB16.  */
+           res1 = (valn & 0xFFFF) - (valm & 0xFFFF);
+           if (res1 & 0x800000)
+             state->Cpsr |= (GE0 | GE1);
+           else
+             state->Cpsr &= ~ (GE0 | GE1);
+
+           res2 = (valn >> 16) - (valm >> 16);
+           if (res2 & 0x800000)
+             state->Cpsr |= (GE2 | GE3);
+           else
+             state->Cpsr &= ~ (GE2 | GE3);
+
+           state->Reg[Rd] = (res1 & 0xFFFF) | (res2 << 16);
+           return 1;
+
+         case 9:  /* UADD8.  */
+           res1 = (valn & 0xFF) + (valm & 0xFF);
+           if (res1 > 0xFF)
+             state->Cpsr |= GE0;
+           else
+             state->Cpsr &= ~ GE0;
+
+           res2 = ((valn >> 8) & 0xFF) + ((valm >> 8) & 0xFF);
+           if (res2 > 0xFF)
+             state->Cpsr |= GE1;
+           else
+             state->Cpsr &= ~ GE1;
+
+           res3 = ((valn >> 16) & 0xFF) + ((valm >> 16) & 0xFF);
+           if (res3 > 0xFF)
+             state->Cpsr |= GE2;
+           else
+             state->Cpsr &= ~ GE2;
+
+           res4 = (valn >> 24) + (valm >> 24);
+           if (res4 > 0xFF)
+             state->Cpsr |= GE3;
+           else
+             state->Cpsr &= ~ GE3;
+
+           state->Reg[Rd] = (res1 & 0xFF) | ((res2 << 8) & 0xFF00)
+             | ((res3 << 16) & 0xFF0000) | (res4 << 24);
+           return 1;
+
+         case 15: /* USUB8.  */
+           res1 = (valn & 0xFF) - (valm & 0xFF);
+           if (res1 & 0x800000)
+             state->Cpsr |= GE0;
+           else
+             state->Cpsr &= ~ GE0;
+
+           res2 = ((valn >> 8) & 0XFF) - ((valm >> 8) & 0xFF);
+           if (res2 & 0x800000)
+             state->Cpsr |= GE1;
+           else
+             state->Cpsr &= ~ GE1;
+
+           res3 = ((valn >> 16) & 0XFF) - ((valm >> 16) & 0xFF);
+           if (res3 & 0x800000)
+             state->Cpsr |= GE2;
+           else
+             state->Cpsr &= ~ GE2;
+
+           res4 = (valn >> 24) - (valm >> 24) ;
+           if (res4 & 0x800000)
+             state->Cpsr |= GE3;
+           else
+             state->Cpsr &= ~ GE3;
+
+           state->Reg[Rd] = (res1 & 0xFF) | ((res2 << 8) & 0xFF00)
+             | ((res3 << 16) & 0xFF0000) | (res4 << 24);
+           return 1;
+
+         default:
+           break;
+         }
+       break;
+      }
+
+    case 0x68:
+      {
+       ARMword res;
+
+       /* PKHBT<c> <Rd>,<Rn>,<Rm>{,LSL #<imm>}
+          PKHTB<c> <Rd>,<Rn>,<Rm>{,ASR #<imm>}
+          SXTAB16<c> <Rd>,<Rn>,<Rm>{,<rotation>}
+          SXTB16<c> <Rd>,<Rm>{,<rotation>}
+          SEL<c> <Rd>,<Rn>,<Rm>
+
+          instr[31,28] = cond
+          instr[27,20] = 0110 1000
+          instr[19,16] = Rn
+          instr[15,12] = Rd
+          instr[11, 7] = imm5 (PKH), 11111 (SEL), rr000 (SXTAB16 & SXTB16),
+          instr[6]     = tb (PKH), 0 (SEL), 1 (SXT)
+          instr[5]     = opcode: PKH (0), SEL/SXT (1)
+          instr[4]     = 1
+          instr[ 3, 0] = Rm.  */
+
+       if (BIT (4) != 1)
+         break;
+
+       if (BIT (5) == 0)
+         {
+           /* FIXME: Add implementation of PKH.  */
+           fprintf (stderr, "PKH: NOT YET IMPLEMENTED\n");
+           ARMul_UndefInstr (state, instr);
+           break;
+         }
+
+       if (BIT (6) == 1)
+         {
+           /* FIXME: Add implementation of SXT.  */
+           fprintf (stderr, "SXT: NOT YET IMPLEMENTED\n");
+           ARMul_UndefInstr (state, instr);
+           break;
+         }
+
+       Rn = BITS (16, 19);
+       Rd = BITS (12, 15);
+       Rm = BITS (0, 3);
+       if (Rn == 15 || Rm == 15 || Rd == 15)
+         {
+           ARMul_UndefInstr (state, instr);
+           state->Emulate = FALSE;
+           break;
+         }
+
+       res  = (state->Reg[(state->Cpsr & GE0) ? Rn : Rm]) & 0xFF;
+       res |= (state->Reg[(state->Cpsr & GE1) ? Rn : Rm]) & 0xFF00;
+       res |= (state->Reg[(state->Cpsr & GE2) ? Rn : Rm]) & 0xFF0000;
+       res |= (state->Reg[(state->Cpsr & GE3) ? Rn : Rm]) & 0xFF000000;
+       state->Reg[Rd] = res;
+       return 1;
+      }
+
+    case 0x6a:
+      {
+       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:
+      {
+       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 0xf3:
+           {
+             /* REV<c> <Rd>,<Rm>
+                instr[31,28] = cond
+                instr[27,20] = 0110 1011
+                instr[19,16] = 1111
+                instr[15,12] = Rd
+                instr[11, 4] = 1111 0011
+                instr[ 3, 0] = Rm.  */
+             if (BITS (16, 19) != 0xF)
+               break;
+
+             Rd = BITS (12, 15);
+             Rm = BITS (0, 3);
+             if (Rd == 15 || Rm == 15)
+               {
+                 ARMul_UndefInstr (state, instr);
+                 state->Emulate = FALSE;
+                 break;
+               }
+
+             val = state->Reg[Rm] << 24;
+             val |= ((state->Reg[Rm] << 8) & 0xFF0000);
+             val |= ((state->Reg[Rm] >> 8) & 0xFF00);
+             val |= ((state->Reg[Rm] >> 24));
+             state->Reg[Rd] = val;
+             return 1;
+           }
+
+         case 0xfb:
+           {
+             /* REV16<c> <Rd>,<Rm>.  */
+             if (BITS (16, 19) != 0xF)
+               break;
+
+             Rd = BITS (12, 15);
+             Rm = BITS (0, 3);
+             if (Rd == 15 || Rm == 15)
+               {
+                 ARMul_UndefInstr (state, instr);
+                 state->Emulate = FALSE;
+                 break;
+               }
+
+             val = 0;
+             val |= ((state->Reg[Rm] >> 8) & 0x00FF00FF);
+             val |= ((state->Reg[Rm] << 8) & 0xFF00FF00);
+             state->Reg[Rd] = val;
+             return 1;
+           }
+
+         default:
+           break;
+         }
+       
+       if (ror == -1)
+         break;
+
+       Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF);
+       if (Rm & 0x8000)
+         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:
+      {
+       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:
+      {
+       int i;
+       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 0xf3: /* RBIT */
+           if (BITS (16, 19) != 0xF)
+             break;
+           Rd = BITS (12, 15);
+           state->Reg[Rd] = 0;
+           Rm = state->Reg[BITS (0, 3)];
+           for (i = 0; i < 32; i++)
+             if (Rm & (1 << i))
+               state->Reg[Rd] |= (1 << (31 - i));
+           return 1;
+
+         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;
+
+    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:
+      {
+       int lsb;
+       int msb;
+       ARMword mask;
+
+       /* BFC<c> <Rd>,#<lsb>,#<width>
+          BFI<c> <Rd>,<Rn>,#<lsb>,#<width>
+
+          instr[31,28] = cond
+          instr[27,21] = 0111 110
+          instr[20,16] = msb
+          instr[15,12] = Rd
+          instr[11, 7] = lsb
+          instr[ 6, 4] = 001 1111
+          instr[ 3, 0] = Rn (BFI) / 1111 (BFC).  */
+
+       if (BITS (4, 6) != 0x1)
+         break;
+
+       Rd = BITS (12, 15);
+       if (Rd == 15)
+         {
+           ARMul_UndefInstr (state, instr);
+           state->Emulate = FALSE;
+         }
+
+       lsb = BITS (7, 11);
+       msb = BITS (16, 20);
+       if (lsb > msb)
+         {
+           ARMul_UndefInstr (state, instr);
+           state->Emulate = FALSE;
+         }
+
+       mask = -(1 << lsb);
+       mask &= ~(-(1 << (msb + 1)));
+       state->Reg[Rd] &= ~ mask;
+
+       Rn = BITS (0, 3);
+       if (Rn != 0xF)
+         {
+           ARMword val = state->Reg[Rn] & ~(-(1 << ((msb + 1) - lsb)));
+           state->Reg[Rd] |= val << lsb;
+         }
+       return 1;
+      }
+    case 0x7b:
+    case 0x7a: /* SBFX<c> <Rd>,<Rn>,#<lsb>,#<width>.  */
+      {
+       int lsb;
+       int widthm1;
+       ARMsword sval;
+
+       if (BITS (4, 6) != 0x5)
+         break;
+
+       Rd = BITS (12, 15);
+       if (Rd == 15)
+         {
+           ARMul_UndefInstr (state, instr);
+           state->Emulate = FALSE;
+         }
+
+       Rn = BITS (0, 3);
+       if (Rn == 15)
+         {
+           ARMul_UndefInstr (state, instr);
+           state->Emulate = FALSE;
+         }
+
+       lsb = BITS (7, 11);
+       widthm1 = BITS (16, 20);
+
+       sval = state->Reg[Rn];
+       sval <<= (31 - (lsb + widthm1));
+       sval >>= (31 - widthm1);
+       state->Reg[Rd] = sval;
+       
+       return 1;
+      }
 
-/* The PC pipeline value depends on whether ARM
-   or Thumb instructions are being executed.  */
-ARMword isize;
+    case 0x7f:
+    case 0x7e:
+      {
+       int lsb;
+       int widthm1;
+
+       /* UBFX<c> <Rd>,<Rn>,#<lsb>,#<width>
+          instr[31,28] = cond
+          instr[27,21] = 0111 111
+          instr[20,16] = widthm1
+          instr[15,12] = Rd
+          instr[11, 7] = lsb
+          instr[ 6, 4] = 101
+          instr[ 3, 0] = Rn.  */
+
+       if (BITS (4, 6) != 0x5)
+         break;
+
+       Rd = BITS (12, 15);
+       if (Rd == 15)
+         {
+           ARMul_UndefInstr (state, instr);
+           state->Emulate = FALSE;
+         }
+
+       Rn = BITS (0, 3);
+       if (Rn == 15)
+         {
+           ARMul_UndefInstr (state, instr);
+           state->Emulate = FALSE;
+         }
+
+       lsb = BITS (7, 11);
+       widthm1 = BITS (16, 20);
+
+       val = state->Reg[Rn];
+       val >>= lsb;
+       val &= ~(-(1 << (widthm1 + 1)));
+
+       state->Reg[Rd] = val;
+       
+       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;
+}
+#endif
+
+static void
+handle_VFP_move (ARMul_State * state, ARMword instr)
+{
+  switch (BITS (20, 27))
+    {
+    case 0xC4:
+    case 0xC5:
+      switch (BITS (4, 11))
+       {
+       case 0xA1:
+       case 0xA3:
+         {
+           /* VMOV two core <-> two VFP single precision.  */
+           int sreg = (BITS (0, 3) << 1) | BIT (5);
+
+           if (BIT (20))
+             {
+               state->Reg[BITS (12, 15)] = VFP_uword (sreg);
+               state->Reg[BITS (16, 19)] = VFP_uword (sreg + 1);
+             }
+           else
+             {
+               VFP_uword (sreg)     = state->Reg[BITS (12, 15)];
+               VFP_uword (sreg + 1) = state->Reg[BITS (16, 19)];
+             }
+         }
+         break;
+
+       case 0xB1:
+       case 0xB3:
+         {
+           /* VMOV two core <-> VFP double precision.  */
+           int dreg = BITS (0, 3) | (BIT (5) << 4);
+
+           if (BIT (20))
+             {
+               if (trace)
+                 fprintf (stderr, " VFP: VMOV: r%d r%d <= d%d\n",
+                          BITS (12, 15), BITS (16, 19), dreg);
+
+               state->Reg[BITS (12, 15)] = VFP_dword (dreg);
+               state->Reg[BITS (16, 19)] = VFP_dword (dreg) >> 32;
+             }
+           else
+             {
+               VFP_dword (dreg) = state->Reg[BITS (16, 19)];
+               VFP_dword (dreg) <<= 32;
+               VFP_dword (dreg) |= state->Reg[BITS (12, 15)];
+
+               if (trace)
+                 fprintf (stderr, " VFP: VMOV: d%d <= r%d r%d : %g\n",
+                          dreg, BITS (16, 19), BITS (12, 15),
+                          VFP_dval (dreg));
+             }
+         }
+         break;
+
+       default:
+         fprintf (stderr, "SIM: VFP: Unimplemented move insn %x\n", BITS (20, 27));
+         break;
+       }
+      break;
+
+    case 0xe0:
+    case 0xe1:
+      /* VMOV single core <-> VFP single precision.  */
+      if (BITS (0, 6) != 0x10 || BITS (8, 11) != 0xA)
+       fprintf (stderr, "SIM: VFP: Unimplemented move insn %x\n", BITS (20, 27));
+      else
+       {
+         int sreg = (BITS (16, 19) << 1) | BIT (7);
+
+         if (BIT (20))
+           state->Reg[DESTReg] = VFP_uword (sreg);
+         else
+           VFP_uword (sreg) = state->Reg[DESTReg];
+       }
+      break;
+
+    default:
+      fprintf (stderr, "SIM: VFP: Unimplemented move insn %x\n", BITS (20, 27));
+      return;
+    }
+}
+
+/* EMULATION of ARM6.  */
 
 ARMword
 #ifdef MODE32
@@ -374,11 +1301,31 @@ ARMul_Emulate26 (ARMul_State * state)
 
       if (state->EventSet)
        ARMul_EnvokeEvent (state);
-#if 0
-      /* Enable this for a helpful bit of debugging when tracing is needed.  */
-      fprintf (stderr, "pc: %x, instr: %x\n", pc & ~1, instr);
-      if (instr == 0)
-       abort ();
+
+      if (! TFLAG && trace)
+       {
+         fprintf (stderr, "pc: %x, ", pc & ~1);
+         if (! disas)
+           fprintf (stderr, "instr: %x\n", instr);
+       }
+
+      if (instr == 0 || pc < 0x10)
+       {
+         ARMul_Abort (state, ARMUndefinedInstrV);
+         state->Emulate = FALSE;
+       }
+
+#if 0 /* Enable this code to help track down stack alignment bugs.  */
+      {
+       static ARMword old_sp = -1;
+
+       if (old_sp != state->Reg[13])
+         {
+           old_sp = state->Reg[13];
+           fprintf (stderr, "pc: %08x: SP set to %08x%s\n",
+                    pc & ~1, old_sp, (old_sp % 8) ? " [UNALIGNED!]" : "");
+         }
+      }
 #endif
 
       if (state->Exception)
@@ -403,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;
@@ -411,8 +1357,8 @@ ARMul_Emulate26 (ARMul_State * state)
            }
          if (state->Debug)
            {
-             fprintf (stderr, "sim: At %08lx Instr %08lx Mode %02lx\n", pc, instr,
-                      state->Mode);
+             fprintf (stderr, "sim: At %08lx Instr %08lx Mode %02lx\n",
+                      (long) pc, (long) instr, (long) state->Mode);
              (void) fgetc (stdin);
            }
        }
@@ -450,6 +1396,14 @@ ARMul_Emulate26 (ARMul_State * state)
 
            case t_decoded:
              /* ARM instruction available.  */
+             if (disas || trace)
+               {
+                 fprintf (stderr, "  emulate as: ");
+                 if (trace)
+                   fprintf (stderr, "%08x ", new);
+                 if (! disas)
+                   fprintf (stderr, "\n");
+               }
              instr = new;
              /* So continue instruction decoding.  */
              break;
@@ -458,6 +1412,8 @@ ARMul_Emulate26 (ARMul_State * state)
            }
        }
 #endif
+      if (disas)
+       print_insn (instr);
 
       /* Check the condition codes.  */
       if ((temp = TOPBITS (28)) == AL)
@@ -476,21 +1432,26 @@ ARMul_Emulate26 (ARMul_State * state)
              if (BITS (25, 27) == 5) /* BLX(1) */
                {
                  ARMword dest;
-                 
+
                  state->Reg[14] = pc + 4;
-                 
-                 dest = pc + 8 + 1; /* Force entry into Thumb mode.  */
+
+                 /* Force entry into Thumb mode.  */
+                 dest = pc + 8 + 1;
                  if (BIT (23))
                    dest += (NEGBRANCH + (BIT (24) << 1));
                  else
                    dest += POSBRANCH + (BIT (24) << 1);
-                 
+
                  WriteR15Branch (state, dest);
                  goto donext;
                }
              else if ((instr & 0xFC70F000) == 0xF450F000)
                /* The PLD instruction.  Ignored.  */
                goto donext;
+             else if (   ((instr & 0xfe500f00) == 0xfc100100)
+                      || ((instr & 0xfe500f00) == 0xfc000100))
+               /* wldrw and wstrw are unconditional.  */
+               goto mainswitch;
              else
                /* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2.  */
                ARMul_UndefInstr (state, instr);
@@ -544,42 +1505,50 @@ ARMul_Emulate26 (ARMul_State * state)
       /* Handle the Clock counter here.  */
       if (state->is_XScale)
        {
-         ARMword cp14r0 = state->CPRead[14] (state, 0, 0);
+         ARMword cp14r0;
+         int ok;
 
-         if (cp14r0 && ARMul_CP14_R0_ENABLE)
+         ok = state->CPRead[14] (state, 0, & cp14r0);
+
+         if (ok && (cp14r0 & ARMul_CP14_R0_ENABLE))
            {
-             unsigned long newcycles, nowtime = ARMul_Time(state);
+             unsigned long newcycles, nowtime = ARMul_Time (state);
 
              newcycles = nowtime - state->LastTime;
              state->LastTime = nowtime;
-             if (cp14r0 && ARMul_CP14_R0_CCD)
+
+             if (cp14r0 & ARMul_CP14_R0_CCD)
                {
                  if (state->CP14R0_CCD == -1)
                    state->CP14R0_CCD = newcycles;
                  else
                    state->CP14R0_CCD += newcycles;
+
                  if (state->CP14R0_CCD >= 64)
                    {
                      newcycles = 0;
+
                      while (state->CP14R0_CCD >= 64)
                        state->CP14R0_CCD -= 64, newcycles++;
+
                      goto check_PMUintr;
                    }
                }
              else
                {
                  ARMword cp14r1;
-                 int do_int = 0;
+                 int do_int;
 
                  state->CP14R0_CCD = -1;
 check_PMUintr:
+                 do_int = 0;
                  cp14r0 |= ARMul_CP14_R0_FLAG2;
                  (void) state->CPWrite[14] (state, 0, cp14r0);
 
-                 cp14r1 = state->CPRead[14] (state, 1, 0);
+                 ok = state->CPRead[14] (state, 1, & cp14r1);
 
                  /* Coded like this for portability.  */
-                 while (newcycles)
+                 while (ok && newcycles)
                    {
                      if (cp14r1 == 0xffffffff)
                        {
@@ -587,14 +1556,19 @@ check_PMUintr:
                          do_int = 1;
                        }
                      else
-                       cp14r1++;
-                       newcycles--;
+                       cp14r1 ++;
+
+                     newcycles --;
                    }
+
                  (void) state->CPWrite[14] (state, 1, cp14r1);
+
                  if (do_int && (cp14r0 & ARMul_CP14_R0_INTEN2))
                    {
-                     if (state->CPRead[13] (state, 8, 0)
-                       && ARMul_CP13_R8_PMUS)
+                     ARMword temp;
+
+                     if (state->CPRead[13] (state, 8, & temp)
+                         && (temp & ARMul_CP13_R8_PMUS))
                        ARMul_Abort (state, ARMul_FIQV);
                      else
                        ARMul_Abort (state, ARMul_IRQV);
@@ -606,8 +1580,8 @@ check_PMUintr:
       /* Handle hardware instructions breakpoints here.  */
       if (state->is_XScale)
        {
-         if ((pc | 3) == (read_cp15_reg (14, 0, 8) | 2)
-           || (pc | 3) == (read_cp15_reg (14, 0, 9) | 2))
+         if (   (pc | 3) == (read_cp15_reg (14, 0, 8) | 2)
+             || (pc | 3) == (read_cp15_reg (14, 0, 9) | 2))
            {
              if (XScale_debug_moe (state, ARMul_CP14_R10_MOE_IB))
                ARMul_OSHandleSWI (state, SWI_Breakpoint);
@@ -615,10 +1589,9 @@ check_PMUintr:
        }
 
       /* Actual execution of instructions begins here.  */
-
+      /* If the condition codes don't match, stop here.  */
       if (temp)
        {
-         /* If the condition codes don't match, stop here.  */
        mainswitch:
 
          if (state->is_XScale)
@@ -631,7 +1604,7 @@ check_PMUintr:
                      ARMword temp = GetLS7RHS (state, instr);
                      ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
                      ARMword addr = BIT (24) ? temp2 : LHS;
-                     
+
                      if (BIT (12))
                        ARMul_UndefInstr (state, instr);
                      else if (addr & 7)
@@ -640,7 +1613,7 @@ check_PMUintr:
                      else
                        {
                          int wb = BIT (21) || (! BIT (24));
-                         
+
                          state->Reg[BITS (12, 15)] =
                            ARMul_LoadWordN (state, addr);
                          state->Reg[BITS (12, 15) + 1] =
@@ -677,6 +1650,9 @@ check_PMUintr:
                      goto donext;
                    }
                }
+
+             if (ARMul_HandleIwmmxt (state, instr))
+               goto donext;
            }
 
          switch ((int) BITS (20, 27))
@@ -703,7 +1679,8 @@ check_PMUintr:
                }
 #endif
              if (BITS (4, 7) == 9)
-               {               /* MUL */
+               {
+                 /* MUL */
                  rhs = state->Reg[MULRHSReg];
                  if (MULLHSReg == MULDESTReg)
                    {
@@ -713,16 +1690,18 @@ check_PMUintr:
                  else if (MULDESTReg != 15)
                    state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs;
                  else
-                   {
-                     UNDEF_MULPCDest;
-                   }
-                 for (dest = 0, temp = 0; dest < 32; dest++)
+                   UNDEF_MULPCDest;
+
+                 for (dest = 0, temp = 0; dest < 32; dest ++)
                    if (rhs & (1L << dest))
-                     temp = dest;      /* mult takes this many/2 I cycles */
+                     temp = dest;
+
+                 /* Mult takes this many/2 I cycles.  */
                  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
                }
              else
-               {               /* AND reg */
+               {
+                 /* AND reg.  */
                  rhs = DPRegRHS;
                  dest = LHS & rhs;
                  WRITEDEST (dest);
@@ -732,15 +1711,15 @@ check_PMUintr:
            case 0x01:          /* ANDS reg and MULS */
 #ifdef MODET
              if ((BITS (4, 11) & 0xF9) == 0x9)
-               {
-                 /* LDR register offset, no write-back, down, post indexed */
-                 LHPOSTDOWN ();
-                 /* fall through to rest of decoding */
-               }
+               /* LDR register offset, no write-back, down, post indexed.  */
+               LHPOSTDOWN ();
+             /* Fall through to rest of decoding.  */
 #endif
              if (BITS (4, 7) == 9)
-               {               /* MULS */
+               {
+                 /* MULS */
                  rhs = state->Reg[MULRHSReg];
+
                  if (MULLHSReg == MULDESTReg)
                    {
                      UNDEF_MULDestEQOp1;
@@ -755,16 +1734,18 @@ check_PMUintr:
                      state->Reg[MULDESTReg] = dest;
                    }
                  else
-                   {
-                     UNDEF_MULPCDest;
-                   }
-                 for (dest = 0, temp = 0; dest < 32; dest++)
+                   UNDEF_MULPCDest;
+
+                 for (dest = 0, temp = 0; dest < 32; dest ++)
                    if (rhs & (1L << dest))
-                     temp = dest;      /* mult takes this many/2 I cycles */
+                     temp = dest;
+
+                 /* Mult takes this many/2 I cycles.  */
                  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
                }
              else
-               {               /* ANDS reg */
+               {
+                 /* ANDS reg.  */
                  rhs = DPSRegRHS;
                  dest = LHS & rhs;
                  WRITESDEST (dest);
@@ -775,7 +1756,7 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 11) == 0xB)
                {
-                 /* STRH register offset, write-back, down, post indexed */
+                 /* STRH register offset, write-back, down, post indexed */
                  SHDOWNWB ();
                  break;
                }
@@ -792,12 +1773,13 @@ check_PMUintr:
                    state->Reg[MULDESTReg] =
                      state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
                  else
-                   {
-                     UNDEF_MULPCDest;
-                   }
-                 for (dest = 0, temp = 0; dest < 32; dest++)
+                   UNDEF_MULPCDest;
+
+                 for (dest = 0, temp = 0; dest < 32; dest ++)
                    if (rhs & (1L << dest))
-                     temp = dest;      /* mult takes this many/2 I cycles */
+                     temp = dest;
+
+                 /* Mult takes this many/2 I cycles.  */
                  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
                }
              else
@@ -811,15 +1793,15 @@ check_PMUintr:
            case 0x03:          /* EORS reg and MLAS */
 #ifdef MODET
              if ((BITS (4, 11) & 0xF9) == 0x9)
-               {
-                 /* LDR register offset, write-back, down, post-indexed */
-                 LHPOSTDOWN ();
-                 /* fall through to rest of the decoding */
-               }
+               /* LDR register offset, write-back, down, post-indexed.  */
+               LHPOSTDOWN ();
+             /* Fall through to rest of the decoding.  */
 #endif
              if (BITS (4, 7) == 9)
-               {               /* MLAS */
+               {
+                 /* MLAS */
                  rhs = state->Reg[MULRHSReg];
+
                  if (MULLHSReg == MULDESTReg)
                    {
                      UNDEF_MULDestEQOp1;
@@ -835,16 +1817,18 @@ check_PMUintr:
                      state->Reg[MULDESTReg] = dest;
                    }
                  else
-                   {
-                     UNDEF_MULPCDest;
-                   }
-                 for (dest = 0, temp = 0; dest < 32; dest++)
+                   UNDEF_MULPCDest;
+
+                 for (dest = 0, temp = 0; dest < 32; dest ++)
                    if (rhs & (1L << dest))
-                     temp = dest;      /* mult takes this many/2 I cycles */
+                     temp = dest;
+
+                 /* Mult takes this many/2 I cycles.  */
                  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
                }
              else
-               {               /* EORS Reg */
+               {
+                 /* EORS Reg.  */
                  rhs = DPSRegRHS;
                  dest = LHS ^ rhs;
                  WRITESDEST (dest);
@@ -855,7 +1839,7 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 7) == 0xB)
                {
-                 /* STRH immediate offset, no write-back, down, post indexed */
+                 /* STRH immediate offset, no write-back, down, post indexed */
                  SHDOWNWB ();
                  break;
                }
@@ -878,15 +1862,14 @@ check_PMUintr:
            case 0x05:          /* SUBS reg */
 #ifdef MODET
              if ((BITS (4, 7) & 0x9) == 0x9)
-               {
-                 /* LDR immediate offset, no write-back, down, post indexed */
-                 LHPOSTDOWN ();
-                 /* fall through to the rest of the instruction decoding */
-               }
+               /* LDR immediate offset, no write-back, down, post indexed.  */
+               LHPOSTDOWN ();
+             /* Fall through to the rest of the instruction decoding.  */
 #endif
              lhs = LHS;
              rhs = DPRegRHS;
              dest = lhs - rhs;
+
              if ((lhs >= rhs) || ((rhs | lhs) >> 31))
                {
                  ARMul_SubCarry (state, lhs, rhs, dest);
@@ -904,7 +1887,7 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 7) == 0xB)
                {
-                 /* STRH immediate offset, write-back, down, post indexed */
+                 /* STRH immediate offset, write-back, down, post indexed */
                  SHDOWNWB ();
                  break;
                }
@@ -917,15 +1900,14 @@ check_PMUintr:
            case 0x07:          /* RSBS reg */
 #ifdef MODET
              if ((BITS (4, 7) & 0x9) == 0x9)
-               {
-                 /* LDR immediate offset, write-back, down, post indexed */
-                 LHPOSTDOWN ();
-                 /* fall through to remainder of instruction decoding */
-               }
+               /* LDR immediate offset, write-back, down, post indexed.  */
+               LHPOSTDOWN ();
+             /* Fall through to remainder of instruction decoding.  */
 #endif
              lhs = LHS;
              rhs = DPRegRHS;
              dest = rhs - lhs;
+
              if ((rhs >= lhs) || ((rhs | lhs) >> 31))
                {
                  ARMul_SubCarry (state, rhs, lhs, dest);
@@ -943,7 +1925,7 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 11) == 0xB)
                {
-                 /* STRH register offset, no write-back, up, post indexed */
+                 /* STRH register offset, no write-back, up, post indexed */
                  SHUPWB ();
                  break;
                }
@@ -960,7 +1942,8 @@ check_PMUintr:
 #endif
 #ifdef MODET
              if (BITS (4, 7) == 0x9)
-               {               /* MULL */
+               {
+                 /* MULL */
                  /* 32x32 = 64 */
                  ARMul_Icycles (state,
                                 Multiply64 (state, instr, LUNSIGNED,
@@ -976,15 +1959,14 @@ check_PMUintr:
            case 0x09:          /* ADDS reg */
 #ifdef MODET
              if ((BITS (4, 11) & 0xF9) == 0x9)
-               {
-                 /* LDR register offset, no write-back, up, post indexed */
-                 LHPOSTUP ();
-                 /* fall through to remaining instruction decoding */
-               }
+               /* LDR register offset, no write-back, up, post indexed.  */
+               LHPOSTUP ();
+             /* Fall through to remaining instruction decoding.  */
 #endif
 #ifdef MODET
              if (BITS (4, 7) == 0x9)
-               {               /* MULL */
+               {
+                 /* MULL */
                  /* 32x32=64 */
                  ARMul_Icycles (state,
                                 Multiply64 (state, instr, LUNSIGNED, LSCC),
@@ -997,7 +1979,8 @@ check_PMUintr:
              dest = lhs + rhs;
              ASSIGNZ (dest == 0);
              if ((lhs | rhs) >> 30)
-               {               /* possible C,V,N to set */
+               {
+                 /* Possible C,V,N to set.  */
                  ASSIGNN (NEG (dest));
                  ARMul_AddCarry (state, lhs, rhs, dest);
                  ARMul_AddOverflow (state, lhs, rhs, dest);
@@ -1015,14 +1998,13 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 11) == 0xB)
                {
-                 /* STRH register offset, write-back, up, post-indexed */
+                 /* STRH register offset, write-back, up, post-indexed */
                  SHUPWB ();
                  break;
                }
-#endif
-#ifdef MODET
              if (BITS (4, 7) == 0x9)
-               {               /* MULL */
+               {
+                 /* MULL */
                  /* 32x32=64 */
                  ARMul_Icycles (state,
                                 MultiplyAdd64 (state, instr, LUNSIGNED,
@@ -1038,15 +2020,12 @@ check_PMUintr:
            case 0x0b:          /* ADCS reg */
 #ifdef MODET
              if ((BITS (4, 11) & 0xF9) == 0x9)
-               {
-                 /* LDR register offset, write-back, up, post indexed */
-                 LHPOSTUP ();
-                 /* fall through to remaining instruction decoding */
-               }
-#endif
-#ifdef MODET
+               /* LDR register offset, write-back, up, post indexed.  */
+               LHPOSTUP ();
+             /* Fall through to remaining instruction decoding.  */
              if (BITS (4, 7) == 0x9)
-               {               /* MULL */
+               {
+                 /* MULL */
                  /* 32x32=64 */
                  ARMul_Icycles (state,
                                 MultiplyAdd64 (state, instr, LUNSIGNED,
@@ -1059,7 +2038,8 @@ check_PMUintr:
              dest = lhs + rhs + CFLAG;
              ASSIGNZ (dest == 0);
              if ((lhs | rhs) >> 30)
-               {               /* possible C,V,N to set */
+               {
+                 /* Possible C,V,N to set.  */
                  ASSIGNN (NEG (dest));
                  ARMul_AddCarry (state, lhs, rhs, dest);
                  ARMul_AddOverflow (state, lhs, rhs, dest);
@@ -1077,7 +2057,7 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 7) == 0xB)
                {
-                 /* STRH immediate offset, no write-back, up post indexed */
+                 /* STRH immediate offset, no write-back, up post indexed */
                  SHUPWB ();
                  break;
                }
@@ -1091,10 +2071,9 @@ check_PMUintr:
                  Handle_Store_Double (state, instr);
                  break;
                }
-#endif
-#ifdef MODET
              if (BITS (4, 7) == 0x9)
-               {               /* MULL */
+               {
+                 /* MULL */
                  /* 32x32=64 */
                  ARMul_Icycles (state,
                                 Multiply64 (state, instr, LSIGNED, LDEFAULT),
@@ -1110,14 +2089,12 @@ check_PMUintr:
            case 0x0d:          /* SBCS reg */
 #ifdef MODET
              if ((BITS (4, 7) & 0x9) == 0x9)
-               {
-                 /* LDR immediate offset, no write-back, up, post indexed */
-                 LHPOSTUP ();
-               }
-#endif
-#ifdef MODET
+               /* LDR immediate offset, no write-back, up, post indexed.  */
+               LHPOSTUP ();
+
              if (BITS (4, 7) == 0x9)
-               {               /* MULL */
+               {
+                 /* MULL */
                  /* 32x32=64 */
                  ARMul_Icycles (state,
                                 Multiply64 (state, instr, LSIGNED, LSCC),
@@ -1145,14 +2122,14 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 7) == 0xB)
                {
-                 /* STRH immediate offset, write-back, up, post indexed */
+                 /* STRH immediate offset, write-back, up, post indexed */
                  SHUPWB ();
                  break;
                }
-#endif
-#ifdef MODET
+
              if (BITS (4, 7) == 0x9)
-               {               /* MULL */
+               {
+                 /* MULL */
                  /* 32x32=64 */
                  ARMul_Icycles (state,
                                 MultiplyAdd64 (state, instr, LSIGNED,
@@ -1168,15 +2145,13 @@ check_PMUintr:
            case 0x0f:          /* RSCS reg */
 #ifdef MODET
              if ((BITS (4, 7) & 0x9) == 0x9)
-               {
-                 /* LDR immediate offset, write-back, up, post indexed */
-                 LHPOSTUP ();
-                 /* fall through to remaining instruction decoding */
-               }
-#endif
-#ifdef MODET
+               /* LDR immediate offset, write-back, up, post indexed.  */
+               LHPOSTUP ();
+             /* Fall through to remaining instruction decoding.  */
+
              if (BITS (4, 7) == 0x9)
-               {               /* MULL */
+               {
+                 /* MULL */
                  /* 32x32=64 */
                  ARMul_Icycles (state,
                                 MultiplyAdd64 (state, instr, LSIGNED, LSCC),
@@ -1187,6 +2162,7 @@ check_PMUintr:
              lhs = LHS;
              rhs = DPRegRHS;
              dest = rhs - lhs - !CFLAG;
+
              if ((rhs >= lhs) || ((rhs | lhs) >> 31))
                {
                  ARMul_SubCarry (state, rhs, lhs, dest);
@@ -1200,7 +2176,7 @@ check_PMUintr:
              WRITESDEST (dest);
              break;
 
-           case 0x10:          /* TST reg and MRS CPSR and SWP word */
+           case 0x10:          /* TST reg and MRS CPSR and SWP word */
              if (state->is_v5e)
                {
                  if (BIT (4) == 0 && BIT (7) == 1)
@@ -1209,7 +2185,7 @@ check_PMUintr:
                      ARMword op1 = state->Reg[BITS (0, 3)];
                      ARMword op2 = state->Reg[BITS (8, 11)];
                      ARMword Rn = state->Reg[BITS (12, 15)];
-                     
+
                      if (BIT (5))
                        op1 >>= 16;
                      if (BIT (6))
@@ -1221,7 +2197,7 @@ check_PMUintr:
                      if (op2 & 0x8000)
                        op2 -= 65536;
                      op1 *= op2;
-                     
+
                      if (AddOverflow (op1, Rn, op1 + Rn))
                        SETS;
                      state->Reg[BITS (16, 19)] = op1 + Rn;
@@ -1246,7 +2222,7 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 11) == 0xB)
                {
-                 /* STRH register offset, no write-back, down, pre indexed */
+                 /* STRH register offset, no write-back, down, pre indexed */
                  SHPREDOWN ();
                  break;
                }
@@ -1262,7 +2238,8 @@ check_PMUintr:
                }
 #endif
              if (BITS (4, 11) == 9)
-               {               /* SWP */
+               {
+                 /* SWP */
                  UNDEF_SWPPC;
                  temp = LHS;
                  BUSUSEDINCPCS;
@@ -1281,9 +2258,7 @@ check_PMUintr:
                  else
                    DEST = dest;
                  if (state->abortSig || state->Aborted)
-                   {
-                     TAKEABORT;
-                   }
+                   TAKEABORT;
                }
              else if ((BITS (0, 11) == 0) && (LHSReg == 15))
                {               /* MRS CPSR */
@@ -1292,6 +2267,11 @@ check_PMUintr:
                }
              else
                {
+#ifdef MODE32
+                 if (state->is_v6
+                     && handle_v6_insn (state, instr))
+                   break;
+#endif
                  UNDEF_Test;
                }
              break;
@@ -1299,14 +2279,13 @@ check_PMUintr:
            case 0x11:          /* TSTP reg */
 #ifdef MODET
              if ((BITS (4, 11) & 0xF9) == 0x9)
-               {
-                 /* LDR register offset, no write-back, down, pre indexed */
-                 LHPREDOWN ();
-                 /* continue with remaining instruction decode */
-               }
+               /* LDR register offset, no write-back, down, pre indexed.  */
+               LHPREDOWN ();
+             /* Continue with remaining instruction decode.  */
 #endif
              if (DESTReg == 15)
-               {               /* TSTP reg */
+               {
+                 /* TSTP reg */
 #ifdef MODE32
                  state->Cpsr = GETSPSR (state->Bank);
                  ARMul_CPSRAltered (state);
@@ -1317,14 +2296,15 @@ check_PMUintr:
 #endif
                }
              else
-               {               /* TST reg */
+               {
+                 /* TST reg */
                  rhs = DPSRegRHS;
                  dest = LHS & rhs;
                  ARMul_NegZero (state, dest);
                }
              break;
 
-           case 0x12:          /* TEQ reg and MSR reg to CPSR (ARM6) */
+           case 0x12:          /* TEQ reg and MSR reg to CPSR (ARM6) */
              if (state->is_v5)
                {
                  if (BITS (4, 7) == 3)
@@ -1349,9 +2329,9 @@ check_PMUintr:
                      && (BIT (5) == 0 || BITS (12, 15) == 0))
                    {
                      /* ElSegundo SMLAWy/SMULWy insn.  */
-                     unsigned long long op1 = state->Reg[BITS (0, 3)];
-                     unsigned long long op2 = state->Reg[BITS (8, 11)];
-                     unsigned long long result;
+                     ARMdword op1 = state->Reg[BITS (0, 3)];
+                     ARMdword op2 = state->Reg[BITS (8, 11)];
+                     ARMdword result;
 
                      if (BIT (6))
                        op2 >>= 16;
@@ -1365,7 +2345,7 @@ check_PMUintr:
                      if (BIT (5) == 0)
                        {
                          ARMword Rn = state->Reg[BITS (12, 15)];
-                         
+
                          if (AddOverflow (result, Rn, result + Rn))
                            SETS;
                          result += Rn;
@@ -1394,7 +2374,7 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 11) == 0xB)
                {
-                 /* STRH register offset, write-back, down, pre indexed */
+                 /* STRH register offset, write-back, down, pre indexed */
                  SHPREDOWNWB ();
                  break;
                }
@@ -1419,7 +2399,6 @@ check_PMUintr:
                {
                  if (BITS (4, 7) == 0x7)
                    {
-                     ARMword value;
                      extern int SWI_vector_installed;
 
                      /* Hardware is allowed to optionally override this
@@ -1436,8 +2415,8 @@ check_PMUintr:
                        ARMul_OSHandleSWI (state, SWI_Breakpoint);
                      else
                        {
-                       /* BKPT - normally this will cause an abort, but on the
-                          XScale we must check the DCSR.  */
+                         /* BKPT - normally this will cause an abort, but on the
+                            XScale we must check the DCSR.  */
                          XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc);
                          if (!XScale_debug_moe (state, ARMul_CP14_R10_MOE_BT))
                            break;
@@ -1450,7 +2429,7 @@ check_PMUintr:
                }
              if (DESTReg == 15)
                {
-                 /* MSR reg to CPSR */
+                 /* MSR reg to CPSR */
                  UNDEF_MSRPC;
                  temp = DPRegRHS;
 #ifdef MODET
@@ -1459,23 +2438,26 @@ check_PMUintr:
 #endif
                  ARMul_FixCPSR (state, instr, temp);
                }
+#ifdef MODE32
+             else if (state->is_v6
+                      && handle_v6_insn (state, instr))
+               break;
+#endif
              else
-               {
-                 UNDEF_Test;
-               }
+               UNDEF_Test;
+
              break;
 
            case 0x13:          /* TEQP reg */
 #ifdef MODET
              if ((BITS (4, 11) & 0xF9) == 0x9)
-               {
-                 /* LDR register offset, write-back, down, pre indexed.  */
-                 LHPREDOWNWB ();
-                 /* Continue with remaining instruction decode.  */
-               }
+               /* LDR register offset, write-back, down, pre indexed.  */
+               LHPREDOWNWB ();
+             /* Continue with remaining instruction decode.  */
 #endif
              if (DESTReg == 15)
-               {               /* TEQP reg */
+               {
+                 /* TEQP reg */
 #ifdef MODE32
                  state->Cpsr = GETSPSR (state->Bank);
                  ARMul_CPSRAltered (state);
@@ -1486,23 +2468,23 @@ check_PMUintr:
 #endif
                }
              else
-               {               /* TEQ Reg */
+               {
+                 /* TEQ Reg.  */
                  rhs = DPSRegRHS;
                  dest = LHS ^ rhs;
                  ARMul_NegZero (state, dest);
                }
              break;
 
-           case 0x14:          /* CMP reg and MRS SPSR and SWP byte */
+           case 0x14:          /* CMP reg and MRS SPSR and SWP byte */
              if (state->is_v5e)
                {
                  if (BIT (4) == 0 && BIT (7) == 1)
                    {
                      /* ElSegundo SMLALxy insn.  */
-                     unsigned long long op1 = state->Reg[BITS (0, 3)];
-                     unsigned long long op2 = state->Reg[BITS (8, 11)];
-                     unsigned long long dest;
-                     unsigned long long result;
+                     ARMdword op1 = state->Reg[BITS (0, 3)];
+                     ARMdword op2 = state->Reg[BITS (8, 11)];
+                     ARMdword dest;
 
                      if (BIT (5))
                        op1 >>= 16;
@@ -1515,7 +2497,7 @@ check_PMUintr:
                      if (op2 & 0x8000)
                        op2 -= 65536;
 
-                     dest = (unsigned long long) state->Reg[BITS (16, 19)] << 32;
+                     dest = (ARMdword) state->Reg[BITS (16, 19)] << 32;
                      dest |= state->Reg[BITS (12, 15)];
                      dest += op1 * op2;
                      state->Reg[BITS (12, 15)] = dest;
@@ -1567,7 +2549,8 @@ check_PMUintr:
                }
 #endif
              if (BITS (4, 11) == 9)
-               {               /* SWP */
+               {
+                 /* SWP */
                  UNDEF_SWPPC;
                  temp = LHS;
                  BUSUSEDINCPCS;
@@ -1582,32 +2565,34 @@ check_PMUintr:
 #endif
                    DEST = ARMul_SwapByte (state, temp, state->Reg[RHSReg]);
                  if (state->abortSig || state->Aborted)
-                   {
-                     TAKEABORT;
-                   }
+                   TAKEABORT;
                }
              else if ((BITS (0, 11) == 0) && (LHSReg == 15))
-               {               /* MRS SPSR */
+               {
+                 /* MRS SPSR */
                  UNDEF_MRSPC;
                  DEST = GETSPSR (state->Bank);
                }
+#ifdef MODE32
+             else if (state->is_v6
+                      && handle_v6_insn (state, instr))
+               break;
+#endif
              else
-               {
-                 UNDEF_Test;
-               }
+               UNDEF_Test;
+
              break;
 
-           case 0x15:          /* CMPP reg */
+           case 0x15:          /* CMPP reg */
 #ifdef MODET
              if ((BITS (4, 7) & 0x9) == 0x9)
-               {
-                 /* LDR immediate offset, no write-back, down, pre indexed */
-                 LHPREDOWN ();
-                 /* continue with remaining instruction decode */
-               }
+               /* LDR immediate offset, no write-back, down, pre indexed.  */
+               LHPREDOWN ();
+             /* Continue with remaining instruction decode.  */
 #endif
              if (DESTReg == 15)
-               {               /* CMPP reg */
+               {
+                 /* CMPP reg.  */
 #ifdef MODE32
                  state->Cpsr = GETSPSR (state->Bank);
                  ARMul_CPSRAltered (state);
@@ -1618,7 +2603,8 @@ check_PMUintr:
 #endif
                }
              else
-               {               /* CMP reg */
+               {
+                 /* CMP reg.  */
                  lhs = LHS;
                  rhs = DPRegRHS;
                  dest = lhs - rhs;
@@ -1644,7 +2630,6 @@ check_PMUintr:
                      /* ElSegundo SMULxy insn.  */
                      ARMword op1 = state->Reg[BITS (0, 3)];
                      ARMword op2 = state->Reg[BITS (8, 11)];
-                     ARMword Rn = state->Reg[BITS (12, 15)];
 
                      if (BIT (5))
                        op1 >>= 16;
@@ -1706,7 +2691,7 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 7) == 0xB)
                {
-                 /* STRH immediate offset, write-back, down, pre indexed */
+                 /* STRH immediate offset, write-back, down, pre indexed */
                  SHPREDOWNWB ();
                  break;
                }
@@ -1722,12 +2707,18 @@ check_PMUintr:
                }
 #endif
              if (DESTReg == 15)
-               {               /* MSR */
+               {
+                 /* MSR */
                  UNDEF_MSRPC;
                  ARMul_FixSPSR (state, instr, DPRegRHS);
                }
              else
                {
+#ifdef MODE32
+                 if (state->is_v6
+                     && handle_v6_insn (state, instr))
+                   break;
+#endif
                  UNDEF_Test;
                }
              break;
@@ -1735,11 +2726,9 @@ check_PMUintr:
            case 0x17:          /* CMNP reg */
 #ifdef MODET
              if ((BITS (4, 7) & 0x9) == 0x9)
-               {
-                 /* LDR immediate offset, write-back, down, pre indexed */
-                 LHPREDOWNWB ();
-                 /* continue with remaining instruction decoding */
-               }
+               /* LDR immediate offset, write-back, down, pre indexed.  */
+               LHPREDOWNWB ();
+             /* Continue with remaining instruction decoding.  */
 #endif
              if (DESTReg == 15)
                {
@@ -1754,13 +2743,15 @@ check_PMUintr:
                  break;
                }
              else
-               {               /* CMN reg */
+               {
+                 /* CMN reg.  */
                  lhs = LHS;
                  rhs = DPRegRHS;
                  dest = lhs + rhs;
                  ASSIGNZ (dest == 0);
                  if ((lhs | rhs) >> 30)
-                   {           /* possible C,V,N to set */
+                   {
+                     /* Possible C,V,N to set.  */
                      ASSIGNN (NEG (dest));
                      ARMul_AddCarry (state, lhs, rhs, dest);
                      ARMul_AddOverflow (state, lhs, rhs, dest);
@@ -1778,7 +2769,7 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 11) == 0xB)
                {
-                 /* STRH register offset, no write-back, up, pre indexed */
+                 /* STRH register offset, no write-back, up, pre indexed */
                  SHPREUP ();
                  break;
                }
@@ -1801,11 +2792,9 @@ check_PMUintr:
            case 0x19:          /* ORRS reg */
 #ifdef MODET
              if ((BITS (4, 11) & 0xF9) == 0x9)
-               {
-                 /* LDR register offset, no write-back, up, pre indexed */
-                 LHPREUP ();
-                 /* continue with remaining instruction decoding */
-               }
+               /* LDR register offset, no write-back, up, pre indexed.  */
+               LHPREUP ();
+             /* Continue with remaining instruction decoding.  */
 #endif
              rhs = DPSRegRHS;
              dest = LHS | rhs;
@@ -1816,7 +2805,7 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 11) == 0xB)
                {
-                 /* STRH register offset, write-back, up, pre indexed */
+                 /* STRH register offset, write-back, up, pre indexed */
                  SHPREUPWB ();
                  break;
                }
@@ -1838,11 +2827,9 @@ check_PMUintr:
            case 0x1b:          /* MOVS reg */
 #ifdef MODET
              if ((BITS (4, 11) & 0xF9) == 0x9)
-               {
-                 /* LDR register offset, write-back, up, pre indexed */
-                 LHPREUPWB ();
-                 /* continue with remaining instruction decoding */
-               }
+               /* LDR register offset, write-back, up, pre indexed.  */
+               LHPREUPWB ();
+             /* Continue with remaining instruction decoding.  */
 #endif
              dest = DPSRegRHS;
              WRITESDEST (dest);
@@ -1852,7 +2839,7 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 7) == 0xB)
                {
-                 /* STRH immediate offset, no write-back, up, pre indexed */
+                 /* STRH immediate offset, no write-back, up, pre indexed */
                  SHPREUP ();
                  break;
                }
@@ -1875,11 +2862,9 @@ check_PMUintr:
            case 0x1d:          /* BICS reg */
 #ifdef MODET
              if ((BITS (4, 7) & 0x9) == 0x9)
-               {
-                 /* LDR immediate offset, no write-back, up, pre indexed */
-                 LHPREUP ();
-                 /* continue with instruction decoding */
-               }
+               /* LDR immediate offset, no write-back, up, pre indexed.  */
+               LHPREUP ();
+             /* Continue with instruction decoding.  */
 #endif
              rhs = DPSRegRHS;
              dest = LHS & ~rhs;
@@ -1890,7 +2875,7 @@ check_PMUintr:
 #ifdef MODET
              if (BITS (4, 7) == 0xB)
                {
-                 /* STRH immediate offset, write-back, up, pre indexed */
+                 /* STRH immediate offset, write-back, up, pre indexed */
                  SHPREUPWB ();
                  break;
                }
@@ -1912,17 +2897,15 @@ check_PMUintr:
            case 0x1f:          /* MVNS reg */
 #ifdef MODET
              if ((BITS (4, 7) & 0x9) == 0x9)
-               {
-                 /* LDR immediate offset, write-back, up, pre indexed */
-                 LHPREUPWB ();
-                 /* continue instruction decoding */
-               }
+               /* LDR immediate offset, write-back, up, pre indexed.  */
+               LHPREUPWB ();
+             /* Continue instruction decoding.  */
 #endif
              dest = ~DPSRegRHS;
              WRITESDEST (dest);
              break;
 
-             
+
              /* Data Processing Immediate RHS Instructions.  */
 
            case 0x20:          /* AND immed */
@@ -1956,6 +2939,7 @@ check_PMUintr:
              lhs = LHS;
              rhs = DPImmRHS;
              dest = lhs - rhs;
+
              if ((lhs >= rhs) || ((rhs | lhs) >> 31))
                {
                  ARMul_SubCarry (state, lhs, rhs, dest);
@@ -1978,6 +2962,7 @@ check_PMUintr:
              lhs = LHS;
              rhs = DPImmRHS;
              dest = rhs - lhs;
+
              if ((rhs >= lhs) || ((rhs | lhs) >> 31))
                {
                  ARMul_SubCarry (state, rhs, lhs, dest);
@@ -2001,8 +2986,10 @@ check_PMUintr:
              rhs = DPImmRHS;
              dest = lhs + rhs;
              ASSIGNZ (dest == 0);
+
              if ((lhs | rhs) >> 30)
-               {               /* possible C,V,N to set */
+               {
+                 /* Possible C,V,N to set.  */
                  ASSIGNN (NEG (dest));
                  ARMul_AddCarry (state, lhs, rhs, dest);
                  ARMul_AddOverflow (state, lhs, rhs, dest);
@@ -2027,7 +3014,8 @@ check_PMUintr:
              dest = lhs + rhs + CFLAG;
              ASSIGNZ (dest == 0);
              if ((lhs | rhs) >> 30)
-               {               /* possible C,V,N to set */
+               {
+                 /* Possible C,V,N to set.  */
                  ASSIGNN (NEG (dest));
                  ARMul_AddCarry (state, lhs, rhs, dest);
                  ARMul_AddOverflow (state, lhs, rhs, dest);
@@ -2085,13 +3073,21 @@ check_PMUintr:
              WRITESDEST (dest);
              break;
 
-           case 0x30:          /* TST immed */
-             UNDEF_Test;
+           case 0x30:          /* MOVW immed */
+#ifdef MODE32
+             if (state->is_v6
+                 && handle_v6_insn (state, instr))
+               break;
+#endif
+             dest = BITS (0, 11);
+             dest |= (BITS (16, 19) << 12);
+             WRITEDEST (dest);
              break;
 
            case 0x31:          /* TSTP immed */
              if (DESTReg == 15)
-               {               /* TSTP immed */
+               {
+                 /* TSTP immed.  */
 #ifdef MODE32
                  state->Cpsr = GETSPSR (state->Bank);
                  ARMul_CPSRAltered (state);
@@ -2102,7 +3098,8 @@ check_PMUintr:
                }
              else
                {
-                 DPSImmRHS;    /* TST immed */
+                 /* TST immed.  */
+                 DPSImmRHS;
                  dest = LHS & rhs;
                  ARMul_NegZero (state, dest);
                }
@@ -2110,18 +3107,21 @@ check_PMUintr:
 
            case 0x32:          /* TEQ immed and MSR immed to CPSR */
              if (DESTReg == 15)
-               {               /* MSR immed to CPSR */
-                 ARMul_FixCPSR (state, instr, DPImmRHS);
-               }
+               /* MSR immed to CPSR.  */
+               ARMul_FixCPSR (state, instr, DPImmRHS);
+#ifdef MODE32
+             else if (state->is_v6
+                      && handle_v6_insn (state, instr))
+               break;
+#endif
              else
-               {
-                 UNDEF_Test;
-               }
+               UNDEF_Test;
              break;
 
            case 0x33:          /* TEQP immed */
              if (DESTReg == 15)
-               {               /* TEQP immed */
+               {
+                 /* TEQP immed.  */
 #ifdef MODE32
                  state->Cpsr = GETSPSR (state->Bank);
                  ARMul_CPSRAltered (state);
@@ -2138,13 +3138,22 @@ check_PMUintr:
                }
              break;
 
-           case 0x34:          /* CMP immed */
-             UNDEF_Test;
+           case 0x34:          /* MOVT immed */
+#ifdef MODE32
+             if (state->is_v6
+                 && handle_v6_insn (state, instr))
+               break;
+#endif
+             DEST &= 0xFFFF;
+             dest  = BITS (0, 11);
+             dest |= (BITS (16, 19) << 12);
+             DEST |= (dest << 16);
              break;
 
            case 0x35:          /* CMPP immed */
              if (DESTReg == 15)
-               {               /* CMPP immed */
+               {
+                 /* CMPP immed.  */
 #ifdef MODE32
                  state->Cpsr = GETSPSR (state->Bank);
                  ARMul_CPSRAltered (state);
@@ -2156,10 +3165,12 @@ check_PMUintr:
                }
              else
                {
-                 lhs = LHS;    /* CMP immed */
+                 /* CMP immed.  */
+                 lhs = LHS;
                  rhs = DPImmRHS;
                  dest = lhs - rhs;
                  ARMul_NegZero (state, dest);
+
                  if ((lhs >= rhs) || ((rhs | lhs) >> 31))
                    {
                      ARMul_SubCarry (state, lhs, rhs, dest);
@@ -2174,17 +3185,21 @@ check_PMUintr:
              break;
 
            case 0x36:          /* CMN immed and MSR immed to SPSR */
-             if (DESTReg == 15)        /* MSR */
+             if (DESTReg == 15)
                ARMul_FixSPSR (state, instr, DPImmRHS);
+#ifdef MODE32
+             else if (state->is_v6
+                      && handle_v6_insn (state, instr))
+               break;
+#endif
              else
-               {
-                 UNDEF_Test;
-               }
+               UNDEF_Test;
              break;
 
-           case 0x37:          /* CMNP immed */
+           case 0x37:          /* CMNP immed */
              if (DESTReg == 15)
-               {               /* CMNP immed */
+               {
+                 /* CMNP immed.  */
 #ifdef MODE32
                  state->Cpsr = GETSPSR (state->Bank);
                  ARMul_CPSRAltered (state);
@@ -2196,12 +3211,14 @@ check_PMUintr:
                }
              else
                {
-                 lhs = LHS;    /* CMN immed */
+                 /* CMN immed.  */
+                 lhs = LHS;
                  rhs = DPImmRHS;
                  dest = lhs + rhs;
                  ASSIGNZ (dest == 0);
                  if ((lhs | rhs) >> 30)
-                   {           /* possible C,V,N to set */
+                   {
+                     /* Possible C,V,N to set.  */
                      ASSIGNN (NEG (dest));
                      ARMul_AddCarry (state, lhs, rhs, dest);
                      ARMul_AddOverflow (state, lhs, rhs, dest);
@@ -2215,63 +3232,64 @@ check_PMUintr:
                }
              break;
 
-           case 0x38:          /* ORR immed */
+           case 0x38:          /* ORR immed */
              dest = LHS | DPImmRHS;
              WRITEDEST (dest);
              break;
 
-           case 0x39:          /* ORRS immed */
+           case 0x39:          /* ORRS immed */
              DPSImmRHS;
              dest = LHS | rhs;
              WRITESDEST (dest);
              break;
 
-           case 0x3a:          /* MOV immed */
+           case 0x3a:          /* MOV immed */
              dest = DPImmRHS;
              WRITEDEST (dest);
              break;
 
-           case 0x3b:          /* MOVS immed */
+           case 0x3b:          /* MOVS immed */
              DPSImmRHS;
              WRITESDEST (rhs);
              break;
 
-           case 0x3c:          /* BIC immed */
+           case 0x3c:          /* BIC immed */
              dest = LHS & ~DPImmRHS;
              WRITEDEST (dest);
              break;
 
-           case 0x3d:          /* BICS immed */
+           case 0x3d:          /* BICS immed */
              DPSImmRHS;
              dest = LHS & ~rhs;
              WRITESDEST (dest);
              break;
 
-           case 0x3e:          /* MVN immed */
+           case 0x3e:          /* MVN immed */
              dest = ~DPImmRHS;
              WRITEDEST (dest);
              break;
 
-           case 0x3f:          /* MVNS immed */
+           case 0x3f:          /* MVNS immed */
              DPSImmRHS;
              WRITESDEST (~rhs);
              break;
 
+
              /* Single Data Transfer Immediate RHS Instructions.  */
 
-           case 0x40:          /* Store Word, No WriteBack, Post Dec, Immed */
+           case 0x40:          /* Store Word, No WriteBack, Post Dec, Immed */
              lhs = LHS;
              if (StoreWord (state, instr, lhs))
                LSBase = lhs - LSImmRHS;
              break;
 
-           case 0x41:          /* Load Word, No WriteBack, Post Dec, Immed */
+           case 0x41:          /* Load Word, No WriteBack, Post Dec, Immed */
              lhs = LHS;
              if (LoadWord (state, instr, lhs))
                LSBase = lhs - LSImmRHS;
              break;
 
-           case 0x42:          /* Store Word, WriteBack, Post Dec, Immed */
+           case 0x42:          /* Store Word, WriteBack, Post Dec, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              lhs = LHS;
@@ -2282,7 +3300,7 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x43:          /* Load Word, WriteBack, Post Dec, Immed */
+           case 0x43:          /* Load Word, WriteBack, Post Dec, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              lhs = LHS;
@@ -2292,19 +3310,19 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x44:          /* Store Byte, No WriteBack, Post Dec, Immed */
+           case 0x44:          /* Store Byte, No WriteBack, Post Dec, Immed */
              lhs = LHS;
              if (StoreByte (state, instr, lhs))
                LSBase = lhs - LSImmRHS;
              break;
 
-           case 0x45:          /* Load Byte, No WriteBack, Post Dec, Immed */
+           case 0x45:          /* Load Byte, No WriteBack, Post Dec, Immed */
              lhs = LHS;
              if (LoadByte (state, instr, lhs, LUNSIGNED))
                LSBase = lhs - LSImmRHS;
              break;
 
-           case 0x46:          /* Store Byte, WriteBack, Post Dec, Immed */
+           case 0x46:          /* Store Byte, WriteBack, Post Dec, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              lhs = LHS;
@@ -2314,7 +3332,7 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x47:          /* Load Byte, WriteBack, Post Dec, Immed */
+           case 0x47:          /* Load Byte, WriteBack, Post Dec, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              lhs = LHS;
@@ -2324,19 +3342,19 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x48:          /* Store Word, No WriteBack, Post Inc, Immed */
+           case 0x48:          /* Store Word, No WriteBack, Post Inc, Immed */
              lhs = LHS;
              if (StoreWord (state, instr, lhs))
                LSBase = lhs + LSImmRHS;
              break;
 
-           case 0x49:          /* Load Word, No WriteBack, Post Inc, Immed */
+           case 0x49:          /* Load Word, No WriteBack, Post Inc, Immed */
              lhs = LHS;
              if (LoadWord (state, instr, lhs))
                LSBase = lhs + LSImmRHS;
              break;
 
-           case 0x4a:          /* Store Word, WriteBack, Post Inc, Immed */
+           case 0x4a:          /* Store Word, WriteBack, Post Inc, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              lhs = LHS;
@@ -2346,7 +3364,7 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x4b:          /* Load Word, WriteBack, Post Inc, Immed */
+           case 0x4b:          /* Load Word, WriteBack, Post Inc, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              lhs = LHS;
@@ -2356,19 +3374,19 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x4c:          /* Store Byte, No WriteBack, Post Inc, Immed */
+           case 0x4c:          /* Store Byte, No WriteBack, Post Inc, Immed */
              lhs = LHS;
              if (StoreByte (state, instr, lhs))
                LSBase = lhs + LSImmRHS;
              break;
 
-           case 0x4d:          /* Load Byte, No WriteBack, Post Inc, Immed */
+           case 0x4d:          /* Load Byte, No WriteBack, Post Inc, Immed */
              lhs = LHS;
              if (LoadByte (state, instr, lhs, LUNSIGNED))
                LSBase = lhs + LSImmRHS;
              break;
 
-           case 0x4e:          /* Store Byte, WriteBack, Post Inc, Immed */
+           case 0x4e:          /* Store Byte, WriteBack, Post Inc, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              lhs = LHS;
@@ -2378,7 +3396,7 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x4f:          /* Load Byte, WriteBack, Post Inc, Immed */
+           case 0x4f:          /* Load Byte, WriteBack, Post Inc, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              lhs = LHS;
@@ -2389,15 +3407,15 @@ check_PMUintr:
              break;
 
 
-           case 0x50:          /* Store Word, No WriteBack, Pre Dec, Immed */
+           case 0x50:          /* Store Word, No WriteBack, Pre Dec, Immed */
              (void) StoreWord (state, instr, LHS - LSImmRHS);
              break;
 
-           case 0x51:          /* Load Word, No WriteBack, Pre Dec, Immed */
+           case 0x51:          /* Load Word, No WriteBack, Pre Dec, Immed */
              (void) LoadWord (state, instr, LHS - LSImmRHS);
              break;
 
-           case 0x52:          /* Store Word, WriteBack, Pre Dec, Immed */
+           case 0x52:          /* Store Word, WriteBack, Pre Dec, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              temp = LHS - LSImmRHS;
@@ -2405,7 +3423,7 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x53:          /* Load Word, WriteBack, Pre Dec, Immed */
+           case 0x53:          /* Load Word, WriteBack, Pre Dec, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              temp = LHS - LSImmRHS;
@@ -2413,15 +3431,15 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x54:          /* Store Byte, No WriteBack, Pre Dec, Immed */
+           case 0x54:          /* Store Byte, No WriteBack, Pre Dec, Immed */
              (void) StoreByte (state, instr, LHS - LSImmRHS);
              break;
 
-           case 0x55:          /* Load Byte, No WriteBack, Pre Dec, Immed */
+           case 0x55:          /* Load Byte, No WriteBack, Pre Dec, Immed */
              (void) LoadByte (state, instr, LHS - LSImmRHS, LUNSIGNED);
              break;
 
-           case 0x56:          /* Store Byte, WriteBack, Pre Dec, Immed */
+           case 0x56:          /* Store Byte, WriteBack, Pre Dec, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              temp = LHS - LSImmRHS;
@@ -2429,7 +3447,7 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x57:          /* Load Byte, WriteBack, Pre Dec, Immed */
+           case 0x57:          /* Load Byte, WriteBack, Pre Dec, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              temp = LHS - LSImmRHS;
@@ -2437,15 +3455,15 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x58:          /* Store Word, No WriteBack, Pre Inc, Immed */
+           case 0x58:          /* Store Word, No WriteBack, Pre Inc, Immed */
              (void) StoreWord (state, instr, LHS + LSImmRHS);
              break;
 
-           case 0x59:          /* Load Word, No WriteBack, Pre Inc, Immed */
+           case 0x59:          /* Load Word, No WriteBack, Pre Inc, Immed */
              (void) LoadWord (state, instr, LHS + LSImmRHS);
              break;
 
-           case 0x5a:          /* Store Word, WriteBack, Pre Inc, Immed */
+           case 0x5a:          /* Store Word, WriteBack, Pre Inc, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              temp = LHS + LSImmRHS;
@@ -2453,7 +3471,7 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x5b:          /* Load Word, WriteBack, Pre Inc, Immed */
+           case 0x5b:          /* Load Word, WriteBack, Pre Inc, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              temp = LHS + LSImmRHS;
@@ -2461,15 +3479,15 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x5c:          /* Store Byte, No WriteBack, Pre Inc, Immed */
+           case 0x5c:          /* Store Byte, No WriteBack, Pre Inc, Immed */
              (void) StoreByte (state, instr, LHS + LSImmRHS);
              break;
 
-           case 0x5d:          /* Load Byte, No WriteBack, Pre Inc, Immed */
+           case 0x5d:          /* Load Byte, No WriteBack, Pre Inc, Immed */
              (void) LoadByte (state, instr, LHS + LSImmRHS, LUNSIGNED);
              break;
 
-           case 0x5e:          /* Store Byte, WriteBack, Pre Inc, Immed */
+           case 0x5e:          /* Store Byte, WriteBack, Pre Inc, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              temp = LHS + LSImmRHS;
@@ -2477,7 +3495,7 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x5f:          /* Load Byte, WriteBack, Pre Inc, Immed */
+           case 0x5f:          /* Load Byte, WriteBack, Pre Inc, Immed */
              UNDEF_LSRBaseEQDestWb;
              UNDEF_LSRPCBaseWb;
              temp = LHS + LSImmRHS;
@@ -2488,9 +3506,14 @@ check_PMUintr:
 
              /* Single Data Transfer Register RHS Instructions.  */
 
-           case 0x60:          /* Store Word, No WriteBack, Post Dec, Reg */
+           case 0x60:          /* Store 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;
                }
@@ -2503,9 +3526,14 @@ check_PMUintr:
                LSBase = lhs - LSRegRHS;
              break;
 
-           case 0x61:          /* Load Word, No WriteBack, Post Dec, Reg */
+           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;
                }
@@ -2519,9 +3547,14 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x62:          /* Store Word, WriteBack, Post Dec, Reg */
+           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;
                }
@@ -2536,9 +3569,14 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x63:          /* Load Word, WriteBack, Post Dec, Reg */
+           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;
                }
@@ -2554,9 +3592,14 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x64:          /* Store Byte, No WriteBack, Post Dec, Reg */
+           case 0x64:          /* Store 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;
                }
@@ -2569,9 +3612,14 @@ check_PMUintr:
                LSBase = lhs - LSRegRHS;
              break;
 
-           case 0x65:          /* Load Byte, No WriteBack, Post Dec, Reg */
+           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;
                }
@@ -2585,9 +3633,14 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x66:          /* Store Byte, WriteBack, Post Dec, Reg */
+           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;
                }
@@ -2602,9 +3655,14 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x67:          /* Load Byte, WriteBack, Post Dec, Reg */
+           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;
                }
@@ -2620,9 +3678,14 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x68:          /* Store Word, No WriteBack, Post Inc, Reg */
+           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;
                }
@@ -2635,9 +3698,14 @@ check_PMUintr:
                LSBase = lhs + LSRegRHS;
              break;
 
-           case 0x69:          /* Load Word, No WriteBack, Post Inc, Reg */
+           case 0x69:          /* Load 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;
                }
@@ -2651,9 +3719,14 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x6a:          /* Store Word, WriteBack, Post Inc, Reg */
+           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;
                }
@@ -2668,9 +3741,14 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x6b:          /* Load Word, WriteBack, Post Inc, Reg */
+           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;
                }
@@ -2686,9 +3764,14 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x6c:          /* Store Byte, No WriteBack, Post Inc, Reg */
+           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;
                }
@@ -2701,9 +3784,14 @@ check_PMUintr:
                LSBase = lhs + LSRegRHS;
              break;
 
-           case 0x6d:          /* Load Byte, No WriteBack, Post Inc, Reg */
+           case 0x6d:          /* Load 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;
                }
@@ -2717,9 +3805,14 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x6e:          /* Store Byte, WriteBack, Post Inc, Reg */
+           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;
                }
@@ -2734,9 +3827,14 @@ check_PMUintr:
              state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
              break;
 
-           case 0x6f:          /* Load Byte, WriteBack, Post Inc, Reg */
+           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;
                }
@@ -2753,27 +3851,42 @@ check_PMUintr:
              break;
 
 
-           case 0x70:          /* Store Word, No WriteBack, Pre Dec, Reg */
+           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;
                }
              (void) StoreWord (state, instr, LHS - LSRegRHS);
              break;
 
-           case 0x71:          /* Load Word, No WriteBack, Pre Dec, Reg */
+           case 0x71:          /* Load 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;
                }
              (void) LoadWord (state, instr, LHS - LSRegRHS);
              break;
 
-           case 0x72:          /* Store Word, WriteBack, Pre Dec, Reg */
+           case 0x72:          /* Store Word, 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;
                }
@@ -2786,9 +3899,14 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x73:          /* Load Word, WriteBack, Pre Dec, Reg */
+           case 0x73:          /* Load Word, 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;
                }
@@ -2801,27 +3919,42 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x74:          /* Store Byte, No WriteBack, Pre Dec, Reg */
+           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;
                }
              (void) StoreByte (state, instr, LHS - LSRegRHS);
              break;
 
-           case 0x75:          /* Load Byte, No WriteBack, Pre Dec, Reg */
+           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;
                }
              (void) LoadByte (state, instr, LHS - LSRegRHS, LUNSIGNED);
              break;
 
-           case 0x76:          /* Store Byte, WriteBack, Pre Dec, Reg */
+           case 0x76:          /* Store Byte, 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;
                }
@@ -2834,9 +3967,14 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x77:          /* Load Byte, WriteBack, Pre Dec, Reg */
+           case 0x77:          /* Load Byte, 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;
                }
@@ -2849,27 +3987,42 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x78:          /* Store Word, No WriteBack, Pre Inc, Reg */
+           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;
                }
              (void) StoreWord (state, instr, LHS + LSRegRHS);
              break;
 
-           case 0x79:          /* Load Word, No WriteBack, Pre Inc, Reg */
+           case 0x79:          /* Load 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;
                }
              (void) LoadWord (state, instr, LHS + LSRegRHS);
              break;
 
-           case 0x7a:          /* Store Word, WriteBack, Pre Inc, Reg */
+           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;
                }
@@ -2882,9 +4035,14 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x7b:          /* Load Word, WriteBack, Pre Inc, Reg */
+           case 0x7b:          /* Load 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;
                }
@@ -2897,27 +4055,42 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x7c:          /* Store Byte, No WriteBack, Pre Inc, Reg */
+           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;
                }
              (void) StoreByte (state, instr, LHS + LSRegRHS);
              break;
 
-           case 0x7d:          /* Load Byte, No WriteBack, Pre Inc, Reg */
+           case 0x7d:          /* Load 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;
                }
              (void) LoadByte (state, instr, LHS + LSRegRHS, LUNSIGNED);
              break;
 
-           case 0x7e:          /* Store Byte, WriteBack, Pre Inc, Reg */
+           case 0x7e:          /* Store Byte, 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;
                }
@@ -2930,7 +4103,7 @@ check_PMUintr:
                LSBase = temp;
              break;
 
-           case 0x7f:          /* Load Byte, WriteBack, Pre Inc, Reg */
+           case 0x7f:          /* Load Byte, WriteBack, Pre Inc, Reg */
              if (BIT (4))
                {
                  /* Check for the special breakpoint opcode.
@@ -2941,6 +4114,11 @@ check_PMUintr:
                      if (!ARMul_OSHandleSWI (state, SWI_Breakpoint))
                        ARMul_Abort (state, ARMul_SWIV);
                    }
+#ifdef MODE32
+                 else if (state->is_v6
+                          && handle_v6_insn (state, instr))
+                   break;
+#endif
                  else
                    ARMul_UndefInstr (state, instr);
                  break;
@@ -2957,146 +4135,146 @@ check_PMUintr:
 
              /* Multiple Data Transfer Instructions.  */
 
-           case 0x80:          /* Store, No WriteBack, Post Dec */
+           case 0x80:          /* Store, No WriteBack, Post Dec */
              STOREMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
              break;
 
-           case 0x81:          /* Load, No WriteBack, Post Dec */
+           case 0x81:          /* Load, No WriteBack, Post Dec */
              LOADMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
              break;
 
-           case 0x82:          /* Store, WriteBack, Post Dec */
+           case 0x82:          /* Store, WriteBack, Post Dec */
              temp = LSBase - LSMNumRegs;
              STOREMULT (instr, temp + 4L, temp);
              break;
 
-           case 0x83:          /* Load, WriteBack, Post Dec */
+           case 0x83:          /* Load, WriteBack, Post Dec */
              temp = LSBase - LSMNumRegs;
              LOADMULT (instr, temp + 4L, temp);
              break;
 
-           case 0x84:          /* Store, Flags, No WriteBack, Post Dec */
+           case 0x84:          /* Store, Flags, No WriteBack, Post Dec */
              STORESMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
              break;
 
-           case 0x85:          /* Load, Flags, No WriteBack, Post Dec */
+           case 0x85:          /* Load, Flags, No WriteBack, Post Dec */
              LOADSMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
              break;
 
-           case 0x86:          /* Store, Flags, WriteBack, Post Dec */
+           case 0x86:          /* Store, Flags, WriteBack, Post Dec */
              temp = LSBase - LSMNumRegs;
              STORESMULT (instr, temp + 4L, temp);
              break;
 
-           case 0x87:          /* Load, Flags, WriteBack, Post Dec */
+           case 0x87:          /* Load, Flags, WriteBack, Post Dec */
              temp = LSBase - LSMNumRegs;
              LOADSMULT (instr, temp + 4L, temp);
              break;
 
-           case 0x88:          /* Store, No WriteBack, Post Inc */
+           case 0x88:          /* Store, No WriteBack, Post Inc */
              STOREMULT (instr, LSBase, 0L);
              break;
 
-           case 0x89:          /* Load, No WriteBack, Post Inc */
+           case 0x89:          /* Load, No WriteBack, Post Inc */
              LOADMULT (instr, LSBase, 0L);
              break;
 
-           case 0x8a:          /* Store, WriteBack, Post Inc */
+           case 0x8a:          /* Store, WriteBack, Post Inc */
              temp = LSBase;
              STOREMULT (instr, temp, temp + LSMNumRegs);
              break;
 
-           case 0x8b:          /* Load, WriteBack, Post Inc */
+           case 0x8b:          /* Load, WriteBack, Post Inc */
              temp = LSBase;
              LOADMULT (instr, temp, temp + LSMNumRegs);
              break;
 
-           case 0x8c:          /* Store, Flags, No WriteBack, Post Inc */
+           case 0x8c:          /* Store, Flags, No WriteBack, Post Inc */
              STORESMULT (instr, LSBase, 0L);
              break;
 
-           case 0x8d:          /* Load, Flags, No WriteBack, Post Inc */
+           case 0x8d:          /* Load, Flags, No WriteBack, Post Inc */
              LOADSMULT (instr, LSBase, 0L);
              break;
 
-           case 0x8e:          /* Store, Flags, WriteBack, Post Inc */
+           case 0x8e:          /* Store, Flags, WriteBack, Post Inc */
              temp = LSBase;
              STORESMULT (instr, temp, temp + LSMNumRegs);
              break;
 
-           case 0x8f:          /* Load, Flags, WriteBack, Post Inc */
+           case 0x8f:          /* Load, Flags, WriteBack, Post Inc */
              temp = LSBase;
              LOADSMULT (instr, temp, temp + LSMNumRegs);
              break;
 
-           case 0x90:          /* Store, No WriteBack, Pre Dec */
+           case 0x90:          /* Store, No WriteBack, Pre Dec */
              STOREMULT (instr, LSBase - LSMNumRegs, 0L);
              break;
 
-           case 0x91:          /* Load, No WriteBack, Pre Dec */
+           case 0x91:          /* Load, No WriteBack, Pre Dec */
              LOADMULT (instr, LSBase - LSMNumRegs, 0L);
              break;
 
-           case 0x92:          /* Store, WriteBack, Pre Dec */
+           case 0x92:          /* Store, WriteBack, Pre Dec */
              temp = LSBase - LSMNumRegs;
              STOREMULT (instr, temp, temp);
              break;
 
-           case 0x93:          /* Load, WriteBack, Pre Dec */
+           case 0x93:          /* Load, WriteBack, Pre Dec */
              temp = LSBase - LSMNumRegs;
              LOADMULT (instr, temp, temp);
              break;
 
-           case 0x94:          /* Store, Flags, No WriteBack, Pre Dec */
+           case 0x94:          /* Store, Flags, No WriteBack, Pre Dec */
              STORESMULT (instr, LSBase - LSMNumRegs, 0L);
              break;
 
-           case 0x95:          /* Load, Flags, No WriteBack, Pre Dec */
+           case 0x95:          /* Load, Flags, No WriteBack, Pre Dec */
              LOADSMULT (instr, LSBase - LSMNumRegs, 0L);
              break;
 
-           case 0x96:          /* Store, Flags, WriteBack, Pre Dec */
+           case 0x96:          /* Store, Flags, WriteBack, Pre Dec */
              temp = LSBase - LSMNumRegs;
              STORESMULT (instr, temp, temp);
              break;
 
-           case 0x97:          /* Load, Flags, WriteBack, Pre Dec */
+           case 0x97:          /* Load, Flags, WriteBack, Pre Dec */
              temp = LSBase - LSMNumRegs;
              LOADSMULT (instr, temp, temp);
              break;
 
-           case 0x98:          /* Store, No WriteBack, Pre Inc */
+           case 0x98:          /* Store, No WriteBack, Pre Inc */
              STOREMULT (instr, LSBase + 4L, 0L);
              break;
 
-           case 0x99:          /* Load, No WriteBack, Pre Inc */
+           case 0x99:          /* Load, No WriteBack, Pre Inc */
              LOADMULT (instr, LSBase + 4L, 0L);
              break;
 
-           case 0x9a:          /* Store, WriteBack, Pre Inc */
+           case 0x9a:          /* Store, WriteBack, Pre Inc */
              temp = LSBase;
              STOREMULT (instr, temp + 4L, temp + LSMNumRegs);
              break;
 
-           case 0x9b:          /* Load, WriteBack, Pre Inc */
+           case 0x9b:          /* Load, WriteBack, Pre Inc */
              temp = LSBase;
              LOADMULT (instr, temp + 4L, temp + LSMNumRegs);
              break;
 
-           case 0x9c:          /* Store, Flags, No WriteBack, Pre Inc */
+           case 0x9c:          /* Store, Flags, No WriteBack, Pre Inc */
              STORESMULT (instr, LSBase + 4L, 0L);
              break;
 
-           case 0x9d:          /* Load, Flags, No WriteBack, Pre Inc */
+           case 0x9d:          /* Load, Flags, No WriteBack, Pre Inc */
              LOADSMULT (instr, LSBase + 4L, 0L);
              break;
 
-           case 0x9e:          /* Store, Flags, WriteBack, Pre Inc */
+           case 0x9e:          /* Store, Flags, WriteBack, Pre Inc */
              temp = LSBase;
              STORESMULT (instr, temp + 4L, temp + LSMNumRegs);
              break;
 
-           case 0x9f:          /* Load, Flags, WriteBack, Pre Inc */
+           case 0x9f:          /* Load, Flags, WriteBack, Pre Inc */
              temp = LSBase;
              LOADSMULT (instr, temp + 4L, temp + LSMNumRegs);
              break;
@@ -3129,7 +4307,6 @@ check_PMUintr:
              FLUSHPIPE;
              break;
 
-
              /* Branch and Link forward.  */
            case 0xb0:
            case 0xb1:
@@ -3147,9 +4324,10 @@ check_PMUintr:
 #endif
              state->Reg[15] = pc + 8 + POSBRANCH;
              FLUSHPIPE;
+             if (trace_funcs)
+               fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
              break;
 
-
              /* Branch and Link backward.  */
            case 0xb8:
            case 0xb9:
@@ -3167,14 +4345,18 @@ check_PMUintr:
 #endif
              state->Reg[15] = pc + 8 + NEGBRANCH;
              FLUSHPIPE;
+             if (trace_funcs)
+               fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
              break;
 
              /* Co-Processor Data Transfers.  */
            case 0xc4:
              if (state->is_v5)
                {
+                 if (CPNum == 10 || CPNum == 11)
+                   handle_VFP_move (state, instr);
                  /* Reading from R15 is UNPREDICTABLE.  */
-                 if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
+                 else if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
                    ARMul_UndefInstr (state, instr);
                  /* Is access to coprocessor 0 allowed ?  */
                  else if (! CP_ACCESS_ALLOWED (state, CPNum))
@@ -3193,27 +4375,29 @@ check_PMUintr:
                        ARMul_UndefInstr (state, instr);
                      else
                        {
-                         /* XScale MAR insn.  Move two registers into accumulator.  */               
+                         /* XScale MAR insn.  Move two registers into accumulator.  */
                          state->Accumulator = state->Reg[BITS (12, 15)];
                          state->Accumulator += (ARMdword) state->Reg[BITS (16, 19)] << 32;
                        }
                    }
                  else
                    /* FIXME: Not sure what to do for other v5 processors.  */
-                   ARMul_UndefInstr (state, instr);                
+                   ARMul_UndefInstr (state, instr);
                  break;
                }
              /* Drop through.  */
-             
-           case 0xc0:          /* Store , No WriteBack , Post Dec */
+
+           case 0xc0:          /* Store , No WriteBack , Post Dec */
              ARMul_STC (state, instr, LHS);
              break;
 
            case 0xc5:
              if (state->is_v5)
                {
+                 if (CPNum == 10 || CPNum == 11)
+                   handle_VFP_move (state, instr);
                  /* Writes to R15 are UNPREDICATABLE.  */
-                 if (DESTReg == 15 || LHSReg == 15)
+                 else if (DESTReg == 15 || LHSReg == 15)
                    ARMul_UndefInstr (state, instr);
                  /* Is access to the coprocessor allowed ?  */
                  else if (! CP_ACCESS_ALLOWED (state, CPNum))
@@ -3250,91 +4434,91 @@ check_PMUintr:
                }
              /* Drop through.  */
 
-           case 0xc1:          /* Load , No WriteBack , Post Dec */
+           case 0xc1:          /* Load , No WriteBack , Post Dec */
              ARMul_LDC (state, instr, LHS);
              break;
 
            case 0xc2:
-           case 0xc6:          /* Store , WriteBack , Post Dec */
+           case 0xc6:          /* Store , WriteBack , Post Dec */
              lhs = LHS;
              state->Base = lhs - LSCOff;
              ARMul_STC (state, instr, lhs);
              break;
 
            case 0xc3:
-           case 0xc7:          /* Load , WriteBack , Post Dec */
+           case 0xc7:          /* Load , WriteBack , Post Dec */
              lhs = LHS;
              state->Base = lhs - LSCOff;
              ARMul_LDC (state, instr, lhs);
              break;
 
            case 0xc8:
-           case 0xcc:          /* Store , No WriteBack , Post Inc */
+           case 0xcc:          /* Store , No WriteBack , Post Inc */
              ARMul_STC (state, instr, LHS);
              break;
 
            case 0xc9:
-           case 0xcd:          /* Load , No WriteBack , Post Inc */
+           case 0xcd:          /* Load , No WriteBack , Post Inc */
              ARMul_LDC (state, instr, LHS);
              break;
 
            case 0xca:
-           case 0xce:          /* Store , WriteBack , Post Inc */
+           case 0xce:          /* Store , WriteBack , Post Inc */
              lhs = LHS;
              state->Base = lhs + LSCOff;
              ARMul_STC (state, instr, LHS);
              break;
 
            case 0xcb:
-           case 0xcf:          /* Load , WriteBack , Post Inc */
+           case 0xcf:          /* Load , WriteBack , Post Inc */
              lhs = LHS;
              state->Base = lhs + LSCOff;
              ARMul_LDC (state, instr, LHS);
              break;
 
            case 0xd0:
-           case 0xd4:          /* Store , No WriteBack , Pre Dec */
+           case 0xd4:          /* Store , No WriteBack , Pre Dec */
              ARMul_STC (state, instr, LHS - LSCOff);
              break;
 
            case 0xd1:
-           case 0xd5:          /* Load , No WriteBack , Pre Dec */
+           case 0xd5:          /* Load , No WriteBack , Pre Dec */
              ARMul_LDC (state, instr, LHS - LSCOff);
              break;
 
            case 0xd2:
-           case 0xd6:          /* Store , WriteBack , Pre Dec */
+           case 0xd6:          /* Store , WriteBack , Pre Dec */
              lhs = LHS - LSCOff;
              state->Base = lhs;
              ARMul_STC (state, instr, lhs);
              break;
 
            case 0xd3:
-           case 0xd7:          /* Load , WriteBack , Pre Dec */
+           case 0xd7:          /* Load , WriteBack , Pre Dec */
              lhs = LHS - LSCOff;
              state->Base = lhs;
              ARMul_LDC (state, instr, lhs);
              break;
 
            case 0xd8:
-           case 0xdc:          /* Store , No WriteBack , Pre Inc */
+           case 0xdc:          /* Store , No WriteBack , Pre Inc */
              ARMul_STC (state, instr, LHS + LSCOff);
              break;
 
            case 0xd9:
-           case 0xdd:          /* Load , No WriteBack , Pre Inc */
+           case 0xdd:          /* Load , No WriteBack , Pre Inc */
              ARMul_LDC (state, instr, LHS + LSCOff);
              break;
 
            case 0xda:
-           case 0xde:          /* Store , WriteBack , Pre Inc */
+           case 0xde:          /* Store , WriteBack , Pre Inc */
              lhs = LHS + LSCOff;
              state->Base = lhs;
              ARMul_STC (state, instr, lhs);
              break;
 
            case 0xdb:
-           case 0xdf:          /* Load , WriteBack , Pre Inc */
+           case 0xdf:          /* Load , WriteBack , Pre Inc */
              lhs = LHS + LSCOff;
              state->Base = lhs;
              ARMul_LDC (state, instr, lhs);
@@ -3342,6 +4526,7 @@ check_PMUintr:
 
 
              /* Co-Processor Register Transfers (MCR) and Data Ops.  */
+
            case 0xe2:
              if (! CP_ACCESS_ALLOWED (state, CPNum))
                {
@@ -3352,78 +4537,84 @@ check_PMUintr:
                switch (BITS (18, 19))
                  {
                  case 0x0:
-                   {
-                     /* XScale MIA instruction.  Signed multiplication of two 32 bit
-                        values and addition to 40 bit accumulator.  */
-                     long long Rm = state->Reg[MULLHSReg];
-                     long long Rs = state->Reg[MULACCReg];
-
-                     if (Rm & (1 << 31))
-                       Rm -= 1ULL << 32;
-                     if (Rs & (1 << 31))
-                       Rs -= 1ULL << 32;
-                     state->Accumulator += Rm * Rs;
-                   }
-                   goto donext;
+                   if (BITS (4, 11) == 1 && BITS (16, 17) == 0)
+                     {
+                       /* XScale MIA instruction.  Signed multiplication of
+                          two 32 bit values and addition to 40 bit accumulator.  */
+                       ARMsdword Rm = state->Reg[MULLHSReg];
+                       ARMsdword Rs = state->Reg[MULACCReg];
+
+                       if (Rm & (1 << 31))
+                         Rm -= 1ULL << 32;
+                       if (Rs & (1 << 31))
+                         Rs -= 1ULL << 32;
+                       state->Accumulator += Rm * Rs;
+                       goto donext;
+                     }
+                   break;
 
                  case 0x2:
-                   {
-                     /* XScale MIAPH instruction.  */
-                     ARMword t1 = state->Reg[MULLHSReg] >> 16;
-                     ARMword t2 = state->Reg[MULACCReg] >> 16;
-                     ARMword t3 = state->Reg[MULLHSReg] & 0xffff;
-                     ARMword t4 = state->Reg[MULACCReg] & 0xffff;
-                     long long t5;
-
-                     if (t1 & (1 << 15))
-                       t1 -= 1 << 16;
-                     if (t2 & (1 << 15))
-                       t2 -= 1 << 16;
-                     if (t3 & (1 << 15))
-                       t3 -= 1 << 16;
-                     if (t4 & (1 << 15))
-                       t4 -= 1 << 16;
-                     t1 *= t2;
-                     t5 = t1;
-                     if (t5 & (1 << 31))
-                       t5 -= 1ULL << 32;
-                     state->Accumulator += t5;
-                     t3 *= t4;
-                     t5 = t3;
-                     if (t5 & (1 << 31))
-                       t5 -= 1ULL << 32;
-                     state->Accumulator += t5;
-                   }
-                   goto donext;
+                   if (BITS (4, 11) == 1 && BITS (16, 17) == 0)
+                     {
+                       /* XScale MIAPH instruction.  */
+                       ARMword t1 = state->Reg[MULLHSReg] >> 16;
+                       ARMword t2 = state->Reg[MULACCReg] >> 16;
+                       ARMword t3 = state->Reg[MULLHSReg] & 0xffff;
+                       ARMword t4 = state->Reg[MULACCReg] & 0xffff;
+                       ARMsdword t5;
+
+                       if (t1 & (1 << 15))
+                         t1 -= 1 << 16;
+                       if (t2 & (1 << 15))
+                         t2 -= 1 << 16;
+                       if (t3 & (1 << 15))
+                         t3 -= 1 << 16;
+                       if (t4 & (1 << 15))
+                         t4 -= 1 << 16;
+                       t1 *= t2;
+                       t5 = t1;
+                       if (t5 & (1 << 31))
+                         t5 -= 1ULL << 32;
+                       state->Accumulator += t5;
+                       t3 *= t4;
+                       t5 = t3;
+                       if (t5 & (1 << 31))
+                         t5 -= 1ULL << 32;
+                       state->Accumulator += t5;
+                       goto donext;
+                     }
+                   break;
 
                  case 0x3:
-                   {
-                     /* XScale MIAxy instruction.  */
-                     ARMword t1;
-                     ARMword t2;
-                     long long t5;
-
-                     if (BIT (17))
-                       t1 = state->Reg[MULLHSReg] >> 16;
-                     else
-                       t1 = state->Reg[MULLHSReg] & 0xffff;
-
-                     if (BIT (16))
-                       t2 = state->Reg[MULACCReg] >> 16;
-                     else
-                       t2 = state->Reg[MULACCReg] & 0xffff;
-
-                     if (t1 & (1 << 15))
-                       t1 -= 1 << 16;
-                     if (t2 & (1 << 15))
-                       t2 -= 1 << 16;
-                     t1 *= t2;
-                     t5 = t1;
-                     if (t5 & (1 << 31))
-                       t5 -= 1ULL << 32;
-                     state->Accumulator += t5;
-                   }
-                   goto donext;
+                   if (BITS (4, 11) == 1)
+                     {
+                       /* XScale MIAxy instruction.  */
+                       ARMword t1;
+                       ARMword t2;
+                       ARMsdword t5;
+
+                       if (BIT (17))
+                         t1 = state->Reg[MULLHSReg] >> 16;
+                       else
+                         t1 = state->Reg[MULLHSReg] & 0xffff;
+
+                       if (BIT (16))
+                         t2 = state->Reg[MULACCReg] >> 16;
+                       else
+                         t2 = state->Reg[MULACCReg] & 0xffff;
+
+                       if (t1 & (1 << 15))
+                         t1 -= 1 << 16;
+                       if (t2 & (1 << 15))
+                         t2 -= 1 << 16;
+                       t1 *= t2;
+                       t5 = t1;
+                       if (t5 & (1 << 31))
+                         t5 -= 1ULL << 32;
+                       state->Accumulator += t5;
+                       goto donext;
+                     }
+                   break;
 
                  default:
                    break;
@@ -3438,8 +4629,11 @@ check_PMUintr:
            case 0xec:
            case 0xee:
              if (BIT (4))
-               {               /* MCR */
-                 if (DESTReg == 15)
+               {
+                 if (CPNum == 10 || CPNum == 11)
+                   handle_VFP_move (state, instr);
+                 /* MCR.  */
+                 else if (DESTReg == 15)
                    {
                      UNDEF_MCRPC;
 #ifdef MODE32
@@ -3452,7 +4646,8 @@ check_PMUintr:
                  else
                    ARMul_MCR (state, instr, DEST);
                }
-             else              /* CDP Part 1 */
+             else
+               /* CDP Part 1.  */
                ARMul_CDP (state, instr);
              break;
 
@@ -3467,24 +4662,78 @@ check_PMUintr:
            case 0xed:
            case 0xef:
              if (BIT (4))
-               {               /* MRC */
-                 temp = ARMul_MRC (state, instr);
-                 if (DESTReg == 15)
+               {
+                 if (CPNum == 10 || CPNum == 11)
                    {
-                     ASSIGNN ((temp & NBIT) != 0);
-                     ASSIGNZ ((temp & ZBIT) != 0);
-                     ASSIGNC ((temp & CBIT) != 0);
-                     ASSIGNV ((temp & VBIT) != 0);
+                     switch (BITS (20, 27))
+                       {
+                       case 0xEF:
+                         if (BITS (16, 19) == 0x1
+                             && BITS (0, 11) == 0xA10)
+                           {
+                             /* VMRS  */
+                             if (DESTReg == 15)
+                               {
+                                 ARMul_SetCPSR (state, (state->FPSCR & 0xF0000000)
+                                                | (ARMul_GetCPSR (state) & 0x0FFFFFFF));
+
+                                 if (trace)
+                                   fprintf (stderr, " VFP: VMRS: set flags to %c%c%c%c\n",
+                                            ARMul_GetCPSR (state) & NBIT ? 'N' : '-',
+                                            ARMul_GetCPSR (state) & ZBIT ? 'Z' : '-',
+                                            ARMul_GetCPSR (state) & CBIT ? 'C' : '-',
+                                            ARMul_GetCPSR (state) & VBIT ? 'V' : '-');
+                               }
+                             else
+                               {
+                                 state->Reg[DESTReg] = state->FPSCR;
+
+                                 if (trace)
+                                   fprintf (stderr, " VFP: VMRS: r%d = %x\n", DESTReg, state->Reg[DESTReg]);
+                               }
+                           }
+                         else
+                           fprintf (stderr, "SIM: VFP: Unimplemented: Compare op\n");
+                         break;
+
+                       case 0xE0:
+                       case 0xE1:
+                         /* VMOV reg <-> single precision.  */
+                         if (BITS (0,6) != 0x10 || BITS (8,11) != 0xA)
+                           fprintf (stderr, "SIM: VFP: Unimplemented: move op\n");
+                         else if (BIT (20))
+                           state->Reg[BITS (12, 15)] = VFP_uword (BITS (16, 19) << 1 | BIT (7));
+                         else
+                           VFP_uword (BITS (16, 19) << 1 | BIT (7)) = state->Reg[BITS (12, 15)];
+                         break;
+
+                       default:
+                         fprintf (stderr, "SIM: VFP: Unimplemented: CDP op\n");
+                         break;
+                       }
                    }
                  else
-                   DEST = temp;
+                   {
+                     /* MRC */
+                     temp = ARMul_MRC (state, instr);
+                     if (DESTReg == 15)
+                       {
+                         ASSIGNN ((temp & NBIT) != 0);
+                         ASSIGNZ ((temp & ZBIT) != 0);
+                         ASSIGNC ((temp & CBIT) != 0);
+                         ASSIGNV ((temp & VBIT) != 0);
+                       }
+                     else
+                       DEST = temp;
+                   }
                }
-             else              /* CDP Part 2 */
+             else
+               /* CDP Part 2.  */
                ARMul_CDP (state, instr);
              break;
 
 
-             /*  SWI instruction.  */
+             /* SWI instruction.  */
            case 0xf0:
            case 0xf1:
            case 0xf2:
@@ -3520,14 +4769,6 @@ check_PMUintr:
     donext:
 #endif
 
-#ifdef NEED_UI_LOOP_HOOK
-      if (ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
-       {
-         ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
-         ui_loop_hook (0);
-       }
-#endif /* NEED_UI_LOOP_HOOK */
-
       if (state->Emulate == ONCE)
        state->Emulate = STOP;
       /* If we have changed mode, allow the PC to advance before stopping.  */
@@ -3588,9 +4829,9 @@ GetDPRegRHS (ARMul_State * state, ARMword instr)
          if (shamt == 0)
            return (base);
          else if (shamt >= 32)
-           return ((ARMword) ((long int) base >> 31L));
+           return ((ARMword) ((ARMsword) base >> 31L));
          else
-           return ((ARMword) ((long int) base >> (int) shamt));
+           return ((ARMword) ((ARMsword) base >> (int) shamt));
        case ROR:
          shamt &= 0x1f;
          if (shamt == 0)
@@ -3620,17 +4861,18 @@ GetDPRegRHS (ARMul_State * state, ARMword instr)
            return (base >> shamt);
        case ASR:
          if (shamt == 0)
-           return ((ARMword) ((long int) base >> 31L));
+           return ((ARMword) ((ARMsword) base >> 31L));
          else
-           return ((ARMword) ((long int) base >> (int) shamt));
+           return ((ARMword) ((ARMsword) base >> (int) shamt));
        case ROR:
-         if (shamt == 0)       /* its an RRX */
+         if (shamt == 0)
+           /* It's an RRX.  */
            return ((base >> 1) | (CFLAG << 31));
          else
            return ((base << (32 - shamt)) | (base >> shamt));
        }
     }
-  
+
   return 0;
 }
 
@@ -3702,12 +4944,12 @@ GetDPSRegRHS (ARMul_State * state, ARMword instr)
          else if (shamt >= 32)
            {
              ASSIGNC (base >> 31L);
-             return ((ARMword) ((long int) base >> 31L));
+             return ((ARMword) ((ARMsword) base >> 31L));
            }
          else
            {
-             ASSIGNC ((ARMword) ((long int) base >> (int) (shamt - 1)) & 1);
-             return ((ARMword) ((long int) base >> (int) shamt));
+             ASSIGNC ((ARMword) ((ARMsword) base >> (int) (shamt - 1)) & 1);
+             return ((ARMword) ((ARMsword) base >> (int) shamt));
            }
        case ROR:
          if (shamt == 0)
@@ -3735,6 +4977,7 @@ GetDPSRegRHS (ARMul_State * state, ARMword instr)
 #endif
        base = state->Reg[base];
       shamt = BITS (7, 11);
+
       switch ((int) BITS (5, 6))
        {
        case LSL:
@@ -3755,16 +4998,17 @@ GetDPSRegRHS (ARMul_State * state, ARMword instr)
          if (shamt == 0)
            {
              ASSIGNC (base >> 31L);
-             return ((ARMword) ((long int) base >> 31L));
+             return ((ARMword) ((ARMsword) base >> 31L));
            }
          else
            {
-             ASSIGNC ((ARMword) ((long int) base >> (int) (shamt - 1)) & 1);
-             return ((ARMword) ((long int) base >> (int) shamt));
+             ASSIGNC ((ARMword) ((ARMsword) base >> (int) (shamt - 1)) & 1);
+             return ((ARMword) ((ARMsword) base >> (int) shamt));
            }
        case ROR:
          if (shamt == 0)
-           {                   /* its an RRX */
+           {
+             /* It's an RRX.  */
              shamt = CFLAG;
              ASSIGNC (base & 1);
              return ((base >> 1) | (shamt << 31));
@@ -3796,13 +5040,17 @@ WriteR15 (ARMul_State * state, ARMword src)
   else
 #endif
     src &= 0xfffffffc;
+
 #ifdef MODE32
   state->Reg[15] = src & PCBITS;
 #else
   state->Reg[15] = (src & R15PCBITS) | ECC | ER15INT | EMODE;
   ARMul_R15Altered (state);
 #endif
+
   FLUSHPIPE;
+  if (trace_funcs)
+    fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
 }
 
 /* This routine handles writes to register 15 when the S bit is set.  */
@@ -3826,17 +5074,22 @@ WriteSR15 (ARMul_State * state, ARMword src)
 #else
 #ifdef MODET
   if (TFLAG)
-    abort (); /* ARMul_R15Altered would have to support it.  */
+    /* ARMul_R15Altered would have to support it.  */
+    abort ();
   else
 #endif
     src &= 0xfffffffc;
+
   if (state->Bank == USERBANK)
     state->Reg[15] = (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE;
   else
     state->Reg[15] = src;
+
   ARMul_R15Altered (state);
 #endif
   FLUSHPIPE;
+  if (trace_funcs)
+    fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
 }
 
 /* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM
@@ -3858,11 +5111,24 @@ WriteR15Branch (ARMul_State * state, ARMword src)
       state->Reg[15] = src & 0xfffffffc;
     }
   FLUSHPIPE;
+  if (trace_funcs)
+    fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
 #else
   WriteR15 (state, src);
 #endif
 }
 
+/* Before ARM_v5 LDR and LDM of pc did not change mode.  */
+
+static void
+WriteR15Load (ARMul_State * state, ARMword src)
+{
+  if (state->is_v5)
+    WriteR15Branch (state, src);
+  else
+    WriteR15 (state, src);
+}
+
 /* This routine evaluates most Load and Store register RHS's.  It is
    intended to be called from the macro LSRegRHS, which filters the
    common case of an unshifted register with in line code.  */
@@ -3875,7 +5141,8 @@ GetLSRegRHS (ARMul_State * state, ARMword instr)
   base = RHSReg;
 #ifndef MODE32
   if (base == 15)
-    base = ECC | ER15INT | R15PC | EMODE;      /* Now forbidden, but ....  */
+    /* Now forbidden, but ...  */
+    base = ECC | ER15INT | R15PC | EMODE;
   else
 #endif
     base = state->Reg[base];
@@ -3892,11 +5159,12 @@ GetLSRegRHS (ARMul_State * state, ARMword instr)
        return (base >> shamt);
     case ASR:
       if (shamt == 0)
-       return ((ARMword) ((long int) base >> 31L));
+       return ((ARMword) ((ARMsword) base >> 31L));
       else
-       return ((ARMword) ((long int) base >> (int) shamt));
+       return ((ARMword) ((ARMsword) base >> (int) shamt));
     case ROR:
-      if (shamt == 0)          /* its an RRX */
+      if (shamt == 0)
+       /* It's an RRX.  */
        return ((base >> 1) | (CFLAG << 31));
       else
        return ((base << (32 - shamt)) | (base >> shamt));
@@ -3916,12 +5184,13 @@ GetLS7RHS (ARMul_State * state, ARMword instr)
       /* Register.  */
 #ifndef MODE32
       if (RHSReg == 15)
-       return ECC | ER15INT | R15PC | EMODE;   /* Now forbidden, but ...  */
+       /* Now forbidden, but ...  */
+       return ECC | ER15INT | R15PC | EMODE;
 #endif
       return state->Reg[RHSReg];
     }
 
-  /* Otherwise an immediate.  */
+  /* Immediate.  */
   return BITS (0, 3) | (BITS (8, 11) << 4);
 }
 
@@ -3943,7 +5212,7 @@ LoadWord (ARMul_State * state, ARMword instr, ARMword address)
   if (state->Aborted)
     {
       TAKEABORT;
-      return (state->lateabtSig);
+      return state->lateabtSig;
     }
   if (address & 3)
     dest = ARMul_Align (state, address, dest);
@@ -3965,22 +5234,19 @@ LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address,
   BUSUSEDINCPCS;
 #ifndef MODE32
   if (ADDREXCEPT (address))
-    {
-      INTERNALABORT (address);
-    }
+    INTERNALABORT (address);
 #endif
   dest = ARMul_LoadHalfWord (state, address);
   if (state->Aborted)
     {
       TAKEABORT;
-      return (state->lateabtSig);
+      return state->lateabtSig;
     }
   UNDEF_LSRBPC;
   if (signextend)
-    {
-      if (dest & 1 << (16 - 1))
-       dest = (dest & ((1 << 16) - 1)) - (1 << 16);
-    }
+    if (dest & 1 << (16 - 1))
+      dest = (dest & ((1 << 16) - 1)) - (1 << 16);
+
   WRITEDEST (dest);
   ARMul_Icycles (state, 1, 0L);
   return (DESTReg != LHSReg);
@@ -3998,24 +5264,22 @@ LoadByte (ARMul_State * state, ARMword instr, ARMword address, int signextend)
   BUSUSEDINCPCS;
 #ifndef MODE32
   if (ADDREXCEPT (address))
-    {
-      INTERNALABORT (address);
-    }
+    INTERNALABORT (address);
 #endif
   dest = ARMul_LoadByte (state, address);
   if (state->Aborted)
     {
       TAKEABORT;
-      return (state->lateabtSig);
+      return state->lateabtSig;
     }
   UNDEF_LSRBPC;
   if (signextend)
-    {
-      if (dest & 1 << (8 - 1))
-       dest = (dest & ((1 << 8) - 1)) - (1 << 8);
-    }
+    if (dest & 1 << (8 - 1))
+      dest = (dest & ((1 << 8) - 1)) - (1 << 8);
+
   WRITEDEST (dest);
   ARMul_Icycles (state, 1, 0L);
+
   return (DESTReg != LHSReg);
 }
 
@@ -4028,7 +5292,7 @@ Handle_Load_Double (ARMul_State * state, ARMword instr)
   ARMword addr_reg;
   ARMword write_back  = BIT (21);
   ARMword immediate   = BIT (22);
-  ARMword add_to_base = BIT (23);        
+  ARMword add_to_base = BIT (23);
   ARMword pre_indexed = BIT (24);
   ARMword offset;
   ARMword addr;
@@ -4036,7 +5300,7 @@ Handle_Load_Double (ARMul_State * state, ARMword instr)
   ARMword base;
   ARMword value1;
   ARMword value2;
-  
+
   BUSUSEDINCPCS;
 
   /* If the writeback bit is set, the pre-index bit must be clear.  */
@@ -4045,13 +5309,13 @@ Handle_Load_Double (ARMul_State * state, ARMword instr)
       ARMul_UndefInstr (state, instr);
       return;
     }
-  
+
   /* Extract the base address register.  */
   addr_reg = LHSReg;
-  
+
   /* Extract the destination register and check it.  */
   dest_reg = DESTReg;
-  
+
   /* Destination register must be even.  */
   if ((dest_reg & 1)
     /* Destination register cannot be LR.  */
@@ -4072,15 +5336,18 @@ Handle_Load_Double (ARMul_State * state, ARMword instr)
     sum = base + offset;
   else
     sum = base - offset;
-  
+
   /* If this is a pre-indexed mode use the sum.  */
   if (pre_indexed)
     addr = sum;
   else
     addr = base;
 
+  if (state->is_v6 && (addr & 0x3) == 0)
+    /* Word alignment is enough for v6.  */
+    ;
   /* The address must be aligned on a 8 byte boundary.  */
-  if (addr & 0x7)
+  else if (addr & 0x7)
     {
 #ifdef ABORTS
       ARMul_DATAABORT (addr);
@@ -4111,17 +5378,17 @@ Handle_Load_Double (ARMul_State * state, ARMword instr)
       TAKEABORT;
       return;
     }
-  
+
   ARMul_Icycles (state, 2, 0L);
 
   /* Store the values.  */
   state->Reg[dest_reg] = value1;
   state->Reg[dest_reg + 1] = value2;
-  
+
   /* Do the post addressing and writeback.  */
   if (! pre_indexed)
     addr = sum;
-  
+
   if (! pre_indexed || write_back)
     state->Reg[addr_reg] = addr;
 }
@@ -4135,7 +5402,7 @@ Handle_Store_Double (ARMul_State * state, ARMword instr)
   ARMword addr_reg;
   ARMword write_back  = BIT (21);
   ARMword immediate   = BIT (22);
-  ARMword add_to_base = BIT (23);        
+  ARMword add_to_base = BIT (23);
   ARMword pre_indexed = BIT (24);
   ARMword offset;
   ARMword addr;
@@ -4150,20 +5417,20 @@ Handle_Store_Double (ARMul_State * state, ARMword instr)
       ARMul_UndefInstr (state, instr);
       return;
     }
-  
+
   /* Extract the base address register.  */
   addr_reg = LHSReg;
-  
+
   /* Base register cannot be PC.  */
   if (addr_reg == 15)
     {
       ARMul_UndefInstr (state, instr);
       return;
     }
-  
+
   /* Extract the source register.  */
   src_reg = DESTReg;
-  
+
   /* Source register must be even.  */
   if (src_reg & 1)
     {
@@ -4182,7 +5449,7 @@ Handle_Store_Double (ARMul_State * state, ARMword instr)
     sum = base + offset;
   else
     sum = base - offset;
-  
+
   /* If this is a pre-indexed mode use the sum.  */
   if (pre_indexed)
     addr = sum;
@@ -4190,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);
@@ -4214,17 +5484,17 @@ Handle_Store_Double (ARMul_State * state, ARMword instr)
   /* Load the words.  */
   ARMul_StoreWordN (state, addr, state->Reg[src_reg]);
   ARMul_StoreWordN (state, addr + 4, state->Reg[src_reg + 1]);
-  
+
   if (state->Aborted)
     {
       TAKEABORT;
       return;
     }
-  
+
   /* Do the post addressing and writeback.  */
   if (! pre_indexed)
     addr = sum;
-  
+
   if (! pre_indexed || write_back)
     state->Reg[addr_reg] = addr;
 }
@@ -4288,7 +5558,6 @@ StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address)
       TAKEABORT;
       return state->lateabtSig;
     }
-
   return TRUE;
 }
 
@@ -4318,7 +5587,7 @@ StoreByte (ARMul_State * state, ARMword instr, ARMword address)
   if (state->Aborted)
     {
       TAKEABORT;
-      return (state->lateabtSig);
+      return state->lateabtSig;
     }
   UNDEF_LSRBPC;
   return TRUE;
@@ -4327,7 +5596,7 @@ StoreByte (ARMul_State * state, ARMword instr, ARMword address)
 /* This function does the work of loading the registers listed in an LDM
    instruction, when the S bit is clear.  The code here is always increment
    after, it's up to the caller to get the input address correct and to
-   handle base register modification.a  */
+   handle base register modification.  */
 
 static void
 LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
@@ -4345,8 +5614,9 @@ LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
   if (BIT (21) && LHSReg != 15)
     LSBase = WBBase;
 
+  /* N cycle first.  */
   for (temp = 0; !BIT (temp); temp++)
-    ;  /* N cycle first */
+    ;
 
   dest = ARMul_LoadWordN (state, address);
 
@@ -4358,9 +5628,11 @@ LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
       state->Aborted = ARMul_DataAbortV;
     }
 
-  for (; temp < 16; temp++)    /* S cycles from here on */
+  /* S cycles from here on.  */
+  for (; temp < 16; temp ++)
     if (BIT (temp))
-      {                                /* load this register */
+      {
+       /* Load this register.  */
        address += 4;
        dest = ARMul_LoadWordS (state, address);
 
@@ -4375,7 +5647,7 @@ LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
 
   if (BIT (15) && !state->Aborted)
     /* PC is in the reg list.  */
-    WriteR15Branch (state, PC);
+    WriteR15Load (state, PC);
 
   /* To write back the final register.  */
   ARMul_Icycles (state, 1, 0L);
@@ -4422,8 +5694,9 @@ LoadSMult (ARMul_State * state,
       UNDEF_LSMUserBankWb;
     }
 
+  /* N cycle first.  */
   for (temp = 0; !BIT (temp); temp ++)
-    ;  /* N cycle first.  */
+    ;
 
   dest = ARMul_LoadWordN (state, address);
 
@@ -4431,12 +5704,12 @@ LoadSMult (ARMul_State * state,
     state->Reg[temp++] = dest;
   else if (!state->Aborted)
     {
-      XScale_set_fsr_far(state, ARMul_CP15_R5_ST_ALIGN, address);
+      XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
       state->Aborted = ARMul_DataAbortV;
     }
 
+  /* S cycles from here on.  */
   for (; temp < 16; temp++)
-    /* S cycles from here on.  */
     if (BIT (temp))
       {
        /* Load this register.  */
@@ -4447,7 +5720,7 @@ LoadSMult (ARMul_State * state,
          state->Reg[temp] = dest;
        else if (!state->Aborted)
          {
-            XScale_set_fsr_far(state, ARMul_CP15_R5_ST_ALIGN, address);
+            XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
            state->Aborted = ARMul_DataAbortV;
          }
       }
@@ -4501,8 +5774,10 @@ LoadSMult (ARMul_State * state,
    handle base register modification.  */
 
 static void
-StoreMult (ARMul_State * state, ARMword instr,
-          ARMword address, ARMword WBBase)
+StoreMult (ARMul_State * state,
+          ARMword instr,
+          ARMword address,
+          ARMword WBBase)
 {
   ARMword temp;
 
@@ -4522,8 +5797,9 @@ StoreMult (ARMul_State * state, ARMword instr,
     PATCHR15;
 #endif
 
-  for (temp = 0; !BIT (temp); temp++)
-    ;  /* N cycle first.  */
+  /* N cycle first.  */
+  for (temp = 0; !BIT (temp); temp ++)
+    ;
 
 #ifdef MODE32
   ARMul_StoreWordN (state, address, state->Reg[temp++]);
@@ -4540,6 +5816,7 @@ StoreMult (ARMul_State * state, ARMword instr,
            address += 4;
            (void) ARMul_LoadWordS (state, address);
          }
+
       if (BIT (21) && LHSReg != 15)
        LSBase = WBBase;
       TAKEABORT;
@@ -4551,14 +5828,15 @@ StoreMult (ARMul_State * state, ARMword instr,
 
   if (state->abortSig && !state->Aborted)
     {
-      XScale_set_fsr_far(state, ARMul_CP15_R5_ST_ALIGN, address);
+      XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
       state->Aborted = ARMul_DataAbortV;
     }
 
   if (BIT (21) && LHSReg != 15)
     LSBase = WBBase;
 
-  for (; temp < 16; temp++)    /* S cycles from here on */
+  /* S cycles from here on.  */
+  for (; temp < 16; temp ++)
     if (BIT (temp))
       {
        /* Save this register.  */
@@ -4568,7 +5846,7 @@ StoreMult (ARMul_State * state, ARMword instr,
 
        if (state->abortSig && !state->Aborted)
          {
-            XScale_set_fsr_far(state, ARMul_CP15_R5_ST_ALIGN, address);
+            XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
            state->Aborted = ARMul_DataAbortV;
          }
       }
@@ -4613,7 +5891,7 @@ StoreSMult (ARMul_State * state,
 
   for (temp = 0; !BIT (temp); temp++)
     ;  /* N cycle first.  */
-  
+
 #ifdef MODE32
   ARMul_StoreWordN (state, address, state->Reg[temp++]);
 #else
@@ -4635,7 +5913,6 @@ StoreSMult (ARMul_State * state,
        LSBase = WBBase;
 
       TAKEABORT;
-
       return;
     }
   else
@@ -4644,12 +5921,12 @@ StoreSMult (ARMul_State * state,
 
   if (state->abortSig && !state->Aborted)
     {
-      XScale_set_fsr_far(state, ARMul_CP15_R5_ST_ALIGN, address);
+      XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
       state->Aborted = ARMul_DataAbortV;
     }
 
+  /* S cycles from here on.  */
   for (; temp < 16; temp++)
-    /* S cycles from here on.  */
     if (BIT (temp))
       {
        /* Save this register.  */
@@ -4659,7 +5936,7 @@ StoreSMult (ARMul_State * state,
 
        if (state->abortSig && !state->Aborted)
          {
-            XScale_set_fsr_far(state, ARMul_CP15_R5_ST_ALIGN, address);
+            XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
            state->Aborted = ARMul_DataAbortV;
          }
       }
@@ -4686,13 +5963,13 @@ Add32 (ARMword a1, ARMword a2, int *carry)
   unsigned int ua1 = (unsigned int) a1;
 
   /* If (result == RdLo) and (state->Reg[nRdLo] == 0),
-     or (result > RdLo) then we have no carry: */
+     or (result > RdLo) then we have no carry */
   if ((uresult == ua1) ? (a2 != 0) : (uresult < ua1))
     *carry = 1;
   else
     *carry = 0;
 
-  return (result);
+  return result;
 }
 
 /* This function does the work of multiplying
@@ -4720,9 +5997,7 @@ Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
       && nRdLo != 15
       && nRs   != 15
       && nRm   != 15
-      && nRdHi != nRdLo
-      && nRdHi != nRm
-      && nRdLo != nRm)
+      && nRdHi != nRdLo)
     {
       /* Intermediate results.  */
       ARMword lo, mid1, mid2, hi;
@@ -4730,16 +6005,24 @@ Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
       ARMword Rs = state->Reg[nRs];
       int sign = 0;
 
+#ifdef MODE32
+      if (state->is_v6)
+       ;
+      else
+#endif
+       /* 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.  */
-
          sign = (Rm ^ Rs) & 0x80000000;
 
-         if (((signed long) Rm) < 0)
+         if (((ARMsword) Rm) < 0)
            Rm = -Rm;
 
-         if (((signed long) Rs) < 0)
+         if (((ARMsword) Rs) < 0)
            Rs = -Rs;
        }
 
@@ -4761,7 +6044,6 @@ Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
       if (sign)
        {
          /* Negate result if necessary.  */
-
          RdLo = ~RdLo;
          RdHi = ~RdHi;
          if (RdLo == 0xFFFFFFFF)
@@ -4772,20 +6054,17 @@ Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
          else
            RdLo += 1;
        }
-      /* Else undefined result.  */
 
       state->Reg[nRdLo] = RdLo;
       state->Reg[nRdHi] = RdHi;
     }
-  else
+  else if (state->Debug)
     fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS\n");
 
   if (scc)
-    {
-      /* Ensure that both RdHi and RdLo are used to compute Z,
-        but don't let RdLo's sign bit make it to N.  */
-      ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
-    }
+    /* Ensure that both RdHi and RdLo are used to compute Z,
+       but don't let RdLo's sign bit make it to N.  */
+    ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
 
   /* The cycle count depends on whether the instruction is a signed or
      unsigned multiply, and what bits are clear in the multiplier.  */