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