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