gdb: Convert language la_value_print field to a method
[deliverable/binutils-gdb.git] / sim / arm / armemu.c
index 7152023d25b752f2c46eb7bc1bc722451c5c8c53..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);
+#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 */
+/* Load post decrement writeback.  */
 #define LHPOSTDOWN()                                    \
 {                                                       \
-  int done = 1 ;                                        \
-  lhs = LHS ;                                           \
-  switch (BITS(5,6)) {                                  \
+  int done = 1;                                                \
+  lhs = LHS;                                           \
+  temp = lhs - GetLS7RHS (state, instr);               \
+                                                       \
+  switch (BITS (5, 6))                                 \
+    {                                                          \
     case 1: /* H */                                     \
-      if (LoadHalfWord(state,instr,lhs,LUNSIGNED))      \
-         LSBase = lhs - GetLS7RHS(state,instr) ;        \
-      break ;                                           \
+      if (LoadHalfWord (state, instr, lhs, LUNSIGNED))  \
+         LSBase = temp;                                        \
+      break;                                                   \
     case 2: /* SB */                                    \
-      if (LoadByte(state,instr,lhs,LSIGNED))            \
-         LSBase = lhs - GetLS7RHS(state,instr) ;        \
-      break ;                                           \
+      if (LoadByte (state, instr, lhs, LSIGNED))        \
+         LSBase = temp;                                        \
+      break;                                                   \
     case 3: /* SH */                                    \
-      if (LoadHalfWord(state,instr,lhs,LSIGNED))        \
-         LSBase = lhs - GetLS7RHS(state,instr) ;        \
-      break ;                                           \
-    case 0: /* SWP handled elsewhere */                 \
+      if (LoadHalfWord (state, instr, lhs, LSIGNED))    \
+         LSBase = temp;                                        \
+      break;                                                   \
+    case 0: /* SWP handled elsewhere.  */               \
     default:                                            \
-      done = 0 ;                                        \
-      break ;                                           \
+      done = 0;                                                \
+      break;                                                   \
     }                                                   \
   if (done)                                             \
-     break ;                                            \
+     break;                                                    \
 }
 
-/* load post increment writeback */
+/* Load post increment writeback.  */
 #define LHPOSTUP()                                      \
 {                                                       \
-  int done = 1 ;                                        \
-  lhs = LHS ;                                           \
-  switch (BITS(5,6)) {                                  \
+  int done = 1;                                                \
+  lhs = LHS;                                                   \
+  temp = lhs + GetLS7RHS (state, instr);               \
+                                                       \
+  switch (BITS (5, 6))                                 \
+    {                                                          \
     case 1: /* H */                                     \
-      if (LoadHalfWord(state,instr,lhs,LUNSIGNED))      \
-         LSBase = lhs + GetLS7RHS(state,instr) ;        \
-      break ;                                           \
+      if (LoadHalfWord (state, instr, lhs, LUNSIGNED))  \
+         LSBase = temp;                                        \
+      break;                                                   \
     case 2: /* SB */                                    \
-      if (LoadByte(state,instr,lhs,LSIGNED))            \
-         LSBase = lhs + GetLS7RHS(state,instr) ;        \
-      break ;                                           \
+      if (LoadByte (state, instr, lhs, LSIGNED))        \
+         LSBase = temp;                                        \
+      break;                                                   \
     case 3: /* SH */                                    \
-      if (LoadHalfWord(state,instr,lhs,LSIGNED))        \
-         LSBase = lhs + GetLS7RHS(state,instr) ;        \
-      break ;                                           \
-    case 0: /* SWP handled elsewhere */                 \
+      if (LoadHalfWord (state, instr, lhs, LSIGNED))    \
+         LSBase = temp;                                        \
+      break;                                                   \
+    case 0: /* SWP handled elsewhere.  */               \
     default:                                            \
-      done = 0 ;                                        \
-      break ;                                           \
+      done = 0;                                                \
+      break;                                                   \
     }                                                   \
   if (done)                                             \
-     break ;                                            \
+     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;                                                            \
 }
 
-/***************************************************************************\
-*                             EMULATION of ARM6                             *
-\***************************************************************************/
-
-/* The PC pipeline value depends on whether ARM or Thumb instructions
-   are being executed: */
-ARMword isize;
+/* Attempt to emulate an ARMv6 instruction.
+   Returns non-zero upon success.  */
 
 #ifdef MODE32
-ARMword
-ARMul_Emulate32 (register ARMul_State * state)
+static int
+handle_v6_insn (ARMul_State * state, ARMword instr)
 {
-#else
-ARMword
-ARMul_Emulate26 (register ARMul_State * state)
+  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;
+
+       default:
+         fprintf (stderr, "SIM: VFP: Unimplemented move insn %x\n", BITS (20, 27));
+         break;
+       }
+      break;
+
+    case 0xe0:
+    case 0xe1:
+      /* VMOV single core <-> VFP single precision.  */
+      if (BITS (0, 6) != 0x10 || BITS (8, 11) != 0xA)
+       fprintf (stderr, "SIM: VFP: Unimplemented move insn %x\n", BITS (20, 27));
+      else
+       {
+         int sreg = (BITS (16, 19) << 1) | BIT (7);
+
+         if (BIT (20))
+           state->Reg[DESTReg] = VFP_uword (sreg);
+         else
+           VFP_uword (sreg) = state->Reg[DESTReg];
+       }
+      break;
+
+    default:
+      fprintf (stderr, "SIM: VFP: Unimplemented move insn %x\n", BITS (20, 27));
+      return;
+    }
+}
+
+/* EMULATION of ARM6.  */
+
+ARMword
+#ifdef MODE32
+ARMul_Emulate32 (ARMul_State * state)
+#else
+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)
     {
@@ -298,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;
@@ -311,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;
@@ -320,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);
@@ -328,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);
@@ -392,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;
@@ -400,8 +1296,8 @@ ARMul_Emulate26 (register ARMul_State * state)
            }
          if (state->Debug)
            {
-             fprintf (stderr, "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);
            }
        }
