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