gdb: Convert language la_value_print field to a method
[deliverable/binutils-gdb.git] / sim / arm / armemu.c
index a7923d42db7ba3e126bb4e200a59060df523bdfa..3a72277683e62b40f367e50e29815e98cd9d4891 100644 (file)
 /*  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"
-
-static ARMword GetDPRegRHS (ARMul_State * state, ARMword instr);
-static ARMword GetDPSRegRHS (ARMul_State * state, ARMword instr);
-static void WriteR15 (ARMul_State * state, ARMword src);
-static void WriteSR15 (ARMul_State * state, ARMword src);
-static void WriteR15Branch (ARMul_State * state, ARMword src);
-static ARMword GetLSRegRHS (ARMul_State * state, ARMword instr);
-static ARMword GetLS7RHS (ARMul_State * state, ARMword instr);
-static unsigned LoadWord (ARMul_State * state, ARMword instr,
-                         ARMword address);
-static unsigned LoadHalfWord (ARMul_State * state, ARMword instr,
-                             ARMword address, int signextend);
-static unsigned LoadByte (ARMul_State * state, ARMword instr, ARMword address,
-                         int signextend);
-static unsigned StoreWord (ARMul_State * state, ARMword instr,
-                          ARMword address);
-static unsigned StoreHalfWord (ARMul_State * state, ARMword instr,
-                              ARMword address);
-static unsigned StoreByte (ARMul_State * state, ARMword instr,
-                          ARMword address);
-static void LoadMult (ARMul_State * state, ARMword address, ARMword instr,
-                     ARMword WBBase);
-static void StoreMult (ARMul_State * state, ARMword address, ARMword instr,
-                      ARMword WBBase);
-static void LoadSMult (ARMul_State * state, ARMword address, ARMword instr,
-                      ARMword WBBase);
-static void StoreSMult (ARMul_State * state, ARMword address, ARMword instr,
-                       ARMword WBBase);
-static unsigned Multiply64 (ARMul_State * state, ARMword instr,
-                           int signextend, int scc);
-static unsigned MultiplyAdd64 (ARMul_State * state, ARMword instr,
-                              int signextend, int scc);
-static void Handle_Load_Double (ARMul_State * state, ARMword instr);
-static void Handle_Store_Double (ARMul_State * state, ARMword instr);
+#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);
+static unsigned LoadHalfWord        (ARMul_State *, ARMword, ARMword, int);
+static unsigned LoadByte            (ARMul_State *, ARMword, ARMword, int);
+static unsigned StoreWord           (ARMul_State *, ARMword, ARMword);
+static unsigned StoreHalfWord       (ARMul_State *, ARMword, ARMword);
+static unsigned StoreByte           (ARMul_State *, ARMword, ARMword);
+static void     LoadMult            (ARMul_State *, ARMword, ARMword, ARMword);
+static void     StoreMult           (ARMul_State *, ARMword, ARMword, ARMword);
+static void     LoadSMult           (ARMul_State *, ARMword, ARMword, ARMword);
+static void     StoreSMult          (ARMul_State *, ARMword, ARMword, ARMword);
+static unsigned Multiply64          (ARMul_State *, ARMword, int, int);
+static unsigned MultiplyAdd64       (ARMul_State *, ARMword, int, int);
+static void     Handle_Load_Double  (ARMul_State *, ARMword);
+static void     Handle_Store_Double (ARMul_State *, ARMword);
 
 #define LUNSIGNED (0)          /* unsigned operation */
 #define LSIGNED   (1)          /* signed operation */
 #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                               *
-\***************************************************************************/
+/* Short-hand macros for LDR/STR.  */
 
-/* store post decrement writeback */
+/* Store post decrement writeback.  */
 #define SHDOWNWB()                                      \
   lhs = LHS ;                                           \
-  if (StoreHalfWord(state, instr, lhs))                 \
-     LSBase = lhs - GetLS7RHS(state, instr) ;
+  if (StoreHalfWord (state, instr, lhs))                \
+     LSBase = lhs - GetLS7RHS (state, instr);
 
-/* store post increment writeback */
+/* Store post increment writeback.  */
 #define SHUPWB()                                        \
   lhs = LHS ;                                           \
-  if (StoreHalfWord(state, instr, lhs))                 \
-     LSBase = lhs + GetLS7RHS(state, instr) ;
+  if (StoreHalfWord (state, instr, lhs))                \
+     LSBase = lhs + GetLS7RHS (state, instr);
 
-/* store pre decrement */
+/* Store pre decrement.  */
 #define SHPREDOWN()                                     \
-  (void)StoreHalfWord(state, instr, LHS - GetLS7RHS(state, instr)) ;
+  (void)StoreHalfWord (state, instr, LHS - GetLS7RHS (state, instr));
 
-/* store pre decrement writeback */
+/* Store pre decrement writeback.  */
 #define SHPREDOWNWB()                                   \
-  temp = LHS - GetLS7RHS(state, instr) ;                \
-  if (StoreHalfWord(state, instr, temp))                \
-     LSBase = temp ;
+  temp = LHS - GetLS7RHS (state, instr);                \
+  if (StoreHalfWord (state, instr, temp))               \
+     LSBase = temp;
 
-/* store pre increment */
+/* Store pre increment.  */
 #define SHPREUP()                                       \
-  (void)StoreHalfWord(state, instr, LHS + GetLS7RHS(state, instr)) ;
+  (void)StoreHalfWord (state, instr, LHS + GetLS7RHS (state, instr));
 
-/* store pre increment writeback */
+/* Store pre increment writeback.  */
 #define SHPREUPWB()                                     \
-  temp = LHS + GetLS7RHS(state, instr) ;                \
-  if (StoreHalfWord(state, instr, temp))                \
-     LSBase = temp ;
+  temp = LHS + GetLS7RHS (state, instr);                \
+  if (StoreHalfWord (state, instr, temp))               \
+     LSBase = temp;
 
 /* Load post decrement writeback.  */
 #define LHPOSTDOWN()                                    \
@@ -168,136 +144,1019 @@ extern int stop_simulator;
      break;                                                    \
 }
 
+/* Load pre decrement.  */
+#define LHPREDOWN()                                            \
+{                                                              \
+  int done = 1;                                                        \
+                                                               \
+  temp = LHS - GetLS7RHS (state, instr);                       \
+  switch (BITS (5, 6))                                         \
+    {                                                                  \
+    case 1: /* H */                                            \
+      (void) LoadHalfWord (state, instr, temp, LUNSIGNED);     \
+      break;                                                           \
+    case 2: /* SB */                                           \
+      (void) LoadByte (state, instr, temp, LSIGNED);           \
+      break;                                                           \
+    case 3: /* SH */                                           \
+      (void) LoadHalfWord (state, instr, temp, LSIGNED);       \
+      break;                                                           \
+    case 0:                                                    \
+      /* SWP handled elsewhere.  */                            \
+    default:                                                   \
+      done = 0;                                                        \
+      break;                                                           \
+    }                                                          \
+  if (done)                                                    \
+     break;                                                            \
+}
 
