xref: /netbsd-src/external/gpl3/gdb/dist/sim/arm/thumbemu.c (revision 6a493d6bc668897c91594964a732d38505b70cbb)
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 }
615