@@ -420,38 +1316,85 @@ 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;
        case NV:
+         if (state->is_v5)
+           {
+             if (BITS (25, 27) == 5) /* BLX(1) */
+               {
+                 ARMword dest;
+
+                 state->Reg[14] = pc + 4;
+
+                 /* 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);
+           }
          temp = FALSE;
          break;
        case EQ:
@@ -498,34 +1441,185 @@ 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)
+           {
+             if (BIT (20) == 0 && BITS (25, 27) == 0)
+               {
+                 if (BITS (4, 7) == 0xD)
+                   {
+                     /* XScale Load Consecutive insn.  */
+                     ARMword temp = GetLS7RHS (state, instr);
+                     ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
+                     ARMword addr = BIT (24) ? temp2 : LHS;
+
+                     if (BIT (12))
+                       ARMul_UndefInstr (state, instr);
+                     else if (addr & 7)
+                       /* Alignment violation.  */
+                       ARMul_Abort (state, ARMul_DataAbortV);
+                     else
+                       {
+                         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 = temp2;
+                       }
+
+                     goto donext;
+                   }
+                 else if (BITS (4, 7) == 0xF)
+                   {
+                     /* XScale Store Consecutive insn.  */
+                     ARMword temp = GetLS7RHS (state, instr);
+                     ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
+                     ARMword addr = BIT (24) ? temp2 : LHS;
+
+                     if (BIT (12))
+                       ARMul_UndefInstr (state, instr);
+                     else if (addr & 7)
+                       /* Alignment violation.  */
+                       ARMul_Abort (state, ARMul_DataAbortV);
+                     else
+                       {
+                         ARMul_StoreWordN (state, addr,
+                                           state->Reg[BITS (12, 15)]);
+                         ARMul_StoreWordN (state, addr + 4,
+                                           state->Reg[BITS (12, 15) + 1]);
+
+                         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;
                }
-             /* TODO: CHECK: should 0xD and 0xF generate undefined intruction aborts? */
+             if (BITS (4, 7) == 0xD)
+               {
+                 Handle_Load_Double (state, instr);
+                 break;
+               }
+             if (BITS (4, 7) == 0xF)
+               {
+                 Handle_Store_Double (state, instr);
+                 break;
+               }
 #endif
              if (BITS (4, 7) == 9)
-               {               /* MUL */
+               {
+                 /* MUL */
                  rhs = state->Reg[MULRHSReg];
                  if (MULLHSReg == MULDESTReg)
                    {
@@ -535,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);
@@ -554,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;
@@ -577,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);
@@ -597,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;
                }
@@ -614,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
@@ -633,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;
@@ -657,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);
@@ -677,10 +1778,20 @@ 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;
                }