-/* load pre decrement */
-#define LHPREDOWN()                                     \
-{                                                       \
-  int done = 1 ;                                        \
-  temp = LHS - GetLS7RHS(state,instr) ;                 \
-  switch (BITS(5,6)) {                                  \
-    case 1: /* H */                                     \
-      (void)LoadHalfWord(state,instr,temp,LUNSIGNED) ;  \
-      break ;                                           \
-    case 2: /* SB */                                    \
-      (void)LoadByte(state,instr,temp,LSIGNED) ;        \
-      break ;                                           \
-    case 3: /* SH */                                    \
-      (void)LoadHalfWord(state,instr,temp,LSIGNED) ;    \
-      break ;                                           \
-    case 0: /* SWP handled elsewhere */                 \
-    default:                                            \
-      done = 0 ;                                        \
-      break ;                                           \
-    }                                                   \
-  if (done)                                             \
-     break ;                                            \
+/* Load pre decrement writeback.  */
+#define LHPREDOWNWB()                                          \
+{                                                              \
+  int done = 1;                                                        \
+                                                               \
+  temp = LHS - GetLS7RHS (state, instr);                       \
+  switch (BITS (5, 6))                                         \
+    {                                                                  \
+    case 1: /* H */                                            \
+      if (LoadHalfWord (state, instr, temp, LUNSIGNED))        \
+         LSBase = temp;                                                \
+      break;                                                           \
+    case 2: /* SB */                                           \
+      if (LoadByte (state, instr, temp, LSIGNED))              \
+         LSBase = temp;                                                \
+      break;                                                           \
+    case 3: /* SH */                                           \
+      if (LoadHalfWord (state, instr, temp, LSIGNED))          \
+         LSBase = temp;                                                \
+      break;                                                           \
+    case 0:                                                    \
+      /* SWP handled elsewhere.  */                            \
+    default:                                                   \
+      done = 0;                                                        \
+      break;                                                           \
+    }                                                          \
+  if (done)                                                    \
+     break;                                                            \
 }
 
-/* load pre decrement writeback */
-#define LHPREDOWNWB()                                   \
-{                                                       \
-  int done = 1 ;                                        \
-  temp = LHS - GetLS7RHS(state, instr) ;                \
-  switch (BITS(5,6)) {                                  \
-    case 1: /* H */                                     \
-      if (LoadHalfWord(state,instr,temp,LUNSIGNED))     \
-         LSBase = temp ;                                \
-      break ;                                           \
-    case 2: /* SB */                                    \
-      if (LoadByte(state,instr,temp,LSIGNED))           \
-         LSBase = temp ;                                \
-      break ;                                           \
-    case 3: /* SH */                                    \
-      if (LoadHalfWord(state,instr,temp,LSIGNED))       \
-         LSBase = temp ;                                \
-      break ;                                           \
-    case 0: /* SWP handled elsewhere */                 \
-    default:                                            \
-      done = 0 ;                                        \
-      break ;                                           \
-    }                                                   \
-  if (done)                                             \
-     break ;                                            \
+/* Load pre increment.  */
+#define LHPREUP()                                              \
+{                                                              \
+  int done = 1;                                                        \
+                                                               \
+  temp = LHS + GetLS7RHS (state, instr);                       \
+  switch (BITS (5, 6))                                         \
+    {                                                                  \
+    case 1: /* H */                                            \
+      (void) LoadHalfWord (state, instr, temp, LUNSIGNED);     \
+      break;                                                           \
+    case 2: /* SB */                                           \
+      (void) LoadByte (state, instr, temp, LSIGNED);           \
+      break;                                                           \
+    case 3: /* SH */                                           \
+      (void) LoadHalfWord (state, instr, temp, LSIGNED);       \
+      break;                                                           \
+    case 0:                                                    \
+      /* SWP handled elsewhere.  */                            \
+    default:                                                   \
+      done = 0;                                                        \
+      break;                                                           \
+    }                                                          \
+  if (done)                                                    \
+     break;                                                            \
 }
 
-/* load pre increment */
-#define LHPREUP()                                       \
-{                                                       \
-  int done = 1 ;                                        \
-  temp = LHS + GetLS7RHS(state,instr) ;                 \
-  switch (BITS(5,6)) {                                  \
-    case 1: /* H */                                     \
-      (void)LoadHalfWord(state,instr,temp,LUNSIGNED) ;  \
-      break ;                                           \
-    case 2: /* SB */                                    \
-      (void)LoadByte(state,instr,temp,LSIGNED) ;        \
-      break ;                                           \
-    case 3: /* SH */                                    \
-      (void)LoadHalfWord(state,instr,temp,LSIGNED) ;    \
-      break ;                                           \
-    case 0: /* SWP handled elsewhere */                 \
-    default:                                            \
-      done = 0 ;                                        \
-      break ;                                           \
-    }                                                   \
-  if (done)                                             \
-     break ;                                            \
+/* Load pre increment writeback.  */
+#define LHPREUPWB()                                            \
+{                                                              \
+  int done = 1;                                                        \
+                                                               \
+  temp = LHS + GetLS7RHS (state, instr);                       \
+  switch (BITS (5, 6))                                         \
+    {                                                                  \
+    case 1: /* H */                                            \
+      if (LoadHalfWord (state, instr, temp, LUNSIGNED))        \
+       LSBase = temp;                                          \
+      break;                                                           \
+    case 2: /* SB */                                           \
+      if (LoadByte (state, instr, temp, LSIGNED))              \
+       LSBase = temp;                                          \
+      break;                                                           \
+    case 3: /* SH */                                           \
+      if (LoadHalfWord (state, instr, temp, LSIGNED))          \
+       LSBase = temp;                                          \
+      break;                                                           \
+    case 0:                                                    \
+      /* SWP handled elsewhere.  */                            \
+    default:                                                   \
+      done = 0;                                                        \
+      break;                                                           \
+    }                                                          \
+  if (done)                                                    \
+     break;                                                            \
 }
 
-/* load pre increment writeback */
-#define LHPREUPWB()                                     \
-{                                                       \
-  int done = 1 ;                                        \
-  temp = LHS + GetLS7RHS(state, instr) ;                \
-  switch (BITS(5,6)) {                                  \
-    case 1: /* H */                                     \
-      if (LoadHalfWord(state,instr,temp,LUNSIGNED))     \
-         LSBase = temp ;                                \
-      break ;                                           \
-    case 2: /* SB */                                    \
-      if (LoadByte(state,instr,temp,LSIGNED))           \
-         LSBase = temp ;                                \
-      break ;                                           \
-    case 3: /* SH */                                    \
-      if (LoadHalfWord(state,instr,temp,LSIGNED))       \
-         LSBase = temp ;                                \
-      break ;                                           \
-    case 0: /* SWP handled elsewhere */                 \
-    default:                                            \
-      done = 0 ;                                        \
-      break ;                                           \
-    }                                                   \
-  if (done)                                             \
-     break ;                                            \
+/* 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 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;
+      }
+
+    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;
 
-/***************************************************************************\
-*                             EMULATION of ARM6                             *
-\***************************************************************************/
+       default:
+         fprintf (stderr, "SIM: VFP: Unimplemented move insn %x\n", BITS (20, 27));
+         break;
+       }
+      break;
 
-/* The PC pipeline value depends on whether ARM or Thumb instructions
-   are being executed: */
-ARMword isize;
+    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.  */
 
-#ifdef MODE32
 ARMword
-ARMul_Emulate32 (register ARMul_State * state)
-{
+#ifdef MODE32
+ARMul_Emulate32 (ARMul_State * state)
 #else
-ARMword
-ARMul_Emulate26 (register ARMul_State * state)
-{
+ARMul_Emulate26 (ARMul_State * state)
 #endif
-  register ARMword instr,      /* the current instruction */
-    dest = 0,                  /* almost the DestBus */
-    temp,                      /* ubiquitous third hand */
-    pc = 0;                    /* the address of the current instruction */
-  ARMword lhs, rhs;            /* almost the ABus and BBus */
-  ARMword decoded = 0, loaded = 0;     /* instruction pipeline */
+{
+  ARMword instr;       /* The current instruction.  */
+  ARMword dest = 0;    /* Almost the DestBus.  */
+  ARMword temp;                /* Ubiquitous third hand.  */
+  ARMword pc = 0;      /* The address of the current instruction.  */
+  ARMword lhs;         /* Almost the ABus and BBus.  */
+  ARMword rhs;
+  ARMword decoded = 0; /* Instruction pipeline.  */
+  ARMword loaded = 0;  
 
-/***************************************************************************\
-*                        Execute the next instruction                       *
-\***************************************************************************/
+  /* Execute the next instruction.  */
 
   if (state->NextInstr < PRIMEPIPE)
     {
@@ -307,12 +1166,15 @@ ARMul_Emulate26 (register ARMul_State * state)
     }
 
   do
-    {                          /* just keep going */
+    {
+      /* Just keep going.  */
       isize = INSN_SIZE;
+
       switch (state->NextInstr)
        {
        case SEQ:
-         state->Reg[15] += isize;      /* Advance the pipeline, and an S cycle */
+         /* Advance the pipeline, and an S cycle.  */
+         state->Reg[15] += isize;
          pc += isize;
          instr = decoded;
          decoded = loaded;
@@ -320,7 +1182,8 @@ ARMul_Emulate26 (register ARMul_State * state)
          break;
 
        case NONSEQ:
-         state->Reg[15] += isize;      /* Advance the pipeline, and an N cycle */
+         /* Advance the pipeline, and an N cycle.  */
+         state->Reg[15] += isize;
          pc += isize;
          instr = decoded;
          decoded = loaded;
@@ -329,7 +1192,8 @@ ARMul_Emulate26 (register ARMul_State * state)
          break;
 
        case PCINCEDSEQ:
-         pc += isize;          /* Program counter advanced, and an S cycle */
+         /* Program counter advanced, and an S cycle.  */
+         pc += isize;
          instr = decoded;
          decoded = loaded;
          loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
@@ -337,51 +1201,75 @@ ARMul_Emulate26 (register ARMul_State * state)
          break;
 
        case PCINCEDNONSEQ:
-         pc += isize;          /* Program counter advanced, and an N cycle */
+         /* Program counter advanced, and an N cycle.  */
+         pc += isize;
          instr = decoded;
          decoded = loaded;
          loaded = ARMul_LoadInstrN (state, pc + (isize * 2), isize);
          NORMALCYCLE;
          break;
 
-       case RESUME:            /* The program counter has been changed */
+       case RESUME:
+         /* The program counter has been changed.  */
          pc = state->Reg[15];
 #ifndef MODE32
          pc = pc & R15PCBITS;
 #endif
          state->Reg[15] = pc + (isize * 2);
          state->Aborted = 0;
-         instr = ARMul_ReLoadInstr (state, pc, isize);
+         instr   = ARMul_ReLoadInstr (state, pc, isize);
          decoded = ARMul_ReLoadInstr (state, pc + isize, isize);
-         loaded = ARMul_ReLoadInstr (state, pc + isize * 2, isize);
+         loaded  = ARMul_ReLoadInstr (state, pc + isize * 2, isize);
          NORMALCYCLE;
          break;
 
-       default:                /* The program counter has been changed */
+       default:
+         /* The program counter has been changed.  */
          pc = state->Reg[15];
 #ifndef MODE32
          pc = pc & R15PCBITS;
 #endif
          state->Reg[15] = pc + (isize * 2);
          state->Aborted = 0;
-         instr = ARMul_LoadInstrN (state, pc, isize);
+         instr   = ARMul_LoadInstrN (state, pc, isize);
          decoded = ARMul_LoadInstrS (state, pc + (isize), isize);
-         loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
+         loaded  = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
          NORMALCYCLE;
          break;
        }
+
       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)
-       {                       /* Any exceptions */
+       {
+         /* Any exceptions ?  */
          if (state->NresetSig == LOW)
            {
              ARMul_Abort (state, ARMul_ResetV);
@@ -401,7 +1289,6 @@ ARMul_Emulate26 (register ARMul_State * state)
 
       if (state->CallDebug > 0)
        {
-         instr = ARMul_Debug (state, pc, instr);
          if (state->Emulate < ONCE)
            {
              state->NextInstr = RESUME;
@@ -409,8 +1296,8 @@ ARMul_Emulate26 (register 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);
            }
        }
@@ -429,34 +1316,52 @@ ARMul_Emulate26 (register ARMul_State * state)
          instr variable, and letting the normal ARM simulator
          execute). There are some caveats to ensure that the correct
          pipelined PC value is used when executing Thumb code, and also for
-         dealing with the BL instruction. */
+         dealing with the BL instruction.  */
       if (TFLAG)
-       {                       /* check if in Thumb mode */
+       {
          ARMword new;
+
+         /* Check if in Thumb mode.  */
          switch (ARMul_ThumbDecode (state, pc, instr, &new))
            {
            case t_undefined:
-             ARMul_UndefInstr (state, instr);  /* This is a Thumb instruction */
+             /* This is a Thumb instruction.  */
+             ARMul_UndefInstr (state, instr);
              goto donext;
 
-           case t_branch:      /* already processed */
+           case t_branch:
+             /* Already processed.  */
              goto donext;
 
-           case t_decoded:     /* ARM instruction available */
-             instr = new;      /* so continue instruction decoding */
+           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;
+           default:
              break;
            }
        }
 #endif
+      if (disas)
+       print_insn (instr);
 
-/***************************************************************************\
-*                       Check the condition codes                           *
-\***************************************************************************/
+      /* Check the condition codes.  */
       if ((temp = TOPBITS (28)) == AL)
-       goto mainswitch;        /* vile deed in the need for speed */
+       /* Vile deed in the need for speed.  */
+       goto mainswitch;
 
+      /* Check the condition code.  */
       switch ((int) TOPBITS (28))
-       {                       /* check the condition code */
+       {
        case AL:
          temp = TRUE;
          break;
@@ -466,21 +1371,26 @@ ARMul_Emulate26 (register 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);
@@ -531,12 +1441,96 @@ ARMul_Emulate26 (register ARMul_State * state)
          break;
        }                       /* cc check */
 
-/***************************************************************************\
-*               Actual execution of instructions begins here                *
-\***************************************************************************/
+      /* Handle the Clock counter here.  */
+      if (state->is_XScale)
+       {
+         ARMword cp14r0;
+         int ok;
+
+         ok = state->CPRead[14] (state, 0, & cp14r0);
+
+         if (ok && (cp14r0 & ARMul_CP14_R0_ENABLE))
+           {
+             unsigned long newcycles, nowtime = ARMul_Time (state);
+
+             newcycles = nowtime - state->LastTime;
+             state->LastTime = nowtime;
+
+             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;
+
+                 state->CP14R0_CCD = -1;
+check_PMUintr:
+                 do_int = 0;
+                 cp14r0 |= ARMul_CP14_R0_FLAG2;
+                 (void) state->CPWrite[14] (state, 0, cp14r0);
+
+                 ok = state->CPRead[14] (state, 1, & cp14r1);
+
+                 /* Coded like this for portability.  */
+                 while (ok && newcycles)
+                   {
+                     if (cp14r1 == 0xffffffff)
+                       {
+                         cp14r1 = 0;
+                         do_int = 1;
+                       }
+                     else
+                       cp14r1 ++;
+
+                     newcycles --;
+                   }
+
+                 (void) state->CPWrite[14] (state, 1, cp14r1);
+
+                 if (do_int && (cp14r0 & ARMul_CP14_R0_INTEN2))
+                   {
+                     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);
+                   }
+               }
+           }
+       }
+
+      /* 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 (XScale_debug_moe (state, ARMul_CP14_R10_MOE_IB))
+               ARMul_OSHandleSWI (state, SWI_Breakpoint);
+           }
+       }
 
+      /* 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)
@@ -548,8 +1542,8 @@ ARMul_Emulate26 (register ARMul_State * state)
                      /* XScale Load Consecutive insn.  */
                      ARMword temp = GetLS7RHS (state, instr);
                      ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
-                     ARMword addr = BIT (24) ? temp2 : temp;
-                     
+                     ARMword addr = BIT (24) ? temp2 : LHS;
+
                      if (BIT (12))
                        ARMul_UndefInstr (state, instr);
                      else if (addr & 7)
@@ -557,14 +1551,14 @@ ARMul_Emulate26 (register ARMul_State * state)
                        ARMul_Abort (state, ARMul_DataAbortV);
                      else
                        {
-                         int wb = BIT (24) && BIT (21);
-                         
+                         int wb = BIT (21) || (! BIT (24));
+
                          state->Reg[BITS (12, 15)] =
                            ARMul_LoadWordN (state, addr);
                          state->Reg[BITS (12, 15) + 1] =
                            ARMul_LoadWordN (state, addr + 4);
                          if (wb)
-                           LSBase = addr;
+                           LSBase = temp2;
                        }
 
                      goto donext;
@@ -574,7 +1568,7 @@ ARMul_Emulate26 (register ARMul_State * state)
                      /* XScale Store Consecutive insn.  */
                      ARMword temp = GetLS7RHS (state, instr);
                      ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
-                     ARMword addr = BIT (24) ? temp2 : temp;
+                     ARMword addr = BIT (24) ? temp2 : LHS;
 
                      if (BIT (12))
                        ARMul_UndefInstr (state, instr);
@@ -588,27 +1582,27 @@ ARMul_Emulate26 (register ARMul_State * state)
                          ARMul_StoreWordN (state, addr + 4,
                                            state->Reg[BITS (12, 15) + 1]);
 
-                         if (BIT (21))
-                           LSBase = addr;
+                         if (BIT (21)|| ! BIT (24))
+                           LSBase = temp2;
                        }
 
                      goto donext;
                    }
                }
+
+             if (ARMul_HandleIwmmxt (state, instr))
+               goto donext;
            }
 
          switch ((int) BITS (20, 27))
            {
-
-/***************************************************************************\
-*                 Data Processing Register RHS Instructions                 *
-\***************************************************************************/
+             /* Data Processing Register RHS Instructions.  */
 
            case 0x00:          /* AND reg and MUL */
 #ifdef MODET
              if (BITS (4, 11) == 0xB)
                {
-                 /* STRH register offset, no write-back, down, post indexed */
+                 /* STRH register offset, no write-back, down, post indexed */
                  SHDOWNWB ();
                  break;
                }
@@ -624,7 +1618,8 @@ ARMul_Emulate26 (register ARMul_State * state)
                }
 #endif
              if (BITS (4, 7) == 9)
-               {               /* MUL */
+               {
+                 /* MUL */
                  rhs = state->Reg[MULRHSReg];
                  if (MULLHSReg == MULDESTReg)
                    {
@@ -634,16 +1629,18 @@ ARMul_Emulate26 (register ARMul_State * state)
                  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);
@@ -653,15 +1650,15 @@ ARMul_Emulate26 (register ARMul_State * state)
            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;
@@ -676,16 +1673,18 @@ ARMul_Emulate26 (register ARMul_State * state)
                      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);
@@ -696,7 +1695,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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;
                }
@@ -713,12 +1712,13 @@ ARMul_Emulate26 (register ARMul_State * state)
                    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
@@ -732,15 +1732,15 @@ ARMul_Emulate26 (register ARMul_State * state)
            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;
@@ -756,16 +1756,18 @@ ARMul_Emulate26 (register ARMul_State * state)
                      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);
@@ -776,7 +1778,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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;
                }
@@ -799,15 +1801,14 @@ ARMul_Emulate26 (register ARMul_State * state)
            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);
@@ -825,7 +1826,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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;
                }
@@ -838,15 +1839,14 @@ ARMul_Emulate26 (register ARMul_State * state)
            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);
