unit at a time
[platform/upstream/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 /* Attempt to emulate an ARMv6 instruction.
34    Stores t_branch into PVALUE upon success or t_undefined otherwise.  */
35
36 static void
37 handle_v6_thumb_insn (ARMul_State * state,
38                       ARMword       tinstr,
39                       tdstate *     pvalid)
40 {
41   if (! state->is_v6)
42     {
43       * pvalid = t_undefined;
44       return;
45     }
46
47   switch (tinstr & 0xFFC0)
48     {
49     case 0xb660: /* cpsie */
50     case 0xb670: /* cpsid */
51     case 0x4600: /* cpy */
52     case 0xba00: /* rev */
53     case 0xba40: /* rev16 */
54     case 0xbac0: /* revsh */
55     case 0xb650: /* setend */
56     default:
57       printf ("Unhandled v6 thumb insn: %04x\n", tinstr);
58       * pvalid = t_undefined;
59       return;
60
61     case 0xb200: /* sxth */
62       {
63         ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
64
65         if (Rm & 0x8000)
66           state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000;
67         else
68           state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
69         break;
70       }
71
72     case 0xb240: /* sxtb */
73       {
74         ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
75
76         if (Rm & 0x80)
77           state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00;
78         else
79           state->Reg [(tinstr & 0x7)] = Rm & 0xff;
80         break;
81       }
82
83     case 0xb280: /* uxth */
84       {
85         ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
86
87         state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
88         break;
89       }
90
91     case 0xb2c0: /* uxtb */
92       {
93         ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
94
95         state->Reg [(tinstr & 0x7)] = Rm & 0xff;
96         break;
97       }
98     }
99   /* Indicate that the instruction has been processed.  */
100   * pvalid = t_branch;
101 }
102
103 /* Decode a 16bit Thumb instruction.  The instruction is in the low
104    16-bits of the tinstr field, with the following Thumb instruction
105    held in the high 16-bits.  Passing in two Thumb instructions allows
106    easier simulation of the special dual BL instruction.  */
107
108 tdstate
109 ARMul_ThumbDecode (ARMul_State * state,
110                    ARMword       pc,
111                    ARMword       tinstr,
112                    ARMword *     ainstr)
113 {
114   tdstate valid = t_decoded;    /* default assumes a valid instruction */
115   ARMword next_instr;
116
117   if (state->bigendSig)
118     {
119       next_instr = tinstr & 0xFFFF;
120       tinstr >>= 16;
121     }
122   else
123     {
124       next_instr = tinstr >> 16;
125       tinstr &= 0xFFFF;
126     }
127
128   if (trace)
129     fprintf (stderr, "pc: %x, Thumb instr: %x", pc & ~1, tinstr);
130
131 #if 1                           /* debugging to catch non updates */
132   *ainstr = 0xDEADC0DE;
133 #endif
134
135   switch ((tinstr & 0xF800) >> 11)
136     {
137     case 0:                     /* LSL */
138     case 1:                     /* LSR */
139     case 2:                     /* ASR */
140       /* Format 1 */
141       *ainstr = 0xE1B00000      /* base opcode */
142         | ((tinstr & 0x1800) >> (11 - 5))       /* shift type */
143         | ((tinstr & 0x07C0) << (7 - 6))        /* imm5 */
144         | ((tinstr & 0x0038) >> 3)      /* Rs */
145         | ((tinstr & 0x0007) << 12);    /* Rd */
146       break;
147     case 3:                     /* ADD/SUB */
148       /* Format 2 */
149       {
150         ARMword subset[4] = {
151           0xE0900000,           /* ADDS Rd,Rs,Rn    */
152           0xE0500000,           /* SUBS Rd,Rs,Rn    */
153           0xE2900000,           /* ADDS Rd,Rs,#imm3 */
154           0xE2500000            /* SUBS Rd,Rs,#imm3 */
155         };
156         /* It is quicker indexing into a table, than performing switch
157            or conditionals: */
158         *ainstr = subset[(tinstr & 0x0600) >> 9]        /* base opcode */
159           | ((tinstr & 0x01C0) >> 6)    /* Rn or imm3 */
160           | ((tinstr & 0x0038) << (16 - 3))     /* Rs */
161           | ((tinstr & 0x0007) << (12 - 0));    /* Rd */
162       }
163       break;
164     case 4:                     /* MOV */
165     case 5:                     /* CMP */
166     case 6:                     /* ADD */
167     case 7:                     /* SUB */
168       /* Format 3 */
169       {
170         ARMword subset[4] = {
171           0xE3B00000,           /* MOVS Rd,#imm8    */
172           0xE3500000,           /* CMP  Rd,#imm8    */
173           0xE2900000,           /* ADDS Rd,Rd,#imm8 */
174           0xE2500000,           /* SUBS Rd,Rd,#imm8 */
175         };
176         *ainstr = subset[(tinstr & 0x1800) >> 11]       /* base opcode */
177           | ((tinstr & 0x00FF) >> 0)    /* imm8 */
178           | ((tinstr & 0x0700) << (16 - 8))     /* Rn */
179           | ((tinstr & 0x0700) << (12 - 8));    /* Rd */
180       }
181       break;
182     case 8:                     /* Arithmetic and high register transfers */
183       /* TODO: Since the subsets for both Format 4 and Format 5
184          instructions are made up of different ARM encodings, we could
185          save the following conditional, and just have one large
186          subset. */
187       if ((tinstr & (1 << 10)) == 0)
188         {
189           /* Format 4 */
190           struct
191           {
192             ARMword opcode;
193             enum
194             { t_norm, t_shift, t_neg, t_mul }
195             otype;
196           }
197           subset[16] =
198           {
199             { 0xE0100000, t_norm},                      /* ANDS Rd,Rd,Rs     */
200             { 0xE0300000, t_norm},                      /* EORS Rd,Rd,Rs     */
201             { 0xE1B00010, t_shift},                     /* MOVS Rd,Rd,LSL Rs */
202             { 0xE1B00030, t_shift},                     /* MOVS Rd,Rd,LSR Rs */
203             { 0xE1B00050, t_shift},                     /* MOVS Rd,Rd,ASR Rs */
204             { 0xE0B00000, t_norm},                      /* ADCS Rd,Rd,Rs     */
205             { 0xE0D00000, t_norm},                      /* SBCS Rd,Rd,Rs     */
206             { 0xE1B00070, t_shift},                     /* MOVS Rd,Rd,ROR Rs */
207             { 0xE1100000, t_norm},                      /* TST  Rd,Rs        */
208             { 0xE2700000, t_neg},                       /* RSBS Rd,Rs,#0     */
209             { 0xE1500000, t_norm},                      /* CMP  Rd,Rs        */
210             { 0xE1700000, t_norm},                      /* CMN  Rd,Rs        */
211             { 0xE1900000, t_norm},                      /* ORRS Rd,Rd,Rs     */
212             { 0xE0100090, t_mul} ,                      /* MULS Rd,Rd,Rs     */
213             { 0xE1D00000, t_norm},                      /* BICS Rd,Rd,Rs     */
214             { 0xE1F00000, t_norm}       /* MVNS Rd,Rs        */
215           };
216           *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode;      /* base */
217           switch (subset[(tinstr & 0x03C0) >> 6].otype)
218             {
219             case t_norm:
220               *ainstr |= ((tinstr & 0x0007) << 16)      /* Rn */
221                 | ((tinstr & 0x0007) << 12)     /* Rd */
222                 | ((tinstr & 0x0038) >> 3);     /* Rs */
223               break;
224             case t_shift:
225               *ainstr |= ((tinstr & 0x0007) << 12)      /* Rd */
226                 | ((tinstr & 0x0007) >> 0)      /* Rm */
227                 | ((tinstr & 0x0038) << (8 - 3));       /* Rs */
228               break;
229             case t_neg:
230               *ainstr |= ((tinstr & 0x0007) << 12)      /* Rd */
231                 | ((tinstr & 0x0038) << (16 - 3));      /* Rn */
232               break;
233             case t_mul:
234               *ainstr |= ((tinstr & 0x0007) << 16)      /* Rd */
235                 | ((tinstr & 0x0007) << 8)      /* Rs */
236                 | ((tinstr & 0x0038) >> 3);     /* Rm */
237               break;
238             }
239         }
240       else
241         {
242           /* Format 5 */
243           ARMword Rd = ((tinstr & 0x0007) >> 0);
244           ARMword Rs = ((tinstr & 0x0038) >> 3);
245           if (tinstr & (1 << 7))
246             Rd += 8;
247           if (tinstr & (1 << 6))
248             Rs += 8;
249           switch ((tinstr & 0x03C0) >> 6)
250             {
251             case 0x1:           /* ADD Rd,Rd,Hs */
252             case 0x2:           /* ADD Hd,Hd,Rs */
253             case 0x3:           /* ADD Hd,Hd,Hs */
254               *ainstr = 0xE0800000      /* base */
255                 | (Rd << 16)    /* Rn */
256                 | (Rd << 12)    /* Rd */
257                 | (Rs << 0);    /* Rm */
258               break;
259             case 0x5:           /* CMP Rd,Hs */
260             case 0x6:           /* CMP Hd,Rs */
261             case 0x7:           /* CMP Hd,Hs */
262               *ainstr = 0xE1500000      /* base */
263                 | (Rd << 16)    /* Rn */
264                 | (Rd << 12)    /* Rd */
265                 | (Rs << 0);    /* Rm */
266               break;
267             case 0x9:           /* MOV Rd,Hs */
268             case 0xA:           /* MOV Hd,Rs */
269             case 0xB:           /* MOV Hd,Hs */
270               *ainstr = 0xE1A00000      /* base */
271                 | (Rd << 16)    /* Rn */
272                 | (Rd << 12)    /* Rd */
273                 | (Rs << 0);    /* Rm */
274               break;
275             case 0xC:           /* BX Rs */
276             case 0xD:           /* BX Hs */
277               *ainstr = 0xE12FFF10      /* base */
278                 | ((tinstr & 0x0078) >> 3);     /* Rd */
279               break;
280             case 0xE:           /* UNDEFINED */
281             case 0xF:           /* UNDEFINED */
282               if (state->is_v5)
283                 {
284                   /* BLX Rs; BLX Hs */
285                   *ainstr = 0xE12FFF30  /* base */
286                     | ((tinstr & 0x0078) >> 3); /* Rd */
287                   break;
288                 }
289               /* Drop through.  */
290             case 0x0:           /* UNDEFINED */
291             case 0x4:           /* UNDEFINED */
292             case 0x8:           /* UNDEFINED */
293               handle_v6_thumb_insn (state, tinstr, & valid);
294               break;
295             }
296         }
297       break;
298     case 9:                     /* LDR Rd,[PC,#imm8] */
299       /* Format 6 */
300       *ainstr = 0xE59F0000      /* base */
301         | ((tinstr & 0x0700) << (12 - 8))       /* Rd */
302         | ((tinstr & 0x00FF) << (2 - 0));       /* off8 */
303       break;
304     case 10:
305     case 11:
306       /* TODO: Format 7 and Format 8 perform the same ARM encoding, so
307          the following could be merged into a single subset, saving on
308          the following boolean: */
309       if ((tinstr & (1 << 9)) == 0)
310         {
311           /* Format 7 */
312           ARMword subset[4] = {
313             0xE7800000,         /* STR  Rd,[Rb,Ro] */
314             0xE7C00000,         /* STRB Rd,[Rb,Ro] */
315             0xE7900000,         /* LDR  Rd,[Rb,Ro] */
316             0xE7D00000          /* LDRB Rd,[Rb,Ro] */
317           };
318           *ainstr = subset[(tinstr & 0x0C00) >> 10]     /* base */
319             | ((tinstr & 0x0007) << (12 - 0))   /* Rd */
320             | ((tinstr & 0x0038) << (16 - 3))   /* Rb */
321             | ((tinstr & 0x01C0) >> 6); /* Ro */
322         }
323       else
324         {
325           /* Format 8 */
326           ARMword subset[4] = {
327             0xE18000B0,         /* STRH  Rd,[Rb,Ro] */
328             0xE19000D0,         /* LDRSB Rd,[Rb,Ro] */
329             0xE19000B0,         /* LDRH  Rd,[Rb,Ro] */
330             0xE19000F0          /* LDRSH Rd,[Rb,Ro] */
331           };
332           *ainstr = subset[(tinstr & 0x0C00) >> 10]     /* base */
333             | ((tinstr & 0x0007) << (12 - 0))   /* Rd */
334             | ((tinstr & 0x0038) << (16 - 3))   /* Rb */
335             | ((tinstr & 0x01C0) >> 6); /* Ro */
336         }
337       break;
338     case 12:                    /* STR Rd,[Rb,#imm5] */
339     case 13:                    /* LDR Rd,[Rb,#imm5] */
340     case 14:                    /* STRB Rd,[Rb,#imm5] */
341     case 15:                    /* LDRB Rd,[Rb,#imm5] */
342       /* Format 9 */
343       {
344         ARMword subset[4] = {
345           0xE5800000,           /* STR  Rd,[Rb,#imm5] */
346           0xE5900000,           /* LDR  Rd,[Rb,#imm5] */
347           0xE5C00000,           /* STRB Rd,[Rb,#imm5] */
348           0xE5D00000            /* LDRB Rd,[Rb,#imm5] */
349         };
350         /* The offset range defends on whether we are transferring a
351            byte or word value: */
352         *ainstr = subset[(tinstr & 0x1800) >> 11]       /* base */
353           | ((tinstr & 0x0007) << (12 - 0))     /* Rd */
354           | ((tinstr & 0x0038) << (16 - 3))     /* Rb */
355           | ((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2)));        /* off5 */
356       }
357       break;
358     case 16:                    /* STRH Rd,[Rb,#imm5] */
359     case 17:                    /* LDRH Rd,[Rb,#imm5] */
360       /* Format 10 */
361       *ainstr = ((tinstr & (1 << 11))   /* base */
362                  ? 0xE1D000B0   /* LDRH */
363                  : 0xE1C000B0)  /* STRH */
364         | ((tinstr & 0x0007) << (12 - 0))       /* Rd */
365         | ((tinstr & 0x0038) << (16 - 3))       /* Rb */
366         | ((tinstr & 0x01C0) >> (6 - 1))        /* off5, low nibble */
367         | ((tinstr & 0x0600) >> (9 - 8));       /* off5, high nibble */
368       break;
369     case 18:                    /* STR Rd,[SP,#imm8] */
370     case 19:                    /* LDR Rd,[SP,#imm8] */
371       /* Format 11 */
372       *ainstr = ((tinstr & (1 << 11))   /* base */
373                  ? 0xE59D0000   /* LDR */
374                  : 0xE58D0000)  /* STR */
375         | ((tinstr & 0x0700) << (12 - 8))       /* Rd */
376         | ((tinstr & 0x00FF) << 2);     /* off8 */
377       break;
378     case 20:                    /* ADD Rd,PC,#imm8 */
379     case 21:                    /* ADD Rd,SP,#imm8 */
380       /* Format 12 */
381       if ((tinstr & (1 << 11)) == 0)
382         {
383           /* NOTE: The PC value used here should by word aligned */
384           /* We encode shift-left-by-2 in the rotate immediate field,
385              so no shift of off8 is needed.  */
386           *ainstr = 0xE28F0F00  /* base */
387             | ((tinstr & 0x0700) << (12 - 8))   /* Rd */
388             | (tinstr & 0x00FF);        /* off8 */
389         }
390       else
391         {
392           /* We encode shift-left-by-2 in the rotate immediate field,
393              so no shift of off8 is needed.  */
394           *ainstr = 0xE28D0F00  /* base */
395             | ((tinstr & 0x0700) << (12 - 8))   /* Rd */
396             | (tinstr & 0x00FF);        /* off8 */
397         }
398       break;
399     case 22:
400     case 23:
401       switch (tinstr & 0x0F00)
402         {
403         case 0x0000:
404           /* Format 13 */
405           /* NOTE: The instruction contains a shift left of 2
406              equivalent (implemented as ROR #30):  */
407           *ainstr = ((tinstr & (1 << 7))        /* base */
408                      ? 0xE24DDF00       /* SUB */
409                      : 0xE28DDF00)      /* ADD */
410             | (tinstr & 0x007F);        /* off7 */
411           break;
412         case 0x0400:
413           /* Format 14 - Push */
414           * ainstr = 0xE92D0000 | (tinstr & 0x00FF);
415           break;
416         case 0x0500:
417           /* Format 14 - Push + LR */
418           * ainstr = 0xE92D4000 | (tinstr & 0x00FF);
419           break;
420         case 0x0c00:
421           /* Format 14 - Pop */
422           * ainstr = 0xE8BD0000 | (tinstr & 0x00FF);
423           break;
424         case 0x0d00:
425           /* Format 14 - Pop + PC */
426           * ainstr = 0xE8BD8000 | (tinstr & 0x00FF);
427           break;
428         case 0x0e00:
429           if (state->is_v5)
430             {
431               /* This is normally an undefined instruction.  The v5t architecture
432                  defines this particular pattern as a BKPT instruction, for
433                  hardware assisted debugging.  We map onto the arm BKPT
434                  instruction.  */
435               * ainstr = 0xE1200070 | ((tinstr & 0xf0) << 4) | (tinstr & 0xf);
436               break;
437             }
438           /* Drop through.  */
439         default:
440           /* Everything else is an undefined instruction.  */
441           handle_v6_thumb_insn (state, tinstr, & valid);
442           break;
443         }
444       break;
445     case 24:                    /* STMIA */
446     case 25:                    /* LDMIA */
447       /* Format 15 */
448       *ainstr = ((tinstr & (1 << 11))   /* base */
449                  ? 0xE8B00000   /* LDMIA */
450                  : 0xE8A00000)  /* STMIA */
451         | ((tinstr & 0x0700) << (16 - 8))       /* Rb */
452         | (tinstr & 0x00FF);    /* mask8 */
453       break;
454     case 26:                    /* Bcc */
455     case 27:                    /* Bcc/SWI */
456       if ((tinstr & 0x0F00) == 0x0F00)
457         {
458           /* Format 17 : SWI */
459           *ainstr = 0xEF000000;
460           /* Breakpoint must be handled specially.  */
461           if ((tinstr & 0x00FF) == 0x18)
462             *ainstr |= ((tinstr & 0x00FF) << 16);
463           /* New breakpoint value.  See gdb/arm-tdep.c  */
464           else if ((tinstr & 0x00FF) == 0xFE)
465             *ainstr |= SWI_Breakpoint;
466           else
467             *ainstr |= (tinstr & 0x00FF);
468         }
469       else if ((tinstr & 0x0F00) != 0x0E00)
470         {
471           /* Format 16 */
472           int doit = FALSE;
473           /* TODO: Since we are doing a switch here, we could just add
474              the SWI and undefined instruction checks into this
475              switch to same on a couple of conditionals: */
476           switch ((tinstr & 0x0F00) >> 8)
477             {
478             case EQ:
479               doit = ZFLAG;
480               break;
481             case NE:
482               doit = !ZFLAG;
483               break;
484             case VS:
485               doit = VFLAG;
486               break;
487             case VC:
488               doit = !VFLAG;
489               break;
490             case MI:
491               doit = NFLAG;
492               break;
493             case PL:
494               doit = !NFLAG;
495               break;
496             case CS:
497               doit = CFLAG;
498               break;
499             case CC:
500               doit = !CFLAG;
501               break;
502             case HI:
503               doit = (CFLAG && !ZFLAG);
504               break;
505             case LS:
506               doit = (!CFLAG || ZFLAG);
507               break;
508             case GE:
509               doit = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
510               break;
511             case LT:
512               doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
513               break;
514             case GT:
515               doit = ((!NFLAG && !VFLAG && !ZFLAG)
516                       || (NFLAG && VFLAG && !ZFLAG));
517               break;
518             case LE:
519               doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
520               break;
521             }
522           if (doit)
523             {
524               state->Reg[15] = (pc + 4
525                                 + (((tinstr & 0x7F) << 1)
526                                    | ((tinstr & (1 << 7)) ? 0xFFFFFF00 : 0)));
527               FLUSHPIPE;
528             }
529           valid = t_branch;
530         }
531       else
532         /* UNDEFINED : cc=1110(AL) uses different format.  */
533         handle_v6_thumb_insn (state, tinstr, & valid);
534       break;
535     case 28:                    /* B */
536       /* Format 18 */
537       state->Reg[15] = (pc + 4
538                         + (((tinstr & 0x3FF) << 1)
539                            | ((tinstr & (1 << 10)) ? 0xFFFFF800 : 0)));
540       FLUSHPIPE;
541       valid = t_branch;
542       break;
543     case 29:                    /* UNDEFINED */
544       if (state->is_v5)
545         {
546           if (tinstr & 1)
547             {
548               handle_v6_thumb_insn (state, tinstr, & valid);
549               break;
550             }
551           /* Drop through.  */
552           
553           /* Format 19 */
554           /* There is no single ARM instruction equivalent for this
555              instruction. Also, it should only ever be matched with the
556              fmt19 "BL/BLX instruction 1" instruction.  However, we do
557              allow the simulation of it on its own, with undefined results
558              if r14 is not suitably initialised.  */
559           {
560             ARMword tmp = (pc + 2);
561
562             state->Reg[15] = ((state->Reg[14] + ((tinstr & 0x07FF) << 1))
563                               & 0xFFFFFFFC);
564             CLEART;
565             state->Reg[14] = (tmp | 1);
566             valid = t_branch;
567             FLUSHPIPE;
568             if (trace_funcs)
569               fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
570             break;
571           }
572         }
573
574       handle_v6_thumb_insn (state, tinstr, & valid);
575       break;
576
577     case 30:                    /* BL instruction 1 */
578       /* Format 19 */
579       /* There is no single ARM instruction equivalent for this Thumb
580          instruction. To keep the simulation simple (from the user
581          perspective) we check if the following instruction is the
582          second half of this BL, and if it is we simulate it
583          immediately.  */
584       state->Reg[14] = state->Reg[15] \
585         + (((tinstr & 0x07FF) << 12) \
586            | ((tinstr & (1 << 10)) ? 0xFF800000 : 0));
587
588       valid = t_branch;         /* in-case we don't have the 2nd half */
589       tinstr = next_instr;      /* move the instruction down */
590       pc += 2;                  /* point the pc at the 2nd half */
591       if (((tinstr & 0xF800) >> 11) != 31)
592         {
593           if (((tinstr & 0xF800) >> 11) == 29)
594             {
595               ARMword tmp = (pc + 2);
596
597               state->Reg[15] = ((state->Reg[14]
598                                  + ((tinstr & 0x07FE) << 1))
599                                 & 0xFFFFFFFC);
600               CLEART;
601               state->Reg[14] = (tmp | 1);
602               valid = t_branch;
603               FLUSHPIPE;
604             }
605           else
606             /* Exit, since not correct instruction. */
607             pc -= 2;
608           break;
609         }
610       /* else we fall through to process the second half of the BL */
611       pc += 2;                  /* point the pc at the 2nd half */
612     case 31:                    /* BL instruction 2 */
613       /* Format 19 */
614       /* There is no single ARM instruction equivalent for this
615          instruction. Also, it should only ever be matched with the
616          fmt19 "BL instruction 1" instruction. However, we do allow
617          the simulation of it on its own, with undefined results if
618          r14 is not suitably initialised.  */
619       {
620         ARMword tmp = pc;
621
622         state->Reg[15] = (state->Reg[14] + ((tinstr & 0x07FF) << 1));
623         state->Reg[14] = (tmp | 1);
624         valid = t_branch;
625         FLUSHPIPE;
626       }
627       break;
628     }
629
630   if (trace && valid != t_decoded)
631     fprintf (stderr, "\n");
632
633   return valid;
634 }