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
19instruction into its corresponding ARM instruction, and using the
20existing 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
37static void
38handle_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
97tdstate
98ARMul_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}
616