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