@@ -864,7 +1864,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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;
                }
@@ -881,7 +1881,8 @@ ARMul_Emulate26 (register ARMul_State * state)
 #endif
 #ifdef MODET
              if (BITS (4, 7) == 0x9)
-               {               /* MULL */
+               {
+                 /* MULL */
                  /* 32x32 = 64 */
                  ARMul_Icycles (state,
                                 Multiply64 (state, instr, LUNSIGNED,
@@ -897,15 +1898,14 @@ ARMul_Emulate26 (register ARMul_State * state)
            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),
@@ -918,7 +1918,8 @@ ARMul_Emulate26 (register ARMul_State * state)
              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);
@@ -936,14 +1937,13 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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,
@@ -959,15 +1959,12 @@ ARMul_Emulate26 (register ARMul_State * state)
            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,
@@ -980,7 +1977,8 @@ ARMul_Emulate26 (register ARMul_State * state)
              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);
@@ -998,7 +1996,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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;
                }
@@ -1012,10 +2010,9 @@ ARMul_Emulate26 (register ARMul_State * state)
                  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),
@@ -1031,14 +2028,12 @@ ARMul_Emulate26 (register ARMul_State * state)
            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),
@@ -1066,14 +2061,14 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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,
@@ -1089,15 +2084,13 @@ ARMul_Emulate26 (register ARMul_State * state)
            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),