+             if (BITS (4, 7) == 0xD)
+               {
+                 Handle_Load_Double (state, instr);
+                 break;
+               }
+             if (BITS (4, 7) == 0xF)
+               {
+                 Handle_Store_Double (state, instr);
+                 break;
+               }
 #endif
              rhs = DPRegRHS;
              dest = LHS - rhs;
@@ -690,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);
@@ -716,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;
                }
@@ -729,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);
@@ -755,14 +1864,25 @@ 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;
                }
+             if (BITS (4, 7) == 0xD)
+               {
+                 Handle_Load_Double (state, instr);
+                 break;
+               }
+             if (BITS (4, 7) == 0xF)
+               {
+                 Handle_Store_Double (state, instr);
+                 break;
+               }
 #endif
 #ifdef MODET
              if (BITS (4, 7) == 0x9)
-               {               /* MULL */
+               {
+                 /* MULL */
                  /* 32x32 = 64 */
                  ARMul_Icycles (state,
                                 Multiply64 (state, instr, LUNSIGNED,
@@ -778,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),
@@ -799,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);
@@ -817,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,
@@ -840,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,
@@ -861,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);
@@ -879,14 +1996,23 @@ 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;
                }
-#endif
-#ifdef MODET
+             if (BITS (4, 7) == 0xD)
+               {
+                 Handle_Load_Double (state, instr);
+                 break;
+               }
+             if (BITS (4, 7) == 0xF)
+               {
+                 Handle_Store_Double (state, instr);
+                 break;
+               }
              if (BITS (4, 7) == 0x9)
-               {               /* MULL */
+               {
+                 /* MULL */
                  /* 32x32=64 */
                  ARMul_Icycles (state,
                                 Multiply64 (state, instr, LSIGNED, LDEFAULT),
@@ -902,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),
@@ -937,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,
@@ -960,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),
@@ -979,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);
@@ -992,17 +2115,70 @@ 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)
+                   {
+                     /* ElSegundo SMLAxy 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;
+                     if (BIT (6))
+                       op2 >>= 16;
+                     op1 &= 0xFFFF;
+                     op2 &= 0xFFFF;
+                     if (op1 & 0x8000)
+                       op1 -= 65536;
+                     if (op2 & 0x8000)
+                       op2 -= 65536;
+                     op1 *= op2;
+
+                     if (AddOverflow (op1, Rn, op1 + Rn))
+                       SETS;
+                     state->Reg[BITS (16, 19)] = op1 + Rn;
+                     break;
+                   }
+
+                 if (BITS (4, 11) == 5)
+                   {
+                     /* ElSegundo QADD insn.  */
+                     ARMword op1 = state->Reg[BITS (0, 3)];
+                     ARMword op2 = state->Reg[BITS (16, 19)];
+                     ARMword result = op1 + op2;
+                     if (AddOverflow (op1, op2, result))
+                       {
+                         result = POS (result) ? 0x80000000 : 0x7fffffff;
+                         SETS;
+                       }
+                     state->Reg[BITS (12, 15)] = result;
+                     break;
+                   }
+               }
 #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;
                }
+             if (BITS (4, 7) == 0xD)
+               {
+                 Handle_Load_Double (state, instr);
+                 break;
+               }
+             if (BITS (4, 7) == 0xF)
+               {
+                 Handle_Store_Double (state, instr);
+                 break;
+               }
 #endif
              if (BITS (4, 11) == 9)
-               {               /* SWP */
+               {
+                 /* SWP */
                  UNDEF_SWPPC;
                  temp = LHS;
                  BUSUSEDINCPCS;
@@ -1021,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 */
@@ -1032,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;
@@ -1039,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);
@@ -1057,52 +2235,168 @@ 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)
+                   {
+                     /* BLX(2) */
+                     ARMword temp;
+
+                     if (TFLAG)
+                       temp = (pc + 2) | 1;
+                     else
+                       temp = pc + 4;
+
+                     WriteR15Branch (state, state->Reg[RHSReg]);
+                     state->Reg[14] = temp;
+                     break;
+                   }
+               }
+
+             if (state->is_v5e)
+               {
+                 if (BIT (4) == 0 && BIT (7) == 1
+                     && (BIT (5) == 0 || BITS (12, 15) == 0))
+                   {
+                     /* ElSegundo SMLAWy/SMULWy insn.  */
+                     ARMdword op1 = state->Reg[BITS (0, 3)];
+                     ARMdword op2 = state->Reg[BITS (8, 11)];
+                     ARMdword result;
+
+                     if (BIT (6))
+                       op2 >>= 16;
+                     if (op1 & 0x80000000)
+                       op1 -= 1ULL << 32;
+                     op2 &= 0xFFFF;
+                     if (op2 & 0x8000)
+                       op2 -= 65536;
+                     result = (op1 * op2) >> 16;
+
+                     if (BIT (5) == 0)
+                       {
+                         ARMword Rn = state->Reg[BITS (12, 15)];
+
+                         if (AddOverflow (result, Rn, result + Rn))
+                           SETS;
+                         result += Rn;
+                       }
+                     state->Reg[BITS (16, 19)] = result;
+                     break;
+                   }
+
+                 if (BITS (4, 11) == 5)
+                   {
+                     /* ElSegundo QSUB insn.  */
+                     ARMword op1 = state->Reg[BITS (0, 3)];
+                     ARMword op2 = state->Reg[BITS (16, 19)];
+                     ARMword result = op1 - op2;
+
+                     if (SubOverflow (op1, op2, result))
+                       {
+                         result = POS (result) ? 0x80000000 : 0x7fffffff;
+                         SETS;
+                       }
+
+                     state->Reg[BITS (12, 15)] = result;
+                     break;
+                   }
+               }
 #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;
                }
