]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/arm/thumbemu.c
Fix invalid left shift of negative value
[thirdparty/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
3fd725ef 6 the Free Software Foundation; either version 3 of the License, or
c906108c 7 (at your option) any later version.
8d052926 8
c906108c
SS
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.
8d052926 13
c906108c 14 You should have received a copy of the GNU General Public License
51b318de 15 along with this program; if not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
16
17/* We can provide simple Thumb simulation by decoding the Thumb
18instruction into its corresponding ARM instruction, and using the
19existing ARM simulator. */
20
dfcd3bfb 21#ifndef MODET /* required for the Thumb instruction support */
c906108c
SS
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"
7a292a7a 31#include "armos.h"
c906108c 32
73cb0348
NC
33#define tBIT(n) ( (ARMword)(tinstr >> (n)) & 1)
34#define tBITS(m,n) ( (ARMword)(tinstr << (31 - (n))) >> ((31 - (n)) + (m)) )
35
36#define ntBIT(n) ( (ARMword)(next_instr >> (n)) & 1)
37#define ntBITS(m,n) ( (ARMword)(next_instr << (31 - (n))) >> ((31 - (n)) + (m)) )
38
39static int
40test_cond (int cond, ARMul_State * state)
41{
42 switch (cond)
43 {
44 case EQ: return ZFLAG;
45 case NE: return !ZFLAG;
46 case VS: return VFLAG;
47 case VC: return !VFLAG;
48 case MI: return NFLAG;
49 case PL: return !NFLAG;
50 case CS: return CFLAG;
51 case CC: return !CFLAG;
52 case HI: return (CFLAG && !ZFLAG);
53 case LS: return (!CFLAG || ZFLAG);
54 case GE: return ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
55 case LT: return ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
56 case GT: return ((!NFLAG && !VFLAG && !ZFLAG)
57 || (NFLAG && VFLAG && !ZFLAG));
58 case LE: return ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
59 case AL: return TRUE;
60 case NV:
61 default: return FALSE;
62 }
63}
64
65static ARMword skipping_32bit_thumb = 0;
66
67static int IT_block_cond = AL;
68static ARMword IT_block_mask = 0;
69static int IT_block_first = FALSE;
70
71static void
72handle_IT_block (ARMul_State * state,
73 ARMword tinstr,
74 tdstate * pvalid)
75{
76 * pvalid = t_branch;
77 IT_block_mask = tBITS (0, 3);
78
79 if (IT_block_mask == 0)
80 // NOP or a HINT.
81 return;
82
83 IT_block_cond = tBITS (4, 7);
84 IT_block_first = TRUE;
85}
86
87static int
88in_IT_block (void)
89{
90 return IT_block_mask != 0;
91}
92
93static int
94IT_block_allow (ARMul_State * state)
95{
96 int cond;
97
98 if (IT_block_mask == 0)
99 return TRUE;
100
101 cond = IT_block_cond;
102
103 if (IT_block_first)
104 IT_block_first = FALSE;
105 else
106 {
107 if ((IT_block_mask & 8) == 0)
108 cond &= 0xe;
109 else
110 cond |= 1;
111 IT_block_mask <<= 1;
112 IT_block_mask &= 0xF;
113 }
114
115 if (IT_block_mask == 0x8)
116 IT_block_mask = 0;
117
118 return test_cond (cond, state);
119}
120
121static ARMword
122ThumbExpandImm (ARMword tinstr)
123{
124 ARMword val;
125
126 if (tBITS (10, 11) == 0)
127 {
128 switch (tBITS (8, 9))
129 {
130 case 0: val = tBITS (0, 7); break;
131 case 1: val = tBITS (0, 7) << 8; break;
132 case 2: val = (tBITS (0, 7) << 8) | (tBITS (0, 7) << 24); break;
133 case 3: val = tBITS (0, 7) * 0x01010101; break;
134 default: val = 0;
135 }
136 }
137 else
138 {
139 int ror = tBITS (7, 11);
454de2ee 140
73cb0348
NC
141 val = (1 << 7) | tBITS (0, 6);
142 val = (val >> ror) | (val << (32 - ror));
143 }
144
145 return val;
146}
147
148#define tASSERT(truth) \
149 do \
150 { \
151 if (! (truth)) \
152 { \
153 fprintf (stderr, "unhandled T2 insn %04x|%04x detected at thumbemu.c:%d\n", \
154 tinstr, next_instr, __LINE__); \
155 return ; \
156 } \
157 } \
158 while (0)
159
160
161/* Attempt to emulate a 32-bit ARMv7 Thumb instruction.
162 Stores t_branch into PVALUE upon success or t_undefined otherwise. */
163
164static void
165handle_T2_insn (ARMul_State * state,
166 ARMword tinstr,
167 ARMword next_instr,
168 ARMword pc,
169 ARMword * ainstr,
170 tdstate * pvalid)
171{
172 * pvalid = t_undefined;
173
174 if (! state->is_v6)
175 return;
176
177 if (trace)
178 fprintf (stderr, "|%04x ", next_instr);
179
180 if (tBITS (11, 15) == 0x1E && ntBIT (15) == 1)
181 {
182 ARMsword simm32 = 0;
183 int S = tBIT (10);
184
185 * pvalid = t_branch;
186 switch ((ntBIT (14) << 1) | ntBIT (12))
187 {
188 case 0: /* B<c>.W */
189 {
190 ARMword cond = tBITS (6, 9);
191 ARMword imm6;
192 ARMword imm11;
193 ARMword J1;
194 ARMword J2;
195
196 tASSERT (cond != AL && cond != NV);
197 if (! test_cond (cond, state))
198 return;
199
200 imm6 = tBITS (0, 5);
201 imm11 = ntBITS (0, 10);
202 J1 = ntBIT (13);
203 J2 = ntBIT (11);
204
205 simm32 = (J1 << 19) | (J2 << 18) | (imm6 << 12) | (imm11 << 1);
206 if (S)
1d19cae7 207 simm32 |= -(1 << 20);
73cb0348
NC
208 break;
209 }
454de2ee 210
73cb0348
NC
211 case 1: /* B.W */
212 {
213 ARMword imm10 = tBITS (0, 9);
214 ARMword imm11 = ntBITS (0, 10);
215 ARMword I1 = (ntBIT (13) ^ S) ? 0 : 1;
216 ARMword I2 = (ntBIT (11) ^ S) ? 0 : 1;
217
218 simm32 = (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
219 if (S)
1d19cae7 220 simm32 |= -(1 << 24);
73cb0348
NC
221 break;
222 }
454de2ee 223
73cb0348
NC
224 case 2: /* BLX <label> */
225 {
226 ARMword imm10h = tBITS (0, 9);
227 ARMword imm10l = ntBITS (1, 10);
228 ARMword I1 = (ntBIT (13) ^ S) ? 0 : 1;
229 ARMword I2 = (ntBIT (11) ^ S) ? 0 : 1;
230
231 simm32 = (I1 << 23) | (I2 << 22) | (imm10h << 12) | (imm10l << 2);
232 if (S)
1d19cae7 233 simm32 |= -(1 << 24);
73cb0348
NC
234
235 CLEART;
236 state->Reg[14] = (pc + 4) | 1;
237 break;
238 }
239
240 case 3: /* BL <label> */
241 {
242 ARMword imm10 = tBITS (0, 9);
243 ARMword imm11 = ntBITS (0, 10);
244 ARMword I1 = (ntBIT (13) ^ S) ? 0 : 1;
245 ARMword I2 = (ntBIT (11) ^ S) ? 0 : 1;
246
247 simm32 = (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
248 if (S)
1d19cae7 249 simm32 |= -(1 << 24);
73cb0348
NC
250 state->Reg[14] = (pc + 4) | 1;
251 break;
252 }
253 }
254
255 state->Reg[15] = (pc + 4 + simm32);
256 FLUSHPIPE;
257 if (trace_funcs)
258 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
259 return;
260 }
454de2ee 261
73cb0348
NC
262 switch (tBITS (5,12))
263 {
264 case 0x29: // TST<c>.W <Rn>,<Rm>{,<shift>}
265 {
266 ARMword Rn = tBITS (0, 3);
267 ARMword Rm = ntBITS (0, 3);
268 ARMword type = ntBITS (4, 5);
269 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
270
271 tASSERT (ntBITS (8, 11) == 0xF);
272
273 * ainstr = 0xE1100000;
274 * ainstr |= (Rn << 16);
275 * ainstr |= (Rm);
276 * ainstr |= (type << 5);
277 * ainstr |= (imm5 << 7);
278 * pvalid = t_decoded;
279 break;
280 }
281
282 case 0x46:
283 if (tBIT (4) && ntBITS (5, 15) == 0x780)
284 {
285 // Table Branch
286 ARMword Rn = tBITS (0, 3);
287 ARMword Rm = ntBITS (0, 3);
288 ARMword address, dest;
289
290 if (ntBIT (4))
291 {
292 // TBH
293 address = state->Reg[Rn] + state->Reg[Rm] * 2;
294 dest = ARMul_LoadHalfWord (state, address);
295 }
296 else
297 {
298 // TBB
299 address = state->Reg[Rn] + state->Reg[Rm];
300 dest = ARMul_LoadByte (state, address);
301 }
302
303 state->Reg[15] = (pc + 4 + dest * 2);
304 FLUSHPIPE;
305 * pvalid = t_branch;
306 break;
307 }
308 /* Fall through. */
309 case 0x42:
310 case 0x43:
311 case 0x47:
312 case 0x4A:
313 case 0x4B:
314 case 0x4E: // STRD
315 case 0x4F: // LDRD
316 {
317 ARMword Rn = tBITS (0, 3);
318 ARMword Rt = ntBITS (12, 15);
319 ARMword Rt2 = ntBITS (8, 11);
320 ARMword imm8 = ntBITS (0, 7);
321 ARMword P = tBIT (8);
322 ARMword U = tBIT (7);
323 ARMword W = tBIT (5);
324
325 tASSERT (Rt2 == Rt + 1);
326 imm8 <<= 2;
327 tASSERT (imm8 <= 255);
328 tASSERT (P != 0 || W != 0);
329
330 // Convert into an ARM A1 encoding.
331 if (Rn == 15)
332 {
333 tASSERT (tBIT (4) == 1);
334 // LDRD (literal)
335 // Ignore W even if 1.
336 * ainstr = 0xE14F00D0;
337 }
338 else
339 {
340 if (tBIT (4) == 1)
341 // LDRD (immediate)
342 * ainstr = 0xE04000D0;
343 else
344 {
345 // STRD<c> <Rt>,<Rt2>,[<Rn>{,#+/-<imm8>}]
346 // STRD<c> <Rt>,<Rt2>,[<Rn>],#+/-<imm8>
347 // STRD<c> <Rt>,<Rt2>,[<Rn>,#+/-<imm8>]!
348 * ainstr = 0xE04000F0;
349 }
350 * ainstr |= (Rn << 16);
351 * ainstr |= (P << 24);
352 * ainstr |= (W << 21);
353 }
354
355 * ainstr |= (U << 23);
356 * ainstr |= (Rt << 12);
357 * ainstr |= ((imm8 << 4) & 0xF00);
358 * ainstr |= (imm8 & 0xF);
359 * pvalid = t_decoded;
360 break;
361 }
362
363 case 0x44:
364 case 0x45: // LDMIA
365 {
366 ARMword Rn = tBITS (0, 3);
367 int W = tBIT (5);
368 ARMword list = (ntBIT (15) << 15) | (ntBIT (14) << 14) | ntBITS (0, 12);
369
370 if (Rn == 13)
371 * ainstr = 0xE8BD0000;
372 else
373 {
374 * ainstr = 0xE8900000;
375 * ainstr |= (W << 21);
376 * ainstr |= (Rn << 16);
377 }
378 * ainstr |= list;
379 * pvalid = t_decoded;
380 break;
381 }
382
383 case 0x48:
384 case 0x49: // STMDB
385 {
386 ARMword Rn = tBITS (0, 3);
387 int W = tBIT (5);
388 ARMword list = (ntBIT (14) << 14) | ntBITS (0, 12);
389
390 if (Rn == 13 && W)
391 * ainstr = 0xE92D0000;
392 else
393 {
394 * ainstr = 0xE9000000;
395 * ainstr |= (W << 21);
396 * ainstr |= (Rn << 16);
397 }
398 * ainstr |= list;
399 * pvalid = t_decoded;
400 break;
401 }
402
454de2ee 403 case 0x50:
73cb0348
NC
404 {
405 ARMword Rd = ntBITS (8, 11);
406 ARMword Rn = tBITS (0, 3);
407 ARMword Rm = ntBITS (0, 3);
408 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
409 ARMword type = ntBITS (4, 5);
410
411 tASSERT (ntBIT (15) == 0);
412
413 if (Rd == 15)
414 {
415 tASSERT (tBIT (4) == 1);
416
417 // TST<c>.W <Rn>,<Rm>{,<shift>}
418 * ainstr = 0xE1100000;
419 }
420 else
421 {
422 // AND{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
423 int S = tBIT (4);
424
425 * ainstr = 0xE0000000;
426
427 if (in_IT_block ())
428 S = 0;
429 * ainstr |= (S << 20);
430 }
431
432 * ainstr |= (Rn << 16);
433 * ainstr |= (imm5 << 7);
434 * ainstr |= (type << 5);
435 * ainstr |= (Rm << 0);
436 * pvalid = t_decoded;
437 break;
438 }
454de2ee 439
73cb0348
NC
440 case 0x51: // BIC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
441 {
442 ARMword Rn = tBITS (0, 3);
443 ARMword S = tBIT(4);
444 ARMword Rm = ntBITS (0, 3);
445 ARMword Rd = ntBITS (8, 11);
446 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
447 ARMword type = ntBITS (4, 5);
448
449 tASSERT (ntBIT (15) == 0);
450
451 * ainstr = 0xE1C00000;
452 * ainstr |= (S << 20);
453 * ainstr |= (Rn << 16);
454 * ainstr |= (Rd << 12);
455 * ainstr |= (imm5 << 7);
456 * ainstr |= (type << 5);
457 * ainstr |= (Rm << 0);
458 * pvalid = t_decoded;
459 break;
460 }
454de2ee
NC
461
462 case 0x52:
73cb0348
NC
463 {
464 ARMword Rn = tBITS (0, 3);
465 ARMword Rd = ntBITS (8, 11);
466 ARMword Rm = ntBITS (0, 3);
467 int S = tBIT (4);
468 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
469 ARMword type = ntBITS (4, 5);
470
471 tASSERT (Rd != 15);
472
473 if (in_IT_block ())
474 S = 0;
475
476 if (Rn == 15)
477 {
478 tASSERT (ntBIT (15) == 0);
479
480 switch (ntBITS (4, 5))
481 {
482 case 0:
483 // LSL{S}<c>.W <Rd>,<Rm>,#<imm5>
484 * ainstr = 0xE1A00000;
485 break;
486 case 1:
487 // LSR{S}<c>.W <Rd>,<Rm>,#<imm>
488 * ainstr = 0xE1A00020;
489 break;
490 case 2:
491 // ASR{S}<c>.W <Rd>,<Rm>,#<imm>
492 * ainstr = 0xE1A00040;
493 break;
494 case 3:
495 // ROR{S}<c> <Rd>,<Rm>,#<imm>
496 * ainstr = 0xE1A00060;
497 break;
498 default:
499 tASSERT (0);
500 * ainstr = 0;
501 }
502 }
503 else
504 {
505 // ORR{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
506 * ainstr = 0xE1800000;
507 * ainstr |= (Rn << 16);
508 * ainstr |= (type << 5);
509 }
510
511 * ainstr |= (Rd << 12);
512 * ainstr |= (S << 20);
513 * ainstr |= (imm5 << 7);
514 * ainstr |= (Rm << 0);
515 * pvalid = t_decoded;
516 break;
517 }
518
519 case 0x53: // MVN{S}<c>.W <Rd>,<Rm>{,<shift>}
520 {
521 ARMword Rd = ntBITS (8, 11);
522 ARMword Rm = ntBITS (0, 3);
523 int S = tBIT (4);
524 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
525 ARMword type = ntBITS (4, 5);
526
527 tASSERT (ntBIT (15) == 0);
528
529 if (in_IT_block ())
530 S = 0;
531
532 * ainstr = 0xE1E00000;
533 * ainstr |= (S << 20);
534 * ainstr |= (Rd << 12);
535 * ainstr |= (imm5 << 7);
536 * ainstr |= (type << 5);
537 * ainstr |= (Rm << 0);
538 * pvalid = t_decoded;
539 break;
540 }
541
454de2ee 542 case 0x54:
73cb0348
NC
543 {
544 ARMword Rn = tBITS (0, 3);
545 ARMword Rd = ntBITS (8, 11);
546 ARMword Rm = ntBITS (0, 3);
547 int S = tBIT (4);
548 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
549 ARMword type = ntBITS (4, 5);
550
551 if (Rd == 15 && S)
552 {
553 // TEQ<c> <Rn>,<Rm>{,<shift>}
554 tASSERT (ntBIT (15) == 0);
555
556 * ainstr = 0xE1300000;
557 }
558 else
559 {
560 // EOR{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
561 if (in_IT_block ())
562 S = 0;
563
564 * ainstr = 0xE0200000;
565 * ainstr |= (S << 20);
566 * ainstr |= (Rd << 8);
567 }
568
569 * ainstr |= (Rn << 16);
570 * ainstr |= (imm5 << 7);
571 * ainstr |= (type << 5);
572 * ainstr |= (Rm << 0);
573 * pvalid = t_decoded;
574 break;
575 }
576
577 case 0x58: // ADD{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
578 {
579 ARMword Rn = tBITS (0, 3);
580 ARMword Rd = ntBITS (8, 11);
581 ARMword Rm = ntBITS (0, 3);
582 int S = tBIT (4);
583 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
584 ARMword type = ntBITS (4, 5);
585
586 tASSERT (! (Rd == 15 && S));
587
588 if (in_IT_block ())
589 S = 0;
590
591 * ainstr = 0xE0800000;
592 * ainstr |= (S << 20);
593 * ainstr |= (Rn << 16);
594 * ainstr |= (Rd << 12);
595 * ainstr |= (imm5 << 7);
596 * ainstr |= (type << 5);
597 * ainstr |= Rm;
598 * pvalid = t_decoded;
599 break;
600 }
601
602 case 0x5A: // ADC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
603 tASSERT (ntBIT (15) == 0);
604 * ainstr = 0xE0A00000;
605 if (! in_IT_block ())
606 * ainstr |= (tBIT (4) << 20); // S
607 * ainstr |= (tBITS (0, 3) << 16); // Rn
608 * ainstr |= (ntBITS (8, 11) << 12); // Rd
609 * ainstr |= ((ntBITS (12, 14) << 2) | ntBITS (6, 7)) << 7; // imm5
610 * ainstr |= (ntBITS (4, 5) << 5); // type
611 * ainstr |= ntBITS (0, 3); // Rm
612 * pvalid = t_decoded;
613 break;
454de2ee 614
73cb0348
NC
615 case 0x5B: // SBC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
616 {
617 ARMword Rn = tBITS (0, 3);
618 ARMword Rd = ntBITS (8, 11);
619 ARMword Rm = ntBITS (0, 3);
620 int S = tBIT (4);
621 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
622 ARMword type = ntBITS (4, 5);
623
624 tASSERT (ntBIT (15) == 0);
625
626 if (in_IT_block ())
627 S = 0;
628
629 * ainstr = 0xE0C00000;
630 * ainstr |= (S << 20);
631 * ainstr |= (Rn << 16);
632 * ainstr |= (Rd << 12);
633 * ainstr |= (imm5 << 7);
634 * ainstr |= (type << 5);
635 * ainstr |= Rm;
636 * pvalid = t_decoded;
637 break;
638 }
454de2ee 639
73cb0348
NC
640 case 0x5E: // RSB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>}
641 case 0x5D: // SUB{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
642 {
643 ARMword Rn = tBITS (0, 3);
644 ARMword Rd = ntBITS (8, 11);
645 ARMword Rm = ntBITS (0, 3);
646 ARMword S = tBIT (4);
647 ARMword type = ntBITS (4, 5);
648 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
649
650 tASSERT (ntBIT(15) == 0);
651
652 if (Rd == 15)
653 {
654 // CMP<c>.W <Rn>, <Rm> {,<shift>}
655 * ainstr = 0xE1500000;
656 Rd = 0;
657 }
658 else if (tBIT (5))
659 * ainstr = 0xE0400000;
660 else
661 * ainstr = 0xE0600000;
662
663 * ainstr |= (S << 20);
664 * ainstr |= (Rn << 16);
665 * ainstr |= (Rd << 12);
666 * ainstr |= (imm5 << 7);
667 * ainstr |= (type << 5);
668 * ainstr |= (Rm << 0);
669 * pvalid = t_decoded;
670 break;
671 }
454de2ee 672
73cb0348
NC
673 case 0x9D: // NOP.W
674 tASSERT (tBITS (0, 15) == 0xF3AF);
675 tASSERT (ntBITS (0, 15) == 0x8000);
676 * pvalid = t_branch;
677 break;
454de2ee 678
73cb0348
NC
679 case 0x80: // AND
680 case 0xA0: // TST
681 {
682 ARMword Rn = tBITS (0, 3);
683 ARMword imm12 = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
684 ARMword Rd = ntBITS (8, 11);
685 ARMword val;
686 int S = tBIT (4);
687
688 imm12 = ThumbExpandImm (imm12);
689 val = state->Reg[Rn] & imm12;
690
691 if (Rd == 15)
692 {
693 // TST<c> <Rn>,#<const>
694 tASSERT (S == 1);
695 }
696 else
697 {
698 // AND{S}<c> <Rd>,<Rn>,#<const>
699 if (in_IT_block ())
454de2ee 700 S = 0;
73cb0348
NC
701
702 state->Reg[Rd] = val;
703 }
704
705 if (S)
706 ARMul_NegZero (state, val);
707 * pvalid = t_branch;
708 break;
709 }
710
711 case 0xA1:
712 case 0x81: // BIC.W
713 {
714 ARMword Rn = tBITS (0, 3);
715 ARMword Rd = ntBITS (8, 11);
716 ARMword S = tBIT (4);
717 ARMword imm8 = (ntBITS (12, 14) << 8) | ntBITS (0, 7);
718
719 tASSERT (ntBIT (15) == 0);
720
721 imm8 = ThumbExpandImm (imm8);
722 state->Reg[Rd] = state->Reg[Rn] & ~ imm8;
723
724 if (S && ! in_IT_block ())
725 ARMul_NegZero (state, state->Reg[Rd]);
726 * pvalid = t_resolved;
727 break;
728 }
454de2ee 729
73cb0348
NC
730 case 0xA2:
731 case 0x82: // MOV{S}<c>.W <Rd>,#<const>
732 {
733 ARMword val = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
734 ARMword Rd = ntBITS (8, 11);
735
736 val = ThumbExpandImm (val);
737 state->Reg[Rd] = val;
738
739 if (tBIT (4) && ! in_IT_block ())
740 ARMul_NegZero (state, val);
741 /* Indicate that the instruction has been processed. */
742 * pvalid = t_branch;
743 break;
744 }
745
746 case 0xA3:
747 case 0x83: // MVN{S}<c> <Rd>,#<const>
748 {
749 ARMword val = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
750 ARMword Rd = ntBITS (8, 11);
751
752 val = ThumbExpandImm (val);
753 val = ~ val;
754 state->Reg[Rd] = val;
755
756 if (tBIT (4) && ! in_IT_block ())
757 ARMul_NegZero (state, val);
758 * pvalid = t_resolved;
759 break;
760 }
761
762 case 0xA4: // EOR
763 case 0x84: // TEQ
764 {
765 ARMword Rn = tBITS (0, 3);
766 ARMword Rd = ntBITS (8, 11);
767 ARMword S = tBIT (4);
768 ARMword imm12 = ((tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7));
769 ARMword result;
770
771 imm12 = ThumbExpandImm (imm12);
772
773 result = state->Reg[Rn] ^ imm12;
774
775 if (Rd == 15 && S)
776 // TEQ<c> <Rn>,#<const>
777 ;
778 else
779 {
780 // EOR{S}<c> <Rd>,<Rn>,#<const>
781 state->Reg[Rd] = result;
782
783 if (in_IT_block ())
784 S = 0;
785 }
454de2ee 786
73cb0348
NC
787 if (S)
788 ARMul_NegZero (state, result);
789 * pvalid = t_resolved;
790 break;
791 }
454de2ee 792
73cb0348
NC
793 case 0xA8: // CMN
794 case 0x88: // ADD
795 {
796 ARMword Rd = ntBITS (8, 11);
797 int S = tBIT (4);
798 ARMword Rn = tBITS (0, 3);
799 ARMword lhs = state->Reg[Rn];
800 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
801 ARMword rhs = ThumbExpandImm (imm12);
802 ARMword res = lhs + rhs;
803
804 if (Rd == 15 && S)
805 {
806 // CMN<c> <Rn>,#<const>
807 res = lhs - rhs;
808 }
809 else
810 {
811 // ADD{S}<c>.W <Rd>,<Rn>,#<const>
812 res = lhs + rhs;
813
814 if (in_IT_block ())
815 S = 0;
816
817 state->Reg[Rd] = res;
818 }
819
820 if (S)
821 {
822 ARMul_NegZero (state, res);
823
824 if ((lhs | rhs) >> 30)
825 {
826 /* Possible C,V,N to set. */
827 ARMul_AddCarry (state, lhs, rhs, res);
828 ARMul_AddOverflow (state, lhs, rhs, res);
829 }
830 else
831 {
832 CLEARC;
833 CLEARV;
834 }
835 }
836
837 * pvalid = t_branch;
838 break;
839 }
840
454de2ee 841 case 0xAA:
73cb0348
NC
842 case 0x8A: // ADC{S}<c> <Rd>,<Rn>,#<const>
843 {
844 ARMword Rn = tBITS (0, 3);
845 ARMword Rd = ntBITS (8, 11);
846 int S = tBIT (4);
847 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
848 ARMword lhs = state->Reg[Rn];
849 ARMword rhs = ThumbExpandImm (imm12);
850 ARMword res;
851
852 tASSERT (ntBIT (15) == 0);
853
854 if (CFLAG)
855 rhs += 1;
856
857 res = lhs + rhs;
858 state->Reg[Rd] = res;
859
860 if (in_IT_block ())
861 S = 0;
862
863 if (S)
864 {
865 ARMul_NegZero (state, res);
866
867 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
868 {
869 ARMul_AddCarry (state, lhs, rhs, res);
870 ARMul_AddOverflow (state, lhs, rhs, res);
871 }
872 else
873 {
874 CLEARC;
875 CLEARV;
876 }
877 }
878
879 * pvalid = t_branch;
880 break;
881 }
454de2ee 882
73cb0348
NC
883 case 0xAB:
884 case 0x8B: // SBC{S}<c> <Rd>,<Rn>,#<const>
885 {
886 ARMword Rn = tBITS (0, 3);
887 ARMword Rd = ntBITS (8, 11);
888 int S = tBIT (4);
889 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
890 ARMword lhs = state->Reg[Rn];
891 ARMword rhs = ThumbExpandImm (imm12);
892 ARMword res;
893
894 tASSERT (ntBIT (15) == 0);
895
896 if (! CFLAG)
897 rhs += 1;
898
899 res = lhs - rhs;
900 state->Reg[Rd] = res;
901
902 if (in_IT_block ())
903 S = 0;
904
905 if (S)
906 {
907 ARMul_NegZero (state, res);
908
909 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
910 {
911 ARMul_SubCarry (state, lhs, rhs, res);
912 ARMul_SubOverflow (state, lhs, rhs, res);
913 }
914 else
915 {
916 CLEARC;
917 CLEARV;
918 }
919 }
920
921 * pvalid = t_branch;
922 break;
923 }
924
925 case 0xAD:
926 case 0x8D: // SUB
927 {
928 ARMword Rn = tBITS (0, 3);
929 ARMword Rd = ntBITS (8, 11);
930 int S = tBIT (4);
931 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
932 ARMword lhs = state->Reg[Rn];
933 ARMword rhs = ThumbExpandImm (imm12);
934 ARMword res = lhs - rhs;
935
936 if (Rd == 15 && S)
937 {
938 // CMP<c>.W <Rn>,#<const>
939 tASSERT (S);
940 }
941 else
942 {
454de2ee 943 // SUB{S}<c>.W <Rd>,<Rn>,#<const>
73cb0348
NC
944 if (in_IT_block ())
945 S = 0;
946
947 state->Reg[Rd] = res;
948 }
949
950 if (S)
951 {
952 ARMul_NegZero (state, res);
953
954 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
955 {
956 ARMul_SubCarry (state, lhs, rhs, res);
957 ARMul_SubOverflow (state, lhs, rhs, res);
958 }
959 else
960 {
961 CLEARC;
962 CLEARV;
963 }
964 }
965
966 * pvalid = t_branch;
967 break;
968 }
969
970 case 0xAE:
971 case 0x8E: // RSB{S}<c>.W <Rd>,<Rn>,#<const>
972 {
973 ARMword Rn = tBITS (0, 3);
974 ARMword Rd = ntBITS (8, 11);
975 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
976 int S = tBIT (4);
977 ARMword lhs = imm12;
978 ARMword rhs = state->Reg[Rn];
979 ARMword res = lhs - rhs;
980
981 tASSERT (ntBIT (15) == 0);
982
983 state->Reg[Rd] = res;
984
985 if (S)
986 {
987 ARMul_NegZero (state, res);
988
989 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
990 {
991 ARMul_SubCarry (state, lhs, rhs, res);
992 ARMul_SubOverflow (state, lhs, rhs, res);
993 }
994 else
995 {
996 CLEARC;
997 CLEARV;
998 }
999 }
454de2ee 1000
73cb0348
NC
1001 * pvalid = t_branch;
1002 break;
1003 }
1004
1005 case 0xB0:
1006 case 0x90: // ADDW<c> <Rd>,<Rn>,#<imm12>
1007 {
1008 ARMword Rn = tBITS (0, 3);
1009 ARMword Rd = ntBITS (8, 11);
1010 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1011
1012 tASSERT (tBIT (4) == 0);
1013 tASSERT (ntBIT (15) == 0);
1014
1015 state->Reg[Rd] = state->Reg[Rn] + imm12;
1016 * pvalid = t_branch;
1017 break;
1018 }
1019
1020 case 0xB2:
1021 case 0x92: // MOVW<c> <Rd>,#<imm16>
1022 {
1023 ARMword Rd = ntBITS (8, 11);
1024 ARMword imm = (tBITS (0, 3) << 12) | (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1025
1026 state->Reg[Rd] = imm;
1027 /* Indicate that the instruction has been processed. */
1028 * pvalid = t_branch;
1029 break;
1030 }
1031
1032 case 0xb5:
1033 case 0x95:// SUBW<c> <Rd>,<Rn>,#<imm12>
1034 {
1035 ARMword Rd = ntBITS (8, 11);
1036 ARMword Rn = tBITS (0, 3);
1037 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1038
1039 tASSERT (tBIT (4) == 0);
1040 tASSERT (ntBIT (15) == 0);
454de2ee 1041
73cb0348
NC
1042 /* Note the ARM ARM indicates special cases for Rn == 15 (ADR)
1043 and Rn == 13 (SUB SP minus immediate), but these are implemented
1044 in exactly the same way as the normal SUBW insn. */
1045 state->Reg[Rd] = state->Reg[Rn] - imm12;
1046
1047 * pvalid = t_resolved;
1048 break;
1049 }
454de2ee 1050
73cb0348
NC
1051 case 0xB6:
1052 case 0x96: // MOVT<c> <Rd>,#<imm16>
1053 {
1054 ARMword Rd = ntBITS (8, 11);
1055 ARMword imm = (tBITS (0, 3) << 12) | (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1056
1057 state->Reg[Rd] &= 0xFFFF;
1058 state->Reg[Rd] |= (imm << 16);
1059 * pvalid = t_resolved;
1060 break;
1061 }
1062
1063 case 0x9A: // SBFXc> <Rd>,<Rn>,#<lsb>,#<width>
1064 tASSERT (tBIT (4) == 0);
1065 tASSERT (ntBIT (15) == 0);
1066 tASSERT (ntBIT (5) == 0);
1067 * ainstr = 0xE7A00050;
1068 * ainstr |= (ntBITS (0, 4) << 16); // widthm1
1069 * ainstr |= (ntBITS (8, 11) << 12); // Rd
1070 * ainstr |= (((ntBITS (12, 14) << 2) | ntBITS (6, 7)) << 7); // lsb
1071 * ainstr |= tBITS (0, 3); // Rn
1072 * pvalid = t_decoded;
1073 break;
1074
1075 case 0x9B:
1076 {
1077 ARMword Rd = ntBITS (8, 11);
1078 ARMword Rn = tBITS (0, 3);
1079 ARMword msbit = ntBITS (0, 5);
1080 ARMword lsbit = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
1d19cae7 1081 ARMword mask = -(1 << lsbit);
73cb0348
NC
1082
1083 tASSERT (tBIT (4) == 0);
1084 tASSERT (ntBIT (15) == 0);
1085 tASSERT (ntBIT (5) == 0);
1086
1087 mask &= ((1 << (msbit + 1)) - 1);
1088
1089 if (lsbit > msbit)
1090 ; // UNPREDICTABLE
1091 else if (Rn == 15)
1092 {
1093 // BFC<c> <Rd>,#<lsb>,#<width>
1094 state->Reg[Rd] &= ~ mask;
1095 }
1096 else
1097 {
1098 // BFI<c> <Rd>,<Rn>,#<lsb>,#<width>
1099 ARMword val = state->Reg[Rn] & (mask >> lsbit);
1100
454de2ee 1101 val <<= lsbit;
73cb0348
NC
1102 state->Reg[Rd] &= ~ mask;
1103 state->Reg[Rd] |= val;
1104 }
1105
1106 * pvalid = t_resolved;
1107 break;
1108 }
1109
1110 case 0x9E: // UBFXc> <Rd>,<Rn>,#<lsb>,#<width>
1111 tASSERT (tBIT (4) == 0);
1112 tASSERT (ntBIT (15) == 0);
1113 tASSERT (ntBIT (5) == 0);
1114 * ainstr = 0xE7E00050;
1115 * ainstr |= (ntBITS (0, 4) << 16); // widthm1
1116 * ainstr |= (ntBITS (8, 11) << 12); // Rd
1117 * ainstr |= (((ntBITS (12, 14) << 2) | ntBITS (6, 7)) << 7); // lsb
1118 * ainstr |= tBITS (0, 3); // Rn
1119 * pvalid = t_decoded;
1120 break;
454de2ee 1121
73cb0348
NC
1122 case 0xC0: // STRB
1123 case 0xC4: // LDRB
1124 {
1125 ARMword Rn = tBITS (0, 3);
1126 ARMword Rt = ntBITS (12, 15);
1127
1128 if (tBIT (4))
1129 {
1130 if (Rn == 15)
1131 {
1132 tASSERT (Rt != 15);
1133
1134 /* LDRB<c> <Rt>,<label> => 1111 1000 U001 1111 */
1135 * ainstr = 0xE55F0000;
1136 * ainstr |= (tBIT (7) << 23);
1137 * ainstr |= ntBITS (0, 11);
1138 }
1139 else if (tBIT (7))
1140 {
1141 /* LDRB<c>.W <Rt>,[<Rn>{,#<imm12>}] => 1111 1000 1001 rrrr */
1142 * ainstr = 0xE5D00000;
1143 * ainstr |= ntBITS (0, 11);
1144 }
1145 else if (ntBIT (11) == 0)
1146 {
1147 /* LDRB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}] => 1111 1000 0001 rrrr */
1148 * ainstr = 0xE7D00000;
1149 * ainstr |= (ntBITS (4, 5) << 7);
1150 * ainstr |= ntBITS (0, 3);
1151 }
1152 else
1153 {
1154 int P = ntBIT (10);
1155 int U = ntBIT (9);
1156 int W = ntBIT (8);
1157
1158 tASSERT (! (Rt == 15 && P && !U && !W));
1159 tASSERT (! (P && U && !W));
454de2ee 1160
73cb0348
NC
1161 /* LDRB<c> <Rt>,[<Rn>,#-<imm8>] => 1111 1000 0001 rrrr
1162 LDRB<c> <Rt>,[<Rn>],#+/-<imm8> => 1111 1000 0001 rrrr
1163 LDRB<c> <Rt>,[<Rn>,#+/-<imm8>]! => 1111 1000 0001 rrrr */
1164 * ainstr = 0xE4500000;
1165 * ainstr |= (P << 24);
1166 * ainstr |= (U << 23);
1167 * ainstr |= (W << 21);
1168 * ainstr |= ntBITS (0, 7);
1169 }
1170 }
1171 else
1172 {
1173 if (tBIT (7) == 1)
1174 {
1175 // STRB<c>.W <Rt>,[<Rn>,#<imm12>]
1176 ARMword imm12 = ntBITS (0, 11);
1177
1178 ARMul_StoreByte (state, state->Reg[Rn] + imm12, state->Reg [Rt]);
1179 * pvalid = t_branch;
1180 break;
1181 }
1182 else if (ntBIT (11))
1183 {
1184 // STRB<c> <Rt>,[<Rn>,#-<imm8>]
1185 // STRB<c> <Rt>,[<Rn>],#+/-<imm8>
1186 // STRB<c> <Rt>,[<Rn>,#+/-<imm8>]!
1187 int P = ntBIT (10);
1188 int U = ntBIT (9);
1189 int W = ntBIT (8);
1190 ARMword imm8 = ntBITS (0, 7);
1191
1192 tASSERT (! (P && U && !W));
1193 tASSERT (! (Rn == 13 && P && !U && W && imm8 == 4));
1194
1195 * ainstr = 0xE4000000;
1196 * ainstr |= (P << 24);
1197 * ainstr |= (U << 23);
1198 * ainstr |= (W << 21);
1199 * ainstr |= imm8;
1200 }
1201 else
1202 {
1203 // STRB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1204 tASSERT (ntBITS (6, 11) == 0);
1205
1206 * ainstr = 0xE7C00000;
1207 * ainstr |= (ntBITS (4, 5) << 7);
1208 * ainstr |= ntBITS (0, 3);
1209 }
1210 }
1211
1212 * ainstr |= (Rn << 16);
1213 * ainstr |= (Rt << 12);
1214 * pvalid = t_decoded;
1215 break;
1216 }
1217
1218 case 0xC2: // LDR, STR
1219 {
1220 ARMword Rn = tBITS (0, 3);
1221 ARMword Rt = ntBITS (12, 15);
1222 ARMword imm8 = ntBITS (0, 7);
1223 ARMword P = ntBIT (10);
1224 ARMword U = ntBIT (9);
1225 ARMword W = ntBIT (8);
1226
1227 tASSERT (Rn != 15);
1228
1229 if (tBIT (4))
1230 {
1231 if (Rn == 15)
1232 {
1233 // LDR<c>.W <Rt>,<label>
1234 * ainstr = 0xE51F0000;
1235 * ainstr |= ntBITS (0, 11);
1236 }
1237 else if (ntBIT (11))
1238 {
1239 tASSERT (! (P && U && ! W));
1240 tASSERT (! (!P && U && W && Rn == 13 && imm8 == 4 && ntBIT (11) == 0));
1241 tASSERT (! (P && !U && W && Rn == 13 && imm8 == 4 && ntBIT (11)));
454de2ee 1242
73cb0348
NC
1243 // LDR<c> <Rt>,[<Rn>,#-<imm8>]
1244 // LDR<c> <Rt>,[<Rn>],#+/-<imm8>
1245 // LDR<c> <Rt>,[<Rn>,#+/-<imm8>]!
1246 if (!P && W)
1247 W = 0;
1248 * ainstr = 0xE4100000;
1249 * ainstr |= (P << 24);
1250 * ainstr |= (U << 23);
1251 * ainstr |= (W << 21);
1252 * ainstr |= imm8;
1253 }
1254 else
1255 {
1256 // LDR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1257
1258 tASSERT (ntBITS (6, 11) == 0);
1259
1260 * ainstr = 0xE7900000;
1261 * ainstr |= ntBITS (4, 5) << 7;
1262 * ainstr |= ntBITS (0, 3);
1263 }
1264 }
1265 else
1266 {
1267 if (ntBIT (11))
1268 {
1269 tASSERT (! (P && U && ! W));
1270 if (Rn == 13 && P && !U && W && imm8 == 4)
1271 {
1272 // PUSH<c>.W <register>
1273 tASSERT (ntBITS (0, 11) == 0xD04);
1274 tASSERT (tBITS (0, 4) == 0x0D);
1275
1276 * ainstr = 0xE92D0000;
1277 * ainstr |= (1 << Rt);
454de2ee 1278
73cb0348
NC
1279 Rt = Rn = 0;
1280 }
1281 else
1282 {
1283 tASSERT (! (P && U && !W));
1284 if (!P && W)
1285 W = 0;
1286 // STR<c> <Rt>,[<Rn>,#-<imm8>]
1287 // STR<c> <Rt>,[<Rn>],#+/-<imm8>
1288 // STR<c> <Rt>,[<Rn>,#+/-<imm8>]!
1289 * ainstr = 0xE4000000;
1290 * ainstr |= (P << 24);
1291 * ainstr |= (U << 23);
1292 * ainstr |= (W << 21);
1293 * ainstr |= imm8;
1294 }
1295 }
1296 else
1297 {
1298 // STR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1299 tASSERT (ntBITS (6, 11) == 0);
1300
1301 * ainstr = 0xE7800000;
1302 * ainstr |= ntBITS (4, 5) << 7;
1303 * ainstr |= ntBITS (0, 3);
1304 }
1305 }
1306
1307 * ainstr |= (Rn << 16);
1308 * ainstr |= (Rt << 12);
1309 * pvalid = t_decoded;
1310 break;
1311 }
1312
1313 case 0xC1: // STRH
1314 case 0xC5: // LDRH
1315 {
1316 ARMword Rn = tBITS (0, 3);
1317 ARMword Rt = ntBITS (12, 15);
1318 ARMword address;
1319
1320 tASSERT (Rn != 15);
1321
1322 if (tBIT (4) == 1)
1323 {
1324 if (tBIT (7))
1325 {
1326 // LDRH<c>.W <Rt>,[<Rn>{,#<imm12>}]
1327 ARMword imm12 = ntBITS (0, 11);
1328 address = state->Reg[Rn] + imm12;
1329 }
1330 else if (ntBIT (11))
1331 {
1332 // LDRH<c> <Rt>,[<Rn>,#-<imm8>]
1333 // LDRH<c> <Rt>,[<Rn>],#+/-<imm8>
1334 // LDRH<c> <Rt>,[<Rn>,#+/-<imm8>]!
1335 ARMword P = ntBIT (10);
1336 ARMword U = ntBIT (9);
1337 ARMword W = ntBIT (8);
1338 ARMword imm8 = ntBITS (0, 7);
1339
1340 tASSERT (Rn != 15);
1341 tASSERT (! (P && U && !W));
1342
1343 * ainstr = 0xE05000B0;
1344 * ainstr |= (P << 24);
1345 * ainstr |= (U << 23);
1346 * ainstr |= (W << 21);
1347 * ainstr |= (Rn << 16);
1348 * ainstr |= (Rt << 12);
1349 * ainstr |= ((imm8 & 0xF0) << 4);
1350 * ainstr |= (imm8 & 0xF);
1351 * pvalid = t_decoded;
1352 break;
1353 }
1354 else
1355 {
1356 // LDRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1357 ARMword Rm = ntBITS (0, 3);
1358 ARMword imm2 = ntBITS (4, 5);
1359
1360 tASSERT (ntBITS (6, 10) == 0);
1361
1362 address = state->Reg[Rn] + (state->Reg[Rm] << imm2);
1363 }
1364
1365 state->Reg[Rt] = ARMul_LoadHalfWord (state, address);
1366 }
1367 else
1368 {
1369 if (tBIT (7))
1370 {
1371 // STRH<c>.W <Rt>,[<Rn>{,#<imm12>}]
1372 ARMword imm12 = ntBITS (0, 11);
1373
1374 address = state->Reg[Rn] + imm12;
1375 }
1376 else if (ntBIT (11))
1377 {
1378 // STRH<c> <Rt>,[<Rn>,#-<imm8>]
1379 // STRH<c> <Rt>,[<Rn>],#+/-<imm8>
1380 // STRH<c> <Rt>,[<Rn>,#+/-<imm8>]!
1381 ARMword P = ntBIT (10);
1382 ARMword U = ntBIT (9);
1383 ARMword W = ntBIT (8);
1384 ARMword imm8 = ntBITS (0, 7);
1385
1386 tASSERT (! (P && U && !W));
1387
1388 * ainstr = 0xE04000B0;
1389 * ainstr |= (P << 24);
1390 * ainstr |= (U << 23);
1391 * ainstr |= (W << 21);
1392 * ainstr |= (Rn << 16);
1393 * ainstr |= (Rt << 12);
1394 * ainstr |= ((imm8 & 0xF0) << 4);
1395 * ainstr |= (imm8 & 0xF);
1396 * pvalid = t_decoded;
1397 break;
1398 }
1399 else
1400 {
1401 // STRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1402 ARMword Rm = ntBITS (0, 3);
1403 ARMword imm2 = ntBITS (4, 5);
1404
1405 tASSERT (ntBITS (6, 10) == 0);
1406
1407 address = state->Reg[Rn] + (state->Reg[Rm] << imm2);
1408 }
1409
1410 ARMul_StoreHalfWord (state, address, state->Reg [Rt]);
1411 }
1412 * pvalid = t_branch;
1413 break;
1414 }
454de2ee 1415
73cb0348
NC
1416 case 0xC6: // LDR.W/STR.W
1417 {
1418 ARMword Rn = tBITS (0, 3);
1419 ARMword Rt = ntBITS (12, 15);
1420 ARMword imm12 = ntBITS (0, 11);
1421 ARMword address = state->Reg[Rn];
1422
1423 if (Rn == 15)
1424 {
1425 // LDR<c>.W <Rt>,<label>
1426 tASSERT (tBIT (4) == 1);
1427 // tASSERT (tBIT (7) == 1)
1428 }
1429
1430 address += imm12;
1431 if (tBIT (4) == 1)
1432 state->Reg[Rt] = ARMul_LoadWordN (state, address);
1433 else
1434 ARMul_StoreWordN (state, address, state->Reg [Rt]);
1435
1436 * pvalid = t_resolved;
1437 break;
1438 }
1439
1440 case 0xC8:
1441 case 0xCC: // LDRSB
1442 {
1443 ARMword Rt = ntBITS (12, 15);
1444 ARMword Rn = tBITS (0, 3);
1445 ARMword U = tBIT (7);
1446 ARMword address = state->Reg[Rn];
1447
1448 tASSERT (tBIT (4) == 1);
1449 tASSERT (Rt != 15); // PLI
1450
1451 if (Rn == 15)
1452 {
1453 // LDRSB<c> <Rt>,<label>
1454 ARMword imm12 = ntBITS (0, 11);
1455 address += (U ? imm12 : - imm12);
454de2ee 1456 }
73cb0348
NC
1457 else if (U)
1458 {
1459 // LDRSB<c> <Rt>,[<Rn>,#<imm12>]
1460 ARMword imm12 = ntBITS (0, 11);
1461 address += imm12;
1462 }
1463 else if (ntBIT (11))
1464 {
1465 // LDRSB<c> <Rt>,[<Rn>,#-<imm8>]
1466 // LDRSB<c> <Rt>,[<Rn>],#+/-<imm8>
1467 // LDRSB<c> <Rt>,[<Rn>,#+/-<imm8>]!
1468 * ainstr = 0xE05000D0;
1469 * ainstr |= ntBIT (10) << 24; // P
1470 * ainstr |= ntBIT (9) << 23; // U
1471 * ainstr |= ntBIT (8) << 21; // W
1472 * ainstr |= Rn << 16;
1473 * ainstr |= Rt << 12;
1474 * ainstr |= ntBITS (4, 7) << 8;
1475 * ainstr |= ntBITS (0, 3);
1476 * pvalid = t_decoded;
1477 break;
1478 }
1479 else
1480 {
1481 // LDRSB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1482 ARMword Rm = ntBITS (0, 3);
1483 ARMword imm2 = ntBITS (4,5);
1484
1485 tASSERT (ntBITS (6, 11) == 0);
1486
1487 address += (state->Reg[Rm] << imm2);
1488 }
1489
1490 state->Reg[Rt] = ARMul_LoadByte (state, address);
1491 if (state->Reg[Rt] & 0x80)
1d19cae7 1492 state->Reg[Rt] |= -(1 << 8);
73cb0348
NC
1493
1494 * pvalid = t_resolved;
1495 break;
1496 }
454de2ee 1497
73cb0348
NC
1498 case 0xC9:
1499 case 0xCD:// LDRSH
1500 {
1501 ARMword Rt = ntBITS (12, 15);
1502 ARMword Rn = tBITS (0, 3);
1503 ARMword U = tBIT (7);
1504 ARMword address = state->Reg[Rn];
1505
1506 tASSERT (tBIT (4) == 1);
1507
1508 if (Rn == 15 || U == 1)
1509 {
1510 // Rn==15 => LDRSH<c> <Rt>,<label>
1511 // Rn!=15 => LDRSH<c> <Rt>,[<Rn>,#<imm12>]
1512 ARMword imm12 = ntBITS (0, 11);
1513
1514 address += (U ? imm12 : - imm12);
1515 }
1516 else if (ntBIT (11))
1517 {
1518 // LDRSH<c> <Rt>,[<Rn>,#-<imm8>]
1519 // LDRSH<c> <Rt>,[<Rn>],#+/-<imm8>
1520 // LDRSH<c> <Rt>,[<Rn>,#+/-<imm8>]!
1521 * ainstr = 0xE05000F0;
1522 * ainstr |= ntBIT (10) << 24; // P
1523 * ainstr |= ntBIT (9) << 23; // U
1524 * ainstr |= ntBIT (8) << 21; // W
1525 * ainstr |= Rn << 16;
1526 * ainstr |= Rt << 12;
1527 * ainstr |= ntBITS (4, 7) << 8;
1528 * ainstr |= ntBITS (0, 3);
1529 * pvalid = t_decoded;
1530 break;
1531 }
1532 else /* U == 0 */
1533 {
1534 // LDRSH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1535 ARMword Rm = ntBITS (0, 3);
1536 ARMword imm2 = ntBITS (4,5);
1537
1538 tASSERT (ntBITS (6, 11) == 0);
1539
1540 address += (state->Reg[Rm] << imm2);
1541 }
1542
1543 state->Reg[Rt] = ARMul_LoadHalfWord (state, address);
1544 if (state->Reg[Rt] & 0x8000)
1d19cae7 1545 state->Reg[Rt] |= -(1 << 16);
73cb0348
NC
1546
1547 * pvalid = t_branch;
1548 break;
1549 }
1550
454de2ee 1551 case 0x0D0:
73cb0348
NC
1552 {
1553 ARMword Rm = ntBITS (0, 3);
1554 ARMword Rd = ntBITS (8, 11);
1555
1556 tASSERT (ntBITS (12, 15) == 15);
1557
1558 if (ntBIT (7) == 1)
1559 {
1560 // SXTH<c>.W <Rd>,<Rm>{,<rotation>}
1561 ARMword ror = ntBITS (4, 5) << 3;
1562 ARMword val;
1563
1564 val = state->Reg[Rm];
1565 val = (val >> ror) | (val << (32 - ror));
1566 if (val & 0x8000)
1d19cae7 1567 val |= -(1 << 16);
73cb0348
NC
1568 state->Reg[Rd] = val;
1569 }
1570 else
1571 {
1572 // LSL{S}<c>.W <Rd>,<Rn>,<Rm>
1573 ARMword Rn = tBITS (0, 3);
1574
1575 tASSERT (ntBITS (4, 6) == 0);
1576
1577 state->Reg[Rd] = state->Reg[Rn] << (state->Reg[Rm] & 0xFF);
1578 if (tBIT (4))
1579 ARMul_NegZero (state, state->Reg[Rd]);
1580 }
1581 * pvalid = t_branch;
1582 break;
1583 }
1584
1585 case 0x0D1: // LSR{S}<c>.W <Rd>,<Rn>,<Rm>
1586 {
1587 ARMword Rd = ntBITS (8, 11);
1588 ARMword Rn = tBITS (0, 3);
1589 ARMword Rm = ntBITS (0, 3);
1590
1591 tASSERT (ntBITS (12, 15) == 15);
1592 tASSERT (ntBITS (4, 7) == 0);
1593
1594 state->Reg[Rd] = state->Reg[Rn] >> (state->Reg[Rm] & 0xFF);
1595 if (tBIT (4))
1596 ARMul_NegZero (state, state->Reg[Rd]);
1597 * pvalid = t_resolved;
1598 break;
1599 }
1600
454de2ee 1601 case 0xD2:
73cb0348
NC
1602 tASSERT (ntBITS (12, 15) == 15);
1603 if (ntBIT (7))
1604 {
1605 tASSERT (ntBIT (6) == 0);
1606 // UXTB<c>.W <Rd>,<Rm>{,<rotation>}
1607 * ainstr = 0xE6EF0070;
1608 * ainstr |= (ntBITS (4, 5) << 10); // rotate
1609 * ainstr |= ntBITS (0, 3); // Rm
1610 }
1611 else
1612 {
1613 // ASR{S}<c>.W <Rd>,<Rn>,<Rm>
1614 tASSERT (ntBITS (4, 7) == 0);
1615 * ainstr = 0xE1A00050;
1616 if (! in_IT_block ())
1617 * ainstr |= (tBIT (4) << 20);
1618 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1619 * ainstr |= tBITS (0, 3); // Rn
1620 }
1621
1622 * ainstr |= (ntBITS (8, 11) << 12); // Rd
1623 * pvalid = t_decoded;
1624 break;
454de2ee 1625
73cb0348
NC
1626 case 0xD3: // ROR{S}<c>.W <Rd>,<Rn>,<Rm>
1627 tASSERT (ntBITS (12, 15) == 15);
1628 tASSERT (ntBITS (4, 7) == 0);
1629 * ainstr = 0xE1A00070;
1630 if (! in_IT_block ())
1631 * ainstr |= (tBIT (4) << 20);
1632 * ainstr |= (ntBITS (8, 11) << 12); // Rd
1633 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1634 * ainstr |= (tBITS (0, 3) << 0); // Rn
1635 * pvalid = t_decoded;
1636 break;
454de2ee 1637
73cb0348
NC
1638 case 0xD4:
1639 {
1640 ARMword Rn = tBITS (0, 3);
1641 ARMword Rd = ntBITS (8, 11);
1642 ARMword Rm = ntBITS (0, 3);
1643
1644 tASSERT (ntBITS (12, 15) == 15);
1645
1646 if (ntBITS (4, 7) == 8)
1647 {
1648 // REV<c>.W <Rd>,<Rm>
1649 ARMword val = state->Reg[Rm];
454de2ee 1650
73cb0348 1651 tASSERT (Rm == Rn);
454de2ee 1652
73cb0348
NC
1653 state->Reg [Rd] =
1654 (val >> 24)
1655 | ((val >> 8) & 0xFF00)
1656 | ((val << 8) & 0xFF0000)
1657 | (val << 24);
1658 * pvalid = t_resolved;
1659 }
1660 else
1661 {
1662 tASSERT (ntBITS (4, 7) == 4);
1663
1664 if (tBIT (4) == 1)
1665 // UADD8<c> <Rd>,<Rn>,<Rm>
1666 * ainstr = 0xE6500F10;
1667 else
1668 // UADD16<c> <Rd>,<Rn>,<Rm>
1669 * ainstr = 0xE6500F90;
1670
1671 * ainstr |= (Rn << 16);
1672 * ainstr |= (Rd << 12);
1673 * ainstr |= (Rm << 0);
1674 * pvalid = t_decoded;
1675 }
1676 break;
1677 }
1678
1679 case 0xD5:
1680 {
1681 ARMword Rn = tBITS (0, 3);
1682 ARMword Rd = ntBITS (8, 11);
1683 ARMword Rm = ntBITS (0, 3);
1684
1685 tASSERT (ntBITS (12, 15) == 15);
1686 tASSERT (ntBITS (4, 7) == 8);
1687
1688 if (tBIT (4))
1689 {
1690 // CLZ<c> <Rd>,<Rm>
1691 tASSERT (Rm == Rn);
1692 * ainstr = 0xE16F0F10;
1693 }
1694 else
1695 {
1696 // SEL<c> <Rd>,<Rn>,<Rm>
1697 * ainstr = 0xE6800FB0;
1698 * ainstr |= (Rn << 16);
1699 }
1700
1701 * ainstr |= (Rd << 12);
1702 * ainstr |= (Rm << 0);
1703 * pvalid = t_decoded;
1704 break;
1705 }
1706
1707 case 0xD8: // MUL
1708 {
1709 ARMword Rn = tBITS (0, 3);
1710 ARMword Rm = ntBITS (0, 3);
1711 ARMword Rd = ntBITS (8, 11);
1712 ARMword Ra = ntBITS (12, 15);
1713
1714 if (tBIT (4))
1715 {
1716 // SMLA<x><y><c> <Rd>,<Rn>,<Rm>,<Ra>
1717 ARMword nval = state->Reg[Rn];
1718 ARMword mval = state->Reg[Rm];
1719 ARMword res;
1720
1721 tASSERT (ntBITS (6, 7) == 0);
1722 tASSERT (Ra != 15);
1723
1724 if (ntBIT (5))
1725 nval >>= 16;
1726 else
1727 nval &= 0xFFFF;
1728
1729 if (ntBIT (4))
1730 mval >>= 16;
1731 else
1732 mval &= 0xFFFF;
1733
1734 res = nval * mval;
1735 res += state->Reg[Ra];
1736 // FIXME: Test and clear/set the Q bit.
1737 state->Reg[Rd] = res;
1738 }
1739 else
1740 {
1741 if (ntBITS (4, 7) == 1)
1742 {
1743 // MLS<c> <Rd>,<Rn>,<Rm>,<Ra>
454de2ee 1744 state->Reg[Rd] = state->Reg[Ra] - (state->Reg[Rn] * state->Reg[Rm]);
73cb0348
NC
1745 }
1746 else
1747 {
1748 tASSERT (ntBITS (4, 7) == 0);
1749
1750 if (Ra == 15)
1751 // MUL<c> <Rd>,<Rn>,<Rm>
1752 state->Reg[Rd] = state->Reg[Rn] * state->Reg[Rm];
1753 else
1754 // MLA<c> <Rd>,<Rn>,<Rm>,<Ra>
1755 state->Reg[Rd] = state->Reg[Rn] * state->Reg[Rm] + state->Reg[Ra];
1756 }
1757 }
1758 * pvalid = t_resolved;
1759 break;
1760 }
1761
1762 case 0xDC: // SMULL
1763 tASSERT (tBIT (4) == 0);
1764 tASSERT (ntBITS (4, 7) == 0);
1765 * ainstr = 0xE0C00090;
1766 * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1767 * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1768 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1769 * ainstr |= tBITS (0, 3); // Rn
1770 * pvalid = t_decoded;
1771 break;
454de2ee 1772
73cb0348
NC
1773 case 0xDD: // UMULL
1774 tASSERT (tBIT (4) == 0);
1775 tASSERT (ntBITS (4, 7) == 0);
1776 * ainstr = 0xE0800090;
1777 * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1778 * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1779 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1780 * ainstr |= tBITS (0, 3); // Rn
1781 * pvalid = t_decoded;
1782 break;
454de2ee 1783
73cb0348
NC
1784 case 0xDF: // UMLAL
1785 tASSERT (tBIT (4) == 0);
1786 tASSERT (ntBITS (4, 7) == 0);
1787 * ainstr = 0xE0A00090;
1788 * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1789 * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1790 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1791 * ainstr |= tBITS (0, 3); // Rn
1792 * pvalid = t_decoded;
1793 break;
1794
454de2ee 1795 default:
73cb0348
NC
1796 fprintf (stderr, "(op = %x) ", tBITS (5,12));
1797 tASSERT (0);
1798 return;
1799 }
1800
1801 /* Tell the Thumb decoder to skip the next 16-bit insn - it was
1802 part of this insn - unless this insn has changed the PC. */
1803 skipping_32bit_thumb = pc + 2;
1804}
1805
546aee7a
NC
1806/* Attempt to emulate an ARMv6 instruction.
1807 Stores t_branch into PVALUE upon success or t_undefined otherwise. */
1808
1809static void
1810handle_v6_thumb_insn (ARMul_State * state,
1811 ARMword tinstr,
73cb0348
NC
1812 ARMword next_instr,
1813 ARMword pc,
1814 ARMword * ainstr,
546aee7a
NC
1815 tdstate * pvalid)
1816{
546aee7a
NC
1817 if (! state->is_v6)
1818 {
1819 * pvalid = t_undefined;
1820 return;
1821 }
1822
73cb0348
NC
1823 if (tBITS (12, 15) == 0xB
1824 && tBIT (10) == 0
1825 && tBIT (8) == 1)
1826 {
1827 // Conditional branch forwards.
1828 ARMword Rn = tBITS (0, 2);
1829 ARMword imm5 = tBIT (9) << 5 | tBITS (3, 7);
1830
1831 if (tBIT (11))
1832 {
1833 if (state->Reg[Rn] != 0)
1834 {
1835 state->Reg[15] = (pc + 4 + imm5 * 2);
1836 FLUSHPIPE;
1837 }
1838 }
1839 else
1840 {
1841 if (state->Reg[Rn] == 0)
1842 {
1843 state->Reg[15] = (pc + 4 + imm5 * 2);
1844 FLUSHPIPE;
1845 }
1846 }
1847 * pvalid = t_branch;
1848 return;
1849 }
1850
546aee7a
NC
1851 switch (tinstr & 0xFFC0)
1852 {
73cb0348
NC
1853 case 0x4400:
1854 case 0x4480:
1855 case 0x4440:
1856 case 0x44C0: // ADD
1857 {
1858 ARMword Rd = (tBIT (7) << 3) | tBITS (0, 2);
1859 ARMword Rm = tBITS (3, 6);
1860 state->Reg[Rd] += state->Reg[Rm];
1861 break;
1862 }
454de2ee 1863
73cb0348
NC
1864 case 0x4600: // MOV<c> <Rd>,<Rm>
1865 {
1866 // instr [15, 8] = 0100 0110
1867 // instr [7] = Rd<high>
1868 // instr [6,3] = Rm
1869 // instr [2,0] = Rd<low>
1870 ARMword Rd = (tBIT(7) << 3) | tBITS (0, 2);
1871 // FIXME: Check for Rd == 15 and ITblock.
1872 state->Reg[Rd] = state->Reg[tBITS (3, 6)];
1873 break;
1874 }
1875
1876 case 0xBF00:
1877 case 0xBF40:
1878 case 0xBF80:
1879 case 0xBFC0:
1880 handle_IT_block (state, tinstr, pvalid);
1881 return;
1882
1883 case 0xE840:
1884 case 0xE880: // LDMIA
1885 case 0xE8C0:
1886 case 0xE900: // STM
1887 case 0xE940:
1888 case 0xE980:
1889 case 0xE9C0: // LDRD
1890 case 0xEA00: // BIC
1891 case 0xEA40: // ORR
1892 case 0xEA80: // EOR
1893 case 0xEAC0:
1894 case 0xEB00: // ADD
1895 case 0xEB40: // SBC
1896 case 0xEB80: // SUB
1897 case 0xEBC0: // RSB
1898 case 0xFA80: // UADD, SEL
1899 handle_T2_insn (state, tinstr, next_instr, pc, ainstr, pvalid);
1900 return;
1901
546aee7a 1902 case 0xba00: /* rev */
73cb0348
NC
1903 {
1904 ARMword val = state->Reg[tBITS (3, 5)];
1905 state->Reg [tBITS (0, 2)] =
1906 (val >> 24)
1907 | ((val >> 8) & 0xFF00)
1908 | ((val << 8) & 0xFF0000)
1909 | (val << 24);
1910 break;
1911 }
1912
546aee7a 1913 case 0xba40: /* rev16 */
73cb0348
NC
1914 {
1915 ARMword val = state->Reg[tBITS (3, 5)];
1916 state->Reg [tBITS (0, 2)] = (val >> 16) | (val << 16);
1917 break;
1918 }
454de2ee 1919
73cb0348
NC
1920 case 0xb660: /* cpsie */
1921 case 0xb670: /* cpsid */
546aee7a
NC
1922 case 0xbac0: /* revsh */
1923 case 0xb650: /* setend */
8d052926 1924 default:
546aee7a
NC
1925 printf ("Unhandled v6 thumb insn: %04x\n", tinstr);
1926 * pvalid = t_undefined;
1927 return;
1928
1929 case 0xb200: /* sxth */
8d052926
NC
1930 {
1931 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1932
1933 if (Rm & 0x8000)
1934 state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000;
1935 else
1936 state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1937 break;
1938 }
1939
546aee7a 1940 case 0xb240: /* sxtb */
8d052926
NC
1941 {
1942 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1943
1944 if (Rm & 0x80)
1945 state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00;
1946 else
1947 state->Reg [(tinstr & 0x7)] = Rm & 0xff;
1948 break;
1949 }
1950
546aee7a 1951 case 0xb280: /* uxth */
8d052926
NC
1952 {
1953 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1954
1955 state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1956 break;
1957 }
1958
546aee7a 1959 case 0xb2c0: /* uxtb */
8d052926
NC
1960 {
1961 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1962
1963 state->Reg [(tinstr & 0x7)] = Rm & 0xff;
1964 break;
1965 }
546aee7a
NC
1966 }
1967 /* Indicate that the instruction has been processed. */
1968 * pvalid = t_branch;
1969}
1970
c906108c
SS
1971/* Decode a 16bit Thumb instruction. The instruction is in the low
1972 16-bits of the tinstr field, with the following Thumb instruction
1973 held in the high 16-bits. Passing in two Thumb instructions allows
1974 easier simulation of the special dual BL instruction. */
1975
546aee7a
NC
1976tdstate
1977ARMul_ThumbDecode (ARMul_State * state,
1978 ARMword pc,
1979 ARMword tinstr,
1980 ARMword * ainstr)
c906108c 1981{
dfcd3bfb 1982 tdstate valid = t_decoded; /* default assumes a valid instruction */
c906108c 1983 ARMword next_instr;
73cb0348
NC
1984 ARMword old_tinstr = tinstr;
1985
1986 if (skipping_32bit_thumb == pc)
1987 {
1988 skipping_32bit_thumb = 0;
1989 return t_branch;
1990 }
1991 skipping_32bit_thumb = 0;
dfcd3bfb 1992
c906108c
SS
1993 if (state->bigendSig)
1994 {
1995 next_instr = tinstr & 0xFFFF;
1996 tinstr >>= 16;
1997 }
1998 else
1999 {
2000 next_instr = tinstr >> 16;
2001 tinstr &= 0xFFFF;
2002 }
dfcd3bfb 2003
73cb0348
NC
2004 if (! IT_block_allow (state))
2005 {
2006 if ( tBITS (11, 15) == 0x1F
2007 || tBITS (11, 15) == 0x1E
2008 || tBITS (11, 15) == 0x1D)
2009 {
2010 if (trace)
2011 fprintf (stderr, "pc: %x, SKIP instr: %04x|%04x\n",
2012 pc & ~1, tinstr, next_instr);
2013 skipping_32bit_thumb = pc + 2;
2014 }
2015 else if (trace)
2016 fprintf (stderr, "pc: %x, SKIP instr: %04x\n", pc & ~1, tinstr);
2017
2018 return t_branch;
2019 }
454de2ee 2020
73cb0348 2021 old_tinstr = tinstr;
8d052926
NC
2022 if (trace)
2023 fprintf (stderr, "pc: %x, Thumb instr: %x", pc & ~1, tinstr);
2024
dfcd3bfb 2025#if 1 /* debugging to catch non updates */
c906108c
SS
2026 *ainstr = 0xDEADC0DE;
2027#endif
2028
2029 switch ((tinstr & 0xF800) >> 11)
2030 {
dfcd3bfb
JM
2031 case 0: /* LSL */
2032 case 1: /* LSR */
2033 case 2: /* ASR */
c906108c 2034 /* Format 1 */
dfcd3bfb
JM
2035 *ainstr = 0xE1B00000 /* base opcode */
2036 | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */
2037 | ((tinstr & 0x07C0) << (7 - 6)) /* imm5 */
2038 | ((tinstr & 0x0038) >> 3) /* Rs */
2039 | ((tinstr & 0x0007) << 12); /* Rd */
c906108c 2040 break;
dfcd3bfb 2041 case 3: /* ADD/SUB */
c906108c
SS
2042 /* Format 2 */
2043 {
73cb0348
NC
2044 ARMword subset[4] =
2045 {
2046 0xE0900000, /* ADDS Rd,Rs,Rn */
2047 0xE0500000, /* SUBS Rd,Rs,Rn */
2048 0xE2900000, /* ADDS Rd,Rs,#imm3 */
2049 0xE2500000 /* SUBS Rd,Rs,#imm3 */
2050 };
dfcd3bfb
JM
2051 /* It is quicker indexing into a table, than performing switch
2052 or conditionals: */
2053 *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */
2054 | ((tinstr & 0x01C0) >> 6) /* Rn or imm3 */
2055 | ((tinstr & 0x0038) << (16 - 3)) /* Rs */
2056 | ((tinstr & 0x0007) << (12 - 0)); /* Rd */
73cb0348
NC
2057
2058 if (in_IT_block ())
2059 *ainstr &= ~ (1 << 20);
c906108c
SS
2060 }
2061 break;
73cb0348
NC
2062 case 4:
2063 * ainstr = 0xE3A00000; /* MOV Rd,#imm8 */
2064 if (! in_IT_block ())
2065 * ainstr |= (1 << 20);
2066 * ainstr |= tBITS (8, 10) << 12;
2067 * ainstr |= tBITS (0, 7);
dfcd3bfb 2068 break;
73cb0348
NC
2069
2070 case 5:
2071 * ainstr = 0xE3500000; /* CMP Rd,#imm8 */
2072 * ainstr |= tBITS (8, 10) << 16;
2073 * ainstr |= tBITS (0, 7);
2074 break;
454de2ee 2075
73cb0348
NC
2076 case 6:
2077 case 7:
2078 * ainstr = tBIT (11)
2079 ? 0xE2400000 /* SUB Rd,Rd,#imm8 */
2080 : 0xE2800000; /* ADD Rd,Rd,#imm8 */
2081 if (! in_IT_block ())
2082 * ainstr |= (1 << 20);
2083 * ainstr |= tBITS (8, 10) << 12;
2084 * ainstr |= tBITS (8, 10) << 16;
2085 * ainstr |= tBITS (0, 7);
2086 break;
2087
dfcd3bfb 2088 case 8: /* Arithmetic and high register transfers */
c906108c
SS
2089 /* TODO: Since the subsets for both Format 4 and Format 5
2090 instructions are made up of different ARM encodings, we could
2091 save the following conditional, and just have one large
2092 subset. */
2093 if ((tinstr & (1 << 10)) == 0)
dfcd3bfb
JM
2094 {
2095 /* Format 4 */
2096 struct
2097 {
2098 ARMword opcode;
2099 enum
2100 { t_norm, t_shift, t_neg, t_mul }
2101 otype;
2102 }
2103 subset[16] =
2104 {
2105 { 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */
2106 { 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */
2107 { 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */
2108 { 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */
2109 { 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */
2110 { 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */
2111 { 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */
2112 { 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */
2113 { 0xE1100000, t_norm}, /* TST Rd,Rs */
2114 { 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */
2115 { 0xE1500000, t_norm}, /* CMP Rd,Rs */
2116 { 0xE1700000, t_norm}, /* CMN Rd,Rs */
2117 { 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */
2118 { 0xE0100090, t_mul} , /* MULS Rd,Rd,Rs */
2119 { 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */
2120 { 0xE1F00000, t_norm} /* MVNS Rd,Rs */
2121 };
2122 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
73cb0348
NC
2123
2124 if (in_IT_block ())
2125 {
2126 struct
2127 {
2128 ARMword opcode;
2129 enum
2130 { t_norm, t_shift, t_neg, t_mul }
2131 otype;
2132 }
2133 subset[16] =
2134 {
2135 { 0xE0000000, t_norm}, /* AND Rd,Rd,Rs */
2136 { 0xE0200000, t_norm}, /* EOR Rd,Rd,Rs */
2137 { 0xE1A00010, t_shift}, /* MOV Rd,Rd,LSL Rs */
2138 { 0xE1A00030, t_shift}, /* MOV Rd,Rd,LSR Rs */
2139 { 0xE1A00050, t_shift}, /* MOV Rd,Rd,ASR Rs */
2140 { 0xE0A00000, t_norm}, /* ADC Rd,Rd,Rs */
2141 { 0xE0C00000, t_norm}, /* SBC Rd,Rd,Rs */
2142 { 0xE1A00070, t_shift}, /* MOV Rd,Rd,ROR Rs */
2143 { 0xE1100000, t_norm}, /* TST Rd,Rs */
2144 { 0xE2600000, t_neg}, /* RSB Rd,Rs,#0 */
2145 { 0xE1500000, t_norm}, /* CMP Rd,Rs */
2146 { 0xE1700000, t_norm}, /* CMN Rd,Rs */
2147 { 0xE1800000, t_norm}, /* ORR Rd,Rd,Rs */
2148 { 0xE0000090, t_mul} , /* MUL Rd,Rd,Rs */
2149 { 0xE1C00000, t_norm}, /* BIC Rd,Rd,Rs */
2150 { 0xE1E00000, t_norm} /* MVN Rd,Rs */
2151 };
2152 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
2153 }
2154
dfcd3bfb
JM
2155 switch (subset[(tinstr & 0x03C0) >> 6].otype)
2156 {
2157 case t_norm:
2158 *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */
2159 | ((tinstr & 0x0007) << 12) /* Rd */
2160 | ((tinstr & 0x0038) >> 3); /* Rs */
2161 break;
2162 case t_shift:
2163 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
2164 | ((tinstr & 0x0007) >> 0) /* Rm */
2165 | ((tinstr & 0x0038) << (8 - 3)); /* Rs */
2166 break;
2167 case t_neg:
2168 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
2169 | ((tinstr & 0x0038) << (16 - 3)); /* Rn */
2170 break;
2171 case t_mul:
2172 *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */
2173 | ((tinstr & 0x0007) << 8) /* Rs */
2174 | ((tinstr & 0x0038) >> 3); /* Rm */
2175 break;
2176 }
2177 }
c906108c 2178 else
dfcd3bfb
JM
2179 {
2180 /* Format 5 */
2181 ARMword Rd = ((tinstr & 0x0007) >> 0);
2182 ARMword Rs = ((tinstr & 0x0038) >> 3);
2183 if (tinstr & (1 << 7))
2184 Rd += 8;
2185 if (tinstr & (1 << 6))
2186 Rs += 8;
2187 switch ((tinstr & 0x03C0) >> 6)
2188 {
2189 case 0x1: /* ADD Rd,Rd,Hs */
2190 case 0x2: /* ADD Hd,Hd,Rs */
2191 case 0x3: /* ADD Hd,Hd,Hs */
2192 *ainstr = 0xE0800000 /* base */
2193 | (Rd << 16) /* Rn */
2194 | (Rd << 12) /* Rd */
2195 | (Rs << 0); /* Rm */
2196 break;
2197 case 0x5: /* CMP Rd,Hs */
2198 case 0x6: /* CMP Hd,Rs */
2199 case 0x7: /* CMP Hd,Hs */
2200 *ainstr = 0xE1500000 /* base */
2201 | (Rd << 16) /* Rn */
2202 | (Rd << 12) /* Rd */
2203 | (Rs << 0); /* Rm */
2204 break;
2205 case 0x9: /* MOV Rd,Hs */
2206 case 0xA: /* MOV Hd,Rs */
2207 case 0xB: /* MOV Hd,Hs */
2208 *ainstr = 0xE1A00000 /* base */
dfcd3bfb
JM
2209 | (Rd << 12) /* Rd */
2210 | (Rs << 0); /* Rm */
2211 break;
2212 case 0xC: /* BX Rs */
2213 case 0xD: /* BX Hs */
2214 *ainstr = 0xE12FFF10 /* base */
2215 | ((tinstr & 0x0078) >> 3); /* Rd */
2216 break;
f1129fb8
NC
2217 case 0xE: /* UNDEFINED */
2218 case 0xF: /* UNDEFINED */
2219 if (state->is_v5)
2220 {
2221 /* BLX Rs; BLX Hs */
2222 *ainstr = 0xE12FFF30 /* base */
2223 | ((tinstr & 0x0078) >> 3); /* Rd */
2224 break;
2225 }
2226 /* Drop through. */
73cb0348 2227 default:
dfcd3bfb
JM
2228 case 0x0: /* UNDEFINED */
2229 case 0x4: /* UNDEFINED */
2230 case 0x8: /* UNDEFINED */
73cb0348 2231 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
dfcd3bfb
JM
2232 break;
2233 }
2234 }
c906108c 2235 break;
dfcd3bfb 2236 case 9: /* LDR Rd,[PC,#imm8] */
c906108c 2237 /* Format 6 */
dfcd3bfb
JM
2238 *ainstr = 0xE59F0000 /* base */
2239 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2240 | ((tinstr & 0x00FF) << (2 - 0)); /* off8 */
c906108c
SS
2241 break;
2242 case 10:
2243 case 11:
2244 /* TODO: Format 7 and Format 8 perform the same ARM encoding, so
2245 the following could be merged into a single subset, saving on
2246 the following boolean: */
2247 if ((tinstr & (1 << 9)) == 0)
dfcd3bfb
JM
2248 {
2249 /* Format 7 */
2250 ARMword subset[4] = {
2251 0xE7800000, /* STR Rd,[Rb,Ro] */
2252 0xE7C00000, /* STRB Rd,[Rb,Ro] */
2253 0xE7900000, /* LDR Rd,[Rb,Ro] */
2254 0xE7D00000 /* LDRB Rd,[Rb,Ro] */
2255 };
2256 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2257 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2258 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2259 | ((tinstr & 0x01C0) >> 6); /* Ro */
2260 }
c906108c 2261 else
dfcd3bfb
JM
2262 {
2263 /* Format 8 */
2264 ARMword subset[4] = {
2265 0xE18000B0, /* STRH Rd,[Rb,Ro] */
2266 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */
2267 0xE19000B0, /* LDRH Rd,[Rb,Ro] */
2268 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */
2269 };
2270 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2271 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2272 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2273 | ((tinstr & 0x01C0) >> 6); /* Ro */
2274 }
c906108c 2275 break;
dfcd3bfb
JM
2276 case 12: /* STR Rd,[Rb,#imm5] */
2277 case 13: /* LDR Rd,[Rb,#imm5] */
2278 case 14: /* STRB Rd,[Rb,#imm5] */
2279 case 15: /* LDRB Rd,[Rb,#imm5] */
c906108c
SS
2280 /* Format 9 */
2281 {
dfcd3bfb
JM
2282 ARMword subset[4] = {
2283 0xE5800000, /* STR Rd,[Rb,#imm5] */
2284 0xE5900000, /* LDR Rd,[Rb,#imm5] */
2285 0xE5C00000, /* STRB Rd,[Rb,#imm5] */
2286 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */
2287 };
2288 /* The offset range defends on whether we are transferring a
2289 byte or word value: */
2290 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */
2291 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2292 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2293 | ((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */
c906108c
SS
2294 }
2295 break;
dfcd3bfb
JM
2296 case 16: /* STRH Rd,[Rb,#imm5] */
2297 case 17: /* LDRH Rd,[Rb,#imm5] */
c906108c 2298 /* Format 10 */
dfcd3bfb
JM
2299 *ainstr = ((tinstr & (1 << 11)) /* base */
2300 ? 0xE1D000B0 /* LDRH */
2301 : 0xE1C000B0) /* STRH */
2302 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2303 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2304 | ((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */
2305 | ((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */
c906108c 2306 break;
dfcd3bfb
JM
2307 case 18: /* STR Rd,[SP,#imm8] */
2308 case 19: /* LDR Rd,[SP,#imm8] */
c906108c 2309 /* Format 11 */
dfcd3bfb
JM
2310 *ainstr = ((tinstr & (1 << 11)) /* base */
2311 ? 0xE59D0000 /* LDR */
2312 : 0xE58D0000) /* STR */
2313 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2314 | ((tinstr & 0x00FF) << 2); /* off8 */
c906108c 2315 break;
dfcd3bfb
JM
2316 case 20: /* ADD Rd,PC,#imm8 */
2317 case 21: /* ADD Rd,SP,#imm8 */
c906108c
SS
2318 /* Format 12 */
2319 if ((tinstr & (1 << 11)) == 0)
dfcd3bfb
JM
2320 {
2321 /* NOTE: The PC value used here should by word aligned */
c906108c
SS
2322 /* We encode shift-left-by-2 in the rotate immediate field,
2323 so no shift of off8 is needed. */
dfcd3bfb
JM
2324 *ainstr = 0xE28F0F00 /* base */
2325 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2326 | (tinstr & 0x00FF); /* off8 */
2327 }
c906108c 2328 else
dfcd3bfb 2329 {
c906108c
SS
2330 /* We encode shift-left-by-2 in the rotate immediate field,
2331 so no shift of off8 is needed. */
dfcd3bfb
JM
2332 *ainstr = 0xE28D0F00 /* base */
2333 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2334 | (tinstr & 0x00FF); /* off8 */
2335 }
c906108c
SS
2336 break;
2337 case 22:
2338 case 23:
f1129fb8 2339 switch (tinstr & 0x0F00)
dfcd3bfb 2340 {
f1129fb8 2341 case 0x0000:
dfcd3bfb
JM
2342 /* Format 13 */
2343 /* NOTE: The instruction contains a shift left of 2
f1129fb8 2344 equivalent (implemented as ROR #30): */
dfcd3bfb
JM
2345 *ainstr = ((tinstr & (1 << 7)) /* base */
2346 ? 0xE24DDF00 /* SUB */
2347 : 0xE28DDF00) /* ADD */
2348 | (tinstr & 0x007F); /* off7 */
f1129fb8
NC
2349 break;
2350 case 0x0400:
2351 /* Format 14 - Push */
2352 * ainstr = 0xE92D0000 | (tinstr & 0x00FF);
2353 break;
2354 case 0x0500:
2355 /* Format 14 - Push + LR */
2356 * ainstr = 0xE92D4000 | (tinstr & 0x00FF);
2357 break;
2358 case 0x0c00:
2359 /* Format 14 - Pop */
2360 * ainstr = 0xE8BD0000 | (tinstr & 0x00FF);
2361 break;
2362 case 0x0d00:
2363 /* Format 14 - Pop + PC */
2364 * ainstr = 0xE8BD8000 | (tinstr & 0x00FF);
2365 break;
2366 case 0x0e00:
2367 if (state->is_v5)
2368 {
8d052926 2369 /* This is normally an undefined instruction. The v5t architecture
f1129fb8
NC
2370 defines this particular pattern as a BKPT instruction, for
2371 hardware assisted debugging. We map onto the arm BKPT
2372 instruction. */
73cb0348
NC
2373 if (state->is_v6)
2374 // Map to the SVC instruction instead of the BKPT instruction.
2375 * ainstr = 0xEF000000 | tBITS (0, 7);
2376 else
2377 * ainstr = 0xE1200070 | ((tinstr & 0xf0) << 4) | (tinstr & 0xf);
f1129fb8
NC
2378 break;
2379 }
2380 /* Drop through. */
2381 default:
2382 /* Everything else is an undefined instruction. */
73cb0348 2383 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
f1129fb8 2384 break;
dfcd3bfb 2385 }
c906108c 2386 break;
dfcd3bfb
JM
2387 case 24: /* STMIA */
2388 case 25: /* LDMIA */
c906108c 2389 /* Format 15 */
dfcd3bfb
JM
2390 *ainstr = ((tinstr & (1 << 11)) /* base */
2391 ? 0xE8B00000 /* LDMIA */
2392 : 0xE8A00000) /* STMIA */
2393 | ((tinstr & 0x0700) << (16 - 8)) /* Rb */
2394 | (tinstr & 0x00FF); /* mask8 */
c906108c 2395 break;
dfcd3bfb
JM
2396 case 26: /* Bcc */
2397 case 27: /* Bcc/SWI */
c906108c 2398 if ((tinstr & 0x0F00) == 0x0F00)
dfcd3bfb
JM
2399 {
2400 /* Format 17 : SWI */
2401 *ainstr = 0xEF000000;
c906108c
SS
2402 /* Breakpoint must be handled specially. */
2403 if ((tinstr & 0x00FF) == 0x18)
2404 *ainstr |= ((tinstr & 0x00FF) << 16);
7a292a7a
SS
2405 /* New breakpoint value. See gdb/arm-tdep.c */
2406 else if ((tinstr & 0x00FF) == 0xFE)
dfcd3bfb 2407 *ainstr |= SWI_Breakpoint;
c906108c
SS
2408 else
2409 *ainstr |= (tinstr & 0x00FF);
dfcd3bfb 2410 }
c906108c 2411 else if ((tinstr & 0x0F00) != 0x0E00)
dfcd3bfb
JM
2412 {
2413 /* Format 16 */
2414 int doit = FALSE;
2415 /* TODO: Since we are doing a switch here, we could just add
2416 the SWI and undefined instruction checks into this
2417 switch to same on a couple of conditionals: */
2418 switch ((tinstr & 0x0F00) >> 8)
2419 {
2420 case EQ:
2421 doit = ZFLAG;
2422 break;
2423 case NE:
2424 doit = !ZFLAG;
2425 break;
2426 case VS:
2427 doit = VFLAG;
2428 break;
2429 case VC:
2430 doit = !VFLAG;
2431 break;
2432 case MI:
2433 doit = NFLAG;
2434 break;
2435 case PL:
2436 doit = !NFLAG;
2437 break;
2438 case CS:
2439 doit = CFLAG;
2440 break;
2441 case CC:
2442 doit = !CFLAG;
2443 break;
2444 case HI:
2445 doit = (CFLAG && !ZFLAG);
2446 break;
2447 case LS:
2448 doit = (!CFLAG || ZFLAG);
2449 break;
2450 case GE:
2451 doit = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
2452 break;
2453 case LT:
2454 doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
2455 break;
2456 case GT:
2457 doit = ((!NFLAG && !VFLAG && !ZFLAG)
2458 || (NFLAG && VFLAG && !ZFLAG));
2459 break;
2460 case LE:
2461 doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
2462 break;
2463 }
2464 if (doit)
2465 {
2466 state->Reg[15] = (pc + 4
2467 + (((tinstr & 0x7F) << 1)
2468 | ((tinstr & (1 << 7)) ? 0xFFFFFF00 : 0)));
2469 FLUSHPIPE;
2470 }
2471 valid = t_branch;
2472 }
546aee7a
NC
2473 else
2474 /* UNDEFINED : cc=1110(AL) uses different format. */
73cb0348 2475 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
c906108c 2476 break;
dfcd3bfb 2477 case 28: /* B */
c906108c 2478 /* Format 18 */
dfcd3bfb
JM
2479 state->Reg[15] = (pc + 4
2480 + (((tinstr & 0x3FF) << 1)
2481 | ((tinstr & (1 << 10)) ? 0xFFFFF800 : 0)));
c906108c
SS
2482 FLUSHPIPE;
2483 valid = t_branch;
2484 break;
dfcd3bfb 2485 case 29: /* UNDEFINED */
73cb0348
NC
2486 if (state->is_v6)
2487 {
2488 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2489 break;
2490 }
2491
f1129fb8
NC
2492 if (state->is_v5)
2493 {
2494 if (tinstr & 1)
2495 {
73cb0348 2496 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
f1129fb8
NC
2497 break;
2498 }
2499 /* Drop through. */
73cb0348 2500
f1129fb8
NC
2501 /* Format 19 */
2502 /* There is no single ARM instruction equivalent for this
2503 instruction. Also, it should only ever be matched with the
2504 fmt19 "BL/BLX instruction 1" instruction. However, we do
2505 allow the simulation of it on its own, with undefined results
2506 if r14 is not suitably initialised. */
2507 {
2508 ARMword tmp = (pc + 2);
7378e198 2509
f1129fb8
NC
2510 state->Reg[15] = ((state->Reg[14] + ((tinstr & 0x07FF) << 1))
2511 & 0xFFFFFFFC);
2512 CLEART;
2513 state->Reg[14] = (tmp | 1);
2514 valid = t_branch;
2515 FLUSHPIPE;
8d052926
NC
2516 if (trace_funcs)
2517 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
f1129fb8
NC
2518 break;
2519 }
2520 }
546aee7a 2521
73cb0348 2522 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
c906108c 2523 break;
546aee7a 2524
dfcd3bfb 2525 case 30: /* BL instruction 1 */
73cb0348
NC
2526 if (state->is_v6)
2527 {
2528 handle_T2_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2529 break;
2530 }
2531
c906108c
SS
2532 /* Format 19 */
2533 /* There is no single ARM instruction equivalent for this Thumb
2534 instruction. To keep the simulation simple (from the user
2535 perspective) we check if the following instruction is the
2536 second half of this BL, and if it is we simulate it
dfcd3bfb 2537 immediately. */
c906108c 2538 state->Reg[14] = state->Reg[15] \
7378e198
NC
2539 + (((tinstr & 0x07FF) << 12) \
2540 | ((tinstr & (1 << 10)) ? 0xFF800000 : 0));
2541
dfcd3bfb
JM
2542 valid = t_branch; /* in-case we don't have the 2nd half */
2543 tinstr = next_instr; /* move the instruction down */
4f3c3dbb 2544 pc += 2; /* point the pc at the 2nd half */
c906108c 2545 if (((tinstr & 0xF800) >> 11) != 31)
f1129fb8
NC
2546 {
2547 if (((tinstr & 0xF800) >> 11) == 29)
2548 {
4f3c3dbb
NC
2549 ARMword tmp = (pc + 2);
2550
4f3c3dbb 2551 state->Reg[15] = ((state->Reg[14]
2984e114 2552 + ((tinstr & 0x07FE) << 1))
4f3c3dbb
NC
2553 & 0xFFFFFFFC);
2554 CLEART;
2555 state->Reg[14] = (tmp | 1);
2556 valid = t_branch;
2557 FLUSHPIPE;
f1129fb8 2558 }
4f3c3dbb
NC
2559 else
2560 /* Exit, since not correct instruction. */
2561 pc -= 2;
2562 break;
f1129fb8 2563 }
c906108c 2564 /* else we fall through to process the second half of the BL */
2984e114 2565 pc += 2; /* point the pc at the 2nd half */
dfcd3bfb 2566 case 31: /* BL instruction 2 */
73cb0348
NC
2567 if (state->is_v6)
2568 {
2569 handle_T2_insn (state, old_tinstr, next_instr, pc, ainstr, & valid);
2570 break;
2571 }
2572
c906108c
SS
2573 /* Format 19 */
2574 /* There is no single ARM instruction equivalent for this
2575 instruction. Also, it should only ever be matched with the
2576 fmt19 "BL instruction 1" instruction. However, we do allow
2577 the simulation of it on its own, with undefined results if
dfcd3bfb 2578 r14 is not suitably initialised. */
c906108c 2579 {
7378e198
NC
2580 ARMword tmp = pc;
2581
dfcd3bfb
JM
2582 state->Reg[15] = (state->Reg[14] + ((tinstr & 0x07FF) << 1));
2583 state->Reg[14] = (tmp | 1);
2584 valid = t_branch;
2585 FLUSHPIPE;
c906108c
SS
2586 }
2587 break;
2588 }
2589
8d052926
NC
2590 if (trace && valid != t_decoded)
2591 fprintf (stderr, "\n");
2592
c906108c
SS
2593 return valid;
2594}