sim: d10v: gut endian logic
[external/binutils.git] / sim / arm / thumbemu.c
1 /*  thumbemu.c -- Thumb instruction emulation.
2     Copyright (C) 1996, Cygnus Software Technologies Ltd.
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 3 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, see <http://www.gnu.org/licenses/>. */
16
17 /* We can provide simple Thumb simulation by decoding the Thumb
18 instruction into its corresponding ARM instruction, and using the
19 existing ARM simulator.  */
20
21 #ifndef MODET                   /* required for the Thumb instruction support */
22 #if 1
23 #error "MODET needs to be defined for the Thumb world to work"
24 #else
25 #define MODET (1)
26 #endif
27 #endif
28
29 #include "armdefs.h"
30 #include "armemu.h"
31 #include "armos.h"
32
33 #define tBIT(n)    ( (ARMword)(tinstr >> (n)) & 1)
34 #define tBITS(m,n) ( (ARMword)(tinstr << (31 - (n))) >> ((31 - (n)) + (m)) )
35
36 #define ntBIT(n)    ( (ARMword)(next_instr >> (n)) & 1)
37 #define ntBITS(m,n) ( (ARMword)(next_instr << (31 - (n))) >> ((31 - (n)) + (m)) )
38
39 static int
40 test_cond (int cond, ARMul_State * state)
41 {
42   switch (cond)
43     {
44     case EQ: return ZFLAG;
45     case NE: return !ZFLAG;
46     case VS: return VFLAG;
47     case VC: return !VFLAG;
48     case MI: return NFLAG;
49     case PL: return !NFLAG;
50     case CS: return CFLAG;
51     case CC: return !CFLAG;
52     case HI: return (CFLAG && !ZFLAG);
53     case LS: return (!CFLAG || ZFLAG);
54     case GE: return ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
55     case LT: return ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
56     case GT: return ((!NFLAG && !VFLAG && !ZFLAG)
57                      || (NFLAG && VFLAG && !ZFLAG));
58     case LE: return ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
59     case AL: return TRUE;
60     case NV:
61     default: return FALSE;
62     }
63 }
64
65 static ARMword skipping_32bit_thumb = 0;
66
67 static int     IT_block_cond = AL;
68 static ARMword IT_block_mask = 0;
69 static int     IT_block_first = FALSE;
70
71 static void
72 handle_IT_block (ARMul_State * state,
73                  ARMword       tinstr,
74                  tdstate *     pvalid)
75 {
76   * pvalid = t_branch;
77   IT_block_mask = tBITS (0, 3);
78
79   if (IT_block_mask == 0)
80     // NOP or a HINT.
81     return;
82
83   IT_block_cond = tBITS (4, 7);
84   IT_block_first = TRUE;
85 }
86
87 static int
88 in_IT_block (void)
89 {
90   return IT_block_mask != 0;
91 }
92
93 static int
94 IT_block_allow (ARMul_State * state)
95 {
96   int cond;
97
98   if (IT_block_mask == 0)
99     return TRUE;
100
101   cond = IT_block_cond;
102
103   if (IT_block_first)
104     IT_block_first = FALSE;
105   else
106     {
107       if ((IT_block_mask & 8) == 0)
108         cond &= 0xe;
109       else
110         cond |= 1;
111       IT_block_mask <<= 1;
112       IT_block_mask &= 0xF;
113     }
114
115   if (IT_block_mask == 0x8)
116     IT_block_mask = 0;
117
118   return test_cond (cond, state);
119 }
120
121 static ARMword
122 ThumbExpandImm (ARMword tinstr)
123 {
124   ARMword val;
125
126   if (tBITS (10, 11) == 0)
127     {
128       switch (tBITS (8, 9))
129         {
130         case 0:  val = tBITS (0, 7); break;
131         case 1:  val = tBITS (0, 7) << 8; break;
132         case 2:  val = (tBITS (0, 7) << 8) | (tBITS (0, 7) << 24); break;
133         case 3:  val = tBITS (0, 7) * 0x01010101; break;
134         default: val = 0;
135         }
136     }
137   else
138     {
139       int ror = tBITS (7, 11);
140
141       val = (1 << 7) | tBITS (0, 6);
142       val = (val >> ror) | (val << (32 - ror));
143     }
144
145   return val;
146 }
147
148 #define tASSERT(truth)                                                  \
149   do                                                                    \
150     {                                                                   \
151       if (! (truth))                                                    \
152         {                                                               \
153           fprintf (stderr, "unhandled T2 insn %04x|%04x detected at thumbemu.c:%d\n", \
154                    tinstr, next_instr, __LINE__);                       \
155           return ;                                                      \
156         }                                                               \
157     }                                                                   \
158   while (0)
159
160
161 /* Attempt to emulate a 32-bit ARMv7 Thumb instruction.
162    Stores t_branch into PVALUE upon success or t_undefined otherwise.  */
163
164 static void
165 handle_T2_insn (ARMul_State * state,
166                 ARMword       tinstr,
167                 ARMword       next_instr,
168                 ARMword       pc,
169                 ARMword *     ainstr,
170                 tdstate *     pvalid)
171 {
172   * pvalid = t_undefined;
173
174   if (! state->is_v6)
175     return;
176
177   if (trace)
178     fprintf (stderr, "|%04x ", next_instr);
179
180   if (tBITS (11, 15) == 0x1E && ntBIT (15) == 1)
181     {
182       ARMsword simm32 = 0;
183       int S = tBIT (10);
184
185       * pvalid = t_branch;
186       switch ((ntBIT (14) << 1) | ntBIT (12))
187         {
188         case 0: /* B<c>.W  */
189           {
190             ARMword cond = tBITS (6, 9);
191             ARMword imm6;
192             ARMword imm11;
193             ARMword J1;
194             ARMword J2;
195
196             tASSERT (cond != AL && cond != NV);
197             if (! test_cond (cond, state))
198               return;
199
200             imm6 = tBITS (0, 5);
201             imm11 = ntBITS (0, 10);
202             J1 = ntBIT (13);
203             J2 = ntBIT (11);
204
205             simm32 = (J1 << 19) | (J2 << 18) | (imm6 << 12) | (imm11 << 1);
206             if (S)
207               simm32 |= -(1 << 20);
208             break;
209           }
210
211         case 1: /* B.W  */
212           {
213             ARMword imm10 = tBITS (0, 9);
214             ARMword imm11 = ntBITS (0, 10);
215             ARMword I1 = (ntBIT (13) ^ S) ? 0 : 1;
216             ARMword I2 = (ntBIT (11) ^ S) ? 0 : 1;
217
218             simm32 = (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
219             if (S)
220               simm32 |= -(1 << 24);
221             break;
222           }
223
224         case 2: /* BLX <label>  */
225           {
226             ARMword imm10h = tBITS (0, 9);
227             ARMword imm10l = ntBITS (1, 10);
228             ARMword I1 = (ntBIT (13) ^ S) ? 0 : 1;
229             ARMword I2 = (ntBIT (11) ^ S) ? 0 : 1;
230
231             simm32 = (I1 << 23) | (I2 << 22) | (imm10h << 12) | (imm10l << 2);
232             if (S)
233               simm32 |= -(1 << 24);
234
235             CLEART;
236             state->Reg[14] = (pc + 4) | 1;
237             break;
238           }
239
240         case 3: /* BL <label>  */
241           {
242             ARMword imm10 = tBITS (0, 9);
243             ARMword imm11 = ntBITS (0, 10);
244             ARMword I1 = (ntBIT (13) ^ S) ? 0 : 1;
245             ARMword I2 = (ntBIT (11) ^ S) ? 0 : 1;
246
247             simm32 = (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
248             if (S)
249               simm32 |= -(1 << 24);
250             state->Reg[14] = (pc + 4) | 1;
251             break;
252           }
253         }
254
255       state->Reg[15] = (pc + 4 + simm32);
256       FLUSHPIPE;
257       if (trace_funcs)
258         fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
259       return;
260     }
261
262   switch (tBITS (5,12))
263     {
264     case 0x29:  // TST<c>.W <Rn>,<Rm>{,<shift>}
265       {
266         ARMword Rn = tBITS (0, 3);
267         ARMword Rm = ntBITS (0, 3);
268         ARMword type = ntBITS (4, 5);
269         ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
270
271         tASSERT (ntBITS (8, 11) == 0xF);
272
273         * ainstr = 0xE1100000;
274         * ainstr |= (Rn << 16);
275         * ainstr |= (Rm);
276         * ainstr |= (type << 5);
277         * ainstr |= (imm5 << 7);
278         * pvalid = t_decoded;
279         break;
280       }
281
282     case 0x46:
283       if (tBIT (4) && ntBITS (5, 15) == 0x780)
284         {
285           // Table Branch
286           ARMword Rn = tBITS (0, 3);
287           ARMword Rm = ntBITS (0, 3);
288           ARMword address, dest;
289
290           if (ntBIT (4))
291             {
292               // TBH
293               address = state->Reg[Rn] + state->Reg[Rm] * 2;
294               dest = ARMul_LoadHalfWord (state, address);
295             }
296           else
297             {
298               // TBB
299               address = state->Reg[Rn] + state->Reg[Rm];
300               dest = ARMul_LoadByte (state, address);
301             }
302
303           state->Reg[15] = (pc + 4 + dest * 2);
304           FLUSHPIPE;
305           * pvalid = t_branch;
306           break;
307         }
308       /* Fall through.  */
309     case 0x42:
310     case 0x43:
311     case 0x47:
312     case 0x4A:
313     case 0x4B:
314     case 0x4E: // STRD
315     case 0x4F: // LDRD
316       {
317         ARMword Rn = tBITS (0, 3);
318         ARMword Rt = ntBITS (12, 15);
319         ARMword Rt2 = ntBITS (8, 11);
320         ARMword imm8 = ntBITS (0, 7);
321         ARMword P = tBIT (8);
322         ARMword U = tBIT (7);
323         ARMword W = tBIT (5);
324
325         tASSERT (Rt2 == Rt + 1);
326         imm8 <<= 2;
327         tASSERT (imm8 <= 255);
328         tASSERT (P != 0 || W != 0);
329
330         // Convert into an ARM A1 encoding.
331         if (Rn == 15)
332           {
333             tASSERT (tBIT (4) == 1);
334             // LDRD (literal)
335             // Ignore W even if 1.
336             * ainstr = 0xE14F00D0;
337           }
338         else
339           {
340             if (tBIT (4) == 1)
341               // LDRD (immediate)
342               * ainstr = 0xE04000D0;
343             else
344               {
345                 // STRD<c> <Rt>,<Rt2>,[<Rn>{,#+/-<imm8>}]
346                 // STRD<c> <Rt>,<Rt2>,[<Rn>],#+/-<imm8>
347                 // STRD<c> <Rt>,<Rt2>,[<Rn>,#+/-<imm8>]!
348                 * ainstr = 0xE04000F0;
349               }
350             * ainstr |= (Rn << 16);
351             * ainstr |= (P << 24);
352             * ainstr |= (W << 21);
353           }
354
355         * ainstr |= (U << 23);
356         * ainstr |= (Rt << 12);
357         * ainstr |= ((imm8 << 4) & 0xF00);
358         * ainstr |= (imm8 & 0xF);
359         * pvalid = t_decoded;
360         break;
361       }
362
363     case 0x44:
364     case 0x45: // LDMIA
365       {
366         ARMword Rn   = tBITS (0, 3);
367         int     W    = tBIT (5);
368         ARMword list = (ntBIT (15) << 15) | (ntBIT (14) << 14) | ntBITS (0, 12);
369
370         if (Rn == 13)
371           * ainstr = 0xE8BD0000;
372         else
373           {
374             * ainstr = 0xE8900000;
375             * ainstr |= (W << 21);
376             * ainstr |= (Rn << 16);
377           }
378         * ainstr |= list;
379         * pvalid = t_decoded;
380         break;
381       }
382
383     case 0x48:
384     case 0x49: // STMDB
385       {
386         ARMword Rn   = tBITS (0, 3);
387         int     W    = tBIT (5);
388         ARMword list = (ntBIT (14) << 14) | ntBITS (0, 12);
389
390         if (Rn == 13 && W)
391           * ainstr = 0xE92D0000;
392         else
393           {
394             * ainstr = 0xE9000000;
395             * ainstr |= (W << 21);
396             * ainstr |= (Rn << 16);
397           }
398         * ainstr |= list;
399         * pvalid = t_decoded;
400         break;
401       }
402
403     case 0x50:
404       {
405         ARMword Rd = ntBITS (8, 11);
406         ARMword Rn = tBITS (0, 3);
407         ARMword Rm = ntBITS (0, 3);
408         ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
409         ARMword type = ntBITS (4, 5);
410
411         tASSERT (ntBIT (15) == 0);
412
413         if (Rd == 15)
414           {
415             tASSERT (tBIT (4) == 1);
416
417             // TST<c>.W <Rn>,<Rm>{,<shift>}
418             * ainstr = 0xE1100000;
419           }
420         else
421           {
422             // AND{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
423             int S = tBIT (4);
424
425             * ainstr = 0xE0000000;
426
427             if (in_IT_block ())
428               S = 0;
429             * ainstr |= (S << 20);
430           }
431         
432         * ainstr |= (Rn << 16);
433         * ainstr |= (imm5 << 7);
434         * ainstr |= (type << 5);
435         * ainstr |= (Rm << 0);
436         * pvalid = t_decoded;
437         break;
438       }
439
440     case 0x51: // BIC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
441       {
442         ARMword Rn = tBITS (0, 3);
443         ARMword S  = tBIT(4);
444         ARMword Rm = ntBITS (0, 3);
445         ARMword Rd = ntBITS (8, 11);
446         ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
447         ARMword type = ntBITS (4, 5);
448         
449         tASSERT (ntBIT (15) == 0);
450
451         * ainstr = 0xE1C00000;
452         * ainstr |= (S << 20);
453         * ainstr |= (Rn << 16);
454         * ainstr |= (Rd << 12);
455         * ainstr |= (imm5 << 7);
456         * ainstr |= (type << 5);
457         * ainstr |= (Rm << 0);
458         * pvalid = t_decoded;
459         break;
460       }
461
462     case 0x52:
463       {
464         ARMword Rn = tBITS (0, 3);
465         ARMword Rd = ntBITS (8, 11);
466         ARMword Rm = ntBITS (0, 3);
467         int S = tBIT (4);
468         ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
469         ARMword type = ntBITS (4, 5);
470
471         tASSERT (Rd != 15);
472
473         if (in_IT_block ())
474           S = 0;
475
476         if (Rn == 15)
477           {
478             tASSERT (ntBIT (15) == 0);
479
480             switch (ntBITS (4, 5))
481               {
482               case 0:
483                 // LSL{S}<c>.W <Rd>,<Rm>,#<imm5>
484                 * ainstr = 0xE1A00000;
485                 break;
486               case 1:
487                 // LSR{S}<c>.W <Rd>,<Rm>,#<imm>
488                 * ainstr = 0xE1A00020;
489                 break;
490               case 2:
491                 // ASR{S}<c>.W <Rd>,<Rm>,#<imm>
492                 * ainstr = 0xE1A00040;
493                 break;
494               case 3:
495                 // ROR{S}<c> <Rd>,<Rm>,#<imm>
496                 * ainstr = 0xE1A00060;
497                 break;
498               default:
499                 tASSERT (0);
500                 * ainstr = 0;
501               }
502           }
503         else
504           {
505             // ORR{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
506             * ainstr = 0xE1800000;
507             * ainstr |= (Rn << 16);
508             * ainstr |= (type << 5);
509           }
510         
511         * ainstr |= (Rd << 12);
512         * ainstr |= (S << 20);
513         * ainstr |= (imm5 << 7);
514         * ainstr |= (Rm <<  0);
515         * pvalid = t_decoded;
516         break;
517       }
518
519     case 0x53: // MVN{S}<c>.W <Rd>,<Rm>{,<shift>}
520       {
521         ARMword Rd = ntBITS (8, 11);
522         ARMword Rm = ntBITS (0, 3);
523         int S = tBIT (4);
524         ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
525         ARMword type = ntBITS (4, 5);
526
527         tASSERT (ntBIT (15) == 0);
528
529         if (in_IT_block ())
530           S = 0;
531
532         * ainstr = 0xE1E00000;
533         * ainstr |= (S << 20);
534         * ainstr |= (Rd << 12);
535         * ainstr |= (imm5 << 7);
536         * ainstr |= (type << 5);
537         * ainstr |= (Rm <<  0);
538         * pvalid = t_decoded;
539         break;
540       }
541
542     case 0x54:
543       {
544         ARMword Rn = tBITS (0, 3);
545         ARMword Rd = ntBITS (8, 11);
546         ARMword Rm = ntBITS (0, 3);
547         int S = tBIT (4);
548         ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
549         ARMword type = ntBITS (4, 5);
550
551         if (Rd == 15 && S)
552           {
553             // TEQ<c> <Rn>,<Rm>{,<shift>}
554             tASSERT (ntBIT (15) == 0);
555
556             * ainstr = 0xE1300000;
557           }
558         else
559           {
560             // EOR{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
561             if (in_IT_block ())
562               S = 0;
563
564             * ainstr = 0xE0200000;
565             * ainstr |= (S << 20);
566             * ainstr |= (Rd << 8);
567           }
568
569         * ainstr |= (Rn <<  16);
570         * ainstr |= (imm5 << 7);
571         * ainstr |= (type << 5);
572         * ainstr |= (Rm <<  0);
573         * pvalid = t_decoded;
574         break;
575       }
576
577     case 0x58: // ADD{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
578       {
579         ARMword Rn = tBITS (0, 3);
580         ARMword Rd = ntBITS (8, 11);
581         ARMword Rm = ntBITS (0, 3);
582         int S = tBIT (4);
583         ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
584         ARMword type = ntBITS (4, 5);
585         
586         tASSERT (! (Rd == 15 && S));
587
588         if (in_IT_block ())
589           S = 0;
590
591         * ainstr = 0xE0800000;
592         * ainstr |= (S << 20);
593         * ainstr |= (Rn << 16);
594         * ainstr |= (Rd << 12);
595         * ainstr |= (imm5 << 7);
596         * ainstr |= (type << 5);
597         * ainstr |= Rm;
598         * pvalid = t_decoded;
599         break;
600       }
601
602     case 0x5A: // ADC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
603       tASSERT (ntBIT (15) == 0);
604       * ainstr = 0xE0A00000;
605       if (! in_IT_block ())
606         * ainstr |= (tBIT (4) << 20); // S
607       * ainstr |= (tBITS (0, 3) << 16); // Rn
608       * ainstr |= (ntBITS (8, 11) << 12); // Rd
609       * ainstr |= ((ntBITS (12, 14) << 2) | ntBITS (6, 7)) << 7; // imm5
610       * ainstr |= (ntBITS (4, 5) << 5); // type
611       * ainstr |= ntBITS (0, 3); // Rm
612       * pvalid = t_decoded;
613       break;
614
615     case 0x5B: // SBC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
616       {
617         ARMword Rn = tBITS (0, 3);
618         ARMword Rd = ntBITS (8, 11);
619         ARMword Rm = ntBITS (0, 3);
620         int S = tBIT (4);
621         ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
622         ARMword type = ntBITS (4, 5);
623         
624         tASSERT (ntBIT (15) == 0);
625
626         if (in_IT_block ())
627           S = 0;
628
629         * ainstr = 0xE0C00000;
630         * ainstr |= (S << 20);
631         * ainstr |= (Rn << 16);
632         * ainstr |= (Rd << 12);
633         * ainstr |= (imm5 << 7);
634         * ainstr |= (type << 5);
635         * ainstr |= Rm;
636         * pvalid = t_decoded;
637         break;
638       }
639
640     case 0x5E: // RSB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>}
641     case 0x5D: // SUB{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
642       {
643         ARMword Rn   = tBITS (0, 3);
644         ARMword Rd   = ntBITS (8, 11);
645         ARMword Rm   = ntBITS (0, 3);
646         ARMword S    = tBIT (4);
647         ARMword type = ntBITS (4, 5);
648         ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
649
650         tASSERT (ntBIT(15) == 0);
651         
652         if (Rd == 15)
653           {
654             // CMP<c>.W <Rn>, <Rm> {,<shift>}
655             * ainstr = 0xE1500000;
656             Rd = 0;
657           }
658         else if (tBIT (5))
659           * ainstr = 0xE0400000;
660         else
661           * ainstr = 0xE0600000;
662
663         * ainstr |= (S << 20);
664         * ainstr |= (Rn << 16);
665         * ainstr |= (Rd << 12);
666         * ainstr |= (imm5 << 7);
667         * ainstr |= (type << 5);
668         * ainstr |= (Rm <<  0);
669         * pvalid = t_decoded;
670         break;
671       }
672
673     case 0x9D: // NOP.W
674       tASSERT (tBITS (0, 15) == 0xF3AF);
675       tASSERT (ntBITS (0, 15) == 0x8000);
676       * pvalid = t_branch;
677       break;
678
679     case 0x80: // AND
680     case 0xA0: // TST
681       {
682         ARMword Rn = tBITS (0, 3);
683         ARMword imm12 = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
684         ARMword Rd = ntBITS (8, 11);
685         ARMword val;
686         int S = tBIT (4);
687
688         imm12 = ThumbExpandImm (imm12); 
689         val = state->Reg[Rn] & imm12;
690
691         if (Rd == 15)
692           {
693             // TST<c> <Rn>,#<const>
694             tASSERT (S == 1);
695           }
696         else
697           {
698             // AND{S}<c> <Rd>,<Rn>,#<const>
699             if (in_IT_block ())
700               S = 0;
701
702             state->Reg[Rd] = val;
703           }
704
705         if (S)
706           ARMul_NegZero (state, val);
707         * pvalid = t_branch;
708         break;
709       }
710
711     case 0xA1:
712     case 0x81: // BIC.W
713       {
714         ARMword Rn = tBITS (0, 3);
715         ARMword Rd = ntBITS (8, 11);
716         ARMword S = tBIT (4);
717         ARMword imm8 = (ntBITS (12, 14) << 8) | ntBITS (0, 7);
718
719         tASSERT (ntBIT (15) == 0);
720
721         imm8 = ThumbExpandImm (imm8);
722         state->Reg[Rd] = state->Reg[Rn] & ~ imm8;
723
724         if (S && ! in_IT_block ())
725           ARMul_NegZero (state, state->Reg[Rd]);
726         * pvalid = t_resolved;
727         break;
728       }
729
730     case 0xA2:
731     case 0x82: // MOV{S}<c>.W <Rd>,#<const>
732       {
733         ARMword val = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
734         ARMword Rd = ntBITS (8, 11);
735
736         val = ThumbExpandImm (val);
737         state->Reg[Rd] = val;
738
739         if (tBIT (4) && ! in_IT_block ())
740           ARMul_NegZero (state, val);
741         /* Indicate that the instruction has been processed.  */
742         * pvalid = t_branch;
743         break;
744       }
745
746     case 0xA3:
747     case 0x83: // MVN{S}<c> <Rd>,#<const>
748       {
749         ARMword val = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
750         ARMword Rd = ntBITS (8, 11);
751
752         val = ThumbExpandImm (val);
753         val = ~ val;
754         state->Reg[Rd] = val;
755
756         if (tBIT (4) && ! in_IT_block ())
757           ARMul_NegZero (state, val);
758         * pvalid = t_resolved;
759         break;
760       }
761
762     case 0xA4: // EOR
763     case 0x84: // TEQ
764       {
765         ARMword Rn = tBITS (0, 3);
766         ARMword Rd = ntBITS (8, 11);
767         ARMword S = tBIT (4);
768         ARMword imm12 = ((tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7));
769         ARMword result;
770
771         imm12 = ThumbExpandImm (imm12);
772
773         result = state->Reg[Rn] ^ imm12;
774
775         if (Rd == 15 && S)
776           // TEQ<c> <Rn>,#<const>
777           ;
778         else
779           {
780             // EOR{S}<c> <Rd>,<Rn>,#<const>
781             state->Reg[Rd] = result;
782
783             if (in_IT_block ())
784               S = 0;
785           }
786
787         if (S)
788           ARMul_NegZero (state, result);
789         * pvalid = t_resolved;
790         break;
791       }
792
793     case 0xA8: // CMN
794     case 0x88: // ADD
795       {
796         ARMword Rd = ntBITS (8, 11);
797         int S = tBIT (4);
798         ARMword Rn = tBITS (0, 3);
799         ARMword lhs = state->Reg[Rn];
800         ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
801         ARMword rhs = ThumbExpandImm (imm12);
802         ARMword res = lhs + rhs;
803
804         if (Rd == 15 && S)
805           {
806             // CMN<c> <Rn>,#<const>
807             res = lhs - rhs;
808           }
809         else
810           {
811             // ADD{S}<c>.W <Rd>,<Rn>,#<const>
812             res = lhs + rhs;
813
814             if (in_IT_block ())
815               S = 0;
816
817             state->Reg[Rd] = res;
818           }
819
820         if (S)
821           {
822             ARMul_NegZero (state, res);
823
824             if ((lhs | rhs) >> 30)
825               {
826                 /* Possible C,V,N to set.  */
827                 ARMul_AddCarry (state, lhs, rhs, res);
828                 ARMul_AddOverflow (state, lhs, rhs, res);
829               }
830             else
831               {
832                 CLEARC;
833                 CLEARV;
834               }
835           }
836         
837         * pvalid = t_branch;
838         break;
839       }
840
841     case 0xAA:
842     case 0x8A: // ADC{S}<c> <Rd>,<Rn>,#<const>
843       {
844         ARMword Rn = tBITS (0, 3);
845         ARMword Rd = ntBITS (8, 11);
846         int S = tBIT (4);
847         ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
848         ARMword lhs = state->Reg[Rn];
849         ARMword rhs = ThumbExpandImm (imm12);
850         ARMword res;
851
852         tASSERT (ntBIT (15) == 0);
853
854         if (CFLAG)
855           rhs += 1;
856
857         res = lhs + rhs;
858         state->Reg[Rd] = res;
859
860         if (in_IT_block ())
861           S = 0;
862
863         if (S)
864           {
865             ARMul_NegZero (state, res);
866
867             if ((lhs >= rhs) || ((rhs | lhs) >> 31))
868               {
869                 ARMul_AddCarry (state, lhs, rhs, res);
870                 ARMul_AddOverflow (state, lhs, rhs, res);
871               }
872             else
873               {
874                 CLEARC;
875                 CLEARV;
876               }
877           }
878
879         * pvalid = t_branch;
880         break;
881       }
882
883     case 0xAB:
884     case 0x8B: // SBC{S}<c> <Rd>,<Rn>,#<const>
885       {
886         ARMword Rn = tBITS (0, 3);
887         ARMword Rd = ntBITS (8, 11);
888         int S = tBIT (4);
889         ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
890         ARMword lhs = state->Reg[Rn];
891         ARMword rhs = ThumbExpandImm (imm12);
892         ARMword res;
893
894         tASSERT (ntBIT (15) == 0);
895
896         if (! CFLAG)
897           rhs += 1;
898
899         res = lhs - rhs;
900         state->Reg[Rd] = res;
901
902         if (in_IT_block ())
903           S = 0;
904
905         if (S)
906           {
907             ARMul_NegZero (state, res);
908
909             if ((lhs >= rhs) || ((rhs | lhs) >> 31))
910               {
911                 ARMul_SubCarry (state, lhs, rhs, res);
912                 ARMul_SubOverflow (state, lhs, rhs, res);
913               }
914             else
915               {
916                 CLEARC;
917                 CLEARV;
918               }
919           }
920
921         * pvalid = t_branch;
922         break;
923       }
924
925     case 0xAD:
926     case 0x8D: // SUB
927       {
928         ARMword Rn = tBITS (0, 3);
929         ARMword Rd = ntBITS (8, 11);
930         int S = tBIT (4);
931         ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
932         ARMword lhs = state->Reg[Rn];
933         ARMword rhs = ThumbExpandImm (imm12);
934         ARMword res = lhs - rhs;
935
936         if (Rd == 15 && S)
937           {
938             // CMP<c>.W <Rn>,#<const>
939             tASSERT (S);
940           }
941         else
942           {
943             // SUB{S}<c>.W <Rd>,<Rn>,#<const>
944             if (in_IT_block ())
945               S = 0;
946
947             state->Reg[Rd] = res;
948           }
949
950         if (S)
951           {
952             ARMul_NegZero (state, res);
953
954             if ((lhs >= rhs) || ((rhs | lhs) >> 31))
955               {
956                 ARMul_SubCarry (state, lhs, rhs, res);
957                 ARMul_SubOverflow (state, lhs, rhs, res);
958               }
959             else
960               {
961                 CLEARC;
962                 CLEARV;
963               }
964           }
965
966         * pvalid = t_branch;
967         break;
968       }
969
970     case 0xAE:
971     case 0x8E: // RSB{S}<c>.W <Rd>,<Rn>,#<const>
972       {
973         ARMword Rn = tBITS (0, 3);
974         ARMword Rd = ntBITS (8, 11);
975         ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
976         int S = tBIT (4);
977         ARMword lhs = imm12;
978         ARMword rhs = state->Reg[Rn];
979         ARMword res = lhs - rhs;
980
981         tASSERT (ntBIT (15) == 0);
982         
983         state->Reg[Rd] = res;
984
985         if (S)
986           {
987             ARMul_NegZero (state, res);
988
989             if ((lhs >= rhs) || ((rhs | lhs) >> 31))
990               {
991                 ARMul_SubCarry (state, lhs, rhs, res);
992                 ARMul_SubOverflow (state, lhs, rhs, res);
993               }
994             else
995               {
996                 CLEARC;
997                 CLEARV;
998               }
999           }
1000
1001         * pvalid = t_branch;
1002         break;
1003       }
1004
1005     case 0xB0:
1006     case 0x90: // ADDW<c> <Rd>,<Rn>,#<imm12>
1007       {
1008         ARMword Rn = tBITS (0, 3);
1009         ARMword Rd = ntBITS (8, 11);
1010         ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1011
1012         tASSERT (tBIT (4) == 0);
1013         tASSERT (ntBIT (15) == 0);
1014         
1015         state->Reg[Rd] = state->Reg[Rn] + imm12;
1016         * pvalid = t_branch;
1017         break;
1018       }
1019
1020     case 0xB2:
1021     case 0x92: // MOVW<c> <Rd>,#<imm16>
1022       {
1023         ARMword Rd = ntBITS (8, 11);
1024         ARMword imm = (tBITS (0, 3) << 12) | (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1025
1026         state->Reg[Rd] = imm;
1027         /* Indicate that the instruction has been processed.  */
1028         * pvalid = t_branch;
1029         break;
1030       }
1031
1032     case 0xb5:
1033     case 0x95:// SUBW<c> <Rd>,<Rn>,#<imm12>
1034       {
1035         ARMword Rd = ntBITS (8, 11);
1036         ARMword Rn = tBITS (0, 3);
1037         ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1038
1039         tASSERT (tBIT (4) == 0);
1040         tASSERT (ntBIT (15) == 0);
1041
1042         /* Note the ARM ARM indicates special cases for Rn == 15 (ADR)
1043            and Rn == 13 (SUB SP minus immediate), but these are implemented
1044            in exactly the same way as the normal SUBW insn.  */
1045         state->Reg[Rd] = state->Reg[Rn] - imm12;
1046
1047         * pvalid = t_resolved;
1048         break;
1049       }
1050
1051     case 0xB6:
1052     case 0x96: // MOVT<c> <Rd>,#<imm16>
1053       {
1054         ARMword Rd = ntBITS (8, 11);
1055         ARMword imm = (tBITS (0, 3) << 12) | (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1056
1057         state->Reg[Rd] &= 0xFFFF;
1058         state->Reg[Rd] |= (imm << 16);
1059         * pvalid = t_resolved;
1060         break;
1061       }
1062
1063     case 0x9A: // SBFXc> <Rd>,<Rn>,#<lsb>,#<width>
1064       tASSERT (tBIT (4) == 0);
1065       tASSERT (ntBIT (15) == 0);
1066       tASSERT (ntBIT (5) == 0);
1067       * ainstr = 0xE7A00050;
1068       * ainstr |= (ntBITS (0, 4) << 16); // widthm1
1069       * ainstr |= (ntBITS (8, 11) << 12); // Rd
1070       * ainstr |= (((ntBITS (12, 14) << 2) | ntBITS (6, 7)) << 7); // lsb
1071       * ainstr |= tBITS (0, 3); // Rn
1072       * pvalid = t_decoded;
1073       break;
1074
1075     case 0x9B:
1076       {
1077         ARMword Rd = ntBITS (8, 11);
1078         ARMword Rn = tBITS (0, 3);
1079         ARMword msbit = ntBITS (0, 5);
1080         ARMword lsbit = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
1081         ARMword mask = -(1 << lsbit);
1082
1083         tASSERT (tBIT (4) == 0);
1084         tASSERT (ntBIT (15) == 0);
1085         tASSERT (ntBIT (5) == 0);
1086
1087         mask &= ((1 << (msbit + 1)) - 1);
1088
1089         if (lsbit > msbit)
1090           ; // UNPREDICTABLE
1091         else if (Rn == 15)
1092           {
1093             // BFC<c> <Rd>,#<lsb>,#<width>
1094             state->Reg[Rd] &= ~ mask;
1095           }
1096         else
1097           {
1098             // BFI<c> <Rd>,<Rn>,#<lsb>,#<width>
1099             ARMword val = state->Reg[Rn] & (mask >> lsbit);
1100
1101             val <<= lsbit;
1102             state->Reg[Rd] &= ~ mask;
1103             state->Reg[Rd] |= val;
1104           }
1105         
1106         * pvalid = t_resolved;
1107         break;
1108       }
1109
1110     case 0x9E: // UBFXc> <Rd>,<Rn>,#<lsb>,#<width>
1111       tASSERT (tBIT (4) == 0);
1112       tASSERT (ntBIT (15) == 0);
1113       tASSERT (ntBIT (5) == 0);
1114       * ainstr = 0xE7E00050;
1115       * ainstr |= (ntBITS (0, 4) << 16); // widthm1
1116       * ainstr |= (ntBITS (8, 11) << 12); // Rd
1117       * ainstr |= (((ntBITS (12, 14) << 2) | ntBITS (6, 7)) << 7); // lsb
1118       * ainstr |= tBITS (0, 3); // Rn
1119       * pvalid = t_decoded;
1120       break;
1121
1122     case 0xC0: // STRB
1123     case 0xC4: // LDRB
1124       {
1125         ARMword Rn = tBITS (0, 3);
1126         ARMword Rt = ntBITS (12, 15);
1127         
1128         if (tBIT (4))
1129           {
1130             if (Rn == 15)
1131               {
1132                 tASSERT (Rt != 15);
1133
1134                 /* LDRB<c> <Rt>,<label>                     => 1111 1000 U001 1111 */
1135                 * ainstr = 0xE55F0000;
1136                 * ainstr |= (tBIT (7) << 23);
1137                 * ainstr |= ntBITS (0, 11);
1138               }
1139             else if (tBIT (7))
1140               {
1141                 /* LDRB<c>.W <Rt>,[<Rn>{,#<imm12>}]         => 1111 1000 1001 rrrr */
1142                 * ainstr = 0xE5D00000;
1143                 * ainstr |= ntBITS (0, 11);
1144               }
1145             else if (ntBIT (11) == 0)
1146               {
1147                 /* LDRB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}] => 1111 1000 0001 rrrr */
1148                 * ainstr = 0xE7D00000;
1149                 * ainstr |= (ntBITS (4, 5) << 7);
1150                 * ainstr |= ntBITS (0, 3);
1151               }
1152             else
1153               {
1154                 int P = ntBIT (10);
1155                 int U = ntBIT (9);
1156                 int W = ntBIT (8);
1157
1158                 tASSERT (! (Rt == 15 && P && !U && !W));
1159                 tASSERT (! (P && U && !W));
1160
1161                 /* LDRB<c> <Rt>,[<Rn>,#-<imm8>]             => 1111 1000 0001 rrrr
1162                    LDRB<c> <Rt>,[<Rn>],#+/-<imm8>           => 1111 1000 0001 rrrr
1163                    LDRB<c> <Rt>,[<Rn>,#+/-<imm8>]!          => 1111 1000 0001 rrrr */
1164                 * ainstr = 0xE4500000;
1165                 * ainstr |= (P << 24);
1166                 * ainstr |= (U << 23);
1167                 * ainstr |= (W << 21);
1168                 * ainstr |= ntBITS (0, 7);
1169               }
1170           }
1171         else
1172           {
1173             if (tBIT (7) == 1)
1174               {
1175                 // STRB<c>.W <Rt>,[<Rn>,#<imm12>]
1176                 ARMword imm12 = ntBITS (0, 11);
1177
1178                 ARMul_StoreByte (state, state->Reg[Rn] + imm12, state->Reg [Rt]);
1179                 * pvalid = t_branch;
1180                 break;
1181               }
1182             else if (ntBIT (11))
1183               {
1184                 // STRB<c> <Rt>,[<Rn>,#-<imm8>]
1185                 // STRB<c> <Rt>,[<Rn>],#+/-<imm8>
1186                 // STRB<c> <Rt>,[<Rn>,#+/-<imm8>]!
1187                 int P = ntBIT (10);
1188                 int U = ntBIT (9);
1189                 int W = ntBIT (8);
1190                 ARMword imm8 = ntBITS (0, 7);
1191
1192                 tASSERT (! (P && U && !W));
1193                 tASSERT (! (Rn == 13 && P && !U && W && imm8 == 4));
1194                 
1195                 * ainstr = 0xE4000000;
1196                 * ainstr |= (P << 24);
1197                 * ainstr |= (U << 23);
1198                 * ainstr |= (W << 21);
1199                 * ainstr |= imm8;
1200               }
1201             else
1202               {
1203                 // STRB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1204                 tASSERT (ntBITS (6, 11) == 0);
1205
1206                 * ainstr = 0xE7C00000;
1207                 * ainstr |= (ntBITS (4, 5) << 7);
1208                 * ainstr |= ntBITS (0, 3);
1209               }
1210           }
1211         
1212         * ainstr |= (Rn << 16);
1213         * ainstr |= (Rt << 12);
1214         * pvalid = t_decoded;
1215         break;
1216       }
1217
1218     case 0xC2: // LDR, STR
1219       {
1220         ARMword Rn = tBITS (0, 3);
1221         ARMword Rt = ntBITS (12, 15);
1222         ARMword imm8 = ntBITS (0, 7);
1223         ARMword P = ntBIT (10);
1224         ARMword U = ntBIT (9);
1225         ARMword W = ntBIT (8);
1226
1227         tASSERT (Rn != 15);
1228
1229         if (tBIT (4))
1230           {
1231             if (Rn == 15)
1232               {
1233                 // LDR<c>.W <Rt>,<label>
1234                 * ainstr = 0xE51F0000;
1235                 * ainstr |= ntBITS (0, 11);
1236               }
1237             else if (ntBIT (11))
1238               {
1239                 tASSERT (! (P && U && ! W));
1240                 tASSERT (! (!P && U && W && Rn == 13 && imm8 == 4 && ntBIT (11) == 0));
1241                 tASSERT (! (P && !U && W && Rn == 13 && imm8 == 4 && ntBIT (11)));
1242
1243                 // LDR<c> <Rt>,[<Rn>,#-<imm8>]
1244                 // LDR<c> <Rt>,[<Rn>],#+/-<imm8>
1245                 // LDR<c> <Rt>,[<Rn>,#+/-<imm8>]!
1246                 if (!P && W)
1247                   W = 0;
1248                 * ainstr = 0xE4100000;
1249                 * ainstr |= (P << 24);
1250                 * ainstr |= (U << 23);
1251                 * ainstr |= (W << 21);
1252                 * ainstr |= imm8;
1253               }
1254             else
1255               {
1256                 // LDR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1257
1258                 tASSERT (ntBITS (6, 11) == 0);
1259
1260                 * ainstr = 0xE7900000;
1261                 * ainstr |= ntBITS (4, 5) << 7;
1262                 * ainstr |= ntBITS (0, 3);
1263               }
1264           }
1265         else
1266           {
1267             if (ntBIT (11))
1268               {
1269                 tASSERT (! (P && U && ! W));
1270                 if (Rn == 13 && P && !U && W && imm8 == 4)
1271                   {
1272                     // PUSH<c>.W <register>
1273                     tASSERT (ntBITS (0, 11) == 0xD04);
1274                     tASSERT (tBITS (0, 4) == 0x0D);
1275
1276                     * ainstr = 0xE92D0000;
1277                     * ainstr |= (1 << Rt);
1278
1279                     Rt = Rn = 0;
1280                   }
1281                 else
1282                   {
1283                     tASSERT (! (P && U && !W));
1284                     if (!P && W)
1285                       W = 0;
1286                     // STR<c> <Rt>,[<Rn>,#-<imm8>]
1287                     // STR<c> <Rt>,[<Rn>],#+/-<imm8>
1288                     // STR<c> <Rt>,[<Rn>,#+/-<imm8>]!
1289                     * ainstr = 0xE4000000;
1290                     * ainstr |= (P << 24);
1291                     * ainstr |= (U << 23);
1292                     * ainstr |= (W << 21);
1293                     * ainstr |= imm8;
1294                   }
1295               }
1296             else
1297               {
1298                 // STR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1299                 tASSERT (ntBITS (6, 11) == 0);
1300
1301                 * ainstr = 0xE7800000;
1302                 * ainstr |= ntBITS (4, 5) << 7;
1303                 * ainstr |= ntBITS (0, 3);
1304               }
1305           }
1306         
1307         * ainstr |= (Rn << 16);
1308         * ainstr |= (Rt << 12);
1309         * pvalid = t_decoded;
1310         break;
1311       }
1312
1313     case 0xC1: // STRH
1314     case 0xC5: // LDRH
1315       {
1316         ARMword Rn = tBITS (0, 3);
1317         ARMword Rt = ntBITS (12, 15);
1318         ARMword address;
1319
1320         tASSERT (Rn != 15);
1321
1322         if (tBIT (4) == 1)
1323           {
1324             if (tBIT (7))
1325               {
1326                 // LDRH<c>.W <Rt>,[<Rn>{,#<imm12>}]
1327                 ARMword imm12 = ntBITS (0, 11);
1328                 address = state->Reg[Rn] + imm12;
1329               }
1330             else if (ntBIT (11))
1331               {
1332                 // LDRH<c> <Rt>,[<Rn>,#-<imm8>]
1333                 // LDRH<c> <Rt>,[<Rn>],#+/-<imm8>
1334                 // LDRH<c> <Rt>,[<Rn>,#+/-<imm8>]!
1335                 ARMword P = ntBIT (10);
1336                 ARMword U = ntBIT (9);
1337                 ARMword W = ntBIT (8);
1338                 ARMword imm8 = ntBITS (0, 7);
1339
1340                 tASSERT (Rn != 15);
1341                 tASSERT (! (P && U && !W));
1342
1343                 * ainstr = 0xE05000B0;
1344                 * ainstr |= (P << 24);
1345                 * ainstr |= (U << 23);
1346                 * ainstr |= (W << 21);
1347                 * ainstr |= (Rn << 16);
1348                 * ainstr |= (Rt << 12);
1349                 * ainstr |= ((imm8 & 0xF0) << 4);
1350                 * ainstr |= (imm8 & 0xF);
1351                 * pvalid = t_decoded;
1352                 break;
1353               }
1354             else
1355               {
1356                 // LDRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1357                 ARMword Rm = ntBITS (0, 3);
1358                 ARMword imm2 = ntBITS (4, 5);
1359                 
1360                 tASSERT (ntBITS (6, 10) == 0);
1361
1362                 address = state->Reg[Rn] + (state->Reg[Rm] << imm2);
1363               }
1364
1365             state->Reg[Rt] = ARMul_LoadHalfWord (state, address);
1366           }
1367         else
1368           {
1369             if (tBIT (7))
1370               {
1371                 // STRH<c>.W <Rt>,[<Rn>{,#<imm12>}]
1372                 ARMword imm12 = ntBITS (0, 11);
1373
1374                 address = state->Reg[Rn] + imm12;
1375               }
1376             else if (ntBIT (11))
1377               {
1378                 // STRH<c> <Rt>,[<Rn>,#-<imm8>]
1379                 // STRH<c> <Rt>,[<Rn>],#+/-<imm8>
1380                 // STRH<c> <Rt>,[<Rn>,#+/-<imm8>]!
1381                 ARMword P = ntBIT (10);
1382                 ARMword U = ntBIT (9);
1383                 ARMword W = ntBIT (8);
1384                 ARMword imm8 = ntBITS (0, 7);
1385
1386                 tASSERT (! (P && U && !W));
1387
1388                 * ainstr = 0xE04000B0;
1389                 * ainstr |= (P << 24);
1390                 * ainstr |= (U << 23);
1391                 * ainstr |= (W << 21);
1392                 * ainstr |= (Rn << 16);
1393                 * ainstr |= (Rt << 12);
1394                 * ainstr |= ((imm8 & 0xF0) << 4);
1395                 * ainstr |= (imm8 & 0xF);
1396                 * pvalid = t_decoded;
1397                 break;
1398               }
1399             else
1400               {
1401                 // STRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1402                 ARMword Rm = ntBITS (0, 3);
1403                 ARMword imm2 = ntBITS (4, 5);
1404                 
1405                 tASSERT (ntBITS (6, 10) == 0);
1406
1407                 address = state->Reg[Rn] + (state->Reg[Rm] << imm2);
1408               }
1409
1410             ARMul_StoreHalfWord (state, address, state->Reg [Rt]);
1411           }
1412         * pvalid = t_branch;
1413         break;
1414       }
1415
1416     case 0xC6: // LDR.W/STR.W
1417       {
1418         ARMword Rn = tBITS (0, 3);
1419         ARMword Rt = ntBITS (12, 15);
1420         ARMword imm12 = ntBITS (0, 11);
1421         ARMword address = state->Reg[Rn];
1422         
1423         if (Rn == 15)
1424           {
1425             // LDR<c>.W <Rt>,<label>
1426             tASSERT (tBIT (4) == 1);
1427             // tASSERT (tBIT (7) == 1)
1428           }
1429
1430         address += imm12;
1431         if (tBIT (4) == 1)
1432           state->Reg[Rt] = ARMul_LoadWordN (state, address);
1433         else
1434           ARMul_StoreWordN (state, address, state->Reg [Rt]);
1435
1436         * pvalid = t_resolved;
1437         break;
1438       }
1439
1440     case 0xC8:
1441     case 0xCC: // LDRSB
1442       {
1443         ARMword Rt = ntBITS (12, 15);
1444         ARMword Rn = tBITS (0, 3);
1445         ARMword U = tBIT (7);
1446         ARMword address = state->Reg[Rn];
1447
1448         tASSERT (tBIT (4) == 1);
1449         tASSERT (Rt != 15); // PLI
1450
1451         if (Rn == 15)
1452           {
1453             // LDRSB<c> <Rt>,<label>
1454             ARMword imm12 = ntBITS (0, 11);
1455             address += (U ? imm12 : - imm12);
1456           }
1457         else if (U)
1458           {
1459             // LDRSB<c> <Rt>,[<Rn>,#<imm12>]
1460             ARMword imm12 = ntBITS (0, 11);
1461             address += imm12;
1462           }
1463         else if (ntBIT (11))
1464           {
1465             // LDRSB<c> <Rt>,[<Rn>,#-<imm8>]
1466             // LDRSB<c> <Rt>,[<Rn>],#+/-<imm8>
1467             // LDRSB<c> <Rt>,[<Rn>,#+/-<imm8>]!
1468             * ainstr = 0xE05000D0;
1469             * ainstr |= ntBIT (10) << 24; // P
1470             * ainstr |= ntBIT (9) << 23; // U
1471             * ainstr |= ntBIT (8) << 21; // W
1472             * ainstr |= Rn << 16;
1473             * ainstr |= Rt << 12;
1474             * ainstr |= ntBITS (4, 7) << 8;
1475             * ainstr |= ntBITS (0, 3);
1476             * pvalid = t_decoded;
1477             break;
1478           }
1479         else
1480           {
1481             // LDRSB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1482             ARMword Rm = ntBITS (0, 3);
1483             ARMword imm2 = ntBITS (4,5);
1484
1485             tASSERT (ntBITS (6, 11) == 0);
1486
1487             address += (state->Reg[Rm] << imm2);
1488           }
1489         
1490         state->Reg[Rt] = ARMul_LoadByte (state, address);
1491         if (state->Reg[Rt] & 0x80)
1492           state->Reg[Rt] |= -(1 << 8);
1493
1494         * pvalid = t_resolved;
1495         break;
1496       }
1497
1498     case 0xC9:
1499     case 0xCD:// LDRSH
1500       {
1501         ARMword Rt = ntBITS (12, 15);
1502         ARMword Rn = tBITS (0, 3);
1503         ARMword U = tBIT (7);
1504         ARMword address = state->Reg[Rn];
1505
1506         tASSERT (tBIT (4) == 1);
1507
1508         if (Rn == 15 || U == 1)
1509           {
1510             // Rn==15 => LDRSH<c> <Rt>,<label>
1511             // Rn!=15 => LDRSH<c> <Rt>,[<Rn>,#<imm12>]
1512             ARMword imm12 = ntBITS (0, 11);
1513
1514             address += (U ? imm12 : - imm12);
1515           }
1516         else if (ntBIT (11))
1517           {
1518             // LDRSH<c> <Rt>,[<Rn>,#-<imm8>]
1519             // LDRSH<c> <Rt>,[<Rn>],#+/-<imm8>
1520             // LDRSH<c> <Rt>,[<Rn>,#+/-<imm8>]!
1521             * ainstr = 0xE05000F0;
1522             * ainstr |= ntBIT (10) << 24; // P
1523             * ainstr |= ntBIT (9) << 23; // U
1524             * ainstr |= ntBIT (8) << 21; // W
1525             * ainstr |= Rn << 16;
1526             * ainstr |= Rt << 12;
1527             * ainstr |= ntBITS (4, 7) << 8;
1528             * ainstr |= ntBITS (0, 3);
1529             * pvalid = t_decoded;
1530             break;
1531           }
1532         else /* U == 0 */
1533           {
1534             // LDRSH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1535             ARMword Rm = ntBITS (0, 3);
1536             ARMword imm2 = ntBITS (4,5);
1537
1538             tASSERT (ntBITS (6, 11) == 0);
1539
1540             address += (state->Reg[Rm] << imm2);
1541           }
1542
1543         state->Reg[Rt] = ARMul_LoadHalfWord (state, address);
1544         if (state->Reg[Rt] & 0x8000)
1545           state->Reg[Rt] |= -(1 << 16);
1546
1547         * pvalid = t_branch;
1548         break;
1549       }
1550
1551     case 0x0D0:
1552       {
1553         ARMword Rm = ntBITS (0, 3);
1554         ARMword Rd = ntBITS (8, 11);
1555
1556         tASSERT (ntBITS (12, 15) == 15);
1557
1558         if (ntBIT (7) == 1)
1559           {
1560             // SXTH<c>.W <Rd>,<Rm>{,<rotation>}
1561             ARMword ror = ntBITS (4, 5) << 3;
1562             ARMword val;
1563
1564             val = state->Reg[Rm];
1565             val = (val >> ror) | (val << (32 - ror));
1566             if (val & 0x8000)
1567               val |= -(1 << 16);
1568             state->Reg[Rd] = val;
1569           }
1570         else
1571           {
1572             // LSL{S}<c>.W <Rd>,<Rn>,<Rm>
1573             ARMword Rn = tBITS (0, 3);
1574
1575             tASSERT (ntBITS (4, 6) == 0);
1576
1577             state->Reg[Rd] = state->Reg[Rn] << (state->Reg[Rm] & 0xFF);
1578             if (tBIT (4))
1579               ARMul_NegZero (state, state->Reg[Rd]);
1580           }
1581         * pvalid = t_branch;
1582         break;
1583       }
1584
1585     case 0x0D1: // LSR{S}<c>.W <Rd>,<Rn>,<Rm>
1586       {
1587         ARMword Rd = ntBITS (8, 11);
1588         ARMword Rn = tBITS (0, 3);
1589         ARMword Rm = ntBITS (0, 3);
1590
1591         tASSERT (ntBITS (12, 15) == 15);
1592         tASSERT (ntBITS (4, 7) == 0);
1593
1594         state->Reg[Rd] = state->Reg[Rn] >> (state->Reg[Rm] & 0xFF);
1595         if (tBIT (4))
1596           ARMul_NegZero (state, state->Reg[Rd]);
1597         * pvalid = t_resolved;
1598         break;
1599       }
1600
1601     case 0xD2:
1602       tASSERT (ntBITS (12, 15) == 15);
1603       if (ntBIT (7))
1604         {
1605           tASSERT (ntBIT (6) == 0);
1606           // UXTB<c>.W <Rd>,<Rm>{,<rotation>}
1607           * ainstr = 0xE6EF0070;
1608           * ainstr |= (ntBITS (4, 5) << 10); // rotate
1609           * ainstr |= ntBITS (0, 3); // Rm
1610         }
1611       else
1612         {
1613           // ASR{S}<c>.W <Rd>,<Rn>,<Rm>
1614           tASSERT (ntBITS (4, 7) == 0);
1615           * ainstr = 0xE1A00050;
1616           if (! in_IT_block ())
1617             * ainstr |= (tBIT (4) << 20);
1618           * ainstr |= (ntBITS (0, 3) << 8); // Rm
1619           * ainstr |= tBITS (0, 3); // Rn
1620         }
1621
1622       * ainstr |= (ntBITS (8, 11) << 12); // Rd
1623       * pvalid = t_decoded;
1624       break;
1625
1626     case 0xD3: // ROR{S}<c>.W <Rd>,<Rn>,<Rm>
1627       tASSERT (ntBITS (12, 15) == 15);
1628       tASSERT (ntBITS (4, 7) == 0);
1629       * ainstr = 0xE1A00070;
1630       if (! in_IT_block ())
1631         * ainstr |= (tBIT (4) << 20);
1632       * ainstr |= (ntBITS (8, 11) << 12); // Rd
1633       * ainstr |= (ntBITS (0, 3) << 8); // Rm
1634       * ainstr |= (tBITS (0, 3) << 0); // Rn
1635       * pvalid = t_decoded;
1636       break;
1637
1638     case 0xD4:
1639       {
1640         ARMword Rn = tBITS (0, 3);
1641         ARMword Rd = ntBITS (8, 11);
1642         ARMword Rm = ntBITS (0, 3);
1643
1644         tASSERT (ntBITS (12, 15) == 15);
1645
1646         if (ntBITS (4, 7) == 8)
1647           {
1648             // REV<c>.W <Rd>,<Rm>
1649             ARMword val = state->Reg[Rm];
1650
1651             tASSERT (Rm == Rn);
1652
1653             state->Reg [Rd] =
1654               (val >> 24)
1655               | ((val >> 8) & 0xFF00)
1656               | ((val << 8) & 0xFF0000)
1657               | (val << 24);
1658             * pvalid = t_resolved;
1659           }
1660         else
1661           {
1662             tASSERT (ntBITS (4, 7) == 4);
1663
1664             if (tBIT (4) == 1)
1665                // UADD8<c> <Rd>,<Rn>,<Rm>
1666               * ainstr = 0xE6500F10;
1667             else
1668               // UADD16<c> <Rd>,<Rn>,<Rm>
1669               * ainstr = 0xE6500F90;
1670         
1671             * ainstr |= (Rn << 16);
1672             * ainstr |= (Rd << 12);
1673             * ainstr |= (Rm <<  0);
1674             * pvalid = t_decoded;
1675           }
1676         break;
1677       }
1678
1679     case 0xD5:
1680       {
1681         ARMword Rn = tBITS (0, 3);
1682         ARMword Rd = ntBITS (8, 11);
1683         ARMword Rm = ntBITS (0, 3);
1684
1685         tASSERT (ntBITS (12, 15) == 15);
1686         tASSERT (ntBITS (4, 7) == 8);
1687
1688         if (tBIT (4))
1689           {
1690             // CLZ<c> <Rd>,<Rm>
1691             tASSERT (Rm == Rn);
1692             * ainstr = 0xE16F0F10;
1693           }
1694         else
1695           {
1696              // SEL<c> <Rd>,<Rn>,<Rm>
1697             * ainstr = 0xE6800FB0;
1698             * ainstr |= (Rn << 16);
1699           }
1700
1701         * ainstr |= (Rd << 12);
1702         * ainstr |= (Rm <<  0);
1703         * pvalid = t_decoded;
1704         break;
1705       }
1706
1707     case 0xD8: // MUL
1708       {
1709         ARMword Rn = tBITS (0, 3);
1710         ARMword Rm = ntBITS (0, 3);
1711         ARMword Rd = ntBITS (8, 11);
1712         ARMword Ra = ntBITS (12, 15);
1713
1714         if (tBIT (4))
1715           {
1716             // SMLA<x><y><c> <Rd>,<Rn>,<Rm>,<Ra>
1717             ARMword nval = state->Reg[Rn];
1718             ARMword mval = state->Reg[Rm];
1719             ARMword res;
1720
1721             tASSERT (ntBITS (6, 7) == 0);
1722             tASSERT (Ra != 15);
1723
1724             if (ntBIT (5))
1725               nval >>= 16;
1726             else
1727               nval &= 0xFFFF;
1728
1729             if (ntBIT (4))
1730               mval >>= 16;
1731             else
1732               mval &= 0xFFFF;
1733
1734             res = nval * mval;
1735             res += state->Reg[Ra];
1736             // FIXME: Test and clear/set the Q bit.
1737             state->Reg[Rd] = res;
1738           }
1739         else
1740           {
1741             if (ntBITS (4, 7) == 1)
1742               {
1743                 // MLS<c> <Rd>,<Rn>,<Rm>,<Ra>
1744                 state->Reg[Rd] = state->Reg[Ra] - (state->Reg[Rn] * state->Reg[Rm]);
1745               }
1746             else
1747               {
1748                 tASSERT (ntBITS (4, 7) == 0);
1749
1750                 if (Ra == 15)
1751                   // MUL<c> <Rd>,<Rn>,<Rm>
1752                   state->Reg[Rd] = state->Reg[Rn] * state->Reg[Rm];
1753                 else
1754                   // MLA<c> <Rd>,<Rn>,<Rm>,<Ra>
1755                   state->Reg[Rd] = state->Reg[Rn] * state->Reg[Rm] + state->Reg[Ra];
1756               }
1757           }
1758         * pvalid = t_resolved;
1759         break;
1760       }
1761
1762     case 0xDC: // SMULL
1763       tASSERT (tBIT (4) == 0);
1764       tASSERT (ntBITS (4, 7) == 0);
1765       * ainstr = 0xE0C00090;
1766       * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1767       * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1768       * ainstr |= (ntBITS (0, 3) << 8); // Rm
1769       * ainstr |= tBITS (0, 3); // Rn
1770       * pvalid = t_decoded;
1771       break;
1772
1773     case 0xDD: // UMULL
1774       tASSERT (tBIT (4) == 0);
1775       tASSERT (ntBITS (4, 7) == 0);
1776       * ainstr = 0xE0800090;
1777       * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1778       * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1779       * ainstr |= (ntBITS (0, 3) << 8); // Rm
1780       * ainstr |= tBITS (0, 3); // Rn
1781       * pvalid = t_decoded;
1782       break;
1783
1784     case 0xDF: // UMLAL
1785       tASSERT (tBIT (4) == 0);
1786       tASSERT (ntBITS (4, 7) == 0);
1787       * ainstr = 0xE0A00090;
1788       * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1789       * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1790       * ainstr |= (ntBITS (0, 3) << 8); // Rm
1791       * ainstr |= tBITS (0, 3); // Rn
1792       * pvalid = t_decoded;
1793       break;
1794
1795     default:
1796       fprintf (stderr, "(op = %x) ", tBITS (5,12));
1797       tASSERT (0);
1798       return;
1799     }
1800
1801   /* Tell the Thumb decoder to skip the next 16-bit insn - it was
1802      part of this insn - unless this insn has changed the PC.  */
1803   skipping_32bit_thumb = pc + 2;
1804 }
1805
1806 /* Attempt to emulate an ARMv6 instruction.
1807    Stores t_branch into PVALUE upon success or t_undefined otherwise.  */
1808
1809 static void
1810 handle_v6_thumb_insn (ARMul_State * state,
1811                       ARMword       tinstr,
1812                       ARMword       next_instr,
1813                       ARMword       pc,
1814                       ARMword *     ainstr,
1815                       tdstate *     pvalid)
1816 {
1817   if (! state->is_v6)
1818     {
1819       * pvalid = t_undefined;
1820       return;
1821     }
1822
1823   if (tBITS (12, 15) == 0xB
1824       && tBIT (10) == 0
1825       && tBIT (8) == 1)
1826     {
1827       // Conditional branch forwards.
1828       ARMword Rn = tBITS (0, 2);
1829       ARMword imm5 = tBIT (9) << 5 | tBITS (3, 7);
1830
1831       if (tBIT (11))
1832         {
1833           if (state->Reg[Rn] != 0)
1834             {
1835               state->Reg[15] = (pc + 4 + imm5 * 2);
1836               FLUSHPIPE;
1837             }
1838         }
1839       else
1840         {
1841           if (state->Reg[Rn] == 0)
1842             {
1843               state->Reg[15] = (pc + 4 + imm5 * 2);
1844               FLUSHPIPE;
1845             }
1846         }
1847       * pvalid = t_branch;
1848       return;
1849     }
1850
1851   switch (tinstr & 0xFFC0)
1852     {
1853     case 0x4400:
1854     case 0x4480:
1855     case 0x4440:
1856     case 0x44C0: // ADD
1857       {
1858         ARMword Rd = (tBIT (7) << 3) | tBITS (0, 2);
1859         ARMword Rm = tBITS (3, 6);
1860         state->Reg[Rd] += state->Reg[Rm];
1861         break;
1862       }
1863
1864     case 0x4600: // MOV<c> <Rd>,<Rm>
1865       {
1866         // instr [15, 8] = 0100 0110
1867         // instr [7]     = Rd<high>
1868         // instr [6,3]   = Rm
1869         // instr [2,0]   = Rd<low>
1870         ARMword Rd = (tBIT(7) << 3) | tBITS (0, 2);
1871         // FIXME: Check for Rd == 15 and ITblock.
1872         state->Reg[Rd] = state->Reg[tBITS (3, 6)];
1873         break;
1874       }
1875
1876     case 0xBF00:
1877     case 0xBF40:
1878     case 0xBF80:
1879     case 0xBFC0:
1880       handle_IT_block (state, tinstr, pvalid);
1881       return;
1882
1883     case 0xE840:
1884     case 0xE880: // LDMIA
1885     case 0xE8C0:
1886     case 0xE900: // STM
1887     case 0xE940:
1888     case 0xE980:
1889     case 0xE9C0: // LDRD
1890     case 0xEA00: // BIC
1891     case 0xEA40: // ORR
1892     case 0xEA80: // EOR
1893     case 0xEAC0:
1894     case 0xEB00: // ADD
1895     case 0xEB40: // SBC
1896     case 0xEB80: // SUB
1897     case 0xEBC0: // RSB
1898     case 0xFA80: // UADD, SEL
1899       handle_T2_insn (state, tinstr, next_instr, pc, ainstr, pvalid);
1900       return;
1901
1902     case 0xba00: /* rev */
1903       {
1904         ARMword val = state->Reg[tBITS (3, 5)];
1905         state->Reg [tBITS (0, 2)] =
1906           (val >> 24)
1907           | ((val >> 8) & 0xFF00)
1908           | ((val << 8) & 0xFF0000)
1909           | (val << 24);
1910         break;
1911       }
1912
1913     case 0xba40: /* rev16 */
1914       {
1915         ARMword val = state->Reg[tBITS (3, 5)];
1916         state->Reg [tBITS (0, 2)] = (val >> 16) | (val << 16);
1917         break;
1918       }
1919
1920     case 0xb660: /* cpsie */
1921     case 0xb670: /* cpsid */
1922     case 0xbac0: /* revsh */
1923     case 0xb650: /* setend */
1924     default:
1925       printf ("Unhandled v6 thumb insn: %04x\n", tinstr);
1926       * pvalid = t_undefined;
1927       return;
1928
1929     case 0xb200: /* sxth */
1930       {
1931         ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1932
1933         if (Rm & 0x8000)
1934           state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000;
1935         else
1936           state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1937         break;
1938       }
1939
1940     case 0xb240: /* sxtb */
1941       {
1942         ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1943
1944         if (Rm & 0x80)
1945           state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00;
1946         else
1947           state->Reg [(tinstr & 0x7)] = Rm & 0xff;
1948         break;
1949       }
1950
1951     case 0xb280: /* uxth */
1952       {
1953         ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1954
1955         state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1956         break;
1957       }
1958
1959     case 0xb2c0: /* uxtb */
1960       {
1961         ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1962
1963         state->Reg [(tinstr & 0x7)] = Rm & 0xff;
1964         break;
1965       }
1966     }
1967   /* Indicate that the instruction has been processed.  */
1968   * pvalid = t_branch;
1969 }
1970
1971 /* Decode a 16bit Thumb instruction.  The instruction is in the low
1972    16-bits of the tinstr field, with the following Thumb instruction
1973    held in the high 16-bits.  Passing in two Thumb instructions allows
1974    easier simulation of the special dual BL instruction.  */
1975
1976 tdstate
1977 ARMul_ThumbDecode (ARMul_State * state,
1978                    ARMword       pc,
1979                    ARMword       tinstr,
1980                    ARMword *     ainstr)
1981 {
1982   tdstate valid = t_decoded;    /* default assumes a valid instruction */
1983   ARMword next_instr;
1984   ARMword  old_tinstr = tinstr;
1985
1986   if (skipping_32bit_thumb == pc)
1987     {
1988       skipping_32bit_thumb = 0;
1989       return t_branch;
1990     }
1991   skipping_32bit_thumb = 0;
1992
1993   if (state->bigendSig)
1994     {
1995       next_instr = tinstr & 0xFFFF;
1996       tinstr >>= 16;
1997     }
1998   else
1999     {
2000       next_instr = tinstr >> 16;
2001       tinstr &= 0xFFFF;
2002     }
2003
2004   if (! IT_block_allow (state))
2005     {
2006       if (   tBITS (11, 15) == 0x1F
2007           || tBITS (11, 15) == 0x1E
2008           || tBITS (11, 15) == 0x1D)
2009         {
2010           if (trace)
2011             fprintf (stderr, "pc: %x, SKIP  instr: %04x|%04x\n",
2012                      pc & ~1, tinstr, next_instr);
2013           skipping_32bit_thumb = pc + 2;
2014         }
2015       else if (trace)
2016         fprintf (stderr, "pc: %x, SKIP  instr: %04x\n", pc & ~1, tinstr);
2017
2018       return t_branch;
2019     }
2020
2021   old_tinstr = tinstr;
2022   if (trace)
2023     fprintf (stderr, "pc: %x, Thumb instr: %x", pc & ~1, tinstr);
2024
2025 #if 1                           /* debugging to catch non updates */
2026   *ainstr = 0xDEADC0DE;
2027 #endif
2028
2029   switch ((tinstr & 0xF800) >> 11)
2030     {
2031     case 0:                     /* LSL */
2032     case 1:                     /* LSR */
2033     case 2:                     /* ASR */
2034       /* Format 1 */
2035       *ainstr = 0xE1B00000      /* base opcode */
2036         | ((tinstr & 0x1800) >> (11 - 5))       /* shift type */
2037         | ((tinstr & 0x07C0) << (7 - 6))        /* imm5 */
2038         | ((tinstr & 0x0038) >> 3)      /* Rs */
2039         | ((tinstr & 0x0007) << 12);    /* Rd */
2040       break;
2041     case 3:                     /* ADD/SUB */
2042       /* Format 2 */
2043       {
2044         ARMword subset[4] =
2045           {
2046             0xE0900000,         /* ADDS Rd,Rs,Rn    */
2047             0xE0500000,         /* SUBS Rd,Rs,Rn    */
2048             0xE2900000,         /* ADDS Rd,Rs,#imm3 */
2049             0xE2500000          /* SUBS Rd,Rs,#imm3 */
2050           };
2051         /* It is quicker indexing into a table, than performing switch
2052            or conditionals: */
2053         *ainstr = subset[(tinstr & 0x0600) >> 9]        /* base opcode */
2054           | ((tinstr & 0x01C0) >> 6)    /* Rn or imm3 */
2055           | ((tinstr & 0x0038) << (16 - 3))     /* Rs */
2056           | ((tinstr & 0x0007) << (12 - 0));    /* Rd */
2057
2058         if (in_IT_block ())
2059           *ainstr &= ~ (1 << 20);
2060       }
2061       break;
2062     case 4:
2063       * ainstr = 0xE3A00000; /* MOV  Rd,#imm8    */
2064       if (! in_IT_block ())
2065         * ainstr |= (1 << 20);
2066       * ainstr |= tBITS (8, 10) << 12;
2067       * ainstr |= tBITS (0, 7);
2068       break;
2069
2070     case 5:
2071       * ainstr = 0xE3500000;    /* CMP  Rd,#imm8    */
2072       * ainstr |= tBITS (8, 10) << 16;
2073       * ainstr |= tBITS (0, 7);
2074       break;
2075
2076     case 6:
2077     case 7:
2078       * ainstr = tBIT (11)
2079         ? 0xE2400000            /* SUB  Rd,Rd,#imm8 */
2080         : 0xE2800000;           /* ADD  Rd,Rd,#imm8 */
2081       if (! in_IT_block ())
2082         * ainstr |= (1 << 20);
2083       * ainstr |= tBITS (8, 10) << 12;
2084       * ainstr |= tBITS (8, 10) << 16;
2085       * ainstr |= tBITS (0, 7);
2086       break;
2087
2088     case 8:                     /* Arithmetic and high register transfers */
2089       /* TODO: Since the subsets for both Format 4 and Format 5
2090          instructions are made up of different ARM encodings, we could
2091          save the following conditional, and just have one large
2092          subset. */
2093       if ((tinstr & (1 << 10)) == 0)
2094         {
2095           /* Format 4 */
2096           struct
2097           {
2098             ARMword opcode;
2099             enum
2100             { t_norm, t_shift, t_neg, t_mul }
2101             otype;
2102           }
2103           subset[16] =
2104           {
2105             { 0xE0100000, t_norm},                      /* ANDS Rd,Rd,Rs     */
2106             { 0xE0300000, t_norm},                      /* EORS Rd,Rd,Rs     */
2107             { 0xE1B00010, t_shift},                     /* MOVS Rd,Rd,LSL Rs */
2108             { 0xE1B00030, t_shift},                     /* MOVS Rd,Rd,LSR Rs */
2109             { 0xE1B00050, t_shift},                     /* MOVS Rd,Rd,ASR Rs */
2110             { 0xE0B00000, t_norm},                      /* ADCS Rd,Rd,Rs     */
2111             { 0xE0D00000, t_norm},                      /* SBCS Rd,Rd,Rs     */
2112             { 0xE1B00070, t_shift},                     /* MOVS Rd,Rd,ROR Rs */
2113             { 0xE1100000, t_norm},                      /* TST  Rd,Rs        */
2114             { 0xE2700000, t_neg},                       /* RSBS Rd,Rs,#0     */
2115             { 0xE1500000, t_norm},                      /* CMP  Rd,Rs        */
2116             { 0xE1700000, t_norm},                      /* CMN  Rd,Rs        */
2117             { 0xE1900000, t_norm},                      /* ORRS Rd,Rd,Rs     */
2118             { 0xE0100090, t_mul} ,                      /* MULS Rd,Rd,Rs     */
2119             { 0xE1D00000, t_norm},                      /* BICS Rd,Rd,Rs     */
2120             { 0xE1F00000, t_norm}       /* MVNS Rd,Rs        */
2121           };
2122           *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode;      /* base */
2123
2124           if (in_IT_block ())
2125             {
2126               struct
2127               {
2128                 ARMword opcode;
2129                 enum
2130                   { t_norm, t_shift, t_neg, t_mul }
2131                   otype;
2132               }
2133               subset[16] =
2134                 {
2135                   { 0xE0000000, t_norm},        /* AND  Rd,Rd,Rs     */
2136                   { 0xE0200000, t_norm},        /* EOR  Rd,Rd,Rs     */
2137                   { 0xE1A00010, t_shift},       /* MOV  Rd,Rd,LSL Rs */
2138                   { 0xE1A00030, t_shift},       /* MOV  Rd,Rd,LSR Rs */
2139                   { 0xE1A00050, t_shift},       /* MOV  Rd,Rd,ASR Rs */
2140                   { 0xE0A00000, t_norm},        /* ADC  Rd,Rd,Rs     */
2141                   { 0xE0C00000, t_norm},        /* SBC  Rd,Rd,Rs     */
2142                   { 0xE1A00070, t_shift},       /* MOV  Rd,Rd,ROR Rs */
2143                   { 0xE1100000, t_norm},        /* TST  Rd,Rs        */
2144                   { 0xE2600000, t_neg},         /* RSB  Rd,Rs,#0     */
2145                   { 0xE1500000, t_norm},        /* CMP  Rd,Rs        */
2146                   { 0xE1700000, t_norm},        /* CMN  Rd,Rs        */
2147                   { 0xE1800000, t_norm},        /* ORR  Rd,Rd,Rs     */
2148                   { 0xE0000090, t_mul} ,        /* MUL  Rd,Rd,Rs     */
2149                   { 0xE1C00000, t_norm},        /* BIC  Rd,Rd,Rs     */
2150                   { 0xE1E00000, t_norm}         /* MVN  Rd,Rs        */
2151                 };
2152               *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode;  /* base */
2153             }
2154
2155           switch (subset[(tinstr & 0x03C0) >> 6].otype)
2156             {
2157             case t_norm:
2158               *ainstr |= ((tinstr & 0x0007) << 16)      /* Rn */
2159                 | ((tinstr & 0x0007) << 12)     /* Rd */
2160                 | ((tinstr & 0x0038) >> 3);     /* Rs */
2161               break;
2162             case t_shift:
2163               *ainstr |= ((tinstr & 0x0007) << 12)      /* Rd */
2164                 | ((tinstr & 0x0007) >> 0)      /* Rm */
2165                 | ((tinstr & 0x0038) << (8 - 3));       /* Rs */
2166               break;
2167             case t_neg:
2168               *ainstr |= ((tinstr & 0x0007) << 12)      /* Rd */
2169                 | ((tinstr & 0x0038) << (16 - 3));      /* Rn */
2170               break;
2171             case t_mul:
2172               *ainstr |= ((tinstr & 0x0007) << 16)      /* Rd */
2173                 | ((tinstr & 0x0007) << 8)      /* Rs */
2174                 | ((tinstr & 0x0038) >> 3);     /* Rm */
2175               break;
2176             }
2177         }
2178       else
2179         {
2180           /* Format 5 */
2181           ARMword Rd = ((tinstr & 0x0007) >> 0);
2182           ARMword Rs = ((tinstr & 0x0038) >> 3);
2183           if (tinstr & (1 << 7))
2184             Rd += 8;
2185           if (tinstr & (1 << 6))
2186             Rs += 8;
2187           switch ((tinstr & 0x03C0) >> 6)
2188             {
2189             case 0x1:           /* ADD Rd,Rd,Hs */
2190             case 0x2:           /* ADD Hd,Hd,Rs */
2191             case 0x3:           /* ADD Hd,Hd,Hs */
2192               *ainstr = 0xE0800000      /* base */
2193                 | (Rd << 16)    /* Rn */
2194                 | (Rd << 12)    /* Rd */
2195                 | (Rs << 0);    /* Rm */
2196               break;
2197             case 0x5:           /* CMP Rd,Hs */
2198             case 0x6:           /* CMP Hd,Rs */
2199             case 0x7:           /* CMP Hd,Hs */
2200               *ainstr = 0xE1500000      /* base */
2201                 | (Rd << 16)    /* Rn */
2202                 | (Rd << 12)    /* Rd */
2203                 | (Rs << 0);    /* Rm */
2204               break;
2205             case 0x9:           /* MOV Rd,Hs */
2206             case 0xA:           /* MOV Hd,Rs */
2207             case 0xB:           /* MOV Hd,Hs */
2208               *ainstr = 0xE1A00000      /* base */
2209                 | (Rd << 12)    /* Rd */
2210                 | (Rs << 0);    /* Rm */
2211               break;
2212             case 0xC:           /* BX Rs */
2213             case 0xD:           /* BX Hs */
2214               *ainstr = 0xE12FFF10      /* base */
2215                 | ((tinstr & 0x0078) >> 3);     /* Rd */
2216               break;
2217             case 0xE:           /* UNDEFINED */
2218             case 0xF:           /* UNDEFINED */
2219               if (state->is_v5)
2220                 {
2221                   /* BLX Rs; BLX Hs */
2222                   *ainstr = 0xE12FFF30  /* base */
2223                     | ((tinstr & 0x0078) >> 3); /* Rd */
2224                   break;
2225                 }
2226               /* Drop through.  */
2227             default:
2228             case 0x0:           /* UNDEFINED */
2229             case 0x4:           /* UNDEFINED */
2230             case 0x8:           /* UNDEFINED */
2231               handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2232               break;
2233             }
2234         }
2235       break;
2236     case 9:                     /* LDR Rd,[PC,#imm8] */
2237       /* Format 6 */
2238       *ainstr = 0xE59F0000      /* base */
2239         | ((tinstr & 0x0700) << (12 - 8))       /* Rd */
2240         | ((tinstr & 0x00FF) << (2 - 0));       /* off8 */
2241       break;
2242     case 10:
2243     case 11:
2244       /* TODO: Format 7 and Format 8 perform the same ARM encoding, so
2245          the following could be merged into a single subset, saving on
2246          the following boolean: */
2247       if ((tinstr & (1 << 9)) == 0)
2248         {
2249           /* Format 7 */
2250           ARMword subset[4] = {
2251             0xE7800000,         /* STR  Rd,[Rb,Ro] */
2252             0xE7C00000,         /* STRB Rd,[Rb,Ro] */
2253             0xE7900000,         /* LDR  Rd,[Rb,Ro] */
2254             0xE7D00000          /* LDRB Rd,[Rb,Ro] */
2255           };
2256           *ainstr = subset[(tinstr & 0x0C00) >> 10]     /* base */
2257             | ((tinstr & 0x0007) << (12 - 0))   /* Rd */
2258             | ((tinstr & 0x0038) << (16 - 3))   /* Rb */
2259             | ((tinstr & 0x01C0) >> 6); /* Ro */
2260         }
2261       else
2262         {
2263           /* Format 8 */
2264           ARMword subset[4] = {
2265             0xE18000B0,         /* STRH  Rd,[Rb,Ro] */
2266             0xE19000D0,         /* LDRSB Rd,[Rb,Ro] */
2267             0xE19000B0,         /* LDRH  Rd,[Rb,Ro] */
2268             0xE19000F0          /* LDRSH Rd,[Rb,Ro] */
2269           };
2270           *ainstr = subset[(tinstr & 0x0C00) >> 10]     /* base */
2271             | ((tinstr & 0x0007) << (12 - 0))   /* Rd */
2272             | ((tinstr & 0x0038) << (16 - 3))   /* Rb */
2273             | ((tinstr & 0x01C0) >> 6); /* Ro */
2274         }
2275       break;
2276     case 12:                    /* STR Rd,[Rb,#imm5] */
2277     case 13:                    /* LDR Rd,[Rb,#imm5] */
2278     case 14:                    /* STRB Rd,[Rb,#imm5] */
2279     case 15:                    /* LDRB Rd,[Rb,#imm5] */
2280       /* Format 9 */
2281       {
2282         ARMword subset[4] = {
2283           0xE5800000,           /* STR  Rd,[Rb,#imm5] */
2284           0xE5900000,           /* LDR  Rd,[Rb,#imm5] */
2285           0xE5C00000,           /* STRB Rd,[Rb,#imm5] */
2286           0xE5D00000            /* LDRB Rd,[Rb,#imm5] */
2287         };
2288         /* The offset range defends on whether we are transferring a
2289            byte or word value: */
2290         *ainstr = subset[(tinstr & 0x1800) >> 11]       /* base */
2291           | ((tinstr & 0x0007) << (12 - 0))     /* Rd */
2292           | ((tinstr & 0x0038) << (16 - 3))     /* Rb */
2293           | ((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2)));        /* off5 */
2294       }
2295       break;
2296     case 16:                    /* STRH Rd,[Rb,#imm5] */
2297     case 17:                    /* LDRH Rd,[Rb,#imm5] */
2298       /* Format 10 */
2299       *ainstr = ((tinstr & (1 << 11))   /* base */
2300                  ? 0xE1D000B0   /* LDRH */
2301                  : 0xE1C000B0)  /* STRH */
2302         | ((tinstr & 0x0007) << (12 - 0))       /* Rd */
2303         | ((tinstr & 0x0038) << (16 - 3))       /* Rb */
2304         | ((tinstr & 0x01C0) >> (6 - 1))        /* off5, low nibble */
2305         | ((tinstr & 0x0600) >> (9 - 8));       /* off5, high nibble */
2306       break;
2307     case 18:                    /* STR Rd,[SP,#imm8] */
2308     case 19:                    /* LDR Rd,[SP,#imm8] */
2309       /* Format 11 */
2310       *ainstr = ((tinstr & (1 << 11))   /* base */
2311                  ? 0xE59D0000   /* LDR */
2312                  : 0xE58D0000)  /* STR */
2313         | ((tinstr & 0x0700) << (12 - 8))       /* Rd */
2314         | ((tinstr & 0x00FF) << 2);     /* off8 */
2315       break;
2316     case 20:                    /* ADD Rd,PC,#imm8 */
2317     case 21:                    /* ADD Rd,SP,#imm8 */
2318       /* Format 12 */
2319       if ((tinstr & (1 << 11)) == 0)
2320         {
2321           /* NOTE: The PC value used here should by word aligned */
2322           /* We encode shift-left-by-2 in the rotate immediate field,
2323              so no shift of off8 is needed.  */
2324           *ainstr = 0xE28F0F00  /* base */
2325             | ((tinstr & 0x0700) << (12 - 8))   /* Rd */
2326             | (tinstr & 0x00FF);        /* off8 */
2327         }
2328       else
2329         {
2330           /* We encode shift-left-by-2 in the rotate immediate field,
2331              so no shift of off8 is needed.  */
2332           *ainstr = 0xE28D0F00  /* base */
2333             | ((tinstr & 0x0700) << (12 - 8))   /* Rd */
2334             | (tinstr & 0x00FF);        /* off8 */
2335         }
2336       break;
2337     case 22:
2338     case 23:
2339       switch (tinstr & 0x0F00)
2340         {
2341         case 0x0000:
2342           /* Format 13 */
2343           /* NOTE: The instruction contains a shift left of 2
2344              equivalent (implemented as ROR #30):  */
2345           *ainstr = ((tinstr & (1 << 7))        /* base */
2346                      ? 0xE24DDF00       /* SUB */
2347                      : 0xE28DDF00)      /* ADD */
2348             | (tinstr & 0x007F);        /* off7 */
2349           break;
2350         case 0x0400:
2351           /* Format 14 - Push */
2352           * ainstr = 0xE92D0000 | (tinstr & 0x00FF);
2353           break;
2354         case 0x0500:
2355           /* Format 14 - Push + LR */
2356           * ainstr = 0xE92D4000 | (tinstr & 0x00FF);
2357           break;
2358         case 0x0c00:
2359           /* Format 14 - Pop */
2360           * ainstr = 0xE8BD0000 | (tinstr & 0x00FF);
2361           break;
2362         case 0x0d00:
2363           /* Format 14 - Pop + PC */
2364           * ainstr = 0xE8BD8000 | (tinstr & 0x00FF);
2365           break;
2366         case 0x0e00:
2367           if (state->is_v5)
2368             {
2369               /* This is normally an undefined instruction.  The v5t architecture
2370                  defines this particular pattern as a BKPT instruction, for
2371                  hardware assisted debugging.  We map onto the arm BKPT
2372                  instruction.  */
2373               if (state->is_v6)
2374                 // Map to the SVC instruction instead of the BKPT instruction.
2375                 * ainstr = 0xEF000000 | tBITS (0, 7);
2376               else
2377                 * ainstr = 0xE1200070 | ((tinstr & 0xf0) << 4) | (tinstr & 0xf);
2378               break;
2379             }
2380           /* Drop through.  */
2381         default:
2382           /* Everything else is an undefined instruction.  */
2383           handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2384           break;
2385         }
2386       break;
2387     case 24:                    /* STMIA */
2388     case 25:                    /* LDMIA */
2389       /* Format 15 */
2390       *ainstr = ((tinstr & (1 << 11))   /* base */
2391                  ? 0xE8B00000   /* LDMIA */
2392                  : 0xE8A00000)  /* STMIA */
2393         | ((tinstr & 0x0700) << (16 - 8))       /* Rb */
2394         | (tinstr & 0x00FF);    /* mask8 */
2395       break;
2396     case 26:                    /* Bcc */
2397     case 27:                    /* Bcc/SWI */
2398       if ((tinstr & 0x0F00) == 0x0F00)
2399         {
2400           /* Format 17 : SWI */
2401           *ainstr = 0xEF000000;
2402           /* Breakpoint must be handled specially.  */
2403           if ((tinstr & 0x00FF) == 0x18)
2404             *ainstr |= ((tinstr & 0x00FF) << 16);
2405           /* New breakpoint value.  See gdb/arm-tdep.c  */
2406           else if ((tinstr & 0x00FF) == 0xFE)
2407             *ainstr |= SWI_Breakpoint;
2408           else
2409             *ainstr |= (tinstr & 0x00FF);
2410         }
2411       else if ((tinstr & 0x0F00) != 0x0E00)
2412         {
2413           /* Format 16 */
2414           int doit = FALSE;
2415           /* TODO: Since we are doing a switch here, we could just add
2416              the SWI and undefined instruction checks into this
2417              switch to same on a couple of conditionals: */
2418           switch ((tinstr & 0x0F00) >> 8)
2419             {
2420             case EQ:
2421               doit = ZFLAG;
2422               break;
2423             case NE:
2424               doit = !ZFLAG;
2425               break;
2426             case VS:
2427               doit = VFLAG;
2428               break;
2429             case VC:
2430               doit = !VFLAG;
2431               break;
2432             case MI:
2433               doit = NFLAG;
2434               break;
2435             case PL:
2436               doit = !NFLAG;
2437               break;
2438             case CS:
2439               doit = CFLAG;
2440               break;
2441             case CC:
2442               doit = !CFLAG;
2443               break;
2444             case HI:
2445               doit = (CFLAG && !ZFLAG);
2446               break;
2447             case LS:
2448               doit = (!CFLAG || ZFLAG);
2449               break;
2450             case GE:
2451               doit = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
2452               break;
2453             case LT:
2454               doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
2455               break;
2456             case GT:
2457               doit = ((!NFLAG && !VFLAG && !ZFLAG)
2458                       || (NFLAG && VFLAG && !ZFLAG));
2459               break;
2460             case LE:
2461               doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
2462               break;
2463             }
2464           if (doit)
2465             {
2466               state->Reg[15] = (pc + 4
2467                                 + (((tinstr & 0x7F) << 1)
2468                                    | ((tinstr & (1 << 7)) ? 0xFFFFFF00 : 0)));
2469               FLUSHPIPE;
2470             }
2471           valid = t_branch;
2472         }
2473       else
2474         /* UNDEFINED : cc=1110(AL) uses different format.  */
2475         handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2476       break;
2477     case 28:                    /* B */
2478       /* Format 18 */
2479       state->Reg[15] = (pc + 4
2480                         + (((tinstr & 0x3FF) << 1)
2481                            | ((tinstr & (1 << 10)) ? 0xFFFFF800 : 0)));
2482       FLUSHPIPE;
2483       valid = t_branch;
2484       break;
2485     case 29:                    /* UNDEFINED */
2486       if (state->is_v6)
2487         {
2488           handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2489           break;
2490         }
2491
2492       if (state->is_v5)
2493         {
2494           if (tinstr & 1)
2495             {
2496               handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2497               break;
2498             }
2499           /* Drop through.  */
2500
2501           /* Format 19 */
2502           /* There is no single ARM instruction equivalent for this
2503              instruction. Also, it should only ever be matched with the
2504              fmt19 "BL/BLX instruction 1" instruction.  However, we do
2505              allow the simulation of it on its own, with undefined results
2506              if r14 is not suitably initialised.  */
2507           {
2508             ARMword tmp = (pc + 2);
2509
2510             state->Reg[15] = ((state->Reg[14] + ((tinstr & 0x07FF) << 1))
2511                               & 0xFFFFFFFC);
2512             CLEART;
2513             state->Reg[14] = (tmp | 1);
2514             valid = t_branch;
2515             FLUSHPIPE;
2516             if (trace_funcs)
2517               fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
2518             break;
2519           }
2520         }
2521
2522       handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2523       break;
2524
2525     case 30:                    /* BL instruction 1 */
2526       if (state->is_v6)
2527         {
2528           handle_T2_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2529           break;
2530         }
2531
2532       /* Format 19 */
2533       /* There is no single ARM instruction equivalent for this Thumb
2534          instruction. To keep the simulation simple (from the user
2535          perspective) we check if the following instruction is the
2536          second half of this BL, and if it is we simulate it
2537          immediately.  */
2538       state->Reg[14] = state->Reg[15] \
2539         + (((tinstr & 0x07FF) << 12) \
2540            | ((tinstr & (1 << 10)) ? 0xFF800000 : 0));
2541
2542       valid = t_branch;         /* in-case we don't have the 2nd half */
2543       tinstr = next_instr;      /* move the instruction down */
2544       pc += 2;                  /* point the pc at the 2nd half */
2545       if (((tinstr & 0xF800) >> 11) != 31)
2546         {
2547           if (((tinstr & 0xF800) >> 11) == 29)
2548             {
2549               ARMword tmp = (pc + 2);
2550
2551               state->Reg[15] = ((state->Reg[14]
2552                                  + ((tinstr & 0x07FE) << 1))
2553                                 & 0xFFFFFFFC);
2554               CLEART;
2555               state->Reg[14] = (tmp | 1);
2556               valid = t_branch;
2557               FLUSHPIPE;
2558             }
2559           else
2560             /* Exit, since not correct instruction. */
2561             pc -= 2;
2562           break;
2563         }
2564       /* else we fall through to process the second half of the BL */
2565       pc += 2;                  /* point the pc at the 2nd half */
2566     case 31:                    /* BL instruction 2 */
2567       if (state->is_v6)
2568         {
2569           handle_T2_insn (state, old_tinstr, next_instr, pc, ainstr, & valid);
2570           break;
2571         }
2572
2573       /* Format 19 */
2574       /* There is no single ARM instruction equivalent for this
2575          instruction. Also, it should only ever be matched with the
2576          fmt19 "BL instruction 1" instruction. However, we do allow
2577          the simulation of it on its own, with undefined results if
2578          r14 is not suitably initialised.  */
2579       {
2580         ARMword tmp = pc;
2581
2582         state->Reg[15] = (state->Reg[14] + ((tinstr & 0x07FF) << 1));
2583         state->Reg[14] = (tmp | 1);
2584         valid = t_branch;
2585         FLUSHPIPE;
2586       }
2587       break;
2588     }
2589
2590   if (trace && valid != t_decoded)
2591     fprintf (stderr, "\n");
2592
2593   return valid;
2594 }