-#endif
-#ifdef MODET
              if (BITS (4, 27) == 0x12FFF1)
-               {               /* BX */
+               {
+                 /* BX */
                  WriteR15Branch (state, state->Reg[RHSReg]);
                  break;
                }
+             if (BITS (4, 7) == 0xD)
+               {
+                 Handle_Load_Double (state, instr);
+                 break;
+               }
+             if (BITS (4, 7) == 0xF)
+               {
+                 Handle_Store_Double (state, instr);
+                 break;
+               }
 #endif
+             if (state->is_v5)
+               {
+                 if (BITS (4, 7) == 0x7)
+                   {
+                     extern int SWI_vector_installed;
+
+                     /* Hardware is allowed to optionally override this
+                        instruction and treat it as a breakpoint.  Since
+                        this is a simulator not hardware, we take the position
+                        that if a SWI vector was not installed, then an Abort
+                        vector was probably not installed either, and so
+                        normally this instruction would be ignored, even if an
+                        Abort is generated.  This is a bad thing, since GDB
+                        uses this instruction for its breakpoints (at least in
+                        Thumb mode it does).  So intercept the instruction here
+                        and generate a breakpoint SWI instead.  */
+                     if (! SWI_vector_installed)
+                       ARMul_OSHandleSWI (state, SWI_Breakpoint);
+                     else
+                       {
+                         /* 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
+                 /* Don't allow TBIT to be set by MSR.  */
+                 temp &= ~ TBIT;
+#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);
@@ -1113,24 +2407,89 @@ 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.  */
+                     ARMdword op1 = state->Reg[BITS (0, 3)];
+                     ARMdword op2 = state->Reg[BITS (8, 11)];
+                     ARMdword dest;
+
+                     if (BIT (5))
+                       op1 >>= 16;
+                     if (BIT (6))
+                       op2 >>= 16;
+                     op1 &= 0xFFFF;
+                     if (op1 & 0x8000)
+                       op1 -= 65536;
+                     op2 &= 0xFFFF;
+                     if (op2 & 0x8000)
+                       op2 -= 65536;
+
+                     dest = (ARMdword) state->Reg[BITS (16, 19)] << 32;
+                     dest |= state->Reg[BITS (12, 15)];
+                     dest += op1 * op2;
+                     state->Reg[BITS (12, 15)] = dest;
+                     state->Reg[BITS (16, 19)] = dest >> 32;
+                     break;
+                   }
+
+                 if (BITS (4, 11) == 5)
+                   {
+                     /* ElSegundo QDADD insn.  */
+                     ARMword op1 = state->Reg[BITS (0, 3)];
+                     ARMword op2 = state->Reg[BITS (16, 19)];
+                     ARMword op2d = op2 + op2;
+                     ARMword result;
+
+                     if (AddOverflow (op2, op2, op2d))
+                       {
+                         SETS;
+                         op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
+                       }
+
+                     result = op1 + op2d;
+                     if (AddOverflow (op1, op2d, result))
+                       {
+                         SETS;
+                         result = POS (result) ? 0x80000000 : 0x7fffffff;
+                       }
+
+                     state->Reg[BITS (12, 15)] = result;
+                     break;
+                   }
+               }
 #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;
                }
+             if (BITS (4, 7) == 0xD)
+               {
+                 Handle_Load_Double (state, instr);
+                 break;
+               }
+             if (BITS (4, 7) == 0xF)
+               {
+                 Handle_Store_Double (state, instr);
+                 break;
+               }
 #endif
              if (BITS (4, 11) == 9)
-               {               /* SWP */
+               {
+                 /* SWP */
                  UNDEF_SWPPC;
                  temp = LHS;
                  BUSUSEDINCPCS;
@@ -1145,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);
@@ -1181,7 +2542,8 @@ ARMul_Emulate26 (register ARMul_State * state)
 #endif
                }
              else
-               {               /* CMP reg */
+               {
+                 /* CMP reg.  */
                  lhs = LHS;
                  rhs = DPRegRHS;
                  dest = lhs - rhs;
@@ -1200,21 +2562,102 @@ ARMul_Emulate26 (register ARMul_State * state)
              break;
 
            case 0x16:          /* CMN reg and MSR reg to SPSR */
+             if (state->is_v5e)
+               {
+                 if (BIT (4) == 0 && BIT (7) == 1 && BITS (12, 15) == 0)
+                   {
+                     /* ElSegundo SMULxy insn.  */
+                     ARMword op1 = state->Reg[BITS (0, 3)];
+                     ARMword op2 = state->Reg[BITS (8, 11)];
+
+                     if (BIT (5))
+                       op1 >>= 16;
+                     if (BIT (6))
+                       op2 >>= 16;
+                     op1 &= 0xFFFF;
+                     op2 &= 0xFFFF;
+                     if (op1 & 0x8000)
+                       op1 -= 65536;
+                     if (op2 & 0x8000)
+                       op2 -= 65536;
+
+                     state->Reg[BITS (16, 19)] = op1 * op2;
+                     break;
+                   }
+
+                 if (BITS (4, 11) == 5)
+                   {
+                     /* ElSegundo QDSUB insn.  */
+                     ARMword op1 = state->Reg[BITS (0, 3)];
+                     ARMword op2 = state->Reg[BITS (16, 19)];
+                     ARMword op2d = op2 + op2;
+                     ARMword result;
+
+                     if (AddOverflow (op2, op2, op2d))
+                       {
+                         SETS;
+                         op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
+                       }
+
+                     result = op1 - op2d;
+                     if (SubOverflow (op1, op2d, result))
+                       {
+                         SETS;
+                         result = POS (result) ? 0x80000000 : 0x7fffffff;
+                       }
+
+                     state->Reg[BITS (12, 15)] = result;
+                     break;
+                   }
+               }
+
+             if (state->is_v5)
+               {
+                 if (BITS (4, 11) == 0xF1 && BITS (16, 19) == 0xF)
+                   {
+                     /* ARM5 CLZ insn.  */
+                     ARMword op1 = state->Reg[BITS (0, 3)];
+                     int result = 32;
+
+                     if (op1)
+                       for (result = 0; (op1 & 0x80000000) == 0; op1 <<= 1)
+                         result++;
+
+                     state->Reg[BITS (12, 15)] = result;
+                     break;
+                   }
+               }
 #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;
                }
+             if (BITS (4, 7) == 0xD)
+               {
+                 Handle_Load_Double (state, instr);
+                 break;
+               }
+             if (BITS (4, 7) == 0xF)
+               {
+                 Handle_Store_Double (state, instr);
+                 break;
+               }
 #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;
@@ -1222,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)
                {
@@ -1241,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);
@@ -1265,10 +2708,20 @@ 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;
                }