@@ -1108,6 +2101,7 @@ ARMul_Emulate26 (register ARMul_State * state)
              lhs = LHS;
              rhs = DPRegRHS;
              dest = rhs - lhs - !CFLAG;
+
              if ((rhs >= lhs) || ((rhs | lhs) >> 31))
                {
                  ARMul_SubCarry (state, rhs, lhs, dest);
@@ -1121,7 +2115,7 @@ ARMul_Emulate26 (register ARMul_State * state)
              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)
@@ -1130,7 +2124,7 @@ ARMul_Emulate26 (register ARMul_State * state)
                      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))
@@ -1142,7 +2136,7 @@ ARMul_Emulate26 (register ARMul_State * state)
                      if (op2 & 0x8000)
                        op2 -= 65536;
                      op1 *= op2;
-                     
+
                      if (AddOverflow (op1, Rn, op1 + Rn))
                        SETS;
                      state->Reg[BITS (16, 19)] = op1 + Rn;
@@ -1167,7 +2161,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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;
                }
@@ -1183,7 +2177,8 @@ ARMul_Emulate26 (register ARMul_State * state)
                }
 #endif
              if (BITS (4, 11) == 9)
-               {               /* SWP */
+               {
+                 /* SWP */
                  UNDEF_SWPPC;
                  temp = LHS;
                  BUSUSEDINCPCS;
@@ -1202,9 +2197,7 @@ ARMul_Emulate26 (register ARMul_State * state)
                  else
                    DEST = dest;
                  if (state->abortSig || state->Aborted)
-                   {
-                     TAKEABORT;
-                   }
+                   TAKEABORT;
                }
              else if ((BITS (0, 11) == 0) && (LHSReg == 15))
                {               /* MRS CPSR */
@@ -1213,6 +2206,11 @@ ARMul_Emulate26 (register ARMul_State * state)
                }
              else
                {
+#ifdef MODE32
+                 if (state->is_v6
+                     && handle_v6_insn (state, instr))
+                   break;
+#endif
                  UNDEF_Test;
                }
              break;
@@ -1220,14 +2218,13 @@ ARMul_Emulate26 (register ARMul_State * state)
            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);
@@ -1238,14 +2235,15 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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)
@@ -1270,9 +2268,9 @@ ARMul_Emulate26 (register ARMul_State * state)
                      && (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;
@@ -1286,7 +2284,7 @@ ARMul_Emulate26 (register ARMul_State * state)
                      if (BIT (5) == 0)
                        {
                          ARMword Rn = state->Reg[BITS (12, 15)];
-                         
+
                          if (AddOverflow (result, Rn, result + Rn))
                            SETS;
                          result += Rn;
@@ -1315,7 +2313,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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;
                }
@@ -1340,7 +2338,6 @@ ARMul_Emulate26 (register ARMul_State * state)
                {
                  if (BITS (4, 7) == 0x7)
                    {
-                     ARMword value;
                      extern int SWI_vector_installed;
 
                      /* Hardware is allowed to optionally override this
@@ -1356,35 +2353,22 @@ ARMul_Emulate26 (register ARMul_State * state)
                      if (! SWI_vector_installed)
                        ARMul_OSHandleSWI (state, SWI_Breakpoint);
                      else
-                   
-                       /* BKPT - normally this will cause an abort, but for the
-                          XScale if bit 31 in register 10 of coprocessor 14 is
-                          clear, then this is treated as a no-op.  */
-                       if (state->is_XScale)
-                         {
-                           if (read_cp14_reg (10) & (1UL << 31))
-                             {
-                               ARMword value;
-                               
-                               value = read_cp14_reg (10);
-                               value &= ~0x1c;
-                               value |= 0xc;
-                               
-                               write_cp14_reg (10, value);
-                               write_cp15_reg (5, 0, 0, 0x200);  /* Set FSR.  */
-                               write_cp15_reg (6, 0, 0, pc);     /* Set FAR.  */
-                             }
-                           else
-                             break;
-                         }
-
-                     ARMul_Abort (state, ARMul_PrefetchAbortV);
+                       {
+                         /* 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;
+                       }
+
+                     /* Force the next instruction to be refetched.  */
+                     state->NextInstr = RESUME;
                      break;
                    }
                }
              if (DESTReg == 15)
                {
-                 /* MSR reg to CPSR */
+                 /* MSR reg to CPSR */
                  UNDEF_MSRPC;
                  temp = DPRegRHS;
 #ifdef MODET
@@ -1393,23 +2377,26 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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);
@@ -1420,23 +2407,23 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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;
@@ -1449,7 +2436,7 @@ ARMul_Emulate26 (register ARMul_State * state)
                      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;
@@ -1485,7 +2472,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 #ifdef MODET
              if (BITS (4, 7) == 0xB)
                {
-                 /* STRH immediate offset, no write-back, down, pre indexed */
+                 /* STRH immediate offset, no write-back, down, pre indexed */
                  SHPREDOWN ();
                  break;
                }
@@ -1501,7 +2488,8 @@ ARMul_Emulate26 (register ARMul_State * state)
                }
 #endif
              if (BITS (4, 11) == 9)
-               {               /* SWP */
+               {
+                 /* SWP */
                  UNDEF_SWPPC;
                  temp = LHS;
                  BUSUSEDINCPCS;
@@ -1516,32 +2504,34 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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);
@@ -1552,7 +2542,8 @@ ARMul_Emulate26 (register ARMul_State * state)
 #endif
                }
              else
-               {               /* CMP reg */
+               {
+                 /* CMP reg.  */
                  lhs = LHS;
                  rhs = DPRegRHS;
                  dest = lhs - rhs;
@@ -1578,7 +2569,6 @@ ARMul_Emulate26 (register ARMul_State * state)
                      /* 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;
@@ -1640,7 +2630,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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;
                }
@@ -1656,12 +2646,18 @@ ARMul_Emulate26 (register ARMul_State * state)
                }
 #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;
@@ -1669,11 +2665,9 @@ ARMul_Emulate26 (register ARMul_State * state)
            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)
                {
@@ -1688,13 +2682,15 @@ ARMul_Emulate26 (register ARMul_State * state)
                  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);
@@ -1712,7 +2708,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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;
                }
@@ -1735,11 +2731,9 @@ ARMul_Emulate26 (register ARMul_State * state)
            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;
@@ -1750,7 +2744,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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;
                }
@@ -1772,11 +2766,9 @@ ARMul_Emulate26 (register ARMul_State * state)
            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);
@@ -1786,7 +2778,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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;
                }
@@ -1809,11 +2801,9 @@ ARMul_Emulate26 (register ARMul_State * state)
            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;
@@ -1824,7 +2814,7 @@ ARMul_Emulate26 (register ARMul_State * state)
 #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;
                }
@@ -1846,19 +2836,16 @@ ARMul_Emulate26 (register ARMul_State * state)
            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                 *
-\***************************************************************************/
+
+             /* Data Processing Immediate RHS Instructions.  */
 
            case 0x20:          /* AND immed */
              dest = LHS & DPImmRHS;
@@ -1891,6 +2878,7 @@ ARMul_Emulate26 (register ARMul_State * state)
              lhs = LHS;
              rhs = DPImmRHS;
              dest = lhs - rhs;
+
              if ((lhs >= rhs) || ((rhs | lhs) >> 31))
                {
                  ARMul_SubCarry (state, lhs, rhs, dest);
@@ -1913,6 +2901,7 @@ ARMul_Emulate26 (register ARMul_State * state)
              lhs = LHS;
              rhs = DPImmRHS;
              dest = rhs - lhs;
+
              if ((rhs >= lhs) || ((rhs | lhs) >> 31))
                {
                  ARMul_SubCarry (state, rhs, lhs, dest);
@@ -1936,8 +2925,10 @@ ARMul_Emulate26 (register ARMul_State * state)
              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);
@@ -1962,7 +2953,8 @@ ARMul_Emulate26 (register ARMul_State * state)
              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);
@@ -2020,13 +3012,21 @@ ARMul_Emulate26 (register ARMul_State * state)
              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);
@@ -2037,7 +3037,8 @@ ARMul_Emulate26 (register ARMul_State * state)
                }
              else
                {
-                 DPSImmRHS;    /* TST immed */
+                 /* TST immed.  */
+                 DPSImmRHS;
                  dest = LHS & rhs;
                  ARMul_NegZero (state, dest);
                }
@@ -2045,18 +3046,21 @@ ARMul_Emulate26 (register ARMul_State * state)
 
            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);
