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