+             if (BITS (4, 7) == 0xD)
+               {
+                 Handle_Load_Double (state, instr);
+                 break;
+               }
+             if (BITS (4, 7) == 0xF)
+               {
+                 Handle_Store_Double (state, instr);
+                 break;
+               }
 #endif
              rhs = DPRegRHS;
              dest = LHS | rhs;
@@ -1278,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;
@@ -1293,10 +2744,20 @@ 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;
                }
+             if (BITS (4, 7) == 0xD)
+               {
+                 Handle_Load_Double (state, instr);
+                 break;
+               }
+             if (BITS (4, 7) == 0xF)
+               {
+                 Handle_Store_Double (state, instr);
+                 break;
+               }
 #endif
              dest = DPRegRHS;
              WRITEDEST (dest);
@@ -1305,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);
@@ -1319,10 +2778,20 @@ 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;
                }
+             if (BITS (4, 7) == 0xD)
+               {
+                 Handle_Load_Double (state, instr);
+                 break;
+               }
+             else if (BITS (4, 7) == 0xF)
+               {
+                 Handle_Store_Double (state, instr);
+                 break;
+               }
 #endif
              rhs = DPRegRHS;
              dest = LHS & ~rhs;
@@ -1332,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;
@@ -1347,10 +2814,20 @@ 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;
                }