@@ -2073,13 +3077,22 @@ ARMul_Emulate26 (register ARMul_State * state)
                }
              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);
@@ -2091,10 +3104,12 @@ ARMul_Emulate26 (register ARMul_State * state)
                }
              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);
@@ -2109,17 +3124,21 @@ ARMul_Emulate26 (register ARMul_State * state)
              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);
@@ -2131,12 +3150,14 @@ ARMul_Emulate26 (register ARMul_State * state)
                }
              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);
@@ -2150,65 +3171,64 @@ ARMul_Emulate26 (register ARMul_State * state)
                }
              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 */
+             /* Single Data Transfer Immediate RHS Instructions.  */
+
+           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;
@@ -2219,7 +3239,7 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
@@ -2229,19 +3249,19 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
@@ -2251,7 +3271,7 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
@@ -2261,19 +3281,19 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
@@ -2283,7 +3303,7 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
@@ -2293,19 +3313,19 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
@@ -2315,7 +3335,7 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
@@ -2326,15 +3346,15 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
@@ -2342,7 +3362,7 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
@@ -2350,15 +3370,15 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
@@ -2366,7 +3386,7 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
@@ -2374,15 +3394,15 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
@@ -2390,7 +3410,7 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
@@ -2398,15 +3418,15 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
@@ -2414,7 +3434,7 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
@@ -2422,13 +3442,17 @@ ARMul_Emulate26 (register ARMul_State * state)
                LSBase = temp;
              break;
 
-/***************************************************************************\
-*              Single Data Transfer Register RHS Instructions               *
-\***************************************************************************/
 
-           case 0x60:          /* Store Word, No WriteBack, Post Dec, Reg */
+             /* Single Data Transfer Register RHS Instructions.  */
+
+           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;
                }
@@ -2441,9 +3465,14 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2457,9 +3486,14 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2474,9 +3508,14 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
                }
@@ -2492,9 +3531,14 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
                }
@@ -2507,9 +3551,14 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2523,9 +3572,14 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2540,9 +3594,14 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
                }
@@ -2558,9 +3617,14 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
                }
@@ -2573,9 +3637,14 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2589,9 +3658,14 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2606,9 +3680,14 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
                }
@@ -2624,9 +3703,14 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
                }
@@ -2639,9 +3723,14 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2655,9 +3744,14 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2672,9 +3766,14 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
                }
@@ -2691,27 +3790,42 @@ ARMul_Emulate26 (register ARMul_State * state)
              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;
                }
@@ -2724,9 +3838,14 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2739,27 +3858,42 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2772,9 +3906,14 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2787,27 +3926,42 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2820,9 +3974,14 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2835,27 +3994,42 @@ ARMul_Emulate26 (register ARMul_State * state)
                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;
                }
@@ -2868,7 +4042,7 @@ ARMul_Emulate26 (register ARMul_State * state)
                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.
@@ -2879,6 +4053,11 @@ ARMul_Emulate26 (register ARMul_State * state)
                      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;
@@ -2892,158 +4071,155 @@ ARMul_Emulate26 (register ARMul_State * state)
                LSBase = temp;
              break;
 
-/***************************************************************************\
-*                   Multiple Data Transfer Instructions                     *
-\***************************************************************************/
 
-           case 0x80:          /* Store, No WriteBack, Post Dec */
+             /* Multiple Data Transfer Instructions.  */
+
+           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;
 
-/***************************************************************************\
-*                            Branch forward                                 *
-\***************************************************************************/
 
+             /* Branch forward.  */
            case 0xa0:
            case 0xa1:
            case 0xa2:
@@ -3056,10 +4232,8 @@ ARMul_Emulate26 (register ARMul_State * state)
              FLUSHPIPE;
              break;
 
-/***************************************************************************\
-*                           Branch backward                                 *
-\***************************************************************************/
 
+             /* Branch backward.  */
            case 0xa8:
            case 0xa9:
            case 0xaa:
@@ -3072,10 +4246,7 @@ ARMul_Emulate26 (register ARMul_State * state)
              FLUSHPIPE;
              break;
 
-/***************************************************************************\
-*                       Branch and Link forward                             *
-\***************************************************************************/
-
+             /* Branch and Link forward.  */
            case 0xb0:
            case 0xb1:
            case 0xb2:
@@ -3084,19 +4255,19 @@ ARMul_Emulate26 (register ARMul_State * state)
            case 0xb5:
            case 0xb6:
            case 0xb7:
+             /* Put PC into Link.  */
 #ifdef MODE32
-             state->Reg[14] = pc + 4;  /* put PC into Link */
+             state->Reg[14] = pc + 4;
 #else
-             state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;        /* put PC into Link */
+             state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
 #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                            *
-\***************************************************************************/
-
+             /* Branch and Link backward.  */
            case 0xb8:
            case 0xb9:
            case 0xba:
@@ -3105,242 +4276,284 @@ ARMul_Emulate26 (register ARMul_State * state)
            case 0xbd:
            case 0xbe:
            case 0xbf:
+             /* Put PC into Link.  */
 #ifdef MODE32
-             state->Reg[14] = pc + 4;  /* put PC into Link */
+             state->Reg[14] = pc + 4;
 #else
-             state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;        /* put PC into Link */
+             state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
 #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                        *
-\***************************************************************************/
-
+             /* Co-Processor Data Transfers.  */
            case 0xc4:
-             if (state->is_XScale)
+             if (state->is_v5)
                {
-                 if (BITS (4, 7) != 0x00)
+                 if (CPNum == 10 || CPNum == 11)
+                   handle_VFP_move (state, instr);
+                 /* Reading from R15 is UNPREDICTABLE.  */
+                 else if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
                    ARMul_UndefInstr (state, instr);
-
-                 if (BITS (8, 11) != 0x00)
-                   ARMul_UndefInstr (state, instr); /* Not CP0.  */
-
-                 /* XScale MAR insn.  Move two registers into accumulator.  */
-                 if (BITS (0, 3) == 0x00)
+                 /* Is access to coprocessor 0 allowed ?  */
+                 else if (! CP_ACCESS_ALLOWED (state, CPNum))
+                   ARMul_UndefInstr (state, instr);
+                 /* Special treatment for XScale coprocessors.  */
+                 else if (state->is_XScale)
                    {
-                     state->Accumulator = state->Reg[BITS (12, 15)];
-                     state->Accumulator += (ARMdword) state->Reg[BITS (16, 19)] << 32;
-                     break;
+                     /* Only opcode 0 is supported.  */
+                     if (BITS (4, 7) != 0x00)
+                       ARMul_UndefInstr (state, instr);
+                     /* Only coporcessor 0 is supported.  */
+                     else if (CPNum != 0x00)
+                       ARMul_UndefInstr (state, instr);
+                     /* Only accumulator 0 is supported.  */
+                     else if (BITS (0, 3) != 0x00)
+                       ARMul_UndefInstr (state, instr);
+                     else
+                       {
+                         /* XScale MAR insn.  Move two registers into accumulator.  */
+                         state->Accumulator = state->Reg[BITS (12, 15)];
+                         state->Accumulator += (ARMdword) state->Reg[BITS (16, 19)] << 32;
+                       }
                    }
-                 /* Access to any other acc is unpredicatable.  */
+                 else
+                   /* FIXME: Not sure what to do for other v5 processors.  */
+                   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_XScale)
+             if (state->is_v5)
                {
-                 if (BITS (4, 7) != 0x00)
+                 if (CPNum == 10 || CPNum == 11)
+                   handle_VFP_move (state, instr);
+                 /* Writes to R15 are UNPREDICATABLE.  */
+                 else if (DESTReg == 15 || LHSReg == 15)
                    ARMul_UndefInstr (state, instr);
-
-                 if (BITS (8, 11) != 0x00)
-                   ARMul_UndefInstr (state, instr); /* Not CP0.  */
-
-                 /* XScale MRA insn.  Move accumulator into two registers.  */
-                 if (BITS (0, 3) == 0x00)
+                 /* Is access to the coprocessor allowed ?  */
+                 else if (! CP_ACCESS_ALLOWED (state, CPNum))
+                   ARMul_UndefInstr (state, instr);
+                 /* Special handling for XScale coprcoessors.  */
+                 else if (state->is_XScale)
                    {
-                     ARMword t1 = (state->Accumulator >> 32) & 255;
+                     /* Only opcode 0 is supported.  */
+                     if (BITS (4, 7) != 0x00)
+                       ARMul_UndefInstr (state, instr);
+                     /* Only coprocessor 0 is supported.  */
+                     else if (CPNum != 0x00)
+                       ARMul_UndefInstr (state, instr);
+                     /* Only accumulator 0 is supported.  */
+                     else if (BITS (0, 3) != 0x00)
+                       ARMul_UndefInstr (state, instr);
+                     else
+                       {
+                         /* XScale MRA insn.  Move accumulator into two registers.  */
+                         ARMword t1 = (state->Accumulator >> 32) & 255;
 
-                     if (t1 & 128)
-                       t1 -= 256;
+                         if (t1 & 128)
+                           t1 -= 256;
 
-                     state->Reg[BITS (12, 15)] = state->Accumulator;
-                     state->Reg[BITS (16, 19)] = t1;
-                     break;
+                         state->Reg[BITS (12, 15)] = state->Accumulator;
+                         state->Reg[BITS (16, 19)] = t1;
+                         break;
+                       }
                    }
-                 /* Access to any other acc is unpredicatable.  */
+                 else
+                   /* FIXME: Not sure what to do for other v5 processors.  */
+                   ARMul_UndefInstr (state, instr);
                  break;
                }
              /* 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);
              break;
 
-/***************************************************************************\
-*            Co-Processor Register Transfers (MCR) and Data Ops             *
-\***************************************************************************/
+
+             /* Co-Processor Register Transfers (MCR) and Data Ops.  */
 
            case 0xe2:
