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