Remove use of __IWMMXT__.
[platform/upstream/binutils.git] / sim / arm / armemu.c
1 /*  armemu.c -- Main instruction emulation:  ARM7 Instruction Emulator.
2     Copyright (C) 1994 Advanced RISC Machines Ltd.
3     Modifications to add arch. v4 support by <jsmith@cygnus.com>.
4  
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9  
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14  
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18
19 #include "armdefs.h"
20 #include "armemu.h"
21 #include "armos.h"
22 #include "iwmmxt.h"
23
24 static ARMword  GetDPRegRHS         (ARMul_State *, ARMword);
25 static ARMword  GetDPSRegRHS        (ARMul_State *, ARMword);
26 static void     WriteR15            (ARMul_State *, ARMword);
27 static void     WriteSR15           (ARMul_State *, ARMword);
28 static void     WriteR15Branch      (ARMul_State *, ARMword);
29 static ARMword  GetLSRegRHS         (ARMul_State *, ARMword);
30 static ARMword  GetLS7RHS           (ARMul_State *, ARMword);
31 static unsigned LoadWord            (ARMul_State *, ARMword, ARMword);
32 static unsigned LoadHalfWord        (ARMul_State *, ARMword, ARMword, int);
33 static unsigned LoadByte            (ARMul_State *, ARMword, ARMword, int);
34 static unsigned StoreWord           (ARMul_State *, ARMword, ARMword);
35 static unsigned StoreHalfWord       (ARMul_State *, ARMword, ARMword);
36 static unsigned StoreByte           (ARMul_State *, ARMword, ARMword);
37 static void     LoadMult            (ARMul_State *, ARMword, ARMword, ARMword);
38 static void     StoreMult           (ARMul_State *, ARMword, ARMword, ARMword);
39 static void     LoadSMult           (ARMul_State *, ARMword, ARMword, ARMword);
40 static void     StoreSMult          (ARMul_State *, ARMword, ARMword, ARMword);
41 static unsigned Multiply64          (ARMul_State *, ARMword, int, int);
42 static unsigned MultiplyAdd64       (ARMul_State *, ARMword, int, int);
43 static void     Handle_Load_Double  (ARMul_State *, ARMword);
44 static void     Handle_Store_Double (ARMul_State *, ARMword);
45
46 #define LUNSIGNED (0)           /* unsigned operation */
47 #define LSIGNED   (1)           /* signed operation */
48 #define LDEFAULT  (0)           /* default : do nothing */
49 #define LSCC      (1)           /* set condition codes on result */
50
51 #ifdef NEED_UI_LOOP_HOOK
52 /* How often to run the ui_loop update, when in use.  */
53 #define UI_LOOP_POLL_INTERVAL 0x32000
54
55 /* Counter for the ui_loop_hook update.  */
56 static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
57
58 /* Actual hook to call to run through gdb's gui event loop.  */
59 extern int (*ui_loop_hook) (int);
60 #endif /* NEED_UI_LOOP_HOOK */
61
62 extern int stop_simulator;
63
64 /* Short-hand macros for LDR/STR.  */
65
66 /* Store post decrement writeback.  */
67 #define SHDOWNWB()                                      \
68   lhs = LHS ;                                           \
69   if (StoreHalfWord (state, instr, lhs))                \
70      LSBase = lhs - GetLS7RHS (state, instr);
71
72 /* Store post increment writeback.  */
73 #define SHUPWB()                                        \
74   lhs = LHS ;                                           \
75   if (StoreHalfWord (state, instr, lhs))                \
76      LSBase = lhs + GetLS7RHS (state, instr);
77
78 /* Store pre decrement.  */
79 #define SHPREDOWN()                                     \
80   (void)StoreHalfWord (state, instr, LHS - GetLS7RHS (state, instr));
81
82 /* Store pre decrement writeback.  */
83 #define SHPREDOWNWB()                                   \
84   temp = LHS - GetLS7RHS (state, instr);                \
85   if (StoreHalfWord (state, instr, temp))               \
86      LSBase = temp;
87
88 /* Store pre increment.  */
89 #define SHPREUP()                                       \
90   (void)StoreHalfWord (state, instr, LHS + GetLS7RHS (state, instr));
91
92 /* Store pre increment writeback.  */
93 #define SHPREUPWB()                                     \
94   temp = LHS + GetLS7RHS (state, instr);                \
95   if (StoreHalfWord (state, instr, temp))               \
96      LSBase = temp;
97
98 /* Load post decrement writeback.  */
99 #define LHPOSTDOWN()                                    \
100 {                                                       \
101   int done = 1;                                         \
102   lhs = LHS;                                            \
103   temp = lhs - GetLS7RHS (state, instr);                \
104                                                         \
105   switch (BITS (5, 6))                                  \
106     {                                                   \
107     case 1: /* H */                                     \
108       if (LoadHalfWord (state, instr, lhs, LUNSIGNED))  \
109          LSBase = temp;                                 \
110       break;                                            \
111     case 2: /* SB */                                    \
112       if (LoadByte (state, instr, lhs, LSIGNED))        \
113          LSBase = temp;                                 \
114       break;                                            \
115     case 3: /* SH */                                    \
116       if (LoadHalfWord (state, instr, lhs, LSIGNED))    \
117          LSBase = temp;                                 \
118       break;                                            \
119     case 0: /* SWP handled elsewhere.  */               \
120     default:                                            \
121       done = 0;                                         \
122       break;                                            \
123     }                                                   \
124   if (done)                                             \
125      break;                                             \
126 }
127
128 /* Load post increment writeback.  */
129 #define LHPOSTUP()                                      \
130 {                                                       \
131   int done = 1;                                         \
132   lhs = LHS;                                            \
133   temp = lhs + GetLS7RHS (state, instr);                \
134                                                         \
135   switch (BITS (5, 6))                                  \
136     {                                                   \
137     case 1: /* H */                                     \
138       if (LoadHalfWord (state, instr, lhs, LUNSIGNED))  \
139          LSBase = temp;                                 \
140       break;                                            \
141     case 2: /* SB */                                    \
142       if (LoadByte (state, instr, lhs, LSIGNED))        \
143          LSBase = temp;                                 \
144       break;                                            \
145     case 3: /* SH */                                    \
146       if (LoadHalfWord (state, instr, lhs, LSIGNED))    \
147          LSBase = temp;                                 \
148       break;                                            \
149     case 0: /* SWP handled elsewhere.  */               \
150     default:                                            \
151       done = 0;                                         \
152       break;                                            \
153     }                                                   \
154   if (done)                                             \
155      break;                                             \
156 }
157
158 /* Load pre decrement.  */
159 #define LHPREDOWN()                                             \
160 {                                                               \
161   int done = 1;                                                 \
162                                                                 \
163   temp = LHS - GetLS7RHS (state, instr);                        \
164   switch (BITS (5, 6))                                          \
165     {                                                           \
166     case 1: /* H */                                             \
167       (void) LoadHalfWord (state, instr, temp, LUNSIGNED);      \
168       break;                                                    \
169     case 2: /* SB */                                            \
170       (void) LoadByte (state, instr, temp, LSIGNED);            \
171       break;                                                    \
172     case 3: /* SH */                                            \
173       (void) LoadHalfWord (state, instr, temp, LSIGNED);        \
174       break;                                                    \
175     case 0:                                                     \
176       /* SWP handled elsewhere.  */                             \
177     default:                                                    \
178       done = 0;                                                 \
179       break;                                                    \
180     }                                                           \
181   if (done)                                                     \
182      break;                                                     \
183 }
184
185 /* Load pre decrement writeback.  */
186 #define LHPREDOWNWB()                                           \
187 {                                                               \
188   int done = 1;                                                 \
189                                                                 \
190   temp = LHS - GetLS7RHS (state, instr);                        \
191   switch (BITS (5, 6))                                          \
192     {                                                           \
193     case 1: /* H */                                             \
194       if (LoadHalfWord (state, instr, temp, LUNSIGNED))         \
195          LSBase = temp;                                         \
196       break;                                                    \
197     case 2: /* SB */                                            \
198       if (LoadByte (state, instr, temp, LSIGNED))               \
199          LSBase = temp;                                         \
200       break;                                                    \
201     case 3: /* SH */                                            \
202       if (LoadHalfWord (state, instr, temp, LSIGNED))           \
203          LSBase = temp;                                         \
204       break;                                                    \
205     case 0:                                                     \
206       /* SWP handled elsewhere.  */                             \
207     default:                                                    \
208       done = 0;                                                 \
209       break;                                                    \
210     }                                                           \
211   if (done)                                                     \
212      break;                                                     \
213 }
214
215 /* Load pre increment.  */
216 #define LHPREUP()                                               \
217 {                                                               \
218   int done = 1;                                                 \
219                                                                 \
220   temp = LHS + GetLS7RHS (state, instr);                        \
221   switch (BITS (5, 6))                                          \
222     {                                                           \
223     case 1: /* H */                                             \
224       (void) LoadHalfWord (state, instr, temp, LUNSIGNED);      \
225       break;                                                    \
226     case 2: /* SB */                                            \
227       (void) LoadByte (state, instr, temp, LSIGNED);            \
228       break;                                                    \
229     case 3: /* SH */                                            \
230       (void) LoadHalfWord (state, instr, temp, LSIGNED);        \
231       break;                                                    \
232     case 0:                                                     \
233       /* SWP handled elsewhere.  */                             \
234     default:                                                    \
235       done = 0;                                                 \
236       break;                                                    \
237     }                                                           \
238   if (done)                                                     \
239      break;                                                     \
240 }
241
242 /* Load pre increment writeback.  */
243 #define LHPREUPWB()                                             \
244 {                                                               \
245   int done = 1;                                                 \
246                                                                 \
247   temp = LHS + GetLS7RHS (state, instr);                        \
248   switch (BITS (5, 6))                                          \
249     {                                                           \
250     case 1: /* H */                                             \
251       if (LoadHalfWord (state, instr, temp, LUNSIGNED))         \
252         LSBase = temp;                                          \
253       break;                                                    \
254     case 2: /* SB */                                            \
255       if (LoadByte (state, instr, temp, LSIGNED))               \
256         LSBase = temp;                                          \
257       break;                                                    \
258     case 3: /* SH */                                            \
259       if (LoadHalfWord (state, instr, temp, LSIGNED))           \
260         LSBase = temp;                                          \
261       break;                                                    \
262     case 0:                                                     \
263       /* SWP handled elsewhere.  */                             \
264     default:                                                    \
265       done = 0;                                                 \
266       break;                                                    \
267     }                                                           \
268   if (done)                                                     \
269      break;                                                     \
270 }
271
272 /* EMULATION of ARM6.  */
273
274 /* The PC pipeline value depends on whether ARM
275    or Thumb instructions are being executed.  */
276 ARMword isize;
277
278 ARMword
279 #ifdef MODE32
280 ARMul_Emulate32 (ARMul_State * state)
281 #else
282 ARMul_Emulate26 (ARMul_State * state)
283 #endif
284 {
285   ARMword instr;        /* The current instruction.  */
286   ARMword dest = 0;     /* Almost the DestBus.  */
287   ARMword temp;         /* Ubiquitous third hand.  */
288   ARMword pc = 0;       /* The address of the current instruction.  */
289   ARMword lhs;          /* Almost the ABus and BBus.  */
290   ARMword rhs;
291   ARMword decoded = 0;  /* Instruction pipeline.  */
292   ARMword loaded = 0;   
293
294   /* Execute the next instruction.  */
295
296   if (state->NextInstr < PRIMEPIPE)
297     {
298       decoded = state->decoded;
299       loaded = state->loaded;
300       pc = state->pc;
301     }
302
303   do
304     {
305       /* Just keep going.  */
306       isize = INSN_SIZE;
307
308       switch (state->NextInstr)
309         {
310         case SEQ:
311           /* Advance the pipeline, and an S cycle.  */
312           state->Reg[15] += isize;
313           pc += isize;
314           instr = decoded;
315           decoded = loaded;
316           loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
317           break;
318
319         case NONSEQ:
320           /* Advance the pipeline, and an N cycle.  */
321           state->Reg[15] += isize;
322           pc += isize;
323           instr = decoded;
324           decoded = loaded;
325           loaded = ARMul_LoadInstrN (state, pc + (isize * 2), isize);
326           NORMALCYCLE;
327           break;
328
329         case PCINCEDSEQ:
330           /* Program counter advanced, and an S cycle.  */
331           pc += isize;
332           instr = decoded;
333           decoded = loaded;
334           loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
335           NORMALCYCLE;
336           break;
337
338         case PCINCEDNONSEQ:
339           /* Program counter advanced, and an N cycle.  */
340           pc += isize;
341           instr = decoded;
342           decoded = loaded;
343           loaded = ARMul_LoadInstrN (state, pc + (isize * 2), isize);
344           NORMALCYCLE;
345           break;
346
347         case RESUME:
348           /* The program counter has been changed.  */
349           pc = state->Reg[15];
350 #ifndef MODE32
351           pc = pc & R15PCBITS;
352 #endif
353           state->Reg[15] = pc + (isize * 2);
354           state->Aborted = 0;
355           instr   = ARMul_ReLoadInstr (state, pc, isize);
356           decoded = ARMul_ReLoadInstr (state, pc + isize, isize);
357           loaded  = ARMul_ReLoadInstr (state, pc + isize * 2, isize);
358           NORMALCYCLE;
359           break;
360
361         default:
362           /* The program counter has been changed.  */
363           pc = state->Reg[15];
364 #ifndef MODE32
365           pc = pc & R15PCBITS;
366 #endif
367           state->Reg[15] = pc + (isize * 2);
368           state->Aborted = 0;
369           instr   = ARMul_LoadInstrN (state, pc, isize);
370           decoded = ARMul_LoadInstrS (state, pc + (isize), isize);
371           loaded  = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
372           NORMALCYCLE;
373           break;
374         }
375
376       if (state->EventSet)
377         ARMul_EnvokeEvent (state);
378 #if 0 /* Enable this for a helpful bit of debugging when tracing is needed.  */
379       fprintf (stderr, "pc: %x, instr: %x\n", pc & ~1, instr);
380       if (instr == 0)
381         abort ();
382 #endif
383 #if 0 /* Enable this code to help track down stack alignment bugs.  */
384       {
385         static ARMword old_sp = -1;
386
387         if (old_sp != state->Reg[13])
388           {
389             old_sp = state->Reg[13];
390             fprintf (stderr, "pc: %08x: SP set to %08x%s\n",
391                      pc & ~1, old_sp, (old_sp % 8) ? " [UNALIGNED!]" : "");
392           }
393       }
394 #endif
395
396       if (state->Exception)
397         {
398           /* Any exceptions ?  */
399           if (state->NresetSig == LOW)
400             {
401               ARMul_Abort (state, ARMul_ResetV);
402               break;
403             }
404           else if (!state->NfiqSig && !FFLAG)
405             {
406               ARMul_Abort (state, ARMul_FIQV);
407               break;
408             }
409           else if (!state->NirqSig && !IFLAG)
410             {
411               ARMul_Abort (state, ARMul_IRQV);
412               break;
413             }
414         }
415
416       if (state->CallDebug > 0)
417         {
418           instr = ARMul_Debug (state, pc, instr);
419           if (state->Emulate < ONCE)
420             {
421               state->NextInstr = RESUME;
422               break;
423             }
424           if (state->Debug)
425             {
426               fprintf (stderr, "sim: At %08lx Instr %08lx Mode %02lx\n", pc, instr,
427                        state->Mode);
428               (void) fgetc (stdin);
429             }
430         }
431       else if (state->Emulate < ONCE)
432         {
433           state->NextInstr = RESUME;
434           break;
435         }
436
437       state->NumInstrs++;
438
439 #ifdef MODET
440       /* Provide Thumb instruction decoding. If the processor is in Thumb
441          mode, then we can simply decode the Thumb instruction, and map it
442          to the corresponding ARM instruction (by directly loading the
443          instr variable, and letting the normal ARM simulator
444          execute). There are some caveats to ensure that the correct
445          pipelined PC value is used when executing Thumb code, and also for
446          dealing with the BL instruction.  */
447       if (TFLAG)
448         {
449           ARMword new;
450
451           /* Check if in Thumb mode.  */
452           switch (ARMul_ThumbDecode (state, pc, instr, &new))
453             {
454             case t_undefined:
455               /* This is a Thumb instruction.  */
456               ARMul_UndefInstr (state, instr);
457               goto donext;
458
459             case t_branch:
460               /* Already processed.  */
461               goto donext;
462
463             case t_decoded:
464               /* ARM instruction available.  */
465               instr = new;
466               /* So continue instruction decoding.  */
467               break;
468             default:
469               break;
470             }
471         }
472 #endif
473
474       /* Check the condition codes.  */
475       if ((temp = TOPBITS (28)) == AL)
476         /* Vile deed in the need for speed.  */
477         goto mainswitch;
478
479       /* Check the condition code.  */
480       switch ((int) TOPBITS (28))
481         {
482         case AL:
483           temp = TRUE;
484           break;
485         case NV:
486           if (state->is_v5)
487             {
488               if (BITS (25, 27) == 5) /* BLX(1) */
489                 {
490                   ARMword dest;
491                   
492                   state->Reg[14] = pc + 4;
493                   
494                   /* Force entry into Thumb mode.  */
495                   dest = pc + 8 + 1;
496                   if (BIT (23))
497                     dest += (NEGBRANCH + (BIT (24) << 1));
498                   else
499                     dest += POSBRANCH + (BIT (24) << 1);
500
501                   WriteR15Branch (state, dest);
502                   goto donext;
503                 }
504               else if ((instr & 0xFC70F000) == 0xF450F000)
505                 /* The PLD instruction.  Ignored.  */
506                 goto donext;
507               else if (   ((instr & 0xfe500f00) == 0xfc100100)
508                        || ((instr & 0xfe500f00) == 0xfc000100))
509                 /* wldrw and wstrw are unconditional.  */
510                 goto mainswitch;
511               else
512                 /* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2.  */
513                 ARMul_UndefInstr (state, instr);
514             }
515           temp = FALSE;
516           break;
517         case EQ:
518           temp = ZFLAG;
519           break;
520         case NE:
521           temp = !ZFLAG;
522           break;
523         case VS:
524           temp = VFLAG;
525           break;
526         case VC:
527           temp = !VFLAG;
528           break;
529         case MI:
530           temp = NFLAG;
531           break;
532         case PL:
533           temp = !NFLAG;
534           break;
535         case CS:
536           temp = CFLAG;
537           break;
538         case CC:
539           temp = !CFLAG;
540           break;
541         case HI:
542           temp = (CFLAG && !ZFLAG);
543           break;
544         case LS:
545           temp = (!CFLAG || ZFLAG);
546           break;
547         case GE:
548           temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
549           break;
550         case LT:
551           temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
552           break;
553         case GT:
554           temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG));
555           break;
556         case LE:
557           temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
558           break;
559         }                       /* cc check */
560
561       /* Handle the Clock counter here.  */
562       if (state->is_XScale)
563         {
564           ARMword cp14r0;
565           int ok;
566
567           ok = state->CPRead[14] (state, 0, & cp14r0);
568
569           if (ok && (cp14r0 & ARMul_CP14_R0_ENABLE))
570             {
571               unsigned long newcycles, nowtime = ARMul_Time (state);
572
573               newcycles = nowtime - state->LastTime;
574               state->LastTime = nowtime;
575
576               if (cp14r0 & ARMul_CP14_R0_CCD)
577                 {
578                   if (state->CP14R0_CCD == -1)
579                     state->CP14R0_CCD = newcycles;
580                   else
581                     state->CP14R0_CCD += newcycles;
582
583                   if (state->CP14R0_CCD >= 64)
584                     {
585                       newcycles = 0;
586
587                       while (state->CP14R0_CCD >= 64)
588                         state->CP14R0_CCD -= 64, newcycles++;
589
590                       goto check_PMUintr;
591                     }
592                 }
593               else
594                 {
595                   ARMword cp14r1;
596                   int do_int = 0;
597
598                   state->CP14R0_CCD = -1;
599 check_PMUintr:
600                   cp14r0 |= ARMul_CP14_R0_FLAG2;
601                   (void) state->CPWrite[14] (state, 0, cp14r0);
602
603                   ok = state->CPRead[14] (state, 1, & cp14r1);
604
605                   /* Coded like this for portability.  */
606                   while (ok && newcycles)
607                     {
608                       if (cp14r1 == 0xffffffff)
609                         {
610                           cp14r1 = 0;
611                           do_int = 1;
612                         }
613                       else
614                         cp14r1 ++;
615
616                       newcycles --;
617                     }
618
619                   (void) state->CPWrite[14] (state, 1, cp14r1);
620
621                   if (do_int && (cp14r0 & ARMul_CP14_R0_INTEN2))
622                     {
623                       ARMword temp;
624
625                       if (state->CPRead[13] (state, 8, & temp)
626                           && (temp & ARMul_CP13_R8_PMUS))
627                         ARMul_Abort (state, ARMul_FIQV);
628                       else
629                         ARMul_Abort (state, ARMul_IRQV);
630                     }
631                 }
632             }
633         }
634
635       /* Handle hardware instructions breakpoints here.  */
636       if (state->is_XScale)
637         {
638           if (   (pc | 3) == (read_cp15_reg (14, 0, 8) | 2)
639               || (pc | 3) == (read_cp15_reg (14, 0, 9) | 2))
640             {
641               if (XScale_debug_moe (state, ARMul_CP14_R10_MOE_IB))
642                 ARMul_OSHandleSWI (state, SWI_Breakpoint);
643             }
644         }
645
646       /* Actual execution of instructions begins here.  */
647       /* If the condition codes don't match, stop here.  */
648       if (temp)
649         {
650         mainswitch:
651
652           if (state->is_XScale)
653             {
654               if (BIT (20) == 0 && BITS (25, 27) == 0)
655                 {
656                   if (BITS (4, 7) == 0xD)
657                     {
658                       /* XScale Load Consecutive insn.  */
659                       ARMword temp = GetLS7RHS (state, instr);
660                       ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
661                       ARMword addr = BIT (24) ? temp2 : LHS;
662                       
663                       if (BIT (12))
664                         ARMul_UndefInstr (state, instr);
665                       else if (addr & 7)
666                         /* Alignment violation.  */
667                         ARMul_Abort (state, ARMul_DataAbortV);
668                       else
669                         {
670                           int wb = BIT (21) || (! BIT (24));
671                           
672                           state->Reg[BITS (12, 15)] =
673                             ARMul_LoadWordN (state, addr);
674                           state->Reg[BITS (12, 15) + 1] =
675                             ARMul_LoadWordN (state, addr + 4);
676                           if (wb)
677                             LSBase = temp2;
678                         }
679
680                       goto donext;
681                     }
682                   else if (BITS (4, 7) == 0xF)
683                     {
684                       /* XScale Store Consecutive insn.  */
685                       ARMword temp = GetLS7RHS (state, instr);
686                       ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
687                       ARMword addr = BIT (24) ? temp2 : LHS;
688
689                       if (BIT (12))
690                         ARMul_UndefInstr (state, instr);
691                       else if (addr & 7)
692                         /* Alignment violation.  */
693                         ARMul_Abort (state, ARMul_DataAbortV);
694                       else
695                         {
696                           ARMul_StoreWordN (state, addr,
697                                             state->Reg[BITS (12, 15)]);
698                           ARMul_StoreWordN (state, addr + 4,
699                                             state->Reg[BITS (12, 15) + 1]);
700
701                           if (BIT (21)|| ! BIT (24))
702                             LSBase = temp2;
703                         }
704
705                       goto donext;
706                     }
707                 }
708
709               if (ARMul_HandleIwmmxt (state, instr))
710                 goto donext;
711             }
712
713           switch ((int) BITS (20, 27))
714             {
715               /* Data Processing Register RHS Instructions.  */
716
717             case 0x00:          /* AND reg and MUL */
718 #ifdef MODET
719               if (BITS (4, 11) == 0xB)
720                 {
721                   /* STRH register offset, no write-back, down, post indexed.  */
722                   SHDOWNWB ();
723                   break;
724                 }
725               if (BITS (4, 7) == 0xD)
726                 {
727                   Handle_Load_Double (state, instr);
728                   break;
729                 }
730               if (BITS (4, 7) == 0xF)
731                 {
732                   Handle_Store_Double (state, instr);
733                   break;
734                 }
735 #endif
736               if (BITS (4, 7) == 9)
737                 {
738                   /* MUL */
739                   rhs = state->Reg[MULRHSReg];
740                   if (MULLHSReg == MULDESTReg)
741                     {
742                       UNDEF_MULDestEQOp1;
743                       state->Reg[MULDESTReg] = 0;
744                     }
745                   else if (MULDESTReg != 15)
746                     state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs;
747                   else
748                     UNDEF_MULPCDest;
749
750                   for (dest = 0, temp = 0; dest < 32; dest ++)
751                     if (rhs & (1L << dest))
752                       temp = dest;
753
754                   /* Mult takes this many/2 I cycles.  */
755                   ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
756                 }
757               else
758                 {
759                   /* AND reg.  */
760                   rhs = DPRegRHS;
761                   dest = LHS & rhs;
762                   WRITEDEST (dest);
763                 }
764               break;
765
766             case 0x01:          /* ANDS reg and MULS */
767 #ifdef MODET
768               if ((BITS (4, 11) & 0xF9) == 0x9)
769                 /* LDR register offset, no write-back, down, post indexed.  */
770                 LHPOSTDOWN ();
771               /* Fall through to rest of decoding.  */
772 #endif
773               if (BITS (4, 7) == 9)
774                 {
775                   /* MULS */
776                   rhs = state->Reg[MULRHSReg];
777
778                   if (MULLHSReg == MULDESTReg)
779                     {
780                       UNDEF_MULDestEQOp1;
781                       state->Reg[MULDESTReg] = 0;
782                       CLEARN;
783                       SETZ;
784                     }
785                   else if (MULDESTReg != 15)
786                     {
787                       dest = state->Reg[MULLHSReg] * rhs;
788                       ARMul_NegZero (state, dest);
789                       state->Reg[MULDESTReg] = dest;
790                     }
791                   else
792                     UNDEF_MULPCDest;
793
794                   for (dest = 0, temp = 0; dest < 32; dest ++)
795                     if (rhs & (1L << dest))
796                       temp = dest;
797
798                   /* Mult takes this many/2 I cycles.  */
799                   ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
800                 }
801               else
802                 {
803                   /* ANDS reg.  */
804                   rhs = DPSRegRHS;
805                   dest = LHS & rhs;
806                   WRITESDEST (dest);
807                 }
808               break;
809
810             case 0x02:          /* EOR reg and MLA */
811 #ifdef MODET
812               if (BITS (4, 11) == 0xB)
813                 {
814                   /* STRH register offset, write-back, down, post indexed.  */
815                   SHDOWNWB ();
816                   break;
817                 }
818 #endif
819               if (BITS (4, 7) == 9)
820                 {               /* MLA */
821                   rhs = state->Reg[MULRHSReg];
822                   if (MULLHSReg == MULDESTReg)
823                     {
824                       UNDEF_MULDestEQOp1;
825                       state->Reg[MULDESTReg] = state->Reg[MULACCReg];
826                     }
827                   else if (MULDESTReg != 15)
828                     state->Reg[MULDESTReg] =
829                       state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
830                   else
831                     UNDEF_MULPCDest;
832
833                   for (dest = 0, temp = 0; dest < 32; dest ++)
834                     if (rhs & (1L << dest))
835                       temp = dest;
836
837                   /* Mult takes this many/2 I cycles.  */
838                   ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
839                 }
840               else
841                 {
842                   rhs = DPRegRHS;
843                   dest = LHS ^ rhs;
844                   WRITEDEST (dest);
845                 }
846               break;
847
848             case 0x03:          /* EORS reg and MLAS */
849 #ifdef MODET
850               if ((BITS (4, 11) & 0xF9) == 0x9)
851                 /* LDR register offset, write-back, down, post-indexed.  */
852                 LHPOSTDOWN ();
853               /* Fall through to rest of the decoding.  */
854 #endif
855               if (BITS (4, 7) == 9)
856                 {
857                   /* MLAS */
858                   rhs = state->Reg[MULRHSReg];
859
860                   if (MULLHSReg == MULDESTReg)
861                     {
862                       UNDEF_MULDestEQOp1;
863                       dest = state->Reg[MULACCReg];
864                       ARMul_NegZero (state, dest);
865                       state->Reg[MULDESTReg] = dest;
866                     }
867                   else if (MULDESTReg != 15)
868                     {
869                       dest =
870                         state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
871                       ARMul_NegZero (state, dest);
872                       state->Reg[MULDESTReg] = dest;
873                     }
874                   else
875                     UNDEF_MULPCDest;
876
877                   for (dest = 0, temp = 0; dest < 32; dest ++)
878                     if (rhs & (1L << dest))
879                       temp = dest;
880
881                   /* Mult takes this many/2 I cycles.  */
882                   ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
883                 }
884               else
885                 {
886                   /* EORS Reg.  */
887                   rhs = DPSRegRHS;
888                   dest = LHS ^ rhs;
889                   WRITESDEST (dest);
890                 }
891               break;
892
893             case 0x04:          /* SUB reg */
894 #ifdef MODET
895               if (BITS (4, 7) == 0xB)
896                 {
897                   /* STRH immediate offset, no write-back, down, post indexed.  */
898                   SHDOWNWB ();
899                   break;
900                 }
901               if (BITS (4, 7) == 0xD)
902                 {
903                   Handle_Load_Double (state, instr);
904                   break;
905                 }
906               if (BITS (4, 7) == 0xF)
907                 {
908                   Handle_Store_Double (state, instr);
909                   break;
910                 }
911 #endif
912               rhs = DPRegRHS;
913               dest = LHS - rhs;
914               WRITEDEST (dest);
915               break;
916
917             case 0x05:          /* SUBS reg */
918 #ifdef MODET
919               if ((BITS (4, 7) & 0x9) == 0x9)
920                 /* LDR immediate offset, no write-back, down, post indexed.  */
921                 LHPOSTDOWN ();
922               /* Fall through to the rest of the instruction decoding.  */
923 #endif
924               lhs = LHS;
925               rhs = DPRegRHS;
926               dest = lhs - rhs;
927
928               if ((lhs >= rhs) || ((rhs | lhs) >> 31))
929                 {
930                   ARMul_SubCarry (state, lhs, rhs, dest);
931                   ARMul_SubOverflow (state, lhs, rhs, dest);
932                 }
933               else
934                 {
935                   CLEARC;
936                   CLEARV;
937                 }
938               WRITESDEST (dest);
939               break;
940
941             case 0x06:          /* RSB reg */
942 #ifdef MODET
943               if (BITS (4, 7) == 0xB)
944                 {
945                   /* STRH immediate offset, write-back, down, post indexed.  */
946                   SHDOWNWB ();
947                   break;
948                 }
949 #endif
950               rhs = DPRegRHS;
951               dest = rhs - LHS;
952               WRITEDEST (dest);
953               break;
954
955             case 0x07:          /* RSBS reg */
956 #ifdef MODET
957               if ((BITS (4, 7) & 0x9) == 0x9)
958                 /* LDR immediate offset, write-back, down, post indexed.  */
959                 LHPOSTDOWN ();
960               /* Fall through to remainder of instruction decoding.  */
961 #endif
962               lhs = LHS;
963               rhs = DPRegRHS;
964               dest = rhs - lhs;
965
966               if ((rhs >= lhs) || ((rhs | lhs) >> 31))
967                 {
968                   ARMul_SubCarry (state, rhs, lhs, dest);
969                   ARMul_SubOverflow (state, rhs, lhs, dest);
970                 }
971               else
972                 {
973                   CLEARC;
974                   CLEARV;
975                 }
976               WRITESDEST (dest);
977               break;
978
979             case 0x08:          /* ADD reg */
980 #ifdef MODET
981               if (BITS (4, 11) == 0xB)
982                 {
983                   /* STRH register offset, no write-back, up, post indexed.  */
984                   SHUPWB ();
985                   break;
986                 }
987               if (BITS (4, 7) == 0xD)
988                 {
989                   Handle_Load_Double (state, instr);
990                   break;
991                 }
992               if (BITS (4, 7) == 0xF)
993                 {
994                   Handle_Store_Double (state, instr);
995                   break;
996                 }
997 #endif
998 #ifdef MODET
999               if (BITS (4, 7) == 0x9)
1000                 {
1001                   /* MULL */
1002                   /* 32x32 = 64 */
1003                   ARMul_Icycles (state,
1004                                  Multiply64 (state, instr, LUNSIGNED,
1005                                              LDEFAULT), 0L);
1006                   break;
1007                 }
1008 #endif
1009               rhs = DPRegRHS;
1010               dest = LHS + rhs;
1011               WRITEDEST (dest);
1012               break;
1013
1014             case 0x09:          /* ADDS reg */
1015 #ifdef MODET
1016               if ((BITS (4, 11) & 0xF9) == 0x9)
1017                 /* LDR register offset, no write-back, up, post indexed.  */
1018                 LHPOSTUP ();
1019               /* Fall through to remaining instruction decoding.  */
1020 #endif
1021 #ifdef MODET
1022               if (BITS (4, 7) == 0x9)
1023                 {
1024                   /* MULL */
1025                   /* 32x32=64 */
1026                   ARMul_Icycles (state,
1027                                  Multiply64 (state, instr, LUNSIGNED, LSCC),
1028                                  0L);
1029                   break;
1030                 }
1031 #endif
1032               lhs = LHS;
1033               rhs = DPRegRHS;
1034               dest = lhs + rhs;
1035               ASSIGNZ (dest == 0);
1036               if ((lhs | rhs) >> 30)
1037                 {
1038                   /* Possible C,V,N to set.  */
1039                   ASSIGNN (NEG (dest));
1040                   ARMul_AddCarry (state, lhs, rhs, dest);
1041                   ARMul_AddOverflow (state, lhs, rhs, dest);
1042                 }
1043               else
1044                 {
1045                   CLEARN;
1046                   CLEARC;
1047                   CLEARV;
1048                 }
1049               WRITESDEST (dest);
1050               break;
1051
1052             case 0x0a:          /* ADC reg */
1053 #ifdef MODET
1054               if (BITS (4, 11) == 0xB)
1055                 {
1056                   /* STRH register offset, write-back, up, post-indexed.  */
1057                   SHUPWB ();
1058                   break;
1059                 }
1060               if (BITS (4, 7) == 0x9)
1061                 {
1062                   /* MULL */
1063                   /* 32x32=64 */
1064                   ARMul_Icycles (state,
1065                                  MultiplyAdd64 (state, instr, LUNSIGNED,
1066                                                 LDEFAULT), 0L);
1067                   break;
1068                 }
1069 #endif
1070               rhs = DPRegRHS;
1071               dest = LHS + rhs + CFLAG;
1072               WRITEDEST (dest);
1073               break;
1074
1075             case 0x0b:          /* ADCS reg */
1076 #ifdef MODET
1077               if ((BITS (4, 11) & 0xF9) == 0x9)
1078                 /* LDR register offset, write-back, up, post indexed.  */
1079                 LHPOSTUP ();
1080               /* Fall through to remaining instruction decoding.  */
1081               if (BITS (4, 7) == 0x9)
1082                 {
1083                   /* MULL */
1084                   /* 32x32=64 */
1085                   ARMul_Icycles (state,
1086                                  MultiplyAdd64 (state, instr, LUNSIGNED,
1087                                                 LSCC), 0L);
1088                   break;
1089                 }
1090 #endif
1091               lhs = LHS;
1092               rhs = DPRegRHS;
1093               dest = lhs + rhs + CFLAG;
1094               ASSIGNZ (dest == 0);
1095               if ((lhs | rhs) >> 30)
1096                 {
1097                   /* Possible C,V,N to set.  */
1098                   ASSIGNN (NEG (dest));
1099                   ARMul_AddCarry (state, lhs, rhs, dest);
1100                   ARMul_AddOverflow (state, lhs, rhs, dest);
1101                 }
1102               else
1103                 {
1104                   CLEARN;
1105                   CLEARC;
1106                   CLEARV;
1107                 }
1108               WRITESDEST (dest);
1109               break;
1110
1111             case 0x0c:          /* SBC reg */
1112 #ifdef MODET
1113               if (BITS (4, 7) == 0xB)
1114                 {
1115                   /* STRH immediate offset, no write-back, up post indexed.  */
1116                   SHUPWB ();
1117                   break;
1118                 }
1119               if (BITS (4, 7) == 0xD)
1120                 {
1121                   Handle_Load_Double (state, instr);
1122                   break;
1123                 }
1124               if (BITS (4, 7) == 0xF)
1125                 {
1126                   Handle_Store_Double (state, instr);
1127                   break;
1128                 }
1129               if (BITS (4, 7) == 0x9)
1130                 {
1131                   /* MULL */
1132                   /* 32x32=64 */
1133                   ARMul_Icycles (state,
1134                                  Multiply64 (state, instr, LSIGNED, LDEFAULT),
1135                                  0L);
1136                   break;
1137                 }
1138 #endif
1139               rhs = DPRegRHS;
1140               dest = LHS - rhs - !CFLAG;
1141               WRITEDEST (dest);
1142               break;
1143
1144             case 0x0d:          /* SBCS reg */
1145 #ifdef MODET
1146               if ((BITS (4, 7) & 0x9) == 0x9)
1147                 /* LDR immediate offset, no write-back, up, post indexed.  */
1148                 LHPOSTUP ();
1149
1150               if (BITS (4, 7) == 0x9)
1151                 {
1152                   /* MULL */
1153                   /* 32x32=64 */
1154                   ARMul_Icycles (state,
1155                                  Multiply64 (state, instr, LSIGNED, LSCC),
1156                                  0L);
1157                   break;
1158                 }
1159 #endif
1160               lhs = LHS;
1161               rhs = DPRegRHS;
1162               dest = lhs - rhs - !CFLAG;
1163               if ((lhs >= rhs) || ((rhs | lhs) >> 31))
1164                 {
1165                   ARMul_SubCarry (state, lhs, rhs, dest);
1166                   ARMul_SubOverflow (state, lhs, rhs, dest);
1167                 }
1168               else
1169                 {
1170                   CLEARC;
1171                   CLEARV;
1172                 }
1173               WRITESDEST (dest);
1174               break;
1175
1176             case 0x0e:          /* RSC reg */
1177 #ifdef MODET
1178               if (BITS (4, 7) == 0xB)
1179                 {
1180                   /* STRH immediate offset, write-back, up, post indexed.  */
1181                   SHUPWB ();
1182                   break;
1183                 }
1184
1185               if (BITS (4, 7) == 0x9)
1186                 {
1187                   /* MULL */
1188                   /* 32x32=64 */
1189                   ARMul_Icycles (state,
1190                                  MultiplyAdd64 (state, instr, LSIGNED,
1191                                                 LDEFAULT), 0L);
1192                   break;
1193                 }
1194 #endif
1195               rhs = DPRegRHS;
1196               dest = rhs - LHS - !CFLAG;
1197               WRITEDEST (dest);
1198               break;
1199
1200             case 0x0f:          /* RSCS reg */
1201 #ifdef MODET
1202               if ((BITS (4, 7) & 0x9) == 0x9)
1203                 /* LDR immediate offset, write-back, up, post indexed.  */
1204                 LHPOSTUP ();
1205               /* Fall through to remaining instruction decoding.  */
1206
1207               if (BITS (4, 7) == 0x9)
1208                 {
1209                   /* MULL */
1210                   /* 32x32=64 */
1211                   ARMul_Icycles (state,
1212                                  MultiplyAdd64 (state, instr, LSIGNED, LSCC),
1213                                  0L);
1214                   break;
1215                 }
1216 #endif
1217               lhs = LHS;
1218               rhs = DPRegRHS;
1219               dest = rhs - lhs - !CFLAG;
1220
1221               if ((rhs >= lhs) || ((rhs | lhs) >> 31))
1222                 {
1223                   ARMul_SubCarry (state, rhs, lhs, dest);
1224                   ARMul_SubOverflow (state, rhs, lhs, dest);
1225                 }
1226               else
1227                 {
1228                   CLEARC;
1229                   CLEARV;
1230                 }
1231               WRITESDEST (dest);
1232               break;
1233
1234             case 0x10:          /* TST reg and MRS CPSR and SWP word.  */
1235               if (state->is_v5e)
1236                 {
1237                   if (BIT (4) == 0 && BIT (7) == 1)
1238                     {
1239                       /* ElSegundo SMLAxy insn.  */
1240                       ARMword op1 = state->Reg[BITS (0, 3)];
1241                       ARMword op2 = state->Reg[BITS (8, 11)];
1242                       ARMword Rn = state->Reg[BITS (12, 15)];
1243                       
1244                       if (BIT (5))
1245                         op1 >>= 16;
1246                       if (BIT (6))
1247                         op2 >>= 16;
1248                       op1 &= 0xFFFF;
1249                       op2 &= 0xFFFF;
1250                       if (op1 & 0x8000)
1251                         op1 -= 65536;
1252                       if (op2 & 0x8000)
1253                         op2 -= 65536;
1254                       op1 *= op2;
1255                       
1256                       if (AddOverflow (op1, Rn, op1 + Rn))
1257                         SETS;
1258                       state->Reg[BITS (16, 19)] = op1 + Rn;
1259                       break;
1260                     }
1261
1262                   if (BITS (4, 11) == 5)
1263                     {
1264                       /* ElSegundo QADD insn.  */
1265                       ARMword op1 = state->Reg[BITS (0, 3)];
1266                       ARMword op2 = state->Reg[BITS (16, 19)];
1267                       ARMword result = op1 + op2;
1268                       if (AddOverflow (op1, op2, result))
1269                         {
1270                           result = POS (result) ? 0x80000000 : 0x7fffffff;
1271                           SETS;
1272                         }
1273                       state->Reg[BITS (12, 15)] = result;
1274                       break;
1275                     }
1276                 }
1277 #ifdef MODET
1278               if (BITS (4, 11) == 0xB)
1279                 {
1280                   /* STRH register offset, no write-back, down, pre indexed.  */
1281                   SHPREDOWN ();
1282                   break;
1283                 }
1284               if (BITS (4, 7) == 0xD)
1285                 {
1286                   Handle_Load_Double (state, instr);
1287                   break;
1288                 }
1289               if (BITS (4, 7) == 0xF)
1290                 {
1291                   Handle_Store_Double (state, instr);
1292                   break;
1293                 }
1294 #endif
1295               if (BITS (4, 11) == 9)
1296                 {
1297                   /* SWP */
1298                   UNDEF_SWPPC;
1299                   temp = LHS;
1300                   BUSUSEDINCPCS;
1301 #ifndef MODE32
1302                   if (VECTORACCESS (temp) || ADDREXCEPT (temp))
1303                     {
1304                       INTERNALABORT (temp);
1305                       (void) ARMul_LoadWordN (state, temp);
1306                       (void) ARMul_LoadWordN (state, temp);
1307                     }
1308                   else
1309 #endif
1310                     dest = ARMul_SwapWord (state, temp, state->Reg[RHSReg]);
1311                   if (temp & 3)
1312                     DEST = ARMul_Align (state, temp, dest);
1313                   else
1314                     DEST = dest;
1315                   if (state->abortSig || state->Aborted)
1316                     TAKEABORT;
1317                 }
1318               else if ((BITS (0, 11) == 0) && (LHSReg == 15))
1319                 {               /* MRS CPSR */
1320                   UNDEF_MRSPC;
1321                   DEST = ECC | EINT | EMODE;
1322                 }
1323               else
1324                 {
1325                   UNDEF_Test;
1326                 }
1327               break;
1328
1329             case 0x11:          /* TSTP reg */
1330 #ifdef MODET
1331               if ((BITS (4, 11) & 0xF9) == 0x9)
1332                 /* LDR register offset, no write-back, down, pre indexed.  */
1333                 LHPREDOWN ();
1334               /* Continue with remaining instruction decode.  */
1335 #endif
1336               if (DESTReg == 15)
1337                 {
1338                   /* TSTP reg */
1339 #ifdef MODE32
1340                   state->Cpsr = GETSPSR (state->Bank);
1341                   ARMul_CPSRAltered (state);
1342 #else
1343                   rhs = DPRegRHS;
1344                   temp = LHS & rhs;
1345                   SETR15PSR (temp);
1346 #endif
1347                 }
1348               else
1349                 {
1350                   /* TST reg */
1351                   rhs = DPSRegRHS;
1352                   dest = LHS & rhs;
1353                   ARMul_NegZero (state, dest);
1354                 }
1355               break;
1356
1357             case 0x12:          /* TEQ reg and MSR reg to CPSR (ARM6).  */
1358               if (state->is_v5)
1359                 {
1360                   if (BITS (4, 7) == 3)
1361                     {
1362                       /* BLX(2) */
1363                       ARMword temp;
1364
1365                       if (TFLAG)
1366                         temp = (pc + 2) | 1;
1367                       else
1368                         temp = pc + 4;
1369
1370                       WriteR15Branch (state, state->Reg[RHSReg]);
1371                       state->Reg[14] = temp;
1372                       break;
1373                     }
1374                 }
1375
1376               if (state->is_v5e)
1377                 {
1378                   if (BIT (4) == 0 && BIT (7) == 1
1379                       && (BIT (5) == 0 || BITS (12, 15) == 0))
1380                     {
1381                       /* ElSegundo SMLAWy/SMULWy insn.  */
1382                       unsigned long long op1 = state->Reg[BITS (0, 3)];
1383                       unsigned long long op2 = state->Reg[BITS (8, 11)];
1384                       unsigned long long result;
1385
1386                       if (BIT (6))
1387                         op2 >>= 16;
1388                       if (op1 & 0x80000000)
1389                         op1 -= 1ULL << 32;
1390                       op2 &= 0xFFFF;
1391                       if (op2 & 0x8000)
1392                         op2 -= 65536;
1393                       result = (op1 * op2) >> 16;
1394
1395                       if (BIT (5) == 0)
1396                         {
1397                           ARMword Rn = state->Reg[BITS (12, 15)];
1398                           
1399                           if (AddOverflow (result, Rn, result + Rn))
1400                             SETS;
1401                           result += Rn;
1402                         }
1403                       state->Reg[BITS (16, 19)] = result;
1404                       break;
1405                     }
1406
1407                   if (BITS (4, 11) == 5)
1408                     {
1409                       /* ElSegundo QSUB insn.  */
1410                       ARMword op1 = state->Reg[BITS (0, 3)];
1411                       ARMword op2 = state->Reg[BITS (16, 19)];
1412                       ARMword result = op1 - op2;
1413
1414                       if (SubOverflow (op1, op2, result))
1415                         {
1416                           result = POS (result) ? 0x80000000 : 0x7fffffff;
1417                           SETS;
1418                         }
1419
1420                       state->Reg[BITS (12, 15)] = result;
1421                       break;
1422                     }
1423                 }
1424 #ifdef MODET
1425               if (BITS (4, 11) == 0xB)
1426                 {
1427                   /* STRH register offset, write-back, down, pre indexed.  */
1428                   SHPREDOWNWB ();
1429                   break;
1430                 }
1431               if (BITS (4, 27) == 0x12FFF1)
1432                 {
1433                   /* BX */
1434                   WriteR15Branch (state, state->Reg[RHSReg]);
1435                   break;
1436                 }
1437               if (BITS (4, 7) == 0xD)
1438                 {
1439                   Handle_Load_Double (state, instr);
1440                   break;
1441                 }
1442               if (BITS (4, 7) == 0xF)
1443                 {
1444                   Handle_Store_Double (state, instr);
1445                   break;
1446                 }
1447 #endif
1448               if (state->is_v5)
1449                 {
1450                   if (BITS (4, 7) == 0x7)
1451                     {
1452                       ARMword value;
1453                       extern int SWI_vector_installed;
1454
1455                       /* Hardware is allowed to optionally override this
1456                          instruction and treat it as a breakpoint.  Since
1457                          this is a simulator not hardware, we take the position
1458                          that if a SWI vector was not installed, then an Abort
1459                          vector was probably not installed either, and so
1460                          normally this instruction would be ignored, even if an
1461                          Abort is generated.  This is a bad thing, since GDB
1462                          uses this instruction for its breakpoints (at least in
1463                          Thumb mode it does).  So intercept the instruction here
1464                          and generate a breakpoint SWI instead.  */
1465                       if (! SWI_vector_installed)
1466                         ARMul_OSHandleSWI (state, SWI_Breakpoint);
1467                       else
1468                         {
1469                           /* BKPT - normally this will cause an abort, but on the
1470                              XScale we must check the DCSR.  */
1471                           XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc);
1472                           if (!XScale_debug_moe (state, ARMul_CP14_R10_MOE_BT))
1473                             break;
1474                         }
1475
1476                       /* Force the next instruction to be refetched.  */
1477                       state->NextInstr = RESUME;
1478                       break;
1479                     }
1480                 }
1481               if (DESTReg == 15)
1482                 {
1483                   /* MSR reg to CPSR.  */
1484                   UNDEF_MSRPC;
1485                   temp = DPRegRHS;
1486 #ifdef MODET
1487                   /* Don't allow TBIT to be set by MSR.  */
1488                   temp &= ~ TBIT;
1489 #endif
1490                   ARMul_FixCPSR (state, instr, temp);
1491                 }
1492               else
1493                 UNDEF_Test;
1494
1495               break;
1496
1497             case 0x13:          /* TEQP reg */
1498 #ifdef MODET
1499               if ((BITS (4, 11) & 0xF9) == 0x9)
1500                 /* LDR register offset, write-back, down, pre indexed.  */
1501                 LHPREDOWNWB ();
1502               /* Continue with remaining instruction decode.  */
1503 #endif
1504               if (DESTReg == 15)
1505                 {
1506                   /* TEQP reg */
1507 #ifdef MODE32
1508                   state->Cpsr = GETSPSR (state->Bank);
1509                   ARMul_CPSRAltered (state);
1510 #else
1511                   rhs = DPRegRHS;
1512                   temp = LHS ^ rhs;
1513                   SETR15PSR (temp);
1514 #endif
1515                 }
1516               else
1517                 {
1518                   /* TEQ Reg.  */
1519                   rhs = DPSRegRHS;
1520                   dest = LHS ^ rhs;
1521                   ARMul_NegZero (state, dest);
1522                 }
1523               break;
1524
1525             case 0x14:          /* CMP reg and MRS SPSR and SWP byte.  */
1526               if (state->is_v5e)
1527                 {
1528                   if (BIT (4) == 0 && BIT (7) == 1)
1529                     {
1530                       /* ElSegundo SMLALxy insn.  */
1531                       unsigned long long op1 = state->Reg[BITS (0, 3)];
1532                       unsigned long long op2 = state->Reg[BITS (8, 11)];
1533                       unsigned long long dest;
1534                       unsigned long long result;
1535
1536                       if (BIT (5))
1537                         op1 >>= 16;
1538                       if (BIT (6))
1539                         op2 >>= 16;
1540                       op1 &= 0xFFFF;
1541                       if (op1 & 0x8000)
1542                         op1 -= 65536;
1543                       op2 &= 0xFFFF;
1544                       if (op2 & 0x8000)
1545                         op2 -= 65536;
1546
1547                       dest = (unsigned long long) state->Reg[BITS (16, 19)] << 32;
1548                       dest |= state->Reg[BITS (12, 15)];
1549                       dest += op1 * op2;
1550                       state->Reg[BITS (12, 15)] = dest;
1551                       state->Reg[BITS (16, 19)] = dest >> 32;
1552                       break;
1553                     }
1554
1555                   if (BITS (4, 11) == 5)
1556                     {
1557                       /* ElSegundo QDADD insn.  */
1558                       ARMword op1 = state->Reg[BITS (0, 3)];
1559                       ARMword op2 = state->Reg[BITS (16, 19)];
1560                       ARMword op2d = op2 + op2;
1561                       ARMword result;
1562
1563                       if (AddOverflow (op2, op2, op2d))
1564                         {
1565                           SETS;
1566                           op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
1567                         }
1568
1569                       result = op1 + op2d;
1570                       if (AddOverflow (op1, op2d, result))
1571                         {
1572                           SETS;
1573                           result = POS (result) ? 0x80000000 : 0x7fffffff;
1574                         }
1575
1576                       state->Reg[BITS (12, 15)] = result;
1577                       break;
1578                     }
1579                 }
1580 #ifdef MODET
1581               if (BITS (4, 7) == 0xB)
1582                 {
1583                   /* STRH immediate offset, no write-back, down, pre indexed.  */
1584                   SHPREDOWN ();
1585                   break;
1586                 }
1587               if (BITS (4, 7) == 0xD)
1588                 {
1589                   Handle_Load_Double (state, instr);
1590                   break;
1591                 }
1592               if (BITS (4, 7) == 0xF)
1593                 {
1594                   Handle_Store_Double (state, instr);
1595                   break;
1596                 }
1597 #endif
1598               if (BITS (4, 11) == 9)
1599                 {
1600                   /* SWP */
1601                   UNDEF_SWPPC;
1602                   temp = LHS;
1603                   BUSUSEDINCPCS;
1604 #ifndef MODE32
1605                   if (VECTORACCESS (temp) || ADDREXCEPT (temp))
1606                     {
1607                       INTERNALABORT (temp);
1608                       (void) ARMul_LoadByte (state, temp);
1609                       (void) ARMul_LoadByte (state, temp);
1610                     }
1611                   else
1612 #endif
1613                     DEST = ARMul_SwapByte (state, temp, state->Reg[RHSReg]);
1614                   if (state->abortSig || state->Aborted)
1615                     TAKEABORT;
1616                 }
1617               else if ((BITS (0, 11) == 0) && (LHSReg == 15))
1618                 {
1619                   /* MRS SPSR */
1620                   UNDEF_MRSPC;
1621                   DEST = GETSPSR (state->Bank);
1622                 }
1623               else
1624                 UNDEF_Test;
1625
1626               break;
1627
1628             case 0x15:          /* CMPP reg.  */
1629 #ifdef MODET
1630               if ((BITS (4, 7) & 0x9) == 0x9)
1631                 /* LDR immediate offset, no write-back, down, pre indexed.  */
1632                 LHPREDOWN ();
1633               /* Continue with remaining instruction decode.  */
1634 #endif
1635               if (DESTReg == 15)
1636                 {
1637                   /* CMPP reg.  */
1638 #ifdef MODE32
1639                   state->Cpsr = GETSPSR (state->Bank);
1640                   ARMul_CPSRAltered (state);
1641 #else
1642                   rhs = DPRegRHS;
1643                   temp = LHS - rhs;
1644                   SETR15PSR (temp);
1645 #endif
1646                 }
1647               else
1648                 {
1649                   /* CMP reg.  */
1650                   lhs = LHS;
1651                   rhs = DPRegRHS;
1652                   dest = lhs - rhs;
1653                   ARMul_NegZero (state, dest);
1654                   if ((lhs >= rhs) || ((rhs | lhs) >> 31))
1655                     {
1656                       ARMul_SubCarry (state, lhs, rhs, dest);
1657                       ARMul_SubOverflow (state, lhs, rhs, dest);
1658                     }
1659                   else
1660                     {
1661                       CLEARC;
1662                       CLEARV;
1663                     }
1664                 }
1665               break;
1666
1667             case 0x16:          /* CMN reg and MSR reg to SPSR */
1668               if (state->is_v5e)
1669                 {
1670                   if (BIT (4) == 0 && BIT (7) == 1 && BITS (12, 15) == 0)
1671                     {
1672                       /* ElSegundo SMULxy insn.  */
1673                       ARMword op1 = state->Reg[BITS (0, 3)];
1674                       ARMword op2 = state->Reg[BITS (8, 11)];
1675                       ARMword Rn = state->Reg[BITS (12, 15)];
1676
1677                       if (BIT (5))
1678                         op1 >>= 16;
1679                       if (BIT (6))
1680                         op2 >>= 16;
1681                       op1 &= 0xFFFF;
1682                       op2 &= 0xFFFF;
1683                       if (op1 & 0x8000)
1684                         op1 -= 65536;
1685                       if (op2 & 0x8000)
1686                         op2 -= 65536;
1687
1688                       state->Reg[BITS (16, 19)] = op1 * op2;
1689                       break;
1690                     }
1691
1692                   if (BITS (4, 11) == 5)
1693                     {
1694                       /* ElSegundo QDSUB insn.  */
1695                       ARMword op1 = state->Reg[BITS (0, 3)];
1696                       ARMword op2 = state->Reg[BITS (16, 19)];
1697                       ARMword op2d = op2 + op2;
1698                       ARMword result;
1699
1700                       if (AddOverflow (op2, op2, op2d))
1701                         {
1702                           SETS;
1703                           op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
1704                         }
1705
1706                       result = op1 - op2d;
1707                       if (SubOverflow (op1, op2d, result))
1708                         {
1709                           SETS;
1710                           result = POS (result) ? 0x80000000 : 0x7fffffff;
1711                         }
1712
1713                       state->Reg[BITS (12, 15)] = result;
1714                       break;
1715                     }
1716                 }
1717
1718               if (state->is_v5)
1719                 {
1720                   if (BITS (4, 11) == 0xF1 && BITS (16, 19) == 0xF)
1721                     {
1722                       /* ARM5 CLZ insn.  */
1723                       ARMword op1 = state->Reg[BITS (0, 3)];
1724                       int result = 32;
1725
1726                       if (op1)
1727                         for (result = 0; (op1 & 0x80000000) == 0; op1 <<= 1)
1728                           result++;
1729
1730                       state->Reg[BITS (12, 15)] = result;
1731                       break;
1732                     }
1733                 }
1734 #ifdef MODET
1735               if (BITS (4, 7) == 0xB)
1736                 {
1737                   /* STRH immediate offset, write-back, down, pre indexed.  */
1738                   SHPREDOWNWB ();
1739                   break;
1740                 }
1741               if (BITS (4, 7) == 0xD)
1742                 {
1743                   Handle_Load_Double (state, instr);
1744                   break;
1745                 }
1746               if (BITS (4, 7) == 0xF)
1747                 {
1748                   Handle_Store_Double (state, instr);
1749                   break;
1750                 }
1751 #endif
1752               if (DESTReg == 15)
1753                 {
1754                   /* MSR */
1755                   UNDEF_MSRPC;
1756                   ARMul_FixSPSR (state, instr, DPRegRHS);
1757                 }
1758               else
1759                 {
1760                   UNDEF_Test;
1761                 }
1762               break;
1763
1764             case 0x17:          /* CMNP reg */
1765 #ifdef MODET
1766               if ((BITS (4, 7) & 0x9) == 0x9)
1767                 /* LDR immediate offset, write-back, down, pre indexed.  */
1768                 LHPREDOWNWB ();
1769               /* Continue with remaining instruction decoding.  */
1770 #endif
1771               if (DESTReg == 15)
1772                 {
1773 #ifdef MODE32
1774                   state->Cpsr = GETSPSR (state->Bank);
1775                   ARMul_CPSRAltered (state);
1776 #else
1777                   rhs = DPRegRHS;
1778                   temp = LHS + rhs;
1779                   SETR15PSR (temp);
1780 #endif
1781                   break;
1782                 }
1783               else
1784                 {
1785                   /* CMN reg.  */
1786                   lhs = LHS;
1787                   rhs = DPRegRHS;
1788                   dest = lhs + rhs;
1789                   ASSIGNZ (dest == 0);
1790                   if ((lhs | rhs) >> 30)
1791                     {
1792                       /* Possible C,V,N to set.  */
1793                       ASSIGNN (NEG (dest));
1794                       ARMul_AddCarry (state, lhs, rhs, dest);
1795                       ARMul_AddOverflow (state, lhs, rhs, dest);
1796                     }
1797                   else
1798                     {
1799                       CLEARN;
1800                       CLEARC;
1801                       CLEARV;
1802                     }
1803                 }
1804               break;
1805
1806             case 0x18:          /* ORR reg */
1807 #ifdef MODET
1808               if (BITS (4, 11) == 0xB)
1809                 {
1810                   /* STRH register offset, no write-back, up, pre indexed.  */
1811                   SHPREUP ();
1812                   break;
1813                 }
1814               if (BITS (4, 7) == 0xD)
1815                 {
1816                   Handle_Load_Double (state, instr);
1817                   break;
1818                 }
1819               if (BITS (4, 7) == 0xF)
1820                 {
1821                   Handle_Store_Double (state, instr);
1822                   break;
1823                 }
1824 #endif
1825               rhs = DPRegRHS;
1826               dest = LHS | rhs;
1827               WRITEDEST (dest);
1828               break;
1829
1830             case 0x19:          /* ORRS reg */
1831 #ifdef MODET
1832               if ((BITS (4, 11) & 0xF9) == 0x9)
1833                 /* LDR register offset, no write-back, up, pre indexed.  */
1834                 LHPREUP ();
1835               /* Continue with remaining instruction decoding.  */
1836 #endif
1837               rhs = DPSRegRHS;
1838               dest = LHS | rhs;
1839               WRITESDEST (dest);
1840               break;
1841
1842             case 0x1a:          /* MOV reg */
1843 #ifdef MODET
1844               if (BITS (4, 11) == 0xB)
1845                 {
1846                   /* STRH register offset, write-back, up, pre indexed.  */
1847                   SHPREUPWB ();
1848                   break;
1849                 }
1850               if (BITS (4, 7) == 0xD)
1851                 {
1852                   Handle_Load_Double (state, instr);
1853                   break;
1854                 }
1855               if (BITS (4, 7) == 0xF)
1856                 {
1857                   Handle_Store_Double (state, instr);
1858                   break;
1859                 }
1860 #endif
1861               dest = DPRegRHS;
1862               WRITEDEST (dest);
1863               break;
1864
1865             case 0x1b:          /* MOVS reg */
1866 #ifdef MODET
1867               if ((BITS (4, 11) & 0xF9) == 0x9)
1868                 /* LDR register offset, write-back, up, pre indexed.  */
1869                 LHPREUPWB ();
1870               /* Continue with remaining instruction decoding.  */
1871 #endif
1872               dest = DPSRegRHS;
1873               WRITESDEST (dest);
1874               break;
1875
1876             case 0x1c:          /* BIC reg */
1877 #ifdef MODET
1878               if (BITS (4, 7) == 0xB)
1879                 {
1880                   /* STRH immediate offset, no write-back, up, pre indexed.  */
1881                   SHPREUP ();
1882                   break;
1883                 }
1884               if (BITS (4, 7) == 0xD)
1885                 {
1886                   Handle_Load_Double (state, instr);
1887                   break;
1888                 }
1889               else if (BITS (4, 7) == 0xF)
1890                 {
1891                   Handle_Store_Double (state, instr);
1892                   break;
1893                 }
1894 #endif
1895               rhs = DPRegRHS;
1896               dest = LHS & ~rhs;
1897               WRITEDEST (dest);
1898               break;
1899
1900             case 0x1d:          /* BICS reg */
1901 #ifdef MODET
1902               if ((BITS (4, 7) & 0x9) == 0x9)
1903                 /* LDR immediate offset, no write-back, up, pre indexed.  */
1904                 LHPREUP ();
1905               /* Continue with instruction decoding.  */
1906 #endif
1907               rhs = DPSRegRHS;
1908               dest = LHS & ~rhs;
1909               WRITESDEST (dest);
1910               break;
1911
1912             case 0x1e:          /* MVN reg */
1913 #ifdef MODET
1914               if (BITS (4, 7) == 0xB)
1915                 {
1916                   /* STRH immediate offset, write-back, up, pre indexed.  */
1917                   SHPREUPWB ();
1918                   break;
1919                 }
1920               if (BITS (4, 7) == 0xD)
1921                 {
1922                   Handle_Load_Double (state, instr);
1923                   break;
1924                 }
1925               if (BITS (4, 7) == 0xF)
1926                 {
1927                   Handle_Store_Double (state, instr);
1928                   break;
1929                 }
1930 #endif
1931               dest = ~DPRegRHS;
1932               WRITEDEST (dest);
1933               break;
1934
1935             case 0x1f:          /* MVNS reg */
1936 #ifdef MODET
1937               if ((BITS (4, 7) & 0x9) == 0x9)
1938                 /* LDR immediate offset, write-back, up, pre indexed.  */
1939                 LHPREUPWB ();
1940               /* Continue instruction decoding.  */
1941 #endif
1942               dest = ~DPSRegRHS;
1943               WRITESDEST (dest);
1944               break;
1945
1946
1947               /* Data Processing Immediate RHS Instructions.  */
1948
1949             case 0x20:          /* AND immed */
1950               dest = LHS & DPImmRHS;
1951               WRITEDEST (dest);
1952               break;
1953
1954             case 0x21:          /* ANDS immed */
1955               DPSImmRHS;
1956               dest = LHS & rhs;
1957               WRITESDEST (dest);
1958               break;
1959
1960             case 0x22:          /* EOR immed */
1961               dest = LHS ^ DPImmRHS;
1962               WRITEDEST (dest);
1963               break;
1964
1965             case 0x23:          /* EORS immed */
1966               DPSImmRHS;
1967               dest = LHS ^ rhs;
1968               WRITESDEST (dest);
1969               break;
1970
1971             case 0x24:          /* SUB immed */
1972               dest = LHS - DPImmRHS;
1973               WRITEDEST (dest);
1974               break;
1975
1976             case 0x25:          /* SUBS immed */
1977               lhs = LHS;
1978               rhs = DPImmRHS;
1979               dest = lhs - rhs;
1980
1981               if ((lhs >= rhs) || ((rhs | lhs) >> 31))
1982                 {
1983                   ARMul_SubCarry (state, lhs, rhs, dest);
1984                   ARMul_SubOverflow (state, lhs, rhs, dest);
1985                 }
1986               else
1987                 {
1988                   CLEARC;
1989                   CLEARV;
1990                 }
1991               WRITESDEST (dest);
1992               break;
1993
1994             case 0x26:          /* RSB immed */
1995               dest = DPImmRHS - LHS;
1996               WRITEDEST (dest);
1997               break;
1998
1999             case 0x27:          /* RSBS immed */
2000               lhs = LHS;
2001               rhs = DPImmRHS;
2002               dest = rhs - lhs;
2003
2004               if ((rhs >= lhs) || ((rhs | lhs) >> 31))
2005                 {
2006                   ARMul_SubCarry (state, rhs, lhs, dest);
2007                   ARMul_SubOverflow (state, rhs, lhs, dest);
2008                 }
2009               else
2010                 {
2011                   CLEARC;
2012                   CLEARV;
2013                 }
2014               WRITESDEST (dest);
2015               break;
2016
2017             case 0x28:          /* ADD immed */
2018               dest = LHS + DPImmRHS;
2019               WRITEDEST (dest);
2020               break;
2021
2022             case 0x29:          /* ADDS immed */
2023               lhs = LHS;
2024               rhs = DPImmRHS;
2025               dest = lhs + rhs;
2026               ASSIGNZ (dest == 0);
2027
2028               if ((lhs | rhs) >> 30)
2029                 {
2030                   /* Possible C,V,N to set.  */
2031                   ASSIGNN (NEG (dest));
2032                   ARMul_AddCarry (state, lhs, rhs, dest);
2033                   ARMul_AddOverflow (state, lhs, rhs, dest);
2034                 }
2035               else
2036                 {
2037                   CLEARN;
2038                   CLEARC;
2039                   CLEARV;
2040                 }
2041               WRITESDEST (dest);
2042               break;
2043
2044             case 0x2a:          /* ADC immed */
2045               dest = LHS + DPImmRHS + CFLAG;
2046               WRITEDEST (dest);
2047               break;
2048
2049             case 0x2b:          /* ADCS immed */
2050               lhs = LHS;
2051               rhs = DPImmRHS;
2052               dest = lhs + rhs + CFLAG;
2053               ASSIGNZ (dest == 0);
2054               if ((lhs | rhs) >> 30)
2055                 {
2056                   /* Possible C,V,N to set.  */
2057                   ASSIGNN (NEG (dest));
2058                   ARMul_AddCarry (state, lhs, rhs, dest);
2059                   ARMul_AddOverflow (state, lhs, rhs, dest);
2060                 }
2061               else
2062                 {
2063                   CLEARN;
2064                   CLEARC;
2065                   CLEARV;
2066                 }
2067               WRITESDEST (dest);
2068               break;
2069
2070             case 0x2c:          /* SBC immed */
2071               dest = LHS - DPImmRHS - !CFLAG;
2072               WRITEDEST (dest);
2073               break;
2074
2075             case 0x2d:          /* SBCS immed */
2076               lhs = LHS;
2077               rhs = DPImmRHS;
2078               dest = lhs - rhs - !CFLAG;
2079               if ((lhs >= rhs) || ((rhs | lhs) >> 31))
2080                 {
2081                   ARMul_SubCarry (state, lhs, rhs, dest);
2082                   ARMul_SubOverflow (state, lhs, rhs, dest);
2083                 }
2084               else
2085                 {
2086                   CLEARC;
2087                   CLEARV;
2088                 }
2089               WRITESDEST (dest);
2090               break;
2091
2092             case 0x2e:          /* RSC immed */
2093               dest = DPImmRHS - LHS - !CFLAG;
2094               WRITEDEST (dest);
2095               break;
2096
2097             case 0x2f:          /* RSCS immed */
2098               lhs = LHS;
2099               rhs = DPImmRHS;
2100               dest = rhs - lhs - !CFLAG;
2101               if ((rhs >= lhs) || ((rhs | lhs) >> 31))
2102                 {
2103                   ARMul_SubCarry (state, rhs, lhs, dest);
2104                   ARMul_SubOverflow (state, rhs, lhs, dest);
2105                 }
2106               else
2107                 {
2108                   CLEARC;
2109                   CLEARV;
2110                 }
2111               WRITESDEST (dest);
2112               break;
2113
2114             case 0x30:          /* TST immed */
2115               UNDEF_Test;
2116               break;
2117
2118             case 0x31:          /* TSTP immed */
2119               if (DESTReg == 15)
2120                 {
2121                   /* TSTP immed.  */
2122 #ifdef MODE32
2123                   state->Cpsr = GETSPSR (state->Bank);
2124                   ARMul_CPSRAltered (state);
2125 #else
2126                   temp = LHS & DPImmRHS;
2127                   SETR15PSR (temp);
2128 #endif
2129                 }
2130               else
2131                 {
2132                   /* TST immed.  */
2133                   DPSImmRHS;
2134                   dest = LHS & rhs;
2135                   ARMul_NegZero (state, dest);
2136                 }
2137               break;
2138
2139             case 0x32:          /* TEQ immed and MSR immed to CPSR */
2140               if (DESTReg == 15)
2141                 /* MSR immed to CPSR.  */
2142                 ARMul_FixCPSR (state, instr, DPImmRHS);
2143               else
2144                 UNDEF_Test;
2145               break;
2146
2147             case 0x33:          /* TEQP immed */
2148               if (DESTReg == 15)
2149                 {
2150                   /* TEQP immed.  */
2151 #ifdef MODE32
2152                   state->Cpsr = GETSPSR (state->Bank);
2153                   ARMul_CPSRAltered (state);
2154 #else
2155                   temp = LHS ^ DPImmRHS;
2156                   SETR15PSR (temp);
2157 #endif
2158                 }
2159               else
2160                 {
2161                   DPSImmRHS;    /* TEQ immed */
2162                   dest = LHS ^ rhs;
2163                   ARMul_NegZero (state, dest);
2164                 }
2165               break;
2166
2167             case 0x34:          /* CMP immed */
2168               UNDEF_Test;
2169               break;
2170
2171             case 0x35:          /* CMPP immed */
2172               if (DESTReg == 15)
2173                 {
2174                   /* CMPP immed.  */
2175 #ifdef MODE32
2176                   state->Cpsr = GETSPSR (state->Bank);
2177                   ARMul_CPSRAltered (state);
2178 #else
2179                   temp = LHS - DPImmRHS;
2180                   SETR15PSR (temp);
2181 #endif
2182                   break;
2183                 }
2184               else
2185                 {
2186                   /* CMP immed.  */
2187                   lhs = LHS;
2188                   rhs = DPImmRHS;
2189                   dest = lhs - rhs;
2190                   ARMul_NegZero (state, dest);
2191
2192                   if ((lhs >= rhs) || ((rhs | lhs) >> 31))
2193                     {
2194                       ARMul_SubCarry (state, lhs, rhs, dest);
2195                       ARMul_SubOverflow (state, lhs, rhs, dest);
2196                     }
2197                   else
2198                     {
2199                       CLEARC;
2200                       CLEARV;
2201                     }
2202                 }
2203               break;
2204
2205             case 0x36:          /* CMN immed and MSR immed to SPSR */
2206               if (DESTReg == 15)
2207                 ARMul_FixSPSR (state, instr, DPImmRHS);
2208               else
2209                 UNDEF_Test;
2210               break;
2211
2212             case 0x37:          /* CMNP immed.  */
2213               if (DESTReg == 15)
2214                 {
2215                   /* CMNP immed.  */
2216 #ifdef MODE32
2217                   state->Cpsr = GETSPSR (state->Bank);
2218                   ARMul_CPSRAltered (state);
2219 #else
2220                   temp = LHS + DPImmRHS;
2221                   SETR15PSR (temp);
2222 #endif
2223                   break;
2224                 }
2225               else
2226                 {
2227                   /* CMN immed.  */
2228                   lhs = LHS;
2229                   rhs = DPImmRHS;
2230                   dest = lhs + rhs;
2231                   ASSIGNZ (dest == 0);
2232                   if ((lhs | rhs) >> 30)
2233                     {
2234                       /* Possible C,V,N to set.  */
2235                       ASSIGNN (NEG (dest));
2236                       ARMul_AddCarry (state, lhs, rhs, dest);
2237                       ARMul_AddOverflow (state, lhs, rhs, dest);
2238                     }
2239                   else
2240                     {
2241                       CLEARN;
2242                       CLEARC;
2243                       CLEARV;
2244                     }
2245                 }
2246               break;
2247
2248             case 0x38:          /* ORR immed.  */
2249               dest = LHS | DPImmRHS;
2250               WRITEDEST (dest);
2251               break;
2252
2253             case 0x39:          /* ORRS immed.  */
2254               DPSImmRHS;
2255               dest = LHS | rhs;
2256               WRITESDEST (dest);
2257               break;
2258
2259             case 0x3a:          /* MOV immed.  */
2260               dest = DPImmRHS;
2261               WRITEDEST (dest);
2262               break;
2263
2264             case 0x3b:          /* MOVS immed.  */
2265               DPSImmRHS;
2266               WRITESDEST (rhs);
2267               break;
2268
2269             case 0x3c:          /* BIC immed.  */
2270               dest = LHS & ~DPImmRHS;
2271               WRITEDEST (dest);
2272               break;
2273
2274             case 0x3d:          /* BICS immed.  */
2275               DPSImmRHS;
2276               dest = LHS & ~rhs;
2277               WRITESDEST (dest);
2278               break;
2279
2280             case 0x3e:          /* MVN immed.  */
2281               dest = ~DPImmRHS;
2282               WRITEDEST (dest);
2283               break;
2284
2285             case 0x3f:          /* MVNS immed.  */
2286               DPSImmRHS;
2287               WRITESDEST (~rhs);
2288               break;
2289
2290
2291               /* Single Data Transfer Immediate RHS Instructions.  */
2292
2293             case 0x40:          /* Store Word, No WriteBack, Post Dec, Immed.  */
2294               lhs = LHS;
2295               if (StoreWord (state, instr, lhs))
2296                 LSBase = lhs - LSImmRHS;
2297               break;
2298
2299             case 0x41:          /* Load Word, No WriteBack, Post Dec, Immed.  */
2300               lhs = LHS;
2301               if (LoadWord (state, instr, lhs))
2302                 LSBase = lhs - LSImmRHS;
2303               break;
2304
2305             case 0x42:          /* Store Word, WriteBack, Post Dec, Immed.  */
2306               UNDEF_LSRBaseEQDestWb;
2307               UNDEF_LSRPCBaseWb;
2308               lhs = LHS;
2309               temp = lhs - LSImmRHS;
2310               state->NtransSig = LOW;
2311               if (StoreWord (state, instr, lhs))
2312                 LSBase = temp;
2313               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2314               break;
2315
2316             case 0x43:          /* Load Word, WriteBack, Post Dec, Immed.  */
2317               UNDEF_LSRBaseEQDestWb;
2318               UNDEF_LSRPCBaseWb;
2319               lhs = LHS;
2320               state->NtransSig = LOW;
2321               if (LoadWord (state, instr, lhs))
2322                 LSBase = lhs - LSImmRHS;
2323               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2324               break;
2325
2326             case 0x44:          /* Store Byte, No WriteBack, Post Dec, Immed.  */
2327               lhs = LHS;
2328               if (StoreByte (state, instr, lhs))
2329                 LSBase = lhs - LSImmRHS;
2330               break;
2331
2332             case 0x45:          /* Load Byte, No WriteBack, Post Dec, Immed.  */
2333               lhs = LHS;
2334               if (LoadByte (state, instr, lhs, LUNSIGNED))
2335                 LSBase = lhs - LSImmRHS;
2336               break;
2337
2338             case 0x46:          /* Store Byte, WriteBack, Post Dec, Immed.  */
2339               UNDEF_LSRBaseEQDestWb;
2340               UNDEF_LSRPCBaseWb;
2341               lhs = LHS;
2342               state->NtransSig = LOW;
2343               if (StoreByte (state, instr, lhs))
2344                 LSBase = lhs - LSImmRHS;
2345               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2346               break;
2347
2348             case 0x47:          /* Load Byte, WriteBack, Post Dec, Immed.  */
2349               UNDEF_LSRBaseEQDestWb;
2350               UNDEF_LSRPCBaseWb;
2351               lhs = LHS;
2352               state->NtransSig = LOW;
2353               if (LoadByte (state, instr, lhs, LUNSIGNED))
2354                 LSBase = lhs - LSImmRHS;
2355               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2356               break;
2357
2358             case 0x48:          /* Store Word, No WriteBack, Post Inc, Immed.  */
2359               lhs = LHS;
2360               if (StoreWord (state, instr, lhs))
2361                 LSBase = lhs + LSImmRHS;
2362               break;
2363
2364             case 0x49:          /* Load Word, No WriteBack, Post Inc, Immed.  */
2365               lhs = LHS;
2366               if (LoadWord (state, instr, lhs))
2367                 LSBase = lhs + LSImmRHS;
2368               break;
2369
2370             case 0x4a:          /* Store Word, WriteBack, Post Inc, Immed.  */
2371               UNDEF_LSRBaseEQDestWb;
2372               UNDEF_LSRPCBaseWb;
2373               lhs = LHS;
2374               state->NtransSig = LOW;
2375               if (StoreWord (state, instr, lhs))
2376                 LSBase = lhs + LSImmRHS;
2377               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2378               break;
2379
2380             case 0x4b:          /* Load Word, WriteBack, Post Inc, Immed.  */
2381               UNDEF_LSRBaseEQDestWb;
2382               UNDEF_LSRPCBaseWb;
2383               lhs = LHS;
2384               state->NtransSig = LOW;
2385               if (LoadWord (state, instr, lhs))
2386                 LSBase = lhs + LSImmRHS;
2387               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2388               break;
2389
2390             case 0x4c:          /* Store Byte, No WriteBack, Post Inc, Immed.  */
2391               lhs = LHS;
2392               if (StoreByte (state, instr, lhs))
2393                 LSBase = lhs + LSImmRHS;
2394               break;
2395
2396             case 0x4d:          /* Load Byte, No WriteBack, Post Inc, Immed.  */
2397               lhs = LHS;
2398               if (LoadByte (state, instr, lhs, LUNSIGNED))
2399                 LSBase = lhs + LSImmRHS;
2400               break;
2401
2402             case 0x4e:          /* Store Byte, WriteBack, Post Inc, Immed.  */
2403               UNDEF_LSRBaseEQDestWb;
2404               UNDEF_LSRPCBaseWb;
2405               lhs = LHS;
2406               state->NtransSig = LOW;
2407               if (StoreByte (state, instr, lhs))
2408                 LSBase = lhs + LSImmRHS;
2409               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2410               break;
2411
2412             case 0x4f:          /* Load Byte, WriteBack, Post Inc, Immed.  */
2413               UNDEF_LSRBaseEQDestWb;
2414               UNDEF_LSRPCBaseWb;
2415               lhs = LHS;
2416               state->NtransSig = LOW;
2417               if (LoadByte (state, instr, lhs, LUNSIGNED))
2418                 LSBase = lhs + LSImmRHS;
2419               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2420               break;
2421
2422
2423             case 0x50:          /* Store Word, No WriteBack, Pre Dec, Immed.  */
2424               (void) StoreWord (state, instr, LHS - LSImmRHS);
2425               break;
2426
2427             case 0x51:          /* Load Word, No WriteBack, Pre Dec, Immed.  */
2428               (void) LoadWord (state, instr, LHS - LSImmRHS);
2429               break;
2430
2431             case 0x52:          /* Store Word, WriteBack, Pre Dec, Immed.  */
2432               UNDEF_LSRBaseEQDestWb;
2433               UNDEF_LSRPCBaseWb;
2434               temp = LHS - LSImmRHS;
2435               if (StoreWord (state, instr, temp))
2436                 LSBase = temp;
2437               break;
2438
2439             case 0x53:          /* Load Word, WriteBack, Pre Dec, Immed.  */
2440               UNDEF_LSRBaseEQDestWb;
2441               UNDEF_LSRPCBaseWb;
2442               temp = LHS - LSImmRHS;
2443               if (LoadWord (state, instr, temp))
2444                 LSBase = temp;
2445               break;
2446
2447             case 0x54:          /* Store Byte, No WriteBack, Pre Dec, Immed.  */
2448               (void) StoreByte (state, instr, LHS - LSImmRHS);
2449               break;
2450
2451             case 0x55:          /* Load Byte, No WriteBack, Pre Dec, Immed.  */
2452               (void) LoadByte (state, instr, LHS - LSImmRHS, LUNSIGNED);
2453               break;
2454
2455             case 0x56:          /* Store Byte, WriteBack, Pre Dec, Immed.  */
2456               UNDEF_LSRBaseEQDestWb;
2457               UNDEF_LSRPCBaseWb;
2458               temp = LHS - LSImmRHS;
2459               if (StoreByte (state, instr, temp))
2460                 LSBase = temp;
2461               break;
2462
2463             case 0x57:          /* Load Byte, WriteBack, Pre Dec, Immed.  */
2464               UNDEF_LSRBaseEQDestWb;
2465               UNDEF_LSRPCBaseWb;
2466               temp = LHS - LSImmRHS;
2467               if (LoadByte (state, instr, temp, LUNSIGNED))
2468                 LSBase = temp;
2469               break;
2470
2471             case 0x58:          /* Store Word, No WriteBack, Pre Inc, Immed.  */
2472               (void) StoreWord (state, instr, LHS + LSImmRHS);
2473               break;
2474
2475             case 0x59:          /* Load Word, No WriteBack, Pre Inc, Immed.  */
2476               (void) LoadWord (state, instr, LHS + LSImmRHS);
2477               break;
2478
2479             case 0x5a:          /* Store Word, WriteBack, Pre Inc, Immed.  */
2480               UNDEF_LSRBaseEQDestWb;
2481               UNDEF_LSRPCBaseWb;
2482               temp = LHS + LSImmRHS;
2483               if (StoreWord (state, instr, temp))
2484                 LSBase = temp;
2485               break;
2486
2487             case 0x5b:          /* Load Word, WriteBack, Pre Inc, Immed.  */
2488               UNDEF_LSRBaseEQDestWb;
2489               UNDEF_LSRPCBaseWb;
2490               temp = LHS + LSImmRHS;
2491               if (LoadWord (state, instr, temp))
2492                 LSBase = temp;
2493               break;
2494
2495             case 0x5c:          /* Store Byte, No WriteBack, Pre Inc, Immed.  */
2496               (void) StoreByte (state, instr, LHS + LSImmRHS);
2497               break;
2498
2499             case 0x5d:          /* Load Byte, No WriteBack, Pre Inc, Immed.  */
2500               (void) LoadByte (state, instr, LHS + LSImmRHS, LUNSIGNED);
2501               break;
2502
2503             case 0x5e:          /* Store Byte, WriteBack, Pre Inc, Immed.  */
2504               UNDEF_LSRBaseEQDestWb;
2505               UNDEF_LSRPCBaseWb;
2506               temp = LHS + LSImmRHS;
2507               if (StoreByte (state, instr, temp))
2508                 LSBase = temp;
2509               break;
2510
2511             case 0x5f:          /* Load Byte, WriteBack, Pre Inc, Immed.  */
2512               UNDEF_LSRBaseEQDestWb;
2513               UNDEF_LSRPCBaseWb;
2514               temp = LHS + LSImmRHS;
2515               if (LoadByte (state, instr, temp, LUNSIGNED))
2516                 LSBase = temp;
2517               break;
2518
2519
2520               /* Single Data Transfer Register RHS Instructions.  */
2521
2522             case 0x60:          /* Store Word, No WriteBack, Post Dec, Reg.  */
2523               if (BIT (4))
2524                 {
2525                   ARMul_UndefInstr (state, instr);
2526                   break;
2527                 }
2528               UNDEF_LSRBaseEQOffWb;
2529               UNDEF_LSRBaseEQDestWb;
2530               UNDEF_LSRPCBaseWb;
2531               UNDEF_LSRPCOffWb;
2532               lhs = LHS;
2533               if (StoreWord (state, instr, lhs))
2534                 LSBase = lhs - LSRegRHS;
2535               break;
2536
2537             case 0x61:          /* Load Word, No WriteBack, Post Dec, Reg.  */
2538               if (BIT (4))
2539                 {
2540                   ARMul_UndefInstr (state, instr);
2541                   break;
2542                 }
2543               UNDEF_LSRBaseEQOffWb;
2544               UNDEF_LSRBaseEQDestWb;
2545               UNDEF_LSRPCBaseWb;
2546               UNDEF_LSRPCOffWb;
2547               lhs = LHS;
2548               temp = lhs - LSRegRHS;
2549               if (LoadWord (state, instr, lhs))
2550                 LSBase = temp;
2551               break;
2552
2553             case 0x62:          /* Store Word, WriteBack, Post Dec, Reg.  */
2554               if (BIT (4))
2555                 {
2556                   ARMul_UndefInstr (state, instr);
2557                   break;
2558                 }
2559               UNDEF_LSRBaseEQOffWb;
2560               UNDEF_LSRBaseEQDestWb;
2561               UNDEF_LSRPCBaseWb;
2562               UNDEF_LSRPCOffWb;
2563               lhs = LHS;
2564               state->NtransSig = LOW;
2565               if (StoreWord (state, instr, lhs))
2566                 LSBase = lhs - LSRegRHS;
2567               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2568               break;
2569
2570             case 0x63:          /* Load Word, WriteBack, Post Dec, Reg.  */
2571               if (BIT (4))
2572                 {
2573                   ARMul_UndefInstr (state, instr);
2574                   break;
2575                 }
2576               UNDEF_LSRBaseEQOffWb;
2577               UNDEF_LSRBaseEQDestWb;
2578               UNDEF_LSRPCBaseWb;
2579               UNDEF_LSRPCOffWb;
2580               lhs = LHS;
2581               temp = lhs - LSRegRHS;
2582               state->NtransSig = LOW;
2583               if (LoadWord (state, instr, lhs))
2584                 LSBase = temp;
2585               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2586               break;
2587
2588             case 0x64:          /* Store Byte, No WriteBack, Post Dec, Reg.  */
2589               if (BIT (4))
2590                 {
2591                   ARMul_UndefInstr (state, instr);
2592                   break;
2593                 }
2594               UNDEF_LSRBaseEQOffWb;
2595               UNDEF_LSRBaseEQDestWb;
2596               UNDEF_LSRPCBaseWb;
2597               UNDEF_LSRPCOffWb;
2598               lhs = LHS;
2599               if (StoreByte (state, instr, lhs))
2600                 LSBase = lhs - LSRegRHS;
2601               break;
2602
2603             case 0x65:          /* Load Byte, No WriteBack, Post Dec, Reg.  */
2604               if (BIT (4))
2605                 {
2606                   ARMul_UndefInstr (state, instr);
2607                   break;
2608                 }
2609               UNDEF_LSRBaseEQOffWb;
2610               UNDEF_LSRBaseEQDestWb;
2611               UNDEF_LSRPCBaseWb;
2612               UNDEF_LSRPCOffWb;
2613               lhs = LHS;
2614               temp = lhs - LSRegRHS;
2615               if (LoadByte (state, instr, lhs, LUNSIGNED))
2616                 LSBase = temp;
2617               break;
2618
2619             case 0x66:          /* Store Byte, WriteBack, Post Dec, Reg.  */
2620               if (BIT (4))
2621                 {
2622                   ARMul_UndefInstr (state, instr);
2623                   break;
2624                 }
2625               UNDEF_LSRBaseEQOffWb;
2626               UNDEF_LSRBaseEQDestWb;
2627               UNDEF_LSRPCBaseWb;
2628               UNDEF_LSRPCOffWb;
2629               lhs = LHS;
2630               state->NtransSig = LOW;
2631               if (StoreByte (state, instr, lhs))
2632                 LSBase = lhs - LSRegRHS;
2633               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2634               break;
2635
2636             case 0x67:          /* Load Byte, WriteBack, Post Dec, Reg.  */
2637               if (BIT (4))
2638                 {
2639                   ARMul_UndefInstr (state, instr);
2640                   break;
2641                 }
2642               UNDEF_LSRBaseEQOffWb;
2643               UNDEF_LSRBaseEQDestWb;
2644               UNDEF_LSRPCBaseWb;
2645               UNDEF_LSRPCOffWb;
2646               lhs = LHS;
2647               temp = lhs - LSRegRHS;
2648               state->NtransSig = LOW;
2649               if (LoadByte (state, instr, lhs, LUNSIGNED))
2650                 LSBase = temp;
2651               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2652               break;
2653
2654             case 0x68:          /* Store Word, No WriteBack, Post Inc, Reg.  */
2655               if (BIT (4))
2656                 {
2657                   ARMul_UndefInstr (state, instr);
2658                   break;
2659                 }
2660               UNDEF_LSRBaseEQOffWb;
2661               UNDEF_LSRBaseEQDestWb;
2662               UNDEF_LSRPCBaseWb;
2663               UNDEF_LSRPCOffWb;
2664               lhs = LHS;
2665               if (StoreWord (state, instr, lhs))
2666                 LSBase = lhs + LSRegRHS;
2667               break;
2668
2669             case 0x69:          /* Load Word, No WriteBack, Post Inc, Reg.  */
2670               if (BIT (4))
2671                 {
2672                   ARMul_UndefInstr (state, instr);
2673                   break;
2674                 }
2675               UNDEF_LSRBaseEQOffWb;
2676               UNDEF_LSRBaseEQDestWb;
2677               UNDEF_LSRPCBaseWb;
2678               UNDEF_LSRPCOffWb;
2679               lhs = LHS;
2680               temp = lhs + LSRegRHS;
2681               if (LoadWord (state, instr, lhs))
2682                 LSBase = temp;
2683               break;
2684
2685             case 0x6a:          /* Store Word, WriteBack, Post Inc, Reg.  */
2686               if (BIT (4))
2687                 {
2688                   ARMul_UndefInstr (state, instr);
2689                   break;
2690                 }
2691               UNDEF_LSRBaseEQOffWb;
2692               UNDEF_LSRBaseEQDestWb;
2693               UNDEF_LSRPCBaseWb;
2694               UNDEF_LSRPCOffWb;
2695               lhs = LHS;
2696               state->NtransSig = LOW;
2697               if (StoreWord (state, instr, lhs))
2698                 LSBase = lhs + LSRegRHS;
2699               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2700               break;
2701
2702             case 0x6b:          /* Load Word, WriteBack, Post Inc, Reg.  */
2703               if (BIT (4))
2704                 {
2705                   ARMul_UndefInstr (state, instr);
2706                   break;
2707                 }
2708               UNDEF_LSRBaseEQOffWb;
2709               UNDEF_LSRBaseEQDestWb;
2710               UNDEF_LSRPCBaseWb;
2711               UNDEF_LSRPCOffWb;
2712               lhs = LHS;
2713               temp = lhs + LSRegRHS;
2714               state->NtransSig = LOW;
2715               if (LoadWord (state, instr, lhs))
2716                 LSBase = temp;
2717               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2718               break;
2719
2720             case 0x6c:          /* Store Byte, No WriteBack, Post Inc, Reg.  */
2721               if (BIT (4))
2722                 {
2723                   ARMul_UndefInstr (state, instr);
2724                   break;
2725                 }
2726               UNDEF_LSRBaseEQOffWb;
2727               UNDEF_LSRBaseEQDestWb;
2728               UNDEF_LSRPCBaseWb;
2729               UNDEF_LSRPCOffWb;
2730               lhs = LHS;
2731               if (StoreByte (state, instr, lhs))
2732                 LSBase = lhs + LSRegRHS;
2733               break;
2734
2735             case 0x6d:          /* Load Byte, No WriteBack, Post Inc, Reg.  */
2736               if (BIT (4))
2737                 {
2738                   ARMul_UndefInstr (state, instr);
2739                   break;
2740                 }
2741               UNDEF_LSRBaseEQOffWb;
2742               UNDEF_LSRBaseEQDestWb;
2743               UNDEF_LSRPCBaseWb;
2744               UNDEF_LSRPCOffWb;
2745               lhs = LHS;
2746               temp = lhs + LSRegRHS;
2747               if (LoadByte (state, instr, lhs, LUNSIGNED))
2748                 LSBase = temp;
2749               break;
2750
2751             case 0x6e:          /* Store Byte, WriteBack, Post Inc, Reg.  */
2752               if (BIT (4))
2753                 {
2754                   ARMul_UndefInstr (state, instr);
2755                   break;
2756                 }
2757               UNDEF_LSRBaseEQOffWb;
2758               UNDEF_LSRBaseEQDestWb;
2759               UNDEF_LSRPCBaseWb;
2760               UNDEF_LSRPCOffWb;
2761               lhs = LHS;
2762               state->NtransSig = LOW;
2763               if (StoreByte (state, instr, lhs))
2764                 LSBase = lhs + LSRegRHS;
2765               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2766               break;
2767
2768             case 0x6f:          /* Load Byte, WriteBack, Post Inc, Reg.  */
2769               if (BIT (4))
2770                 {
2771                   ARMul_UndefInstr (state, instr);
2772                   break;
2773                 }
2774               UNDEF_LSRBaseEQOffWb;
2775               UNDEF_LSRBaseEQDestWb;
2776               UNDEF_LSRPCBaseWb;
2777               UNDEF_LSRPCOffWb;
2778               lhs = LHS;
2779               temp = lhs + LSRegRHS;
2780               state->NtransSig = LOW;
2781               if (LoadByte (state, instr, lhs, LUNSIGNED))
2782                 LSBase = temp;
2783               state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2784               break;
2785
2786
2787             case 0x70:          /* Store Word, No WriteBack, Pre Dec, Reg.  */
2788               if (BIT (4))
2789                 {
2790                   ARMul_UndefInstr (state, instr);
2791                   break;
2792                 }
2793               (void) StoreWord (state, instr, LHS - LSRegRHS);
2794               break;
2795
2796             case 0x71:          /* Load Word, No WriteBack, Pre Dec, Reg.  */
2797               if (BIT (4))
2798                 {
2799                   ARMul_UndefInstr (state, instr);
2800                   break;
2801                 }
2802               (void) LoadWord (state, instr, LHS - LSRegRHS);
2803               break;
2804
2805             case 0x72:          /* Store Word, WriteBack, Pre Dec, Reg.  */
2806               if (BIT (4))
2807                 {
2808                   ARMul_UndefInstr (state, instr);
2809                   break;
2810                 }
2811               UNDEF_LSRBaseEQOffWb;
2812               UNDEF_LSRBaseEQDestWb;
2813               UNDEF_LSRPCBaseWb;
2814               UNDEF_LSRPCOffWb;
2815               temp = LHS - LSRegRHS;
2816               if (StoreWord (state, instr, temp))
2817                 LSBase = temp;
2818               break;
2819
2820             case 0x73:          /* Load Word, WriteBack, Pre Dec, Reg.  */
2821               if (BIT (4))
2822                 {
2823                   ARMul_UndefInstr (state, instr);
2824                   break;
2825                 }
2826               UNDEF_LSRBaseEQOffWb;
2827               UNDEF_LSRBaseEQDestWb;
2828               UNDEF_LSRPCBaseWb;
2829               UNDEF_LSRPCOffWb;
2830               temp = LHS - LSRegRHS;
2831               if (LoadWord (state, instr, temp))
2832                 LSBase = temp;
2833               break;
2834
2835             case 0x74:          /* Store Byte, No WriteBack, Pre Dec, Reg.  */
2836               if (BIT (4))
2837                 {
2838                   ARMul_UndefInstr (state, instr);
2839                   break;
2840                 }
2841               (void) StoreByte (state, instr, LHS - LSRegRHS);
2842               break;
2843
2844             case 0x75:          /* Load Byte, No WriteBack, Pre Dec, Reg.  */
2845               if (BIT (4))
2846                 {
2847                   ARMul_UndefInstr (state, instr);
2848                   break;
2849                 }
2850               (void) LoadByte (state, instr, LHS - LSRegRHS, LUNSIGNED);
2851               break;
2852
2853             case 0x76:          /* Store Byte, WriteBack, Pre Dec, Reg.  */
2854               if (BIT (4))
2855                 {
2856                   ARMul_UndefInstr (state, instr);
2857                   break;
2858                 }
2859               UNDEF_LSRBaseEQOffWb;
2860               UNDEF_LSRBaseEQDestWb;
2861               UNDEF_LSRPCBaseWb;
2862               UNDEF_LSRPCOffWb;
2863               temp = LHS - LSRegRHS;
2864               if (StoreByte (state, instr, temp))
2865                 LSBase = temp;
2866               break;
2867
2868             case 0x77:          /* Load Byte, WriteBack, Pre Dec, Reg.  */
2869               if (BIT (4))
2870                 {
2871                   ARMul_UndefInstr (state, instr);
2872                   break;
2873                 }
2874               UNDEF_LSRBaseEQOffWb;
2875               UNDEF_LSRBaseEQDestWb;
2876               UNDEF_LSRPCBaseWb;
2877               UNDEF_LSRPCOffWb;
2878               temp = LHS - LSRegRHS;
2879               if (LoadByte (state, instr, temp, LUNSIGNED))
2880                 LSBase = temp;
2881               break;
2882
2883             case 0x78:          /* Store Word, No WriteBack, Pre Inc, Reg.  */
2884               if (BIT (4))
2885                 {
2886                   ARMul_UndefInstr (state, instr);
2887                   break;
2888                 }
2889               (void) StoreWord (state, instr, LHS + LSRegRHS);
2890               break;
2891
2892             case 0x79:          /* Load Word, No WriteBack, Pre Inc, Reg.  */
2893               if (BIT (4))
2894                 {
2895                   ARMul_UndefInstr (state, instr);
2896                   break;
2897                 }
2898               (void) LoadWord (state, instr, LHS + LSRegRHS);
2899               break;
2900
2901             case 0x7a:          /* Store Word, WriteBack, Pre Inc, Reg.  */
2902               if (BIT (4))
2903                 {
2904                   ARMul_UndefInstr (state, instr);
2905                   break;
2906                 }
2907               UNDEF_LSRBaseEQOffWb;
2908               UNDEF_LSRBaseEQDestWb;
2909               UNDEF_LSRPCBaseWb;
2910               UNDEF_LSRPCOffWb;
2911               temp = LHS + LSRegRHS;
2912               if (StoreWord (state, instr, temp))
2913                 LSBase = temp;
2914               break;
2915
2916             case 0x7b:          /* Load Word, WriteBack, Pre Inc, Reg.  */
2917               if (BIT (4))
2918                 {
2919                   ARMul_UndefInstr (state, instr);
2920                   break;
2921                 }
2922               UNDEF_LSRBaseEQOffWb;
2923               UNDEF_LSRBaseEQDestWb;
2924               UNDEF_LSRPCBaseWb;
2925               UNDEF_LSRPCOffWb;
2926               temp = LHS + LSRegRHS;
2927               if (LoadWord (state, instr, temp))
2928                 LSBase = temp;
2929               break;
2930
2931             case 0x7c:          /* Store Byte, No WriteBack, Pre Inc, Reg.  */
2932               if (BIT (4))
2933                 {
2934                   ARMul_UndefInstr (state, instr);
2935                   break;
2936                 }
2937               (void) StoreByte (state, instr, LHS + LSRegRHS);
2938               break;
2939
2940             case 0x7d:          /* Load Byte, No WriteBack, Pre Inc, Reg.  */
2941               if (BIT (4))
2942                 {
2943                   ARMul_UndefInstr (state, instr);
2944                   break;
2945                 }
2946               (void) LoadByte (state, instr, LHS + LSRegRHS, LUNSIGNED);
2947               break;
2948
2949             case 0x7e:          /* Store Byte, WriteBack, Pre Inc, Reg.  */
2950               if (BIT (4))
2951                 {
2952                   ARMul_UndefInstr (state, instr);
2953                   break;
2954                 }
2955               UNDEF_LSRBaseEQOffWb;
2956               UNDEF_LSRBaseEQDestWb;
2957               UNDEF_LSRPCBaseWb;
2958               UNDEF_LSRPCOffWb;
2959               temp = LHS + LSRegRHS;
2960               if (StoreByte (state, instr, temp))
2961                 LSBase = temp;
2962               break;
2963
2964             case 0x7f:          /* Load Byte, WriteBack, Pre Inc, Reg.  */
2965               if (BIT (4))
2966                 {
2967                   /* Check for the special breakpoint opcode.
2968                      This value should correspond to the value defined
2969                      as ARM_BE_BREAKPOINT in gdb/arm/tm-arm.h.  */
2970                   if (BITS (0, 19) == 0xfdefe)
2971                     {
2972                       if (!ARMul_OSHandleSWI (state, SWI_Breakpoint))
2973                         ARMul_Abort (state, ARMul_SWIV);
2974                     }
2975                   else
2976                     ARMul_UndefInstr (state, instr);
2977                   break;
2978                 }
2979               UNDEF_LSRBaseEQOffWb;
2980               UNDEF_LSRBaseEQDestWb;
2981               UNDEF_LSRPCBaseWb;
2982               UNDEF_LSRPCOffWb;
2983               temp = LHS + LSRegRHS;
2984               if (LoadByte (state, instr, temp, LUNSIGNED))
2985                 LSBase = temp;
2986               break;
2987
2988
2989               /* Multiple Data Transfer Instructions.  */
2990
2991             case 0x80:          /* Store, No WriteBack, Post Dec.  */
2992               STOREMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
2993               break;
2994
2995             case 0x81:          /* Load, No WriteBack, Post Dec.  */
2996               LOADMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
2997               break;
2998
2999             case 0x82:          /* Store, WriteBack, Post Dec.  */
3000               temp = LSBase - LSMNumRegs;
3001               STOREMULT (instr, temp + 4L, temp);
3002               break;
3003
3004             case 0x83:          /* Load, WriteBack, Post Dec.  */
3005               temp = LSBase - LSMNumRegs;
3006               LOADMULT (instr, temp + 4L, temp);
3007               break;
3008
3009             case 0x84:          /* Store, Flags, No WriteBack, Post Dec.  */
3010               STORESMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
3011               break;
3012
3013             case 0x85:          /* Load, Flags, No WriteBack, Post Dec.  */
3014               LOADSMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
3015               break;
3016
3017             case 0x86:          /* Store, Flags, WriteBack, Post Dec.  */
3018               temp = LSBase - LSMNumRegs;
3019               STORESMULT (instr, temp + 4L, temp);
3020               break;
3021
3022             case 0x87:          /* Load, Flags, WriteBack, Post Dec.  */
3023               temp = LSBase - LSMNumRegs;
3024               LOADSMULT (instr, temp + 4L, temp);
3025               break;
3026
3027             case 0x88:          /* Store, No WriteBack, Post Inc.  */
3028               STOREMULT (instr, LSBase, 0L);
3029               break;
3030
3031             case 0x89:          /* Load, No WriteBack, Post Inc.  */
3032               LOADMULT (instr, LSBase, 0L);
3033               break;
3034
3035             case 0x8a:          /* Store, WriteBack, Post Inc.  */
3036               temp = LSBase;
3037               STOREMULT (instr, temp, temp + LSMNumRegs);
3038               break;
3039
3040             case 0x8b:          /* Load, WriteBack, Post Inc.  */
3041               temp = LSBase;
3042               LOADMULT (instr, temp, temp + LSMNumRegs);
3043               break;
3044
3045             case 0x8c:          /* Store, Flags, No WriteBack, Post Inc.  */
3046               STORESMULT (instr, LSBase, 0L);
3047               break;
3048
3049             case 0x8d:          /* Load, Flags, No WriteBack, Post Inc.  */
3050               LOADSMULT (instr, LSBase, 0L);
3051               break;
3052
3053             case 0x8e:          /* Store, Flags, WriteBack, Post Inc.  */
3054               temp = LSBase;
3055               STORESMULT (instr, temp, temp + LSMNumRegs);
3056               break;
3057
3058             case 0x8f:          /* Load, Flags, WriteBack, Post Inc.  */
3059               temp = LSBase;
3060               LOADSMULT (instr, temp, temp + LSMNumRegs);
3061               break;
3062
3063             case 0x90:          /* Store, No WriteBack, Pre Dec.  */
3064               STOREMULT (instr, LSBase - LSMNumRegs, 0L);
3065               break;
3066
3067             case 0x91:          /* Load, No WriteBack, Pre Dec.  */
3068               LOADMULT (instr, LSBase - LSMNumRegs, 0L);
3069               break;
3070
3071             case 0x92:          /* Store, WriteBack, Pre Dec.  */
3072               temp = LSBase - LSMNumRegs;
3073               STOREMULT (instr, temp, temp);
3074               break;
3075
3076             case 0x93:          /* Load, WriteBack, Pre Dec.  */
3077               temp = LSBase - LSMNumRegs;
3078               LOADMULT (instr, temp, temp);
3079               break;
3080
3081             case 0x94:          /* Store, Flags, No WriteBack, Pre Dec.  */
3082               STORESMULT (instr, LSBase - LSMNumRegs, 0L);
3083               break;
3084
3085             case 0x95:          /* Load, Flags, No WriteBack, Pre Dec.  */
3086               LOADSMULT (instr, LSBase - LSMNumRegs, 0L);
3087               break;
3088
3089             case 0x96:          /* Store, Flags, WriteBack, Pre Dec.  */
3090               temp = LSBase - LSMNumRegs;
3091               STORESMULT (instr, temp, temp);
3092               break;
3093
3094             case 0x97:          /* Load, Flags, WriteBack, Pre Dec.  */
3095               temp = LSBase - LSMNumRegs;
3096               LOADSMULT (instr, temp, temp);
3097               break;
3098
3099             case 0x98:          /* Store, No WriteBack, Pre Inc.  */
3100               STOREMULT (instr, LSBase + 4L, 0L);
3101               break;
3102
3103             case 0x99:          /* Load, No WriteBack, Pre Inc.  */
3104               LOADMULT (instr, LSBase + 4L, 0L);
3105               break;
3106
3107             case 0x9a:          /* Store, WriteBack, Pre Inc.  */
3108               temp = LSBase;
3109               STOREMULT (instr, temp + 4L, temp + LSMNumRegs);
3110               break;
3111
3112             case 0x9b:          /* Load, WriteBack, Pre Inc.  */
3113               temp = LSBase;
3114               LOADMULT (instr, temp + 4L, temp + LSMNumRegs);
3115               break;
3116
3117             case 0x9c:          /* Store, Flags, No WriteBack, Pre Inc.  */
3118               STORESMULT (instr, LSBase + 4L, 0L);
3119               break;
3120
3121             case 0x9d:          /* Load, Flags, No WriteBack, Pre Inc.  */
3122               LOADSMULT (instr, LSBase + 4L, 0L);
3123               break;
3124
3125             case 0x9e:          /* Store, Flags, WriteBack, Pre Inc.  */
3126               temp = LSBase;
3127               STORESMULT (instr, temp + 4L, temp + LSMNumRegs);
3128               break;
3129
3130             case 0x9f:          /* Load, Flags, WriteBack, Pre Inc.  */
3131               temp = LSBase;
3132               LOADSMULT (instr, temp + 4L, temp + LSMNumRegs);
3133               break;
3134
3135
3136               /* Branch forward.  */
3137             case 0xa0:
3138             case 0xa1:
3139             case 0xa2:
3140             case 0xa3:
3141             case 0xa4:
3142             case 0xa5:
3143             case 0xa6:
3144             case 0xa7:
3145               state->Reg[15] = pc + 8 + POSBRANCH;
3146               FLUSHPIPE;
3147               break;
3148
3149
3150               /* Branch backward.  */
3151             case 0xa8:
3152             case 0xa9:
3153             case 0xaa:
3154             case 0xab:
3155             case 0xac:
3156             case 0xad:
3157             case 0xae:
3158             case 0xaf:
3159               state->Reg[15] = pc + 8 + NEGBRANCH;
3160               FLUSHPIPE;
3161               break;
3162
3163
3164               /* Branch and Link forward.  */
3165             case 0xb0:
3166             case 0xb1:
3167             case 0xb2:
3168             case 0xb3:
3169             case 0xb4:
3170             case 0xb5:
3171             case 0xb6:
3172             case 0xb7:
3173               /* Put PC into Link.  */
3174 #ifdef MODE32
3175               state->Reg[14] = pc + 4;
3176 #else
3177               state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
3178 #endif
3179               state->Reg[15] = pc + 8 + POSBRANCH;
3180               FLUSHPIPE;
3181               break;
3182
3183
3184               /* Branch and Link backward.  */
3185             case 0xb8:
3186             case 0xb9:
3187             case 0xba:
3188             case 0xbb:
3189             case 0xbc:
3190             case 0xbd:
3191             case 0xbe:
3192             case 0xbf:
3193               /* Put PC into Link.  */
3194 #ifdef MODE32
3195               state->Reg[14] = pc + 4;
3196 #else
3197               state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
3198 #endif
3199               state->Reg[15] = pc + 8 + NEGBRANCH;
3200               FLUSHPIPE;
3201               break;
3202
3203
3204               /* Co-Processor Data Transfers.  */
3205             case 0xc4:
3206               if (state->is_v5)
3207                 {
3208                   /* Reading from R15 is UNPREDICTABLE.  */
3209                   if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
3210                     ARMul_UndefInstr (state, instr);
3211                   /* Is access to coprocessor 0 allowed ?  */
3212                   else if (! CP_ACCESS_ALLOWED (state, CPNum))
3213                     ARMul_UndefInstr (state, instr);
3214                   /* Special treatment for XScale coprocessors.  */
3215                   else if (state->is_XScale)
3216                     {
3217                       /* Only opcode 0 is supported.  */
3218                       if (BITS (4, 7) != 0x00)
3219                         ARMul_UndefInstr (state, instr);
3220                       /* Only coporcessor 0 is supported.  */
3221                       else if (CPNum != 0x00)
3222                         ARMul_UndefInstr (state, instr);
3223                       /* Only accumulator 0 is supported.  */
3224                       else if (BITS (0, 3) != 0x00)
3225                         ARMul_UndefInstr (state, instr);
3226                       else
3227                         {
3228                           /* XScale MAR insn.  Move two registers into accumulator.  */
3229                           state->Accumulator = state->Reg[BITS (12, 15)];
3230                           state->Accumulator += (ARMdword) state->Reg[BITS (16, 19)] << 32;
3231                         }
3232                     }
3233                   else
3234                     /* FIXME: Not sure what to do for other v5 processors.  */
3235                     ARMul_UndefInstr (state, instr);                
3236                   break;
3237                 }
3238               /* Drop through.  */
3239               
3240             case 0xc0:          /* Store , No WriteBack , Post Dec.  */
3241               ARMul_STC (state, instr, LHS);
3242               break;
3243
3244             case 0xc5:
3245               if (state->is_v5)
3246                 {
3247                   /* Writes to R15 are UNPREDICATABLE.  */
3248                   if (DESTReg == 15 || LHSReg == 15)
3249                     ARMul_UndefInstr (state, instr);
3250                   /* Is access to the coprocessor allowed ?  */
3251                   else if (! CP_ACCESS_ALLOWED (state, CPNum))
3252                     ARMul_UndefInstr (state, instr);
3253                   /* Special handling for XScale coprcoessors.  */
3254                   else if (state->is_XScale)
3255                     {
3256                       /* Only opcode 0 is supported.  */
3257                       if (BITS (4, 7) != 0x00)
3258                         ARMul_UndefInstr (state, instr);
3259                       /* Only coprocessor 0 is supported.  */
3260                       else if (CPNum != 0x00)
3261                         ARMul_UndefInstr (state, instr);
3262                       /* Only accumulator 0 is supported.  */
3263                       else if (BITS (0, 3) != 0x00)
3264                         ARMul_UndefInstr (state, instr);
3265                       else
3266                         {
3267                           /* XScale MRA insn.  Move accumulator into two registers.  */
3268                           ARMword t1 = (state->Accumulator >> 32) & 255;
3269
3270                           if (t1 & 128)
3271                             t1 -= 256;
3272
3273                           state->Reg[BITS (12, 15)] = state->Accumulator;
3274                           state->Reg[BITS (16, 19)] = t1;
3275                           break;
3276                         }
3277                     }
3278                   else
3279                     /* FIXME: Not sure what to do for other v5 processors.  */
3280                     ARMul_UndefInstr (state, instr);
3281                   break;
3282                 }
3283               /* Drop through.  */
3284
3285             case 0xc1:          /* Load , No WriteBack , Post Dec.  */
3286               ARMul_LDC (state, instr, LHS);
3287               break;
3288
3289             case 0xc2:
3290             case 0xc6:          /* Store , WriteBack , Post Dec.  */
3291               lhs = LHS;
3292               state->Base = lhs - LSCOff;
3293               ARMul_STC (state, instr, lhs);
3294               break;
3295
3296             case 0xc3:
3297             case 0xc7:          /* Load , WriteBack , Post Dec.  */
3298               lhs = LHS;
3299               state->Base = lhs - LSCOff;
3300               ARMul_LDC (state, instr, lhs);
3301               break;
3302
3303             case 0xc8:
3304             case 0xcc:          /* Store , No WriteBack , Post Inc.  */
3305               ARMul_STC (state, instr, LHS);
3306               break;
3307
3308             case 0xc9:
3309             case 0xcd:          /* Load , No WriteBack , Post Inc.  */
3310               ARMul_LDC (state, instr, LHS);
3311               break;
3312
3313             case 0xca:
3314             case 0xce:          /* Store , WriteBack , Post Inc.  */
3315               lhs = LHS;
3316               state->Base = lhs + LSCOff;
3317               ARMul_STC (state, instr, LHS);
3318               break;
3319
3320             case 0xcb:
3321             case 0xcf:          /* Load , WriteBack , Post Inc.  */
3322               lhs = LHS;
3323               state->Base = lhs + LSCOff;
3324               ARMul_LDC (state, instr, LHS);
3325               break;
3326
3327             case 0xd0:
3328             case 0xd4:          /* Store , No WriteBack , Pre Dec.  */
3329               ARMul_STC (state, instr, LHS - LSCOff);
3330               break;
3331
3332             case 0xd1:
3333             case 0xd5:          /* Load , No WriteBack , Pre Dec.  */
3334               ARMul_LDC (state, instr, LHS - LSCOff);
3335               break;
3336
3337             case 0xd2:
3338             case 0xd6:          /* Store , WriteBack , Pre Dec.  */
3339               lhs = LHS - LSCOff;
3340               state->Base = lhs;
3341               ARMul_STC (state, instr, lhs);
3342               break;
3343
3344             case 0xd3:
3345             case 0xd7:          /* Load , WriteBack , Pre Dec.  */
3346               lhs = LHS - LSCOff;
3347               state->Base = lhs;
3348               ARMul_LDC (state, instr, lhs);
3349               break;
3350
3351             case 0xd8:
3352             case 0xdc:          /* Store , No WriteBack , Pre Inc.  */
3353               ARMul_STC (state, instr, LHS + LSCOff);
3354               break;
3355
3356             case 0xd9:
3357             case 0xdd:          /* Load , No WriteBack , Pre Inc.  */
3358               ARMul_LDC (state, instr, LHS + LSCOff);
3359               break;
3360
3361             case 0xda:
3362             case 0xde:          /* Store , WriteBack , Pre Inc.  */
3363               lhs = LHS + LSCOff;
3364               state->Base = lhs;
3365               ARMul_STC (state, instr, lhs);
3366               break;
3367
3368             case 0xdb:
3369             case 0xdf:          /* Load , WriteBack , Pre Inc.  */
3370               lhs = LHS + LSCOff;
3371               state->Base = lhs;
3372               ARMul_LDC (state, instr, lhs);
3373               break;
3374
3375
3376               /* Co-Processor Register Transfers (MCR) and Data Ops.  */
3377
3378             case 0xe2:
3379               if (! CP_ACCESS_ALLOWED (state, CPNum))
3380                 {
3381                   ARMul_UndefInstr (state, instr);
3382                   break;
3383                 }
3384               if (state->is_XScale)
3385                 switch (BITS (18, 19))
3386                   {
3387                   case 0x0:
3388                     if (BITS (4, 11) == 1 && BITS (16, 17) == 0)
3389                       {
3390                         /* XScale MIA instruction.  Signed multiplication of
3391                            two 32 bit values and addition to 40 bit accumulator.  */
3392                         long long Rm = state->Reg[MULLHSReg];
3393                         long long Rs = state->Reg[MULACCReg];
3394
3395                         if (Rm & (1 << 31))
3396                           Rm -= 1ULL << 32;
3397                         if (Rs & (1 << 31))
3398                           Rs -= 1ULL << 32;
3399                         state->Accumulator += Rm * Rs;
3400                         goto donext;
3401                       }
3402                     break;
3403
3404                   case 0x2:
3405                     if (BITS (4, 11) == 1 && BITS (16, 17) == 0)
3406                       {
3407                         /* XScale MIAPH instruction.  */
3408                         ARMword t1 = state->Reg[MULLHSReg] >> 16;
3409                         ARMword t2 = state->Reg[MULACCReg] >> 16;
3410                         ARMword t3 = state->Reg[MULLHSReg] & 0xffff;
3411                         ARMword t4 = state->Reg[MULACCReg] & 0xffff;
3412                         long long t5;
3413
3414                         if (t1 & (1 << 15))
3415                           t1 -= 1 << 16;
3416                         if (t2 & (1 << 15))
3417                           t2 -= 1 << 16;
3418                         if (t3 & (1 << 15))
3419                           t3 -= 1 << 16;
3420                         if (t4 & (1 << 15))
3421                           t4 -= 1 << 16;
3422                         t1 *= t2;
3423                         t5 = t1;
3424                         if (t5 & (1 << 31))
3425                           t5 -= 1ULL << 32;
3426                         state->Accumulator += t5;
3427                         t3 *= t4;
3428                         t5 = t3;
3429                         if (t5 & (1 << 31))
3430                           t5 -= 1ULL << 32;
3431                         state->Accumulator += t5;
3432                         goto donext;
3433                       }
3434                     break;
3435
3436                   case 0x3:
3437                     if (BITS (4, 11) == 1)
3438                       {
3439                         /* XScale MIAxy instruction.  */
3440                         ARMword t1;
3441                         ARMword t2;
3442                         long long t5;
3443
3444                         if (BIT (17))
3445                           t1 = state->Reg[MULLHSReg] >> 16;
3446                         else
3447                           t1 = state->Reg[MULLHSReg] & 0xffff;
3448
3449                         if (BIT (16))
3450                           t2 = state->Reg[MULACCReg] >> 16;
3451                         else
3452                           t2 = state->Reg[MULACCReg] & 0xffff;
3453
3454                         if (t1 & (1 << 15))
3455                           t1 -= 1 << 16;
3456                         if (t2 & (1 << 15))
3457                           t2 -= 1 << 16;
3458                         t1 *= t2;
3459                         t5 = t1;
3460                         if (t5 & (1 << 31))
3461                           t5 -= 1ULL << 32;
3462                         state->Accumulator += t5;
3463                         goto donext;
3464                       }
3465                     break;
3466
3467                   default:
3468                     break;
3469                   }
3470               /* Drop through.  */
3471
3472             case 0xe0:
3473             case 0xe4:
3474             case 0xe6:
3475             case 0xe8:
3476             case 0xea:
3477             case 0xec:
3478             case 0xee:
3479               if (BIT (4))
3480                 {
3481                   /* MCR.  */
3482                   if (DESTReg == 15)
3483                     {
3484                       UNDEF_MCRPC;
3485 #ifdef MODE32
3486                       ARMul_MCR (state, instr, state->Reg[15] + isize);
3487 #else
3488                       ARMul_MCR (state, instr, ECC | ER15INT | EMODE |
3489                                  ((state->Reg[15] + isize) & R15PCBITS));
3490 #endif
3491                     }
3492                   else
3493                     ARMul_MCR (state, instr, DEST);
3494                 }
3495               else
3496                 /* CDP Part 1.  */
3497                 ARMul_CDP (state, instr);
3498               break;
3499
3500
3501               /* Co-Processor Register Transfers (MRC) and Data Ops.  */
3502             case 0xe1:
3503             case 0xe3:
3504             case 0xe5:
3505             case 0xe7:
3506             case 0xe9:
3507             case 0xeb:
3508             case 0xed:
3509             case 0xef:
3510               if (BIT (4))
3511                 {
3512                   /* MRC */
3513                   temp = ARMul_MRC (state, instr);
3514                   if (DESTReg == 15)
3515                     {
3516                       ASSIGNN ((temp & NBIT) != 0);
3517                       ASSIGNZ ((temp & ZBIT) != 0);
3518                       ASSIGNC ((temp & CBIT) != 0);
3519                       ASSIGNV ((temp & VBIT) != 0);
3520                     }
3521                   else
3522                     DEST = temp;
3523                 }
3524               else
3525                 /* CDP Part 2.  */
3526                 ARMul_CDP (state, instr);
3527               break;
3528
3529
3530               /* SWI instruction.  */
3531             case 0xf0:
3532             case 0xf1:
3533             case 0xf2:
3534             case 0xf3:
3535             case 0xf4:
3536             case 0xf5:
3537             case 0xf6:
3538             case 0xf7:
3539             case 0xf8:
3540             case 0xf9:
3541             case 0xfa:
3542             case 0xfb:
3543             case 0xfc:
3544             case 0xfd:
3545             case 0xfe:
3546             case 0xff:
3547               if (instr == ARMul_ABORTWORD && state->AbortAddr == pc)
3548                 {
3549                   /* A prefetch abort.  */
3550                   XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc);
3551                   ARMul_Abort (state, ARMul_PrefetchAbortV);
3552                   break;
3553                 }
3554
3555               if (!ARMul_OSHandleSWI (state, BITS (0, 23)))
3556                 ARMul_Abort (state, ARMul_SWIV);
3557
3558               break;
3559             }
3560         }
3561
3562 #ifdef MODET
3563     donext:
3564 #endif
3565
3566 #ifdef NEED_UI_LOOP_HOOK
3567       if (ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
3568         {
3569           ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
3570           ui_loop_hook (0);
3571         }
3572 #endif /* NEED_UI_LOOP_HOOK */
3573
3574       if (state->Emulate == ONCE)
3575         state->Emulate = STOP;
3576       /* If we have changed mode, allow the PC to advance before stopping.  */
3577       else if (state->Emulate == CHANGEMODE)
3578         continue;
3579       else if (state->Emulate != RUN)
3580         break;
3581     }
3582   while (!stop_simulator);
3583
3584   state->decoded = decoded;
3585   state->loaded = loaded;
3586   state->pc = pc;
3587
3588   return pc;
3589 }
3590
3591 /* This routine evaluates most Data Processing register RHS's with the S
3592    bit clear.  It is intended to be called from the macro DPRegRHS, which
3593    filters the common case of an unshifted register with in line code.  */
3594
3595 static ARMword
3596 GetDPRegRHS (ARMul_State * state, ARMword instr)
3597 {
3598   ARMword shamt, base;
3599
3600   base = RHSReg;
3601   if (BIT (4))
3602     {
3603       /* Shift amount in a register.  */
3604       UNDEF_Shift;
3605       INCPC;
3606 #ifndef MODE32
3607       if (base == 15)
3608         base = ECC | ER15INT | R15PC | EMODE;
3609       else
3610 #endif
3611         base = state->Reg[base];
3612       ARMul_Icycles (state, 1, 0L);
3613       shamt = state->Reg[BITS (8, 11)] & 0xff;
3614       switch ((int) BITS (5, 6))
3615         {
3616         case LSL:
3617           if (shamt == 0)
3618             return (base);
3619           else if (shamt >= 32)
3620             return (0);
3621           else
3622             return (base << shamt);
3623         case LSR:
3624           if (shamt == 0)
3625             return (base);
3626           else if (shamt >= 32)
3627             return (0);
3628           else
3629             return (base >> shamt);
3630         case ASR:
3631           if (shamt == 0)
3632             return (base);
3633           else if (shamt >= 32)
3634             return ((ARMword) ((long int) base >> 31L));
3635           else
3636             return ((ARMword) ((long int) base >> (int) shamt));
3637         case ROR:
3638           shamt &= 0x1f;
3639           if (shamt == 0)
3640             return (base);
3641           else
3642             return ((base << (32 - shamt)) | (base >> shamt));
3643         }
3644     }
3645   else
3646     {
3647       /* Shift amount is a constant.  */
3648 #ifndef MODE32
3649       if (base == 15)
3650         base = ECC | ER15INT | R15PC | EMODE;
3651       else
3652 #endif
3653         base = state->Reg[base];
3654       shamt = BITS (7, 11);
3655       switch ((int) BITS (5, 6))
3656         {
3657         case LSL:
3658           return (base << shamt);
3659         case LSR:
3660           if (shamt == 0)
3661             return (0);
3662           else
3663             return (base >> shamt);
3664         case ASR:
3665           if (shamt == 0)
3666             return ((ARMword) ((long int) base >> 31L));
3667           else
3668             return ((ARMword) ((long int) base >> (int) shamt));
3669         case ROR:
3670           if (shamt == 0)
3671             /* It's an RRX.  */
3672             return ((base >> 1) | (CFLAG << 31));
3673           else
3674             return ((base << (32 - shamt)) | (base >> shamt));
3675         }
3676     }
3677
3678   return 0;
3679 }
3680
3681 /* This routine evaluates most Logical Data Processing register RHS's
3682    with the S bit set.  It is intended to be called from the macro
3683    DPSRegRHS, which filters the common case of an unshifted register
3684    with in line code.  */
3685
3686 static ARMword
3687 GetDPSRegRHS (ARMul_State * state, ARMword instr)
3688 {
3689   ARMword shamt, base;
3690
3691   base = RHSReg;
3692   if (BIT (4))
3693     {
3694       /* Shift amount in a register.  */
3695       UNDEF_Shift;
3696       INCPC;
3697 #ifndef MODE32
3698       if (base == 15)
3699         base = ECC | ER15INT | R15PC | EMODE;
3700       else
3701 #endif
3702         base = state->Reg[base];
3703       ARMul_Icycles (state, 1, 0L);
3704       shamt = state->Reg[BITS (8, 11)] & 0xff;
3705       switch ((int) BITS (5, 6))
3706         {
3707         case LSL:
3708           if (shamt == 0)
3709             return (base);
3710           else if (shamt == 32)
3711             {
3712               ASSIGNC (base & 1);
3713               return (0);
3714             }
3715           else if (shamt > 32)
3716             {
3717               CLEARC;
3718               return (0);
3719             }
3720           else
3721             {
3722               ASSIGNC ((base >> (32 - shamt)) & 1);
3723               return (base << shamt);
3724             }
3725         case LSR:
3726           if (shamt == 0)
3727             return (base);
3728           else if (shamt == 32)
3729             {
3730               ASSIGNC (base >> 31);
3731               return (0);
3732             }
3733           else if (shamt > 32)
3734             {
3735               CLEARC;
3736               return (0);
3737             }
3738           else
3739             {
3740               ASSIGNC ((base >> (shamt - 1)) & 1);
3741               return (base >> shamt);
3742             }
3743         case ASR:
3744           if (shamt == 0)
3745             return (base);
3746           else if (shamt >= 32)
3747             {
3748               ASSIGNC (base >> 31L);
3749               return ((ARMword) ((long int) base >> 31L));
3750             }
3751           else
3752             {
3753               ASSIGNC ((ARMword) ((long int) base >> (int) (shamt - 1)) & 1);
3754               return ((ARMword) ((long int) base >> (int) shamt));
3755             }
3756         case ROR:
3757           if (shamt == 0)
3758             return (base);
3759           shamt &= 0x1f;
3760           if (shamt == 0)
3761             {
3762               ASSIGNC (base >> 31);
3763               return (base);
3764             }
3765           else
3766             {
3767               ASSIGNC ((base >> (shamt - 1)) & 1);
3768               return ((base << (32 - shamt)) | (base >> shamt));
3769             }
3770         }
3771     }
3772   else
3773     {
3774       /* Shift amount is a constant.  */
3775 #ifndef MODE32
3776       if (base == 15)
3777         base = ECC | ER15INT | R15PC | EMODE;
3778       else
3779 #endif
3780         base = state->Reg[base];
3781       shamt = BITS (7, 11);
3782
3783       switch ((int) BITS (5, 6))
3784         {
3785         case LSL:
3786           ASSIGNC ((base >> (32 - shamt)) & 1);
3787           return (base << shamt);
3788         case LSR:
3789           if (shamt == 0)
3790             {
3791               ASSIGNC (base >> 31);
3792               return (0);
3793             }
3794           else
3795             {
3796               ASSIGNC ((base >> (shamt - 1)) & 1);
3797               return (base >> shamt);
3798             }
3799         case ASR:
3800           if (shamt == 0)
3801             {
3802               ASSIGNC (base >> 31L);
3803               return ((ARMword) ((long int) base >> 31L));
3804             }
3805           else
3806             {
3807               ASSIGNC ((ARMword) ((long int) base >> (int) (shamt - 1)) & 1);
3808               return ((ARMword) ((long int) base >> (int) shamt));
3809             }
3810         case ROR:
3811           if (shamt == 0)
3812             {
3813               /* It's an RRX.  */
3814               shamt = CFLAG;
3815               ASSIGNC (base & 1);
3816               return ((base >> 1) | (shamt << 31));
3817             }
3818           else
3819             {
3820               ASSIGNC ((base >> (shamt - 1)) & 1);
3821               return ((base << (32 - shamt)) | (base >> shamt));
3822             }
3823         }
3824     }
3825
3826   return 0;
3827 }
3828
3829 /* This routine handles writes to register 15 when the S bit is not set.  */
3830
3831 static void
3832 WriteR15 (ARMul_State * state, ARMword src)
3833 {
3834   /* The ARM documentation states that the two least significant bits
3835      are discarded when setting PC, except in the cases handled by
3836      WriteR15Branch() below.  It's probably an oversight: in THUMB
3837      mode, the second least significant bit should probably not be
3838      discarded.  */
3839 #ifdef MODET
3840   if (TFLAG)
3841     src &= 0xfffffffe;
3842   else
3843 #endif
3844     src &= 0xfffffffc;
3845
3846 #ifdef MODE32
3847   state->Reg[15] = src & PCBITS;
3848 #else
3849   state->Reg[15] = (src & R15PCBITS) | ECC | ER15INT | EMODE;
3850   ARMul_R15Altered (state);
3851 #endif
3852
3853   FLUSHPIPE;
3854 }
3855
3856 /* This routine handles writes to register 15 when the S bit is set.  */
3857
3858 static void
3859 WriteSR15 (ARMul_State * state, ARMword src)
3860 {
3861 #ifdef MODE32
3862   if (state->Bank > 0)
3863     {
3864       state->Cpsr = state->Spsr[state->Bank];
3865       ARMul_CPSRAltered (state);
3866     }
3867 #ifdef MODET
3868   if (TFLAG)
3869     src &= 0xfffffffe;
3870   else
3871 #endif
3872     src &= 0xfffffffc;
3873   state->Reg[15] = src & PCBITS;
3874 #else
3875 #ifdef MODET
3876   if (TFLAG)
3877     /* ARMul_R15Altered would have to support it.  */
3878     abort ();
3879   else
3880 #endif
3881     src &= 0xfffffffc;
3882
3883   if (state->Bank == USERBANK)
3884     state->Reg[15] = (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE;
3885   else
3886     state->Reg[15] = src;
3887
3888   ARMul_R15Altered (state);
3889 #endif
3890   FLUSHPIPE;
3891 }
3892
3893 /* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM
3894    will switch to Thumb mode if the least significant bit is set.  */
3895
3896 static void
3897 WriteR15Branch (ARMul_State * state, ARMword src)
3898 {
3899 #ifdef MODET
3900   if (src & 1)
3901     {
3902       /* Thumb bit.  */
3903       SETT;
3904       state->Reg[15] = src & 0xfffffffe;
3905     }
3906   else
3907     {
3908       CLEART;
3909       state->Reg[15] = src & 0xfffffffc;
3910     }
3911   FLUSHPIPE;
3912 #else
3913   WriteR15 (state, src);
3914 #endif
3915 }
3916
3917 /* This routine evaluates most Load and Store register RHS's.  It is
3918    intended to be called from the macro LSRegRHS, which filters the
3919    common case of an unshifted register with in line code.  */
3920
3921 static ARMword
3922 GetLSRegRHS (ARMul_State * state, ARMword instr)
3923 {
3924   ARMword shamt, base;
3925
3926   base = RHSReg;
3927 #ifndef MODE32
3928   if (base == 15)
3929     /* Now forbidden, but ...  */
3930     base = ECC | ER15INT | R15PC | EMODE;
3931   else
3932 #endif
3933     base = state->Reg[base];
3934
3935   shamt = BITS (7, 11);
3936   switch ((int) BITS (5, 6))
3937     {
3938     case LSL:
3939       return (base << shamt);
3940     case LSR:
3941       if (shamt == 0)
3942         return (0);
3943       else
3944         return (base >> shamt);
3945     case ASR:
3946       if (shamt == 0)
3947         return ((ARMword) ((long int) base >> 31L));
3948       else
3949         return ((ARMword) ((long int) base >> (int) shamt));
3950     case ROR:
3951       if (shamt == 0)
3952         /* It's an RRX.  */
3953         return ((base >> 1) | (CFLAG << 31));
3954       else
3955         return ((base << (32 - shamt)) | (base >> shamt));
3956     default:
3957       break;
3958     }
3959   return 0;
3960 }
3961
3962 /* This routine evaluates the ARM7T halfword and signed transfer RHS's.  */
3963
3964 static ARMword
3965 GetLS7RHS (ARMul_State * state, ARMword instr)
3966 {
3967   if (BIT (22) == 0)
3968     {
3969       /* Register.  */
3970 #ifndef MODE32
3971       if (RHSReg == 15)
3972         /* Now forbidden, but ...  */
3973         return ECC | ER15INT | R15PC | EMODE;
3974 #endif
3975       return state->Reg[RHSReg];
3976     }
3977
3978   /* Immediate.  */
3979   return BITS (0, 3) | (BITS (8, 11) << 4);
3980 }
3981
3982 /* This function does the work of loading a word for a LDR instruction.  */
3983
3984 static unsigned
3985 LoadWord (ARMul_State * state, ARMword instr, ARMword address)
3986 {
3987   ARMword dest;
3988
3989   BUSUSEDINCPCS;
3990 #ifndef MODE32
3991   if (ADDREXCEPT (address))
3992     INTERNALABORT (address);
3993 #endif
3994
3995   dest = ARMul_LoadWordN (state, address);
3996
3997   if (state->Aborted)
3998     {
3999       TAKEABORT;
4000       return state->lateabtSig;
4001     }
4002   if (address & 3)
4003     dest = ARMul_Align (state, address, dest);
4004   WRITEDESTB (dest);
4005   ARMul_Icycles (state, 1, 0L);
4006
4007   return (DESTReg != LHSReg);
4008 }
4009
4010 #ifdef MODET
4011 /* This function does the work of loading a halfword.  */
4012
4013 static unsigned
4014 LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address,
4015               int signextend)
4016 {
4017   ARMword dest;
4018
4019   BUSUSEDINCPCS;
4020 #ifndef MODE32
4021   if (ADDREXCEPT (address))
4022     INTERNALABORT (address);
4023 #endif
4024   dest = ARMul_LoadHalfWord (state, address);
4025   if (state->Aborted)
4026     {
4027       TAKEABORT;
4028       return state->lateabtSig;
4029     }
4030   UNDEF_LSRBPC;
4031   if (signextend)
4032     if (dest & 1 << (16 - 1))
4033       dest = (dest & ((1 << 16) - 1)) - (1 << 16);
4034
4035   WRITEDEST (dest);
4036   ARMul_Icycles (state, 1, 0L);
4037   return (DESTReg != LHSReg);
4038 }
4039
4040 #endif /* MODET */
4041
4042 /* This function does the work of loading a byte for a LDRB instruction.  */
4043
4044 static unsigned
4045 LoadByte (ARMul_State * state, ARMword instr, ARMword address, int signextend)
4046 {
4047   ARMword dest;
4048
4049   BUSUSEDINCPCS;
4050 #ifndef MODE32
4051   if (ADDREXCEPT (address))
4052     INTERNALABORT (address);
4053 #endif
4054   dest = ARMul_LoadByte (state, address);
4055   if (state->Aborted)
4056     {
4057       TAKEABORT;
4058       return state->lateabtSig;
4059     }
4060   UNDEF_LSRBPC;
4061   if (signextend)
4062     if (dest & 1 << (8 - 1))
4063       dest = (dest & ((1 << 8) - 1)) - (1 << 8);
4064
4065   WRITEDEST (dest);
4066   ARMul_Icycles (state, 1, 0L);
4067
4068   return (DESTReg != LHSReg);
4069 }
4070
4071 /* This function does the work of loading two words for a LDRD instruction.  */
4072
4073 static void
4074 Handle_Load_Double (ARMul_State * state, ARMword instr)
4075 {
4076   ARMword dest_reg;
4077   ARMword addr_reg;
4078   ARMword write_back  = BIT (21);
4079   ARMword immediate   = BIT (22);
4080   ARMword add_to_base = BIT (23);        
4081   ARMword pre_indexed = BIT (24);
4082   ARMword offset;
4083   ARMword addr;
4084   ARMword sum;
4085   ARMword base;
4086   ARMword value1;
4087   ARMword value2;
4088   
4089   BUSUSEDINCPCS;
4090
4091   /* If the writeback bit is set, the pre-index bit must be clear.  */
4092   if (write_back && ! pre_indexed)
4093     {
4094       ARMul_UndefInstr (state, instr);
4095       return;
4096     }
4097   
4098   /* Extract the base address register.  */
4099   addr_reg = LHSReg;
4100   
4101   /* Extract the destination register and check it.  */
4102   dest_reg = DESTReg;
4103   
4104   /* Destination register must be even.  */
4105   if ((dest_reg & 1)
4106     /* Destination register cannot be LR.  */
4107       || (dest_reg == 14))
4108     {
4109       ARMul_UndefInstr (state, instr);
4110       return;
4111     }
4112
4113   /* Compute the base address.  */
4114   base = state->Reg[addr_reg];
4115
4116   /* Compute the offset.  */
4117   offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg];
4118
4119   /* Compute the sum of the two.  */
4120   if (add_to_base)
4121     sum = base + offset;
4122   else
4123     sum = base - offset;
4124   
4125   /* If this is a pre-indexed mode use the sum.  */
4126   if (pre_indexed)
4127     addr = sum;
4128   else
4129     addr = base;
4130
4131   /* The address must be aligned on a 8 byte boundary.  */
4132   if (addr & 0x7)
4133     {
4134 #ifdef ABORTS
4135       ARMul_DATAABORT (addr);
4136 #else
4137       ARMul_UndefInstr (state, instr);
4138 #endif
4139       return;
4140     }
4141
4142   /* For pre indexed or post indexed addressing modes,
4143      check that the destination registers do not overlap
4144      the address registers.  */
4145   if ((! pre_indexed || write_back)
4146       && (   addr_reg == dest_reg
4147           || addr_reg == dest_reg + 1))
4148     {
4149       ARMul_UndefInstr (state, instr);
4150       return;
4151     }
4152
4153   /* Load the words.  */
4154   value1 = ARMul_LoadWordN (state, addr);
4155   value2 = ARMul_LoadWordN (state, addr + 4);
4156
4157   /* Check for data aborts.  */
4158   if (state->Aborted)
4159     {
4160       TAKEABORT;
4161       return;
4162     }
4163   
4164   ARMul_Icycles (state, 2, 0L);
4165
4166   /* Store the values.  */
4167   state->Reg[dest_reg] = value1;
4168   state->Reg[dest_reg + 1] = value2;
4169   
4170   /* Do the post addressing and writeback.  */
4171   if (! pre_indexed)
4172     addr = sum;
4173   
4174   if (! pre_indexed || write_back)
4175     state->Reg[addr_reg] = addr;
4176 }
4177
4178 /* This function does the work of storing two words for a STRD instruction.  */
4179
4180 static void
4181 Handle_Store_Double (ARMul_State * state, ARMword instr)
4182 {
4183   ARMword src_reg;
4184   ARMword addr_reg;
4185   ARMword write_back  = BIT (21);
4186   ARMword immediate   = BIT (22);
4187   ARMword add_to_base = BIT (23);        
4188   ARMword pre_indexed = BIT (24);
4189   ARMword offset;
4190   ARMword addr;
4191   ARMword sum;
4192   ARMword base;
4193
4194   BUSUSEDINCPCS;
4195
4196   /* If the writeback bit is set, the pre-index bit must be clear.  */
4197   if (write_back && ! pre_indexed)
4198     {
4199       ARMul_UndefInstr (state, instr);
4200       return;
4201     }
4202   
4203   /* Extract the base address register.  */
4204   addr_reg = LHSReg;
4205   
4206   /* Base register cannot be PC.  */
4207   if (addr_reg == 15)
4208     {
4209       ARMul_UndefInstr (state, instr);
4210       return;
4211     }
4212   
4213   /* Extract the source register.  */
4214   src_reg = DESTReg;
4215   
4216   /* Source register must be even.  */
4217   if (src_reg & 1)
4218     {
4219       ARMul_UndefInstr (state, instr);
4220       return;
4221     }
4222
4223   /* Compute the base address.  */
4224   base = state->Reg[addr_reg];
4225
4226   /* Compute the offset.  */
4227   offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg];
4228
4229   /* Compute the sum of the two.  */
4230   if (add_to_base)
4231     sum = base + offset;
4232   else
4233     sum = base - offset;
4234   
4235   /* If this is a pre-indexed mode use the sum.  */
4236   if (pre_indexed)
4237     addr = sum;
4238   else
4239     addr = base;
4240
4241   /* The address must be aligned on a 8 byte boundary.  */
4242   if (addr & 0x7)
4243     {
4244 #ifdef ABORTS
4245       ARMul_DATAABORT (addr);
4246 #else
4247       ARMul_UndefInstr (state, instr);
4248 #endif
4249       return;
4250     }
4251
4252   /* For pre indexed or post indexed addressing modes,
4253      check that the destination registers do not overlap
4254      the address registers.  */
4255   if ((! pre_indexed || write_back)
4256       && (   addr_reg == src_reg
4257           || addr_reg == src_reg + 1))
4258     {
4259       ARMul_UndefInstr (state, instr);
4260       return;
4261     }
4262
4263   /* Load the words.  */
4264   ARMul_StoreWordN (state, addr, state->Reg[src_reg]);
4265   ARMul_StoreWordN (state, addr + 4, state->Reg[src_reg + 1]);
4266   
4267   if (state->Aborted)
4268     {
4269       TAKEABORT;
4270       return;
4271     }
4272   
4273   /* Do the post addressing and writeback.  */
4274   if (! pre_indexed)
4275     addr = sum;
4276   
4277   if (! pre_indexed || write_back)
4278     state->Reg[addr_reg] = addr;
4279 }
4280
4281 /* This function does the work of storing a word from a STR instruction.  */
4282
4283 static unsigned
4284 StoreWord (ARMul_State * state, ARMword instr, ARMword address)
4285 {
4286   BUSUSEDINCPCN;
4287 #ifndef MODE32
4288   if (DESTReg == 15)
4289     state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
4290 #endif
4291 #ifdef MODE32
4292   ARMul_StoreWordN (state, address, DEST);
4293 #else
4294   if (VECTORACCESS (address) || ADDREXCEPT (address))
4295     {
4296       INTERNALABORT (address);
4297       (void) ARMul_LoadWordN (state, address);
4298     }
4299   else
4300     ARMul_StoreWordN (state, address, DEST);
4301 #endif
4302   if (state->Aborted)
4303     {
4304       TAKEABORT;
4305       return state->lateabtSig;
4306     }
4307   return TRUE;
4308 }
4309
4310 #ifdef MODET
4311 /* This function does the work of storing a byte for a STRH instruction.  */
4312
4313 static unsigned
4314 StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address)
4315 {
4316   BUSUSEDINCPCN;
4317
4318 #ifndef MODE32
4319   if (DESTReg == 15)
4320     state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
4321 #endif
4322
4323 #ifdef MODE32
4324   ARMul_StoreHalfWord (state, address, DEST);
4325 #else
4326   if (VECTORACCESS (address) || ADDREXCEPT (address))
4327     {
4328       INTERNALABORT (address);
4329       (void) ARMul_LoadHalfWord (state, address);
4330     }
4331   else
4332     ARMul_StoreHalfWord (state, address, DEST);
4333 #endif
4334
4335   if (state->Aborted)
4336     {
4337       TAKEABORT;
4338       return state->lateabtSig;
4339     }
4340   return TRUE;
4341 }
4342
4343 #endif /* MODET */
4344
4345 /* This function does the work of storing a byte for a STRB instruction.  */
4346
4347 static unsigned
4348 StoreByte (ARMul_State * state, ARMword instr, ARMword address)
4349 {
4350   BUSUSEDINCPCN;
4351 #ifndef MODE32
4352   if (DESTReg == 15)
4353     state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
4354 #endif
4355 #ifdef MODE32
4356   ARMul_StoreByte (state, address, DEST);
4357 #else
4358   if (VECTORACCESS (address) || ADDREXCEPT (address))
4359     {
4360       INTERNALABORT (address);
4361       (void) ARMul_LoadByte (state, address);
4362     }
4363   else
4364     ARMul_StoreByte (state, address, DEST);
4365 #endif
4366   if (state->Aborted)
4367     {
4368       TAKEABORT;
4369       return state->lateabtSig;
4370     }
4371   UNDEF_LSRBPC;
4372   return TRUE;
4373 }
4374
4375 /* This function does the work of loading the registers listed in an LDM
4376    instruction, when the S bit is clear.  The code here is always increment
4377    after, it's up to the caller to get the input address correct and to
4378    handle base register modification.  */
4379
4380 static void
4381 LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
4382 {
4383   ARMword dest, temp;
4384
4385   UNDEF_LSMNoRegs;
4386   UNDEF_LSMPCBase;
4387   UNDEF_LSMBaseInListWb;
4388   BUSUSEDINCPCS;
4389 #ifndef MODE32
4390   if (ADDREXCEPT (address))
4391     INTERNALABORT (address);
4392 #endif
4393   if (BIT (21) && LHSReg != 15)
4394     LSBase = WBBase;
4395
4396   /* N cycle first.  */
4397   for (temp = 0; !BIT (temp); temp++)
4398     ;
4399
4400   dest = ARMul_LoadWordN (state, address);
4401
4402   if (!state->abortSig && !state->Aborted)
4403     state->Reg[temp++] = dest;
4404   else if (!state->Aborted)
4405     {
4406       XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4407       state->Aborted = ARMul_DataAbortV;
4408     }
4409
4410   /* S cycles from here on.  */
4411   for (; temp < 16; temp ++)
4412     if (BIT (temp))
4413       {
4414         /* Load this register.  */
4415         address += 4;
4416         dest = ARMul_LoadWordS (state, address);
4417
4418         if (!state->abortSig && !state->Aborted)
4419           state->Reg[temp] = dest;
4420         else if (!state->Aborted)
4421           {
4422             XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4423             state->Aborted = ARMul_DataAbortV;
4424           }
4425       }
4426
4427   if (BIT (15) && !state->Aborted)
4428     /* PC is in the reg list.  */
4429     WriteR15Branch (state, PC);
4430
4431   /* To write back the final register.  */
4432   ARMul_Icycles (state, 1, 0L);
4433
4434   if (state->Aborted)
4435     {
4436       if (BIT (21) && LHSReg != 15)
4437         LSBase = WBBase;
4438       TAKEABORT;
4439     }
4440 }
4441
4442 /* This function does the work of loading the registers listed in an LDM
4443    instruction, when the S bit is set. The code here is always increment
4444    after, it's up to the caller to get the input address correct and to
4445    handle base register modification.  */
4446
4447 static void
4448 LoadSMult (ARMul_State * state,
4449            ARMword       instr,
4450            ARMword       address,
4451            ARMword       WBBase)
4452 {
4453   ARMword dest, temp;
4454
4455   UNDEF_LSMNoRegs;
4456   UNDEF_LSMPCBase;
4457   UNDEF_LSMBaseInListWb;
4458
4459   BUSUSEDINCPCS;
4460
4461 #ifndef MODE32
4462   if (ADDREXCEPT (address))
4463     INTERNALABORT (address);
4464 #endif
4465
4466   if (BIT (21) && LHSReg != 15)
4467     LSBase = WBBase;
4468
4469   if (!BIT (15) && state->Bank != USERBANK)
4470     {
4471       /* Temporary reg bank switch.  */
4472       (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
4473       UNDEF_LSMUserBankWb;
4474     }
4475
4476   /* N cycle first.  */
4477   for (temp = 0; !BIT (temp); temp ++)
4478     ;
4479
4480   dest = ARMul_LoadWordN (state, address);
4481
4482   if (!state->abortSig)
4483     state->Reg[temp++] = dest;
4484   else if (!state->Aborted)
4485     {
4486       XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4487       state->Aborted = ARMul_DataAbortV;
4488     }
4489
4490   /* S cycles from here on.  */
4491   for (; temp < 16; temp++)
4492     if (BIT (temp))
4493       {
4494         /* Load this register.  */
4495         address += 4;
4496         dest = ARMul_LoadWordS (state, address);
4497
4498         if (!state->abortSig && !state->Aborted)
4499           state->Reg[temp] = dest;
4500         else if (!state->Aborted)
4501           {
4502             XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4503             state->Aborted = ARMul_DataAbortV;
4504           }
4505       }
4506
4507   if (BIT (15) && !state->Aborted)
4508     {
4509       /* PC is in the reg list.  */
4510 #ifdef MODE32
4511       if (state->Mode != USER26MODE && state->Mode != USER32MODE)
4512         {
4513           state->Cpsr = GETSPSR (state->Bank);
4514           ARMul_CPSRAltered (state);
4515         }
4516
4517       WriteR15 (state, PC);
4518 #else
4519       if (state->Mode == USER26MODE || state->Mode == USER32MODE)
4520         {
4521           /* Protect bits in user mode.  */
4522           ASSIGNN ((state->Reg[15] & NBIT) != 0);
4523           ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
4524           ASSIGNC ((state->Reg[15] & CBIT) != 0);
4525           ASSIGNV ((state->Reg[15] & VBIT) != 0);
4526         }
4527       else
4528         ARMul_R15Altered (state);
4529
4530       FLUSHPIPE;
4531 #endif
4532     }
4533
4534   if (!BIT (15) && state->Mode != USER26MODE && state->Mode != USER32MODE)
4535     /* Restore the correct bank.  */
4536     (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
4537
4538   /* To write back the final register.  */
4539   ARMul_Icycles (state, 1, 0L);
4540
4541   if (state->Aborted)
4542     {
4543       if (BIT (21) && LHSReg != 15)
4544         LSBase = WBBase;
4545
4546       TAKEABORT;
4547     }
4548 }
4549
4550 /* This function does the work of storing the registers listed in an STM
4551    instruction, when the S bit is clear.  The code here is always increment
4552    after, it's up to the caller to get the input address correct and to
4553    handle base register modification.  */
4554
4555 static void
4556 StoreMult (ARMul_State * state,
4557            ARMword instr,
4558            ARMword address,
4559            ARMword WBBase)
4560 {
4561   ARMword temp;
4562
4563   UNDEF_LSMNoRegs;
4564   UNDEF_LSMPCBase;
4565   UNDEF_LSMBaseInListWb;
4566
4567   if (!TFLAG)
4568     /* N-cycle, increment the PC and update the NextInstr state.  */
4569     BUSUSEDINCPCN;
4570
4571 #ifndef MODE32
4572   if (VECTORACCESS (address) || ADDREXCEPT (address))
4573     INTERNALABORT (address);
4574
4575   if (BIT (15))
4576     PATCHR15;
4577 #endif
4578
4579   /* N cycle first.  */
4580   for (temp = 0; !BIT (temp); temp ++)
4581     ;
4582
4583 #ifdef MODE32
4584   ARMul_StoreWordN (state, address, state->Reg[temp++]);
4585 #else
4586   if (state->Aborted)
4587     {
4588       (void) ARMul_LoadWordN (state, address);
4589
4590       /* Fake the Stores as Loads.  */
4591       for (; temp < 16; temp++)
4592         if (BIT (temp))
4593           {
4594             /* Save this register.  */
4595             address += 4;
4596             (void) ARMul_LoadWordS (state, address);
4597           }
4598
4599       if (BIT (21) && LHSReg != 15)
4600         LSBase = WBBase;
4601       TAKEABORT;
4602       return;
4603     }
4604   else
4605     ARMul_StoreWordN (state, address, state->Reg[temp++]);
4606 #endif
4607
4608   if (state->abortSig && !state->Aborted)
4609     {
4610       XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4611       state->Aborted = ARMul_DataAbortV;
4612     }
4613
4614   if (BIT (21) && LHSReg != 15)
4615     LSBase = WBBase;
4616
4617   /* S cycles from here on.  */
4618   for (; temp < 16; temp ++)
4619     if (BIT (temp))
4620       {
4621         /* Save this register.  */
4622         address += 4;
4623
4624         ARMul_StoreWordS (state, address, state->Reg[temp]);
4625
4626         if (state->abortSig && !state->Aborted)
4627           {
4628             XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4629             state->Aborted = ARMul_DataAbortV;
4630           }
4631       }
4632
4633   if (state->Aborted)
4634     TAKEABORT;
4635 }
4636
4637 /* This function does the work of storing the registers listed in an STM
4638    instruction when the S bit is set.  The code here is always increment
4639    after, it's up to the caller to get the input address correct and to
4640    handle base register modification.  */
4641
4642 static void
4643 StoreSMult (ARMul_State * state,
4644             ARMword       instr,
4645             ARMword       address,
4646             ARMword       WBBase)
4647 {
4648   ARMword temp;
4649
4650   UNDEF_LSMNoRegs;
4651   UNDEF_LSMPCBase;
4652   UNDEF_LSMBaseInListWb;
4653
4654   BUSUSEDINCPCN;
4655
4656 #ifndef MODE32
4657   if (VECTORACCESS (address) || ADDREXCEPT (address))
4658     INTERNALABORT (address);
4659
4660   if (BIT (15))
4661     PATCHR15;
4662 #endif
4663
4664   if (state->Bank != USERBANK)
4665     {
4666       /* Force User Bank.  */
4667       (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
4668       UNDEF_LSMUserBankWb;
4669     }
4670
4671   for (temp = 0; !BIT (temp); temp++)
4672     ;   /* N cycle first.  */
4673   
4674 #ifdef MODE32
4675   ARMul_StoreWordN (state, address, state->Reg[temp++]);
4676 #else
4677   if (state->Aborted)
4678     {
4679       (void) ARMul_LoadWordN (state, address);
4680
4681       for (; temp < 16; temp++)
4682         /* Fake the Stores as Loads.  */
4683         if (BIT (temp))
4684           {
4685             /* Save this register.  */
4686             address += 4;
4687
4688             (void) ARMul_LoadWordS (state, address);
4689           }
4690
4691       if (BIT (21) && LHSReg != 15)
4692         LSBase = WBBase;
4693
4694       TAKEABORT;
4695       return;
4696     }
4697   else
4698     ARMul_StoreWordN (state, address, state->Reg[temp++]);
4699 #endif
4700
4701   if (state->abortSig && !state->Aborted)
4702     {
4703       XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4704       state->Aborted = ARMul_DataAbortV;
4705     }
4706
4707   /* S cycles from here on.  */
4708   for (; temp < 16; temp++)
4709     if (BIT (temp))
4710       {
4711         /* Save this register.  */
4712         address += 4;
4713
4714         ARMul_StoreWordS (state, address, state->Reg[temp]);
4715
4716         if (state->abortSig && !state->Aborted)
4717           {
4718             XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4719             state->Aborted = ARMul_DataAbortV;
4720           }
4721       }
4722
4723   if (state->Mode != USER26MODE && state->Mode != USER32MODE)
4724     /* Restore the correct bank.  */
4725     (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
4726
4727   if (BIT (21) && LHSReg != 15)
4728     LSBase = WBBase;
4729
4730   if (state->Aborted)
4731     TAKEABORT;
4732 }
4733
4734 /* This function does the work of adding two 32bit values
4735    together, and calculating if a carry has occurred.  */
4736
4737 static ARMword
4738 Add32 (ARMword a1, ARMword a2, int *carry)
4739 {
4740   ARMword result = (a1 + a2);
4741   unsigned int uresult = (unsigned int) result;
4742   unsigned int ua1 = (unsigned int) a1;
4743
4744   /* If (result == RdLo) and (state->Reg[nRdLo] == 0),
4745      or (result > RdLo) then we have no carry.  */
4746   if ((uresult == ua1) ? (a2 != 0) : (uresult < ua1))
4747     *carry = 1;
4748   else
4749     *carry = 0;
4750
4751   return result;
4752 }
4753
4754 /* This function does the work of multiplying
4755    two 32bit values to give a 64bit result.  */
4756
4757 static unsigned
4758 Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
4759 {
4760   /* Operand register numbers.  */
4761   int nRdHi, nRdLo, nRs, nRm;
4762   ARMword RdHi = 0, RdLo = 0, Rm;
4763   /* Cycle count.  */
4764   int scount;
4765
4766   nRdHi = BITS (16, 19);
4767   nRdLo = BITS (12, 15);
4768   nRs = BITS (8, 11);
4769   nRm = BITS (0, 3);
4770
4771   /* Needed to calculate the cycle count.  */
4772   Rm = state->Reg[nRm];
4773
4774   /* Check for illegal operand combinations first.  */
4775   if (   nRdHi != 15
4776       && nRdLo != 15
4777       && nRs   != 15
4778       && nRm   != 15
4779       && nRdHi != nRdLo
4780       && nRdHi != nRm
4781       && nRdLo != nRm)
4782     {
4783       /* Intermediate results.  */
4784       ARMword lo, mid1, mid2, hi;
4785       int carry;
4786       ARMword Rs = state->Reg[nRs];
4787       int sign = 0;
4788
4789       if (msigned)
4790         {
4791           /* Compute sign of result and adjust operands if necessary.  */
4792           sign = (Rm ^ Rs) & 0x80000000;
4793
4794           if (((signed long) Rm) < 0)
4795             Rm = -Rm;
4796
4797           if (((signed long) Rs) < 0)
4798             Rs = -Rs;
4799         }
4800
4801       /* We can split the 32x32 into four 16x16 operations. This
4802          ensures that we do not lose precision on 32bit only hosts.  */
4803       lo = ((Rs & 0xFFFF) * (Rm & 0xFFFF));
4804       mid1 = ((Rs & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
4805       mid2 = (((Rs >> 16) & 0xFFFF) * (Rm & 0xFFFF));
4806       hi = (((Rs >> 16) & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
4807
4808       /* We now need to add all of these results together, taking
4809          care to propogate the carries from the additions.  */
4810       RdLo = Add32 (lo, (mid1 << 16), &carry);
4811       RdHi = carry;
4812       RdLo = Add32 (RdLo, (mid2 << 16), &carry);
4813       RdHi +=
4814         (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
4815
4816       if (sign)
4817         {
4818           /* Negate result if necessary.  */
4819           RdLo = ~RdLo;
4820           RdHi = ~RdHi;
4821           if (RdLo == 0xFFFFFFFF)
4822             {
4823               RdLo = 0;
4824               RdHi += 1;
4825             }
4826           else
4827             RdLo += 1;
4828         }
4829
4830       state->Reg[nRdLo] = RdLo;
4831       state->Reg[nRdHi] = RdHi;
4832     }
4833   else
4834     fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS\n");
4835
4836   if (scc)
4837     /* Ensure that both RdHi and RdLo are used to compute Z,
4838        but don't let RdLo's sign bit make it to N.  */
4839     ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
4840
4841   /* The cycle count depends on whether the instruction is a signed or
4842      unsigned multiply, and what bits are clear in the multiplier.  */
4843   if (msigned && (Rm & ((unsigned) 1 << 31)))
4844     /* Invert the bits to make the check against zero.  */
4845     Rm = ~Rm;                   
4846
4847   if ((Rm & 0xFFFFFF00) == 0)
4848     scount = 1;
4849   else if ((Rm & 0xFFFF0000) == 0)
4850     scount = 2;
4851   else if ((Rm & 0xFF000000) == 0)
4852     scount = 3;
4853   else
4854     scount = 4;
4855
4856   return 2 + scount;
4857 }
4858
4859 /* This function does the work of multiplying two 32bit
4860    values and adding a 64bit value to give a 64bit result.  */
4861
4862 static unsigned
4863 MultiplyAdd64 (ARMul_State * state, ARMword instr, int msigned, int scc)
4864 {
4865   unsigned scount;
4866   ARMword RdLo, RdHi;
4867   int nRdHi, nRdLo;
4868   int carry = 0;
4869
4870   nRdHi = BITS (16, 19);
4871   nRdLo = BITS (12, 15);
4872
4873   RdHi = state->Reg[nRdHi];
4874   RdLo = state->Reg[nRdLo];
4875
4876   scount = Multiply64 (state, instr, msigned, LDEFAULT);
4877
4878   RdLo = Add32 (RdLo, state->Reg[nRdLo], &carry);
4879   RdHi = (RdHi + state->Reg[nRdHi]) + carry;
4880
4881   state->Reg[nRdLo] = RdLo;
4882   state->Reg[nRdHi] = RdHi;
4883
4884   if (scc)
4885     /* Ensure that both RdHi and RdLo are used to compute Z,
4886        but don't let RdLo's sign bit make it to N.  */
4887     ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
4888
4889   /* Extra cycle for addition.  */
4890   return scount + 1;
4891 }