+             if (! CP_ACCESS_ALLOWED (state, CPNum))
+               {
+                 ARMul_UndefInstr (state, instr);
+                 break;
+               }
              if (state->is_XScale)
                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;
@@ -3355,8 +4568,11 @@ ARMul_Emulate26 (register ARMul_State * state)
            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
@@ -3369,14 +4585,13 @@ ARMul_Emulate26 (register ARMul_State * state)
                  else
                    ARMul_MCR (state, instr, DEST);
                }
-             else              /* CDP Part 1 */
+             else
+               /* CDP Part 1.  */
                ARMul_CDP (state, instr);
              break;
 
-/***************************************************************************\
-*            Co-Processor Register Transfers (MRC) and Data Ops             *
-\***************************************************************************/
 
+             /* Co-Processor Register Transfers (MRC) and Data Ops.  */
            case 0xe1:
            case 0xe3:
            case 0xe5:
@@ -3386,26 +4601,78 @@ ARMul_Emulate26 (register ARMul_State * state)
            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:
@@ -3423,31 +4690,24 @@ ARMul_Emulate26 (register ARMul_State * state)
            case 0xfe:
            case 0xff:
              if (instr == ARMul_ABORTWORD && state->AbortAddr == pc)
-               {               /* a prefetch abort */
+               {
+                 /* A prefetch abort.  */
+                 XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc);
                  ARMul_Abort (state, ARMul_PrefetchAbortV);
                  break;
                }
 
              if (!ARMul_OSHandleSWI (state, BITS (0, 23)))
-               {
-                 ARMul_Abort (state, ARMul_SWIV);
-               }
+               ARMul_Abort (state, ARMul_SWIV);
+
              break;
-           }                   /* 256 way main switch */
-       }                       /* if temp */
+           }
+       }
 
 #ifdef MODET
     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.  */
@@ -3456,21 +4716,18 @@ ARMul_Emulate26 (register ARMul_State * state)
       else if (state->Emulate != RUN)
        break;
     }
-  while (!stop_simulator);     /* do loop */
+  while (!stop_simulator);
 
   state->decoded = decoded;
   state->loaded = loaded;
   state->pc = pc;
 
   return pc;
-}                              /* Emulate 26/32 in instruction based mode */
-
+}
 
-/***************************************************************************\
-* This routine evaluates most Data Processing register RHS's with the S     *
-* bit clear.  It is intended to be called from the macro DPRegRHS, which    *
-* filters the common case of an unshifted register with in line code        *
-\***************************************************************************/
+/* This routine evaluates most Data Processing register RHS's with the S
+   bit clear.  It is intended to be called from the macro DPRegRHS, which
+   filters the common case of an unshifted register with in line code.  */
 
 static ARMword
 GetDPRegRHS (ARMul_State * state, ARMword instr)
@@ -3479,7 +4736,8 @@ GetDPRegRHS (ARMul_State * state, ARMword instr)
 
   base = RHSReg;
   if (BIT (4))
-    {                          /* shift amount in a register */
+    {
+      /* Shift amount in a register.  */
       UNDEF_Shift;
       INCPC;
 #ifndef MODE32
@@ -3510,9 +4768,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)
@@ -3522,7 +4780,8 @@ GetDPRegRHS (ARMul_State * state, ARMword instr)
        }
     }
   else
-    {                          /* shift amount is a constant */
+    {
+      /* Shift amount is a constant.  */
 #ifndef MODE32
       if (base == 15)
        base = ECC | ER15INT | R15PC | EMODE;
@@ -3541,25 +4800,25 @@ 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);                  /* just to shut up lint */
+
+  return 0;
 }
 
-/***************************************************************************\
-* This routine evaluates most Logical Data Processing register RHS's        *
-* with the S bit set.  It is intended to be called from the macro           *
-* DPSRegRHS, which filters the common case of an unshifted register         *
-* with in line code                                                         *
-\***************************************************************************/
+/* This routine evaluates most Logical Data Processing register RHS's
+   with the S bit set.  It is intended to be called from the macro
+   DPSRegRHS, which filters the common case of an unshifted register
+   with in line code.  */
 
 static ARMword
 GetDPSRegRHS (ARMul_State * state, ARMword instr)
@@ -3568,7 +4827,8 @@ GetDPSRegRHS (ARMul_State * state, ARMword instr)
 
   base = RHSReg;
   if (BIT (4))
-    {                          /* shift amount in a register */
+    {
+      /* Shift amount in a register.  */
       UNDEF_Shift;
       INCPC;
 #ifndef MODE32
@@ -3623,12 +4883,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)
@@ -3647,7 +4907,8 @@ GetDPSRegRHS (ARMul_State * state, ARMword instr)
        }
     }
   else
-    {                          /* shift amount is a constant */
+    {
+      /* Shift amount is a constant.  */
 #ifndef MODE32
       if (base == 15)
        base = ECC | ER15INT | R15PC | EMODE;
@@ -3655,6 +4916,7 @@ GetDPSRegRHS (ARMul_State * state, ARMword instr)
 #endif
        base = state->Reg[base];
       shamt = BITS (7, 11);
+
       switch ((int) BITS (5, 6))
        {
        case LSL:
@@ -3675,16 +4937,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));
@@ -3696,12 +4959,11 @@ GetDPSRegRHS (ARMul_State * state, ARMword instr)
            }
        }
     }
-  return (0);                  /* just to shut up lint */
+
+  return 0;
 }
 
-/***************************************************************************\
-* This routine handles writes to register 15 when the S bit is not set.     *
-\***************************************************************************/
+/* This routine handles writes to register 15 when the S bit is not set.  */
 
 static void
 WriteR15 (ARMul_State * state, ARMword src)
@@ -3717,18 +4979,20 @@ 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.         *
-\***************************************************************************/
+/* This routine handles writes to register 15 when the S bit is set.  */
 
 static void
 WriteSR15 (ARMul_State * state, ARMword src)
@@ -3749,28 +5013,34 @@ 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
-   will switch to Thumb mode if the least significant bit is set. */
+   will switch to Thumb mode if the least significant bit is set.  */
 
 static void
 WriteR15Branch (ARMul_State * state, ARMword src)
 {
 #ifdef MODET
   if (src & 1)
-    {          /* Thumb bit */
+    {
+      /* Thumb bit.  */
       SETT;
       state->Reg[15] = src & 0xfffffffe;
     }
@@ -3780,16 +5050,27 @@ 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
 }
 
-/***************************************************************************\
-* 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                    *
-\***************************************************************************/
+/* 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.  */
 
 static ARMword
 GetLSRegRHS (ARMul_State * state, ARMword instr)
@@ -3799,7 +5080,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];
@@ -3816,41 +5098,42 @@ 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));
+    default:
+      break;
     }
-  return (0);                  /* just to shut up lint */
+  return 0;
 }
 