+             if (BITS (4, 7) == 0xD)
+               {
+                 Handle_Load_Double (state, instr);
+                 break;
+               }
+             if (BITS (4, 7) == 0xF)
+               {
+                 Handle_Store_Double (state, instr);
+                 break;
+               }
 #endif
              dest = ~DPRegRHS;
              WRITEDEST (dest);
@@ -1359,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;
@@ -1404,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);
@@ -1426,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);
@@ -1449,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);
@@ -1475,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);
@@ -1533,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);
@@ -1550,7 +3037,8 @@ ARMul_Emulate26 (register ARMul_State * state)
                }
              else
                {
-                 DPSImmRHS;    /* TST immed */
+                 /* TST immed.  */
+                 DPSImmRHS;
                  dest = LHS & rhs;
                  ARMul_NegZero (state, dest);
                }
@@ -1558,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);
@@ -1586,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);
@@ -1604,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);
@@ -1622,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);
@@ -1644,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);
@@ -1663,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;
@@ -1732,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;
@@ -1742,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;
@@ -1764,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;
@@ -1774,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;
@@ -1796,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;
@@ -1806,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;
@@ -1828,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;
@@ -1839,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;
@@ -1855,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;
@@ -1863,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;
@@ -1879,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;
@@ -1887,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;
@@ -1903,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;
@@ -1911,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;
@@ -1927,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;
@@ -1935,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;
                }
@@ -1954,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;
                }
@@ -1970,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;
                }
@@ -1987,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;
                }
@@ -2005,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;
                }
@@ -2020,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;
                }
@@ -2036,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;
                }
@@ -2053,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;
                }
@@ -2071,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;
                }
@@ -2086,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;
                }
@@ -2102,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;
                }
@@ -2119,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;
                }
@@ -2137,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;
                }
@@ -2152,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;
                }
@@ -2168,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;
                }
@@ -2185,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;
                }
@@ -2204,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;
                }
@@ -2237,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;
                }
@@ -2252,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;
                }
@@ -2285,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;
                }
@@ -2300,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;
                }
@@ -2333,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;
                }
@@ -2348,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;
                }
@@ -2381,17 +4042,22 @@ 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.
                     This value should correspond to the value defined
-                    as ARM_BE_BREAKPOINT in gdb/arm-tdep.c.  */
+                    as ARM_BE_BREAKPOINT in gdb/arm/tm-arm.h.  */
                  if (BITS (0, 19) == 0xfdefe)
                    {
                      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;
@@ -2405,161 +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:
@@ -2572,10 +4232,8 @@ ARMul_Emulate26 (register ARMul_State * state)
              FLUSHPIPE;
              break;
 
-/***************************************************************************\
-*                           Branch backward                                 *
-\***************************************************************************/
 
+             /* Branch backward.  */
            case 0xa8:
            case 0xa9:
            case 0xaa:
@@ -2588,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:
@@ -2600,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:
@@ -2621,121 +4276,290 @@ 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_v5)
+               {
+                 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);
+                 /* 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)
+                   {
+                     /* 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;
+                       }
+                   }
+                 else
+                   /* FIXME: Not sure what to do for other v5 processors.  */
+                   ARMul_UndefInstr (state, instr);
+                 break;
+               }
+             /* Drop through.  */
 
-           case 0xc4:
-           case 0xc0:          /* Store , No WriteBack , Post Dec */
+           case 0xc0:          /* Store , No WriteBack , Post Dec.  */
              ARMul_STC (state, instr, LHS);
              break;
 
            case 0xc5:
-           case 0xc1:          /* Load , No WriteBack , Post Dec */
+             if (state->is_v5)
+               {
+                 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);
+                 /* 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)
+                   {
+                     /* 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;
+
+                         state->Reg[BITS (12, 15)] = state->Accumulator;
+                         state->Reg[BITS (16, 19)] = t1;
+                         break;
+                       }
+                   }
+                 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.  */
              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:
+                   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:
+                   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:
+                   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;
+                 }
+             /* Drop through.  */
+
            case 0xe0:
            case 0xe4:
            case 0xe6:
