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