-/***************************************************************************\
-* This routine evaluates the ARM7T halfword and signed transfer RHS's.      *
-\***************************************************************************/
+/* This routine evaluates the ARM7T halfword and signed transfer RHS's.  */
 
 static ARMword
 GetLS7RHS (ARMul_State * state, ARMword instr)
 {
   if (BIT (22) == 0)
-    {                          /* register */
+    {
+      /* 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];
     }
 
-  /* else immediate */
+  /* Immediate.  */
   return BITS (0, 3) | (BITS (8, 11) << 4);
 }
 
-/***************************************************************************\
-* This function does the work of loading a word for a LDR instruction.      *
-\***************************************************************************/
+/* This function does the work of loading a word for a LDR instruction.  */
 
 static unsigned
 LoadWord (ARMul_State * state, ARMword instr, ARMword address)
@@ -3860,15 +5143,15 @@ LoadWord (ARMul_State * state, ARMword instr, ARMword address)
   BUSUSEDINCPCS;
 #ifndef MODE32
   if (ADDREXCEPT (address))
-    {
-      INTERNALABORT (address);
-    }
+    INTERNALABORT (address);
 #endif
+
   dest = ARMul_LoadWordN (state, address);
+
   if (state->Aborted)
     {
       TAKEABORT;
-      return (state->lateabtSig);
+      return state->lateabtSig;
     }
   if (address & 3)
     dest = ARMul_Align (state, address, dest);
@@ -3879,9 +5162,7 @@ LoadWord (ARMul_State * state, ARMword instr, ARMword address)
 }
 
 #ifdef MODET
-/***************************************************************************\
-* This function does the work of loading a halfword.                        *
-\***************************************************************************/
+/* This function does the work of loading a halfword.  */
 
 static unsigned
 LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address,
@@ -3892,22 +5173,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);
@@ -3915,9 +5193,7 @@ LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address,
 
 #endif /* MODET */
 
-/***************************************************************************\
-* This function does the work of loading a byte for a LDRB instruction.     *
-\***************************************************************************/
+/* This function does the work of loading a byte for a LDRB instruction.  */
 
 static unsigned
 LoadByte (ARMul_State * state, ARMword instr, ARMword address, int signextend)
@@ -3927,30 +5203,26 @@ 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);
 }
 
-/***************************************************************************\
-* This function does the work of loading two words for a LDRD instruction. *
-\***************************************************************************/
+/* This function does the work of loading two words for a LDRD instruction.  */
 
 static void
 Handle_Load_Double (ARMul_State * state, ARMword instr)
@@ -3959,7 +5231,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;
@@ -3967,7 +5239,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.  */
@@ -3976,13 +5248,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.  */
@@ -4003,15 +5275,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);
@@ -4042,24 +5317,22 @@ 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;
 }
 
-/***************************************************************************\
-* This function does the work of storing two words for a STRD instruction. *
-\***************************************************************************/
+/* This function does the work of storing two words for a STRD instruction.  */
 
 static void
 Handle_Store_Double (ARMul_State * state, ARMword instr)
@@ -4068,7 +5341,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;
@@ -4083,20 +5356,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)
     {
@@ -4115,7 +5388,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;
@@ -4147,24 +5420,22 @@ 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;
 }
 
-/***************************************************************************\
-* This function does the work of storing a word from a STR instruction.     *
-\***************************************************************************/
+/* This function does the work of storing a word from a STR instruction.  */
 
 static unsigned
 StoreWord (ARMul_State * state, ARMword instr, ARMword address)
@@ -4188,15 +5459,13 @@ StoreWord (ARMul_State * state, ARMword instr, ARMword address)
   if (state->Aborted)
     {
       TAKEABORT;
-      return (state->lateabtSig);
+      return state->lateabtSig;
     }
-  return (TRUE);
+  return TRUE;
 }
 
 #ifdef MODET
-/***************************************************************************\
-* This function does the work of storing a byte for a STRH instruction.     *
-\***************************************************************************/
+/* This function does the work of storing a byte for a STRH instruction.  */
 
 static unsigned
 StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address)
@@ -4223,17 +5492,14 @@ StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address)
   if (state->Aborted)
     {
       TAKEABORT;
-      return (state->lateabtSig);
+      return state->lateabtSig;
     }
-
-  return (TRUE);
+  return TRUE;
 }
 
 #endif /* MODET */
 
-/***************************************************************************\
-* This function does the work of storing a byte for a STRB instruction.     *
-\***************************************************************************/
+/* This function does the work of storing a byte for a STRB instruction.  */
 
 static unsigned
 StoreByte (ARMul_State * state, ARMword instr, ARMword address)
@@ -4257,18 +5523,16 @@ StoreByte (ARMul_State * state, ARMword instr, ARMword address)
   if (state->Aborted)
     {
       TAKEABORT;
-      return (state->lateabtSig);
+      return state->lateabtSig;
     }
   UNDEF_LSRBPC;
-  return (TRUE);
+  return TRUE;
 }
 
-/***************************************************************************\
-* 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.                                        *
-\***************************************************************************/
+/* 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.  */
 
 static void
 LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
@@ -4281,37 +5545,48 @@ LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
   BUSUSEDINCPCS;
 #ifndef MODE32
   if (ADDREXCEPT (address))
-    {
-      INTERNALABORT (address);
-    }
+    INTERNALABORT (address);
 #endif
   if (BIT (21) && LHSReg != 15)
     LSBase = WBBase;
 
-  for (temp = 0; !BIT (temp); temp++); /* N cycle first */
+  /* N cycle first.  */
+  for (temp = 0; !BIT (temp); temp++)
+    ;
+
   dest = ARMul_LoadWordN (state, address);
+
   if (!state->abortSig && !state->Aborted)
     state->Reg[temp++] = dest;
   else if (!state->Aborted)
-    state->Aborted = ARMul_DataAbortV;
+    {
+      XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
+      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);
+
        if (!state->abortSig && !state->Aborted)
          state->Reg[temp] = dest;
        else if (!state->Aborted)
-         state->Aborted = ARMul_DataAbortV;
+         {
+            XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
+           state->Aborted = ARMul_DataAbortV;
+         }
       }
 
   if (BIT (15) && !state->Aborted)
-    {                          /* PC is in the reg list */
-      WriteR15Branch(state, PC);
-    }
+    /* PC is in the reg list.  */
+    WriteR15Load (state, PC);
 
-  ARMul_Icycles (state, 1, 0L);        /* to write back the final register */
+  /* To write back the final register.  */
+  ARMul_Icycles (state, 1, 0L);
 
   if (state->Aborted)
     {
@@ -4321,16 +5596,16 @@ LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
     }
 }
 
-/***************************************************************************\
-* This function does the work of loading the registers listed in an LDM     *
-* instruction, when the S bit is set. 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.                                        *
-\***************************************************************************/
+/* This function does the work of loading the registers listed in an LDM
+   instruction, when the S bit is set. 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.  */
 
 static void