@@ -2744,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
@@ -2758,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:
@@ -2775,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:
@@ -2812,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.  */
@@ -2845,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)
@@ -2868,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
@@ -2899,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)
@@ -2911,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;
@@ -2930,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)
@@ -2957,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
@@ -3012,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)
@@ -3036,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;
@@ -3044,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:
@@ -3064,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));
@@ -3085,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)
@@ -3106,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)
@@ -3138,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;
     }
@@ -3169,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)
@@ -3188,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];
@@ -3205,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)
@@ -3249,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);
@@ -3268,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,
@@ -3281,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);
@@ -3304,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)
@@ -3316,30 +5203,239 @@ 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 storing a word from a STR instruction.     *
-\***************************************************************************/
+/* This function does the work of loading two words for a LDRD instruction.  */
+
+static void
+Handle_Load_Double (ARMul_State * state, ARMword instr)
+{
+  ARMword dest_reg;
+  ARMword addr_reg;
+  ARMword write_back  = BIT (21);
+  ARMword immediate   = BIT (22);
+  ARMword add_to_base = BIT (23);
+  ARMword pre_indexed = BIT (24);
+  ARMword offset;
+  ARMword addr;
+  ARMword sum;
+  ARMword base;
+  ARMword value1;
+  ARMword value2;
+
+  BUSUSEDINCPCS;
+
+  /* If the writeback bit is set, the pre-index bit must be clear.  */
+  if (write_back && ! pre_indexed)
+    {
+      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.  */
+      || (dest_reg == 14))
+    {
+      ARMul_UndefInstr (state, instr);
+      return;
+    }
+
+  /* Compute the base address.  */
+  base = state->Reg[addr_reg];
+
+  /* Compute the offset.  */
+  offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg];
+
+  /* Compute the sum of the two.  */
+  if (add_to_base)
+    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.  */
+  else if (addr & 0x7)
+    {
+#ifdef ABORTS
+      ARMul_DATAABORT (addr);
+#else
+      ARMul_UndefInstr (state, instr);
+#endif
+      return;
+    }
+
+  /* For pre indexed or post indexed addressing modes,
+     check that the destination registers do not overlap
+     the address registers.  */
+  if ((! pre_indexed || write_back)
+      && (   addr_reg == dest_reg
+         || addr_reg == dest_reg + 1))
+    {
+      ARMul_UndefInstr (state, instr);
+      return;
+    }
+
+  /* Load the words.  */
+  value1 = ARMul_LoadWordN (state, addr);
+  value2 = ARMul_LoadWordN (state, addr + 4);
+
+  /* Check for data aborts.  */
+  if (state->Aborted)
+    {
+      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.  */
+
+static void
+Handle_Store_Double (ARMul_State * state, ARMword instr)
+{
+  ARMword src_reg;
+  ARMword addr_reg;
+  ARMword write_back  = BIT (21);
+  ARMword immediate   = BIT (22);
+  ARMword add_to_base = BIT (23);
+  ARMword pre_indexed = BIT (24);
+  ARMword offset;
+  ARMword addr;
+  ARMword sum;
+  ARMword base;
+
+  BUSUSEDINCPCS;
+
+  /* If the writeback bit is set, the pre-index bit must be clear.  */
+  if (write_back && ! pre_indexed)
+    {
+      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)
+    {
+      ARMul_UndefInstr (state, instr);
+      return;
+    }
+
+  /* Compute the base address.  */
+  base = state->Reg[addr_reg];
+
+  /* Compute the offset.  */
+  offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg];
+
+  /* Compute the sum of the two.  */
+  if (add_to_base)
+    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;
+
+  /* The address must be aligned on a 8 byte boundary.  */
+  if (addr & 0x7)
+    {
+#ifdef ABORTS
+      ARMul_DATAABORT (addr);
+#else
+      ARMul_UndefInstr (state, instr);
+#endif
+      return;
+    }
+
+  /* For pre indexed or post indexed addressing modes,
+     check that the destination registers do not overlap
+     the address registers.  */
+  if ((! pre_indexed || write_back)
+      && (   addr_reg == src_reg
+         || addr_reg == src_reg + 1))
+    {
+      ARMul_UndefInstr (state, instr);
+      return;
+    }
+
+  /* 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.  */
 
 static unsigned
 StoreWord (ARMul_State * state, ARMword instr, ARMword address)
@@ -3363,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)
@@ -3398,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)
@@ -3432,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)
@@ -3456,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)
     {
@@ -3496,69 +5596,86 @@ 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;
 
   UNDEF_LSMNoRegs;
   UNDEF_LSMPCBase;
   UNDEF_LSMBaseInListWb;
+
   BUSUSEDINCPCS;
+
 #ifndef MODE32
   if (ADDREXCEPT (address))
-    {
-      INTERNALABORT (address);
-    }
+    INTERNALABORT (address);
 #endif
 
+  if (BIT (21) && LHSReg != 15)
+    LSBase = WBBase;
+
   if (!BIT (15) && state->Bank != USERBANK)
     {
-      (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);        /* temporary reg bank switch */
+      /* Temporary reg bank switch.  */
+      (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
       UNDEF_LSMUserBankWb;
     }
 
-  if (BIT (21) && LHSReg != 15)
-    LSBase = WBBase;
+  /* N cycle first.  */
+  for (temp = 0; !BIT (temp); temp ++)
+    ;
 
-  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;
+    }
 
-  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 */
+    {
+      /* PC is in the reg list.  */
 #ifdef MODE32
       if (state->Mode != USER26MODE && state->Mode != USER32MODE)
        {
          state->Cpsr = GETSPSR (state->Bank);
          ARMul_CPSRAltered (state);
        }
+
       WriteR15 (state, PC);
 #else
       if (state->Mode == USER26MODE || state->Mode == USER32MODE)
-       {                       /* protect bits in user mode */
+       {
+         /* Protect bits in user mode.  */
          ASSIGNN ((state->Reg[15] & NBIT) != 0);
          ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
          ASSIGNC ((state->Reg[15] & CBIT) != 0);
@@ -3566,67 +5683,76 @@ LoadSMult (ARMul_State * state, ARMword instr,
        }
       else
        ARMul_R15Altered (state);
+
       FLUSHPIPE;
 #endif
     }
 
   if (!BIT (15) && state->Mode != USER26MODE && state->Mode != USER32MODE)
-    (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);  /* restore the correct bank */
+    /* Restore the correct bank.  */
+    (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
 
-  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)
     {
       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;
@@ -3635,107 +5761,135 @@ 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, ARMword instr,
-           ARMword address, ARMword WBBase)
+StoreSMult (ARMul_State * state,
+           ARMword       instr,
+           ARMword       address,
+           ARMword       WBBase)
 {
   ARMword temp;
 
   UNDEF_LSMNoRegs;
   UNDEF_LSMPCBase;
   UNDEF_LSMBaseInListWb;
+
   BUSUSEDINCPCN;
+
 #ifndef MODE32
   if (VECTORACCESS (address) || ADDREXCEPT (address))
-    {
-      INTERNALABORT (address);
-    }
+    INTERNALABORT (address);
+
   if (BIT (15))
     PATCHR15;
 #endif
 
   if (state->Bank != USERBANK)
     {
-      (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);        /* Force User Bank */
+      /* Force User Bank.  */
+      (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
       UNDEF_LSMUserBankWb;
     }
 
-  for (temp = 0; !BIT (temp); temp++); /* N cycle first */
+  for (temp = 0; !BIT (temp); temp++)
+    ;  /* N cycle first.  */
+
 #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 */
+
+      for (; temp < 16; temp++)
+       /* Fake the Stores as Loads.  */
        if (BIT (temp))
-         {                     /* save this register */
+         {
+           /* Save this register.  */
            address += 4;
+
            (void) ARMul_LoadWordS (state, address);
          }
+
       if (BIT (21) && LHSReg != 15)
        LSBase = WBBase;
+
       TAKEABORT;
       return;
     }
   else
     ARMul_StoreWordN (state, address, state->Reg[temp++]);
 #endif
-  if (state->abortSig && !state->Aborted)
-    state->Aborted = ARMul_DataAbortV;
 
-  if (BIT (21) && LHSReg != 15)
-    LSBase = WBBase;
+  if (state->abortSig && !state->Aborted)
+    {
+      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))
-      {                                /* 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->Mode != USER26MODE && state->Mode != USER32MODE)
-    (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);  /* restore the correct bank */
+    /* Restore the correct bank.  */
+    (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
+
+  if (BIT (21) && LHSReg != 15)
+    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)
@@ -3745,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);
@@ -3816,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)
@@ -3830,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
-    fprintf (stderr, "MULTIPLY64 - INVALID ARGUMENTS\n");
+    }
+  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;
@@ -3858,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)
@@ -3886,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.096325 seconds and 4 git commands to generate.