-LoadSMult (ARMul_State * state, ARMword instr,
-          ARMword address, ARMword WBBase)
+LoadSMult (ARMul_State * state,
+          ARMword       instr,
+          ARMword       address,
+          ARMword       WBBase)
 {
   ARMword dest, temp;
 
@@ -4342,9 +5617,7 @@ LoadSMult (ARMul_State * state, ARMword instr,
 
 #ifndef MODE32
   if (ADDREXCEPT (address))
-    {
-      INTERNALABORT (address);
-    }
+    INTERNALABORT (address);
 #endif
 
   if (BIT (21) && LHSReg != 15)
@@ -4357,18 +5630,22 @@ LoadSMult (ARMul_State * state, ARMword instr,
       UNDEF_LSMUserBankWb;
     }
 
+  /* N cycle first.  */
   for (temp = 0; !BIT (temp); temp ++)
-    ;  /* N cycle first.  */
+    ;
 
   dest = ARMul_LoadWordN (state, address);
 
   if (!state->abortSig)
     state->Reg[temp++] = dest;
   else if (!state->Aborted)
-    state->Aborted = ARMul_DataAbortV;
+    {
+      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.  */
@@ -4378,7 +5655,10 @@ LoadSMult (ARMul_State * state, ARMword instr,
        if (!state->abortSig && !state->Aborted)
          state->Reg[temp] = dest;
        else if (!state->Aborted)
-         state->Aborted = ARMul_DataAbortV;
+         {
+            XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
+           state->Aborted = ARMul_DataAbortV;
+         }
       }
 
   if (BIT (15) && !state->Aborted)
@@ -4403,6 +5683,7 @@ LoadSMult (ARMul_State * state, ARMword instr,
        }
       else
        ARMul_R15Altered (state);
+
       FLUSHPIPE;
 #endif
     }
@@ -4418,53 +5699,60 @@ LoadSMult (ARMul_State * state, ARMword instr,
     {
       if (BIT (21) && LHSReg != 15)
        LSBase = WBBase;
+
       TAKEABORT;
     }
 }
 
-/***************************************************************************\
-* This function does the work of storing the registers listed in an STM     *
-* 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.                                        *
-\***************************************************************************/
+/* This function does the work of storing the registers listed in an STM
+   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.  */
 
 static void
-StoreMult (ARMul_State * state, ARMword instr,
-          ARMword address, ARMword WBBase)
+StoreMult (ARMul_State * state,
+          ARMword instr,
+          ARMword address,
+          ARMword WBBase)
 {
   ARMword temp;
 
   UNDEF_LSMNoRegs;
   UNDEF_LSMPCBase;
   UNDEF_LSMBaseInListWb;
+
   if (!TFLAG)
-    {
-      BUSUSEDINCPCN;           /* N-cycle, increment the PC and update the NextInstr state */
-    }
+    /* N-cycle, increment the PC and update the NextInstr state.  */
+    BUSUSEDINCPCN;
 
 #ifndef MODE32
   if (VECTORACCESS (address) || ADDREXCEPT (address))
-    {
-      INTERNALABORT (address);
-    }
+    INTERNALABORT (address);
+
   if (BIT (15))
     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++]);
 #else
   if (state->Aborted)
     {
       (void) ARMul_LoadWordN (state, address);
-      for (; temp < 16; temp++)        /* Fake the Stores as Loads */
+
+      /* Fake the Stores as Loads.  */
+      for (; temp < 16; temp++)
        if (BIT (temp))
-         {                     /* save this register */
+         {
+           /* Save this register.  */
            address += 4;
            (void) ARMul_LoadWordS (state, address);
          }
+
       if (BIT (21) && LHSReg != 15)
        LSBase = WBBase;
       TAKEABORT;
@@ -4473,36 +5761,43 @@ StoreMult (ARMul_State * state, ARMword instr,
   else
     ARMul_StoreWordN (state, address, state->Reg[temp++]);
 #endif
+
   if (state->abortSig && !state->Aborted)
-    state->Aborted = ARMul_DataAbortV;
+    {
+      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 */
+      {
+       /* Save this register.  */
        address += 4;
+
        ARMul_StoreWordS (state, address, state->Reg[temp]);
+
        if (state->abortSig && !state->Aborted)
-         state->Aborted = ARMul_DataAbortV;
+         {
+            XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
+           state->Aborted = ARMul_DataAbortV;
+         }
       }
+
   if (state->Aborted)
-    {
-      TAKEABORT;
-    }
+    TAKEABORT;
 }
 
-/***************************************************************************\
-* This function does the work of storing the registers listed in an STM     *
-* instruction when the S bit is set.  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.                                        *
-\***************************************************************************/
+/* This function does the work of storing the registers listed in an STM
+   instruction when the S bit is set.  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.  */
 
 static void
-StoreSMult (
-           ARMul_State * state,
+StoreSMult (ARMul_State * state,
            ARMword       instr,
            ARMword       address,
            ARMword       WBBase)
@@ -4517,9 +5812,7 @@ StoreSMult (
 
 #ifndef MODE32
   if (VECTORACCESS (address) || ADDREXCEPT (address))
-    {
-      INTERNALABORT (address);
-    }
+    INTERNALABORT (address);
 
   if (BIT (15))
     PATCHR15;
@@ -4534,7 +5827,7 @@ StoreSMult (
 
   for (temp = 0; !BIT (temp); temp++)
     ;  /* N cycle first.  */
-  
+
 #ifdef MODE32
   ARMul_StoreWordN (state, address, state->Reg[temp++]);
 #else
@@ -4548,14 +5841,14 @@ StoreSMult (
          {
            /* Save this register.  */
            address += 4;
+
            (void) ARMul_LoadWordS (state, address);
          }
-      
+
       if (BIT (21) && LHSReg != 15)
        LSBase = WBBase;
 
       TAKEABORT;
-
       return;
     }
   else
@@ -4563,10 +5856,13 @@ StoreSMult (
 #endif
 
   if (state->abortSig && !state->Aborted)
-    state->Aborted = ARMul_DataAbortV;
+    {
+      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.  */
@@ -4575,7 +5871,10 @@ StoreSMult (
        ARMul_StoreWordS (state, address, state->Reg[temp]);
 
        if (state->abortSig && !state->Aborted)
-         state->Aborted = ARMul_DataAbortV;
+         {
+            XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
+           state->Aborted = ARMul_DataAbortV;
+         }
       }
 
   if (state->Mode != USER26MODE && state->Mode != USER32MODE)
@@ -4586,15 +5885,11 @@ StoreSMult (
     LSBase = WBBase;
 
   if (state->Aborted)
-    {
-      TAKEABORT;
-    }
+    TAKEABORT;
 }
 
-/***************************************************************************\
-* This function does the work of adding two 32bit values together, and      *
-* calculating if a carry has occurred.                                      *
-\***************************************************************************/
+/* This function does the work of adding two 32bit values
+   together, and calculating if a carry has occurred.  */
 
 static ARMword
 Add32 (ARMword a1, ARMword a2, int *carry)
@@ -4604,68 +5899,78 @@ 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 two 32bit values to give a     *
-* 64bit result.                                                             *
-\***************************************************************************/
+/* This function does the work of multiplying
+   two 32bit values to give a 64bit result.  */
 
 static unsigned
 Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
 {
-  int nRdHi, nRdLo, nRs, nRm;  /* operand register numbers */
+  /* Operand register numbers.  */
+  int nRdHi, nRdLo, nRs, nRm;
   ARMword RdHi = 0, RdLo = 0, Rm;
-  int scount;                  /* cycle count */
+  /* Cycle count.  */
+  int scount;
 
   nRdHi = BITS (16, 19);
   nRdLo = BITS (12, 15);
   nRs = BITS (8, 11);
   nRm = BITS (0, 3);
 
-  /* Needed to calculate the cycle count: */
+  /* Needed to calculate the cycle count */
   Rm = state->Reg[nRm];
 
-  /* Check for illegal operand combinations first: */
-  if (nRdHi != 15
+  /* Check for illegal operand combinations first */
+  if (   nRdHi != 15
       && nRdLo != 15
-      && nRs != 15
-      && nRm != 15 && nRdHi != nRdLo && nRdHi != nRm && nRdLo != nRm)
+      && nRs   != 15
+      && nRm   != 15
+      && nRdHi != nRdLo)
     {
-      ARMword lo, mid1, mid2, hi;      /* intermediate results */
+      /* Intermediate results.  */
+      ARMword lo, mid1, mid2, hi;
       int carry;
       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;
        }
 
-      /* We can split the 32x32 into four 16x16 operations. This ensures
-         that we do not lose precision on 32bit only hosts: */
+      /* We can split the 32x32 into four 16x16 operations. This
+        ensures that we do not lose precision on 32bit only hosts.  */
       lo = ((Rs & 0xFFFF) * (Rm & 0xFFFF));
       mid1 = ((Rs & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
       mid2 = (((Rs >> 16) & 0xFFFF) * (Rm & 0xFFFF));
       hi = (((Rs >> 16) & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
 
-      /* We now need to add all of these results together, taking care
-         to propogate the carries from the additions: */
+      /* We now need to add all of these results together, taking
+        care to propogate the carries from the additions.  */
       RdLo = Add32 (lo, (mid1 << 16), &carry);
       RdHi = carry;
       RdLo = Add32 (RdLo, (mid2 << 16), &carry);
@@ -4675,7 +5980,6 @@ Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
       if (sign)
        {
          /* Negate result if necessary.  */
-
          RdLo = ~RdLo;
          RdHi = ~RdHi;
          if (RdLo == 0xFFFFFFFF)
@@ -4689,21 +5993,20 @@ Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
 
       state->Reg[nRdLo] = RdLo;
       state->Reg[nRdHi] = RdHi;
-    }                          /* else undefined result */
-  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: */
+     unsigned multiply, and what bits are clear in the multiplier */
   if (msigned && (Rm & ((unsigned) 1 << 31)))
-    Rm = ~Rm;                  /* invert the bits to make the check against zero */
+    /* Invert the bits to make the check against zero.  */
+    Rm = ~Rm;                  
 
   if ((Rm & 0xFFFFFF00) == 0)
     scount = 1;
@@ -4717,10 +6020,8 @@ Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
   return 2 + scount;
 }
 
-/***************************************************************************\
-* This function does the work of multiplying two 32bit values and adding    *
-* a 64bit value to give a 64bit result.                                     *
-\***************************************************************************/
+/* This function does the work of multiplying two 32bit
+   values and adding a 64bit value to give a 64bit result.  */
 
 static unsigned
 MultiplyAdd64 (ARMul_State * state, ARMword instr, int msigned, int scc)
@@ -4745,11 +6046,10 @@ MultiplyAdd64 (ARMul_State * state, ARMword instr, int msigned, int scc)
   state->Reg[nRdHi] = RdHi;
 
   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));
 
-  return scount + 1;           /* extra cycle for addition */
+  /* Extra cycle for addition.  */
+  return scount + 1;
 }
This page took 0.132964 seconds and 4 git commands to generate.