1 /* thumbemu.c -- Thumb instruction emulation.
2 Copyright (C) 1996, Cygnus Software Technologies Ltd.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
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.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>. */
17 /* We can provide simple Thumb simulation by decoding the Thumb
18 instruction into its corresponding ARM instruction, and using the
19 existing ARM simulator. */
21 #ifndef MODET /* required for the Thumb instruction support */
23 #error "MODET needs to be defined for the Thumb world to work"
33 #define tBIT(n) ( (ARMword)(tinstr >> (n)) & 1)
34 #define tBITS(m,n) ( (ARMword)(tinstr << (31 - (n))) >> ((31 - (n)) + (m)) )
36 #define ntBIT(n) ( (ARMword)(next_instr >> (n)) & 1)
37 #define ntBITS(m,n) ( (ARMword)(next_instr << (31 - (n))) >> ((31 - (n)) + (m)) )
40 test_cond (int cond
, ARMul_State
* state
)
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
;
61 default: return FALSE
;
65 static ARMword skipping_32bit_thumb
= 0;
67 static int IT_block_cond
= AL
;
68 static ARMword IT_block_mask
= 0;
69 static int IT_block_first
= FALSE
;
72 handle_IT_block (ARMul_State
* state
,
77 IT_block_mask
= tBITS (0, 3);
79 if (IT_block_mask
== 0)
83 IT_block_cond
= tBITS (4, 7);
84 IT_block_first
= TRUE
;
90 return IT_block_mask
!= 0;
94 IT_block_allow (ARMul_State
* state
)
98 if (IT_block_mask
== 0)
101 cond
= IT_block_cond
;
104 IT_block_first
= FALSE
;
107 if ((IT_block_mask
& 8) == 0)
112 IT_block_mask
&= 0xF;
115 if (IT_block_mask
== 0x8)
118 return test_cond (cond
, state
);
122 ThumbExpandImm (ARMword tinstr
)
126 if (tBITS (10, 11) == 0)
128 switch (tBITS (8, 9))
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;
139 int ror
= tBITS (7, 11);
141 val
= (1 << 7) | tBITS (0, 6);
142 val
= (val
>> ror
) | (val
<< (32 - ror
));
148 #define tASSERT(truth) \
153 fprintf (stderr, "unhandled T2 insn %04x|%04x detected at thumbemu.c:%d\n", \
154 tinstr, next_instr, __LINE__); \
161 /* Attempt to emulate a 32-bit ARMv7 Thumb instruction.
162 Stores t_branch into PVALUE upon success or t_undefined otherwise. */
165 handle_T2_insn (ARMul_State
* state
,
172 * pvalid
= t_undefined
;
178 fprintf (stderr
, "|%04x ", next_instr
);
180 if (tBITS (11, 15) == 0x1E && ntBIT (15) == 1)
186 switch ((ntBIT (14) << 1) | ntBIT (12))
190 ARMword cond
= tBITS (6, 9);
196 tASSERT (cond
!= AL
&& cond
!= NV
);
197 if (! test_cond (cond
, state
))
201 imm11
= ntBITS (0, 10);
205 simm32
= (J1
<< 19) | (J2
<< 18) | (imm6
<< 12) | (imm11
<< 1);
207 simm32
|= -(1 << 20);
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;
218 simm32
= (I1
<< 23) | (I2
<< 22) | (imm10
<< 12) | (imm11
<< 1);
220 simm32
|= -(1 << 24);
224 case 2: /* BLX <label> */
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;
231 simm32
= (I1
<< 23) | (I2
<< 22) | (imm10h
<< 12) | (imm10l
<< 2);
233 simm32
|= -(1 << 24);
236 state
->Reg
[14] = (pc
+ 4) | 1;
240 case 3: /* BL <label> */
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;
247 simm32
= (I1
<< 23) | (I2
<< 22) | (imm10
<< 12) | (imm11
<< 1);
249 simm32
|= -(1 << 24);
250 state
->Reg
[14] = (pc
+ 4) | 1;
255 state
->Reg
[15] = (pc
+ 4 + simm32
);
258 fprintf (stderr
, " pc changed to %x\n", state
->Reg
[15]);
262 switch (tBITS (5,12))
264 case 0x29: // TST<c>.W <Rn>,<Rm>{,<shift>}
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);
271 tASSERT (ntBITS (8, 11) == 0xF);
273 * ainstr
= 0xE1100000;
274 * ainstr
|= (Rn
<< 16);
276 * ainstr
|= (type
<< 5);
277 * ainstr
|= (imm5
<< 7);
278 * pvalid
= t_decoded
;
283 if (tBIT (4) && ntBITS (5, 15) == 0x780)
286 ARMword Rn
= tBITS (0, 3);
287 ARMword Rm
= ntBITS (0, 3);
288 ARMword address
, dest
;
293 address
= state
->Reg
[Rn
] + state
->Reg
[Rm
] * 2;
294 dest
= ARMul_LoadHalfWord (state
, address
);
299 address
= state
->Reg
[Rn
] + state
->Reg
[Rm
];
300 dest
= ARMul_LoadByte (state
, address
);
303 state
->Reg
[15] = (pc
+ 4 + dest
* 2);
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);
325 tASSERT (Rt2
== Rt
+ 1);
327 tASSERT (imm8
<= 255);
328 tASSERT (P
!= 0 || W
!= 0);
330 // Convert into an ARM A1 encoding.
333 tASSERT (tBIT (4) == 1);
335 // Ignore W even if 1.
336 * ainstr
= 0xE14F00D0;
342 * ainstr
= 0xE04000D0;
345 // STRD<c> <Rt>,<Rt2>,[<Rn>{,#+/-<imm8>}]
346 // STRD<c> <Rt>,<Rt2>,[<Rn>],#+/-<imm8>
347 // STRD<c> <Rt>,<Rt2>,[<Rn>,#+/-<imm8>]!
348 * ainstr
= 0xE04000F0;
350 * ainstr
|= (Rn
<< 16);
351 * ainstr
|= (P
<< 24);
352 * ainstr
|= (W
<< 21);
355 * ainstr
|= (U
<< 23);
356 * ainstr
|= (Rt
<< 12);
357 * ainstr
|= ((imm8
<< 4) & 0xF00);
358 * ainstr
|= (imm8
& 0xF);
359 * pvalid
= t_decoded
;
366 ARMword Rn
= tBITS (0, 3);
368 ARMword list
= (ntBIT (15) << 15) | (ntBIT (14) << 14) | ntBITS (0, 12);
371 * ainstr
= 0xE8BD0000;
374 * ainstr
= 0xE8900000;
375 * ainstr
|= (W
<< 21);
376 * ainstr
|= (Rn
<< 16);
379 * pvalid
= t_decoded
;
386 ARMword Rn
= tBITS (0, 3);
388 ARMword list
= (ntBIT (14) << 14) | ntBITS (0, 12);
391 * ainstr
= 0xE92D0000;
394 * ainstr
= 0xE9000000;
395 * ainstr
|= (W
<< 21);
396 * ainstr
|= (Rn
<< 16);
399 * pvalid
= t_decoded
;
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);
411 tASSERT (ntBIT (15) == 0);
415 tASSERT (tBIT (4) == 1);
417 // TST<c>.W <Rn>,<Rm>{,<shift>}
418 * ainstr
= 0xE1100000;
422 // AND{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
425 * ainstr
= 0xE0000000;
429 * ainstr
|= (S
<< 20);
432 * ainstr
|= (Rn
<< 16);
433 * ainstr
|= (imm5
<< 7);
434 * ainstr
|= (type
<< 5);
435 * ainstr
|= (Rm
<< 0);
436 * pvalid
= t_decoded
;
440 case 0x51: // BIC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
442 ARMword Rn
= tBITS (0, 3);
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);
449 tASSERT (ntBIT (15) == 0);
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
;
464 ARMword Rn
= tBITS (0, 3);
465 ARMword Rd
= ntBITS (8, 11);
466 ARMword Rm
= ntBITS (0, 3);
468 ARMword imm5
= (ntBITS (12, 14) << 2) | ntBITS (6, 7);
469 ARMword type
= ntBITS (4, 5);
478 tASSERT (ntBIT (15) == 0);
480 switch (ntBITS (4, 5))
483 // LSL{S}<c>.W <Rd>,<Rm>,#<imm5>
484 * ainstr
= 0xE1A00000;
487 // LSR{S}<c>.W <Rd>,<Rm>,#<imm>
488 * ainstr
= 0xE1A00020;
491 // ASR{S}<c>.W <Rd>,<Rm>,#<imm>
492 * ainstr
= 0xE1A00040;
495 // ROR{S}<c> <Rd>,<Rm>,#<imm>
496 * ainstr
= 0xE1A00060;
505 // ORR{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
506 * ainstr
= 0xE1800000;
507 * ainstr
|= (Rn
<< 16);
508 * ainstr
|= (type
<< 5);
511 * ainstr
|= (Rd
<< 12);
512 * ainstr
|= (S
<< 20);
513 * ainstr
|= (imm5
<< 7);
514 * ainstr
|= (Rm
<< 0);
515 * pvalid
= t_decoded
;
519 case 0x53: // MVN{S}<c>.W <Rd>,<Rm>{,<shift>}
521 ARMword Rd
= ntBITS (8, 11);
522 ARMword Rm
= ntBITS (0, 3);
524 ARMword imm5
= (ntBITS (12, 14) << 2) | ntBITS (6, 7);
525 ARMword type
= ntBITS (4, 5);
527 tASSERT (ntBIT (15) == 0);
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
;
544 ARMword Rn
= tBITS (0, 3);
545 ARMword Rd
= ntBITS (8, 11);
546 ARMword Rm
= ntBITS (0, 3);
548 ARMword imm5
= (ntBITS (12, 14) << 2) | ntBITS (6, 7);
549 ARMword type
= ntBITS (4, 5);
553 // TEQ<c> <Rn>,<Rm>{,<shift>}
554 tASSERT (ntBIT (15) == 0);
556 * ainstr
= 0xE1300000;
560 // EOR{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
564 * ainstr
= 0xE0200000;
565 * ainstr
|= (S
<< 20);
566 * ainstr
|= (Rd
<< 8);
569 * ainstr
|= (Rn
<< 16);
570 * ainstr
|= (imm5
<< 7);
571 * ainstr
|= (type
<< 5);
572 * ainstr
|= (Rm
<< 0);
573 * pvalid
= t_decoded
;
577 case 0x58: // ADD{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
579 ARMword Rn
= tBITS (0, 3);
580 ARMword Rd
= ntBITS (8, 11);
581 ARMword Rm
= ntBITS (0, 3);
583 ARMword imm5
= (ntBITS (12, 14) << 2) | ntBITS (6, 7);
584 ARMword type
= ntBITS (4, 5);
586 tASSERT (! (Rd
== 15 && S
));
591 * ainstr
= 0xE0800000;
592 * ainstr
|= (S
<< 20);
593 * ainstr
|= (Rn
<< 16);
594 * ainstr
|= (Rd
<< 12);
595 * ainstr
|= (imm5
<< 7);
596 * ainstr
|= (type
<< 5);
598 * pvalid
= t_decoded
;
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
;
615 case 0x5B: // SBC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
617 ARMword Rn
= tBITS (0, 3);
618 ARMword Rd
= ntBITS (8, 11);
619 ARMword Rm
= ntBITS (0, 3);
621 ARMword imm5
= (ntBITS (12, 14) << 2) | ntBITS (6, 7);
622 ARMword type
= ntBITS (4, 5);
624 tASSERT (ntBIT (15) == 0);
629 * ainstr
= 0xE0C00000;
630 * ainstr
|= (S
<< 20);
631 * ainstr
|= (Rn
<< 16);
632 * ainstr
|= (Rd
<< 12);
633 * ainstr
|= (imm5
<< 7);
634 * ainstr
|= (type
<< 5);
636 * pvalid
= t_decoded
;
640 case 0x5E: // RSB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>}
641 case 0x5D: // SUB{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
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);
650 tASSERT (ntBIT(15) == 0);
654 // CMP<c>.W <Rn>, <Rm> {,<shift>}
655 * ainstr
= 0xE1500000;
659 * ainstr
= 0xE0400000;
661 * ainstr
= 0xE0600000;
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
;
674 tASSERT (tBITS (0, 15) == 0xF3AF);
675 tASSERT (ntBITS (0, 15) == 0x8000);
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);
688 imm12
= ThumbExpandImm (imm12
);
689 val
= state
->Reg
[Rn
] & imm12
;
693 // TST<c> <Rn>,#<const>
698 // AND{S}<c> <Rd>,<Rn>,#<const>
702 state
->Reg
[Rd
] = val
;
706 ARMul_NegZero (state
, val
);
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);
719 tASSERT (ntBIT (15) == 0);
721 imm8
= ThumbExpandImm (imm8
);
722 state
->Reg
[Rd
] = state
->Reg
[Rn
] & ~ imm8
;
724 if (S
&& ! in_IT_block ())
725 ARMul_NegZero (state
, state
->Reg
[Rd
]);
726 * pvalid
= t_resolved
;
731 case 0x82: // MOV{S}<c>.W <Rd>,#<const>
733 ARMword val
= (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
734 ARMword Rd
= ntBITS (8, 11);
736 val
= ThumbExpandImm (val
);
737 state
->Reg
[Rd
] = val
;
739 if (tBIT (4) && ! in_IT_block ())
740 ARMul_NegZero (state
, val
);
741 /* Indicate that the instruction has been processed. */
747 case 0x83: // MVN{S}<c> <Rd>,#<const>
749 ARMword val
= (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
750 ARMword Rd
= ntBITS (8, 11);
752 val
= ThumbExpandImm (val
);
754 state
->Reg
[Rd
] = val
;
756 if (tBIT (4) && ! in_IT_block ())
757 ARMul_NegZero (state
, val
);
758 * pvalid
= t_resolved
;
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));
771 imm12
= ThumbExpandImm (imm12
);
773 result
= state
->Reg
[Rn
] ^ imm12
;
776 // TEQ<c> <Rn>,#<const>
780 // EOR{S}<c> <Rd>,<Rn>,#<const>
781 state
->Reg
[Rd
] = result
;
788 ARMul_NegZero (state
, result
);
789 * pvalid
= t_resolved
;
796 ARMword Rd
= ntBITS (8, 11);
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
;
806 // CMN<c> <Rn>,#<const>
811 // ADD{S}<c>.W <Rd>,<Rn>,#<const>
817 state
->Reg
[Rd
] = res
;
822 ARMul_NegZero (state
, res
);
824 if ((lhs
| rhs
) >> 30)
826 /* Possible C,V,N to set. */
827 ARMul_AddCarry (state
, lhs
, rhs
, res
);
828 ARMul_AddOverflow (state
, lhs
, rhs
, res
);
842 case 0x8A: // ADC{S}<c> <Rd>,<Rn>,#<const>
844 ARMword Rn
= tBITS (0, 3);
845 ARMword Rd
= ntBITS (8, 11);
847 ARMword imm12
= (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
848 ARMword lhs
= state
->Reg
[Rn
];
849 ARMword rhs
= ThumbExpandImm (imm12
);
852 tASSERT (ntBIT (15) == 0);
858 state
->Reg
[Rd
] = res
;
865 ARMul_NegZero (state
, res
);
867 if ((lhs
>= rhs
) || ((rhs
| lhs
) >> 31))
869 ARMul_AddCarry (state
, lhs
, rhs
, res
);
870 ARMul_AddOverflow (state
, lhs
, rhs
, res
);
884 case 0x8B: // SBC{S}<c> <Rd>,<Rn>,#<const>
886 ARMword Rn
= tBITS (0, 3);
887 ARMword Rd
= ntBITS (8, 11);
889 ARMword imm12
= (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
890 ARMword lhs
= state
->Reg
[Rn
];
891 ARMword rhs
= ThumbExpandImm (imm12
);
894 tASSERT (ntBIT (15) == 0);
900 state
->Reg
[Rd
] = res
;
907 ARMul_NegZero (state
, res
);
909 if ((lhs
>= rhs
) || ((rhs
| lhs
) >> 31))
911 ARMul_SubCarry (state
, lhs
, rhs
, res
);
912 ARMul_SubOverflow (state
, lhs
, rhs
, res
);
928 ARMword Rn
= tBITS (0, 3);
929 ARMword Rd
= ntBITS (8, 11);
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
;
938 // CMP<c>.W <Rn>,#<const>
943 // SUB{S}<c>.W <Rd>,<Rn>,#<const>
947 state
->Reg
[Rd
] = res
;
952 ARMul_NegZero (state
, res
);
954 if ((lhs
>= rhs
) || ((rhs
| lhs
) >> 31))
956 ARMul_SubCarry (state
, lhs
, rhs
, res
);
957 ARMul_SubOverflow (state
, lhs
, rhs
, res
);
971 case 0x8E: // RSB{S}<c>.W <Rd>,<Rn>,#<const>
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);
978 ARMword rhs
= state
->Reg
[Rn
];
979 ARMword res
= lhs
- rhs
;
981 tASSERT (ntBIT (15) == 0);
983 state
->Reg
[Rd
] = res
;
987 ARMul_NegZero (state
, res
);
989 if ((lhs
>= rhs
) || ((rhs
| lhs
) >> 31))
991 ARMul_SubCarry (state
, lhs
, rhs
, res
);
992 ARMul_SubOverflow (state
, lhs
, rhs
, res
);
1001 * pvalid
= t_branch
;
1006 case 0x90: // ADDW<c> <Rd>,<Rn>,#<imm12>
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);
1012 tASSERT (tBIT (4) == 0);
1013 tASSERT (ntBIT (15) == 0);
1015 state
->Reg
[Rd
] = state
->Reg
[Rn
] + imm12
;
1016 * pvalid
= t_branch
;
1021 case 0x92: // MOVW<c> <Rd>,#<imm16>
1023 ARMword Rd
= ntBITS (8, 11);
1024 ARMword imm
= (tBITS (0, 3) << 12) | (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1026 state
->Reg
[Rd
] = imm
;
1027 /* Indicate that the instruction has been processed. */
1028 * pvalid
= t_branch
;
1033 case 0x95:// SUBW<c> <Rd>,<Rn>,#<imm12>
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);
1039 tASSERT (tBIT (4) == 0);
1040 tASSERT (ntBIT (15) == 0);
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
;
1047 * pvalid
= t_resolved
;
1052 case 0x96: // MOVT<c> <Rd>,#<imm16>
1054 ARMword Rd
= ntBITS (8, 11);
1055 ARMword imm
= (tBITS (0, 3) << 12) | (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1057 state
->Reg
[Rd
] &= 0xFFFF;
1058 state
->Reg
[Rd
] |= (imm
<< 16);
1059 * pvalid
= t_resolved
;
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
;
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);
1081 ARMword mask
= -(1 << lsbit
);
1083 tASSERT (tBIT (4) == 0);
1084 tASSERT (ntBIT (15) == 0);
1085 tASSERT (ntBIT (5) == 0);
1087 mask
&= ((1 << (msbit
+ 1)) - 1);
1093 // BFC<c> <Rd>,#<lsb>,#<width>
1094 state
->Reg
[Rd
] &= ~ mask
;
1098 // BFI<c> <Rd>,<Rn>,#<lsb>,#<width>
1099 ARMword val
= state
->Reg
[Rn
] & (mask
>> lsbit
);
1102 state
->Reg
[Rd
] &= ~ mask
;
1103 state
->Reg
[Rd
] |= val
;
1106 * pvalid
= t_resolved
;
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
;
1125 ARMword Rn
= tBITS (0, 3);
1126 ARMword Rt
= ntBITS (12, 15);
1134 /* LDRB<c> <Rt>,<label> => 1111 1000 U001 1111 */
1135 * ainstr
= 0xE55F0000;
1136 * ainstr
|= (tBIT (7) << 23);
1137 * ainstr
|= ntBITS (0, 11);
1141 /* LDRB<c>.W <Rt>,[<Rn>{,#<imm12>}] => 1111 1000 1001 rrrr */
1142 * ainstr
= 0xE5D00000;
1143 * ainstr
|= ntBITS (0, 11);
1145 else if (ntBIT (11) == 0)
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);
1158 tASSERT (! (Rt
== 15 && P
&& !U
&& !W
));
1159 tASSERT (! (P
&& U
&& !W
));
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);
1175 // STRB<c>.W <Rt>,[<Rn>,#<imm12>]
1176 ARMword imm12
= ntBITS (0, 11);
1178 ARMul_StoreByte (state
, state
->Reg
[Rn
] + imm12
, state
->Reg
[Rt
]);
1179 * pvalid
= t_branch
;
1182 else if (ntBIT (11))
1184 // STRB<c> <Rt>,[<Rn>,#-<imm8>]
1185 // STRB<c> <Rt>,[<Rn>],#+/-<imm8>
1186 // STRB<c> <Rt>,[<Rn>,#+/-<imm8>]!
1190 ARMword imm8
= ntBITS (0, 7);
1192 tASSERT (! (P
&& U
&& !W
));
1193 tASSERT (! (Rn
== 13 && P
&& !U
&& W
&& imm8
== 4));
1195 * ainstr
= 0xE4000000;
1196 * ainstr
|= (P
<< 24);
1197 * ainstr
|= (U
<< 23);
1198 * ainstr
|= (W
<< 21);
1203 // STRB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1204 tASSERT (ntBITS (6, 11) == 0);
1206 * ainstr
= 0xE7C00000;
1207 * ainstr
|= (ntBITS (4, 5) << 7);
1208 * ainstr
|= ntBITS (0, 3);
1212 * ainstr
|= (Rn
<< 16);
1213 * ainstr
|= (Rt
<< 12);
1214 * pvalid
= t_decoded
;
1218 case 0xC2: // LDR, STR
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);
1233 // LDR<c>.W <Rt>,<label>
1234 * ainstr
= 0xE51F0000;
1235 * ainstr
|= ntBITS (0, 11);
1237 else if (ntBIT (11))
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)));
1243 // LDR<c> <Rt>,[<Rn>,#-<imm8>]
1244 // LDR<c> <Rt>,[<Rn>],#+/-<imm8>
1245 // LDR<c> <Rt>,[<Rn>,#+/-<imm8>]!
1248 * ainstr
= 0xE4100000;
1249 * ainstr
|= (P
<< 24);
1250 * ainstr
|= (U
<< 23);
1251 * ainstr
|= (W
<< 21);
1256 // LDR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1258 tASSERT (ntBITS (6, 11) == 0);
1260 * ainstr
= 0xE7900000;
1261 * ainstr
|= ntBITS (4, 5) << 7;
1262 * ainstr
|= ntBITS (0, 3);
1269 tASSERT (! (P
&& U
&& ! W
));
1270 if (Rn
== 13 && P
&& !U
&& W
&& imm8
== 4)
1272 // PUSH<c>.W <register>
1273 tASSERT (ntBITS (0, 11) == 0xD04);
1274 tASSERT (tBITS (0, 4) == 0x0D);
1276 * ainstr
= 0xE92D0000;
1277 * ainstr
|= (1 << Rt
);
1283 tASSERT (! (P
&& U
&& !W
));
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);
1298 // STR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1299 tASSERT (ntBITS (6, 11) == 0);
1301 * ainstr
= 0xE7800000;
1302 * ainstr
|= ntBITS (4, 5) << 7;
1303 * ainstr
|= ntBITS (0, 3);
1307 * ainstr
|= (Rn
<< 16);
1308 * ainstr
|= (Rt
<< 12);
1309 * pvalid
= t_decoded
;
1316 ARMword Rn
= tBITS (0, 3);
1317 ARMword Rt
= ntBITS (12, 15);
1326 // LDRH<c>.W <Rt>,[<Rn>{,#<imm12>}]
1327 ARMword imm12
= ntBITS (0, 11);
1328 address
= state
->Reg
[Rn
] + imm12
;
1330 else if (ntBIT (11))
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);
1341 tASSERT (! (P
&& U
&& !W
));
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
;
1356 // LDRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1357 ARMword Rm
= ntBITS (0, 3);
1358 ARMword imm2
= ntBITS (4, 5);
1360 tASSERT (ntBITS (6, 10) == 0);
1362 address
= state
->Reg
[Rn
] + (state
->Reg
[Rm
] << imm2
);
1365 state
->Reg
[Rt
] = ARMul_LoadHalfWord (state
, address
);
1371 // STRH<c>.W <Rt>,[<Rn>{,#<imm12>}]
1372 ARMword imm12
= ntBITS (0, 11);
1374 address
= state
->Reg
[Rn
] + imm12
;
1376 else if (ntBIT (11))
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);
1386 tASSERT (! (P
&& U
&& !W
));
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
;
1401 // STRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1402 ARMword Rm
= ntBITS (0, 3);
1403 ARMword imm2
= ntBITS (4, 5);
1405 tASSERT (ntBITS (6, 10) == 0);
1407 address
= state
->Reg
[Rn
] + (state
->Reg
[Rm
] << imm2
);
1410 ARMul_StoreHalfWord (state
, address
, state
->Reg
[Rt
]);
1412 * pvalid
= t_branch
;
1416 case 0xC6: // LDR.W/STR.W
1418 ARMword Rn
= tBITS (0, 3);
1419 ARMword Rt
= ntBITS (12, 15);
1420 ARMword imm12
= ntBITS (0, 11);
1421 ARMword address
= state
->Reg
[Rn
];
1425 // LDR<c>.W <Rt>,<label>
1426 tASSERT (tBIT (4) == 1);
1427 // tASSERT (tBIT (7) == 1)
1432 state
->Reg
[Rt
] = ARMul_LoadWordN (state
, address
);
1434 ARMul_StoreWordN (state
, address
, state
->Reg
[Rt
]);
1436 * pvalid
= t_resolved
;
1443 ARMword Rt
= ntBITS (12, 15);
1444 ARMword Rn
= tBITS (0, 3);
1445 ARMword U
= tBIT (7);
1446 ARMword address
= state
->Reg
[Rn
];
1448 tASSERT (tBIT (4) == 1);
1449 tASSERT (Rt
!= 15); // PLI
1453 // LDRSB<c> <Rt>,<label>
1454 ARMword imm12
= ntBITS (0, 11);
1455 address
+= (U
? imm12
: - imm12
);
1459 // LDRSB<c> <Rt>,[<Rn>,#<imm12>]
1460 ARMword imm12
= ntBITS (0, 11);
1463 else if (ntBIT (11))
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
;
1481 // LDRSB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1482 ARMword Rm
= ntBITS (0, 3);
1483 ARMword imm2
= ntBITS (4,5);
1485 tASSERT (ntBITS (6, 11) == 0);
1487 address
+= (state
->Reg
[Rm
] << imm2
);
1490 state
->Reg
[Rt
] = ARMul_LoadByte (state
, address
);
1491 if (state
->Reg
[Rt
] & 0x80)
1492 state
->Reg
[Rt
] |= -(1 << 8);
1494 * pvalid
= t_resolved
;
1501 ARMword Rt
= ntBITS (12, 15);
1502 ARMword Rn
= tBITS (0, 3);
1503 ARMword U
= tBIT (7);
1504 ARMword address
= state
->Reg
[Rn
];
1506 tASSERT (tBIT (4) == 1);
1508 if (Rn
== 15 || U
== 1)
1510 // Rn==15 => LDRSH<c> <Rt>,<label>
1511 // Rn!=15 => LDRSH<c> <Rt>,[<Rn>,#<imm12>]
1512 ARMword imm12
= ntBITS (0, 11);
1514 address
+= (U
? imm12
: - imm12
);
1516 else if (ntBIT (11))
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
;
1534 // LDRSH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1535 ARMword Rm
= ntBITS (0, 3);
1536 ARMword imm2
= ntBITS (4,5);
1538 tASSERT (ntBITS (6, 11) == 0);
1540 address
+= (state
->Reg
[Rm
] << imm2
);
1543 state
->Reg
[Rt
] = ARMul_LoadHalfWord (state
, address
);
1544 if (state
->Reg
[Rt
] & 0x8000)
1545 state
->Reg
[Rt
] |= -(1 << 16);
1547 * pvalid
= t_branch
;
1553 ARMword Rm
= ntBITS (0, 3);
1554 ARMword Rd
= ntBITS (8, 11);
1556 tASSERT (ntBITS (12, 15) == 15);
1560 // SXTH<c>.W <Rd>,<Rm>{,<rotation>}
1561 ARMword ror
= ntBITS (4, 5) << 3;
1564 val
= state
->Reg
[Rm
];
1565 val
= (val
>> ror
) | (val
<< (32 - ror
));
1568 state
->Reg
[Rd
] = val
;
1572 // LSL{S}<c>.W <Rd>,<Rn>,<Rm>
1573 ARMword Rn
= tBITS (0, 3);
1575 tASSERT (ntBITS (4, 6) == 0);
1577 state
->Reg
[Rd
] = state
->Reg
[Rn
] << (state
->Reg
[Rm
] & 0xFF);
1579 ARMul_NegZero (state
, state
->Reg
[Rd
]);
1581 * pvalid
= t_branch
;
1585 case 0x0D1: // LSR{S}<c>.W <Rd>,<Rn>,<Rm>
1587 ARMword Rd
= ntBITS (8, 11);
1588 ARMword Rn
= tBITS (0, 3);
1589 ARMword Rm
= ntBITS (0, 3);
1591 tASSERT (ntBITS (12, 15) == 15);
1592 tASSERT (ntBITS (4, 7) == 0);
1594 state
->Reg
[Rd
] = state
->Reg
[Rn
] >> (state
->Reg
[Rm
] & 0xFF);
1596 ARMul_NegZero (state
, state
->Reg
[Rd
]);
1597 * pvalid
= t_resolved
;
1602 tASSERT (ntBITS (12, 15) == 15);
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
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
1622 * ainstr
|= (ntBITS (8, 11) << 12); // Rd
1623 * pvalid
= t_decoded
;
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
;
1640 ARMword Rn
= tBITS (0, 3);
1641 ARMword Rd
= ntBITS (8, 11);
1642 ARMword Rm
= ntBITS (0, 3);
1644 tASSERT (ntBITS (12, 15) == 15);
1646 if (ntBITS (4, 7) == 8)
1648 // REV<c>.W <Rd>,<Rm>
1649 ARMword val
= state
->Reg
[Rm
];
1655 | ((val
>> 8) & 0xFF00)
1656 | ((val
<< 8) & 0xFF0000)
1658 * pvalid
= t_resolved
;
1662 tASSERT (ntBITS (4, 7) == 4);
1665 // UADD8<c> <Rd>,<Rn>,<Rm>
1666 * ainstr
= 0xE6500F10;
1668 // UADD16<c> <Rd>,<Rn>,<Rm>
1669 * ainstr
= 0xE6500F90;
1671 * ainstr
|= (Rn
<< 16);
1672 * ainstr
|= (Rd
<< 12);
1673 * ainstr
|= (Rm
<< 0);
1674 * pvalid
= t_decoded
;
1681 ARMword Rn
= tBITS (0, 3);
1682 ARMword Rd
= ntBITS (8, 11);
1683 ARMword Rm
= ntBITS (0, 3);
1685 tASSERT (ntBITS (12, 15) == 15);
1686 tASSERT (ntBITS (4, 7) == 8);
1692 * ainstr
= 0xE16F0F10;
1696 // SEL<c> <Rd>,<Rn>,<Rm>
1697 * ainstr
= 0xE6800FB0;
1698 * ainstr
|= (Rn
<< 16);
1701 * ainstr
|= (Rd
<< 12);
1702 * ainstr
|= (Rm
<< 0);
1703 * pvalid
= t_decoded
;
1709 ARMword Rn
= tBITS (0, 3);
1710 ARMword Rm
= ntBITS (0, 3);
1711 ARMword Rd
= ntBITS (8, 11);
1712 ARMword Ra
= ntBITS (12, 15);
1716 // SMLA<x><y><c> <Rd>,<Rn>,<Rm>,<Ra>
1717 ARMword nval
= state
->Reg
[Rn
];
1718 ARMword mval
= state
->Reg
[Rm
];
1721 tASSERT (ntBITS (6, 7) == 0);
1735 res
+= state
->Reg
[Ra
];
1736 // FIXME: Test and clear/set the Q bit.
1737 state
->Reg
[Rd
] = res
;
1741 if (ntBITS (4, 7) == 1)
1743 // MLS<c> <Rd>,<Rn>,<Rm>,<Ra>
1744 state
->Reg
[Rd
] = state
->Reg
[Ra
] - (state
->Reg
[Rn
] * state
->Reg
[Rm
]);
1748 tASSERT (ntBITS (4, 7) == 0);
1751 // MUL<c> <Rd>,<Rn>,<Rm>
1752 state
->Reg
[Rd
] = state
->Reg
[Rn
] * state
->Reg
[Rm
];
1754 // MLA<c> <Rd>,<Rn>,<Rm>,<Ra>
1755 state
->Reg
[Rd
] = state
->Reg
[Rn
] * state
->Reg
[Rm
] + state
->Reg
[Ra
];
1758 * pvalid
= t_resolved
;
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
;
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
;
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
;
1796 fprintf (stderr
, "(op = %x) ", tBITS (5,12));
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;
1806 /* Attempt to emulate an ARMv6 instruction.
1807 Stores t_branch into PVALUE upon success or t_undefined otherwise. */
1810 handle_v6_thumb_insn (ARMul_State
* state
,
1819 * pvalid
= t_undefined
;
1823 if (tBITS (12, 15) == 0xB
1827 // Conditional branch forwards.
1828 ARMword Rn
= tBITS (0, 2);
1829 ARMword imm5
= tBIT (9) << 5 | tBITS (3, 7);
1833 if (state
->Reg
[Rn
] != 0)
1835 state
->Reg
[15] = (pc
+ 4 + imm5
* 2);
1841 if (state
->Reg
[Rn
] == 0)
1843 state
->Reg
[15] = (pc
+ 4 + imm5
* 2);
1847 * pvalid
= t_branch
;
1851 switch (tinstr
& 0xFFC0)
1858 ARMword Rd
= (tBIT (7) << 3) | tBITS (0, 2);
1859 ARMword Rm
= tBITS (3, 6);
1860 state
->Reg
[Rd
] += state
->Reg
[Rm
];
1864 case 0x4600: // MOV<c> <Rd>,<Rm>
1866 // instr [15, 8] = 0100 0110
1867 // instr [7] = Rd<high>
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)];
1880 handle_IT_block (state
, tinstr
, pvalid
);
1884 case 0xE880: // LDMIA
1889 case 0xE9C0: // LDRD
1898 case 0xFA80: // UADD, SEL
1899 handle_T2_insn (state
, tinstr
, next_instr
, pc
, ainstr
, pvalid
);
1902 case 0xba00: /* rev */
1904 ARMword val
= state
->Reg
[tBITS (3, 5)];
1905 state
->Reg
[tBITS (0, 2)] =
1907 | ((val
>> 8) & 0xFF00)
1908 | ((val
<< 8) & 0xFF0000)
1913 case 0xba40: /* rev16 */
1915 ARMword val
= state
->Reg
[tBITS (3, 5)];
1916 state
->Reg
[tBITS (0, 2)] = (val
>> 16) | (val
<< 16);
1920 case 0xb660: /* cpsie */
1921 case 0xb670: /* cpsid */
1922 case 0xbac0: /* revsh */
1923 case 0xb650: /* setend */
1925 printf ("Unhandled v6 thumb insn: %04x\n", tinstr
);
1926 * pvalid
= t_undefined
;
1929 case 0xb200: /* sxth */
1931 ARMword Rm
= state
->Reg
[(tinstr
& 0x38) >> 3];
1934 state
->Reg
[(tinstr
& 0x7)] = (Rm
& 0xffff) | 0xffff0000;
1936 state
->Reg
[(tinstr
& 0x7)] = Rm
& 0xffff;
1940 case 0xb240: /* sxtb */
1942 ARMword Rm
= state
->Reg
[(tinstr
& 0x38) >> 3];
1945 state
->Reg
[(tinstr
& 0x7)] = (Rm
& 0xff) | 0xffffff00;
1947 state
->Reg
[(tinstr
& 0x7)] = Rm
& 0xff;
1951 case 0xb280: /* uxth */
1953 ARMword Rm
= state
->Reg
[(tinstr
& 0x38) >> 3];
1955 state
->Reg
[(tinstr
& 0x7)] = Rm
& 0xffff;
1959 case 0xb2c0: /* uxtb */
1961 ARMword Rm
= state
->Reg
[(tinstr
& 0x38) >> 3];
1963 state
->Reg
[(tinstr
& 0x7)] = Rm
& 0xff;
1967 /* Indicate that the instruction has been processed. */
1968 * pvalid
= t_branch
;
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. */
1977 ARMul_ThumbDecode (ARMul_State
* state
,
1982 tdstate valid
= t_decoded
; /* default assumes a valid instruction */
1984 ARMword old_tinstr
= tinstr
;
1986 if (skipping_32bit_thumb
== pc
)
1988 skipping_32bit_thumb
= 0;
1991 skipping_32bit_thumb
= 0;
1993 if (state
->bigendSig
)
1995 next_instr
= tinstr
& 0xFFFF;
2000 next_instr
= tinstr
>> 16;
2004 if (! IT_block_allow (state
))
2006 if ( tBITS (11, 15) == 0x1F
2007 || tBITS (11, 15) == 0x1E
2008 || tBITS (11, 15) == 0x1D)
2011 fprintf (stderr
, "pc: %x, SKIP instr: %04x|%04x\n",
2012 pc
& ~1, tinstr
, next_instr
);
2013 skipping_32bit_thumb
= pc
+ 2;
2016 fprintf (stderr
, "pc: %x, SKIP instr: %04x\n", pc
& ~1, tinstr
);
2021 old_tinstr
= tinstr
;
2023 fprintf (stderr
, "pc: %x, Thumb instr: %x", pc
& ~1, tinstr
);
2025 #if 1 /* debugging to catch non updates */
2026 *ainstr
= 0xDEADC0DE;
2029 switch ((tinstr
& 0xF800) >> 11)
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 */
2041 case 3: /* ADD/SUB */
2046 0xE0900000, /* ADDS Rd,Rs,Rn */
2047 0xE0500000, /* SUBS Rd,Rs,Rn */
2048 0xE2900000, /* ADDS Rd,Rs,#imm3 */
2049 0xE2500000 /* SUBS Rd,Rs,#imm3 */
2051 /* It is quicker indexing into a table, than performing switch
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 */
2059 *ainstr
&= ~ (1 << 20);
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);
2071 * ainstr
= 0xE3500000; /* CMP Rd,#imm8 */
2072 * ainstr
|= tBITS (8, 10) << 16;
2073 * ainstr
|= tBITS (0, 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);
2088 case 8: /* Arithmetic and high register transfers */
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
2093 if ((tinstr
& (1 << 10)) == 0)
2100 { t_norm
, t_shift
, t_neg
, t_mul
}
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 */
2122 *ainstr
= subset
[(tinstr
& 0x03C0) >> 6].opcode
; /* base */
2130 { t_norm
, t_shift
, t_neg
, t_mul
}
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 */
2152 *ainstr
= subset
[(tinstr
& 0x03C0) >> 6].opcode
; /* base */
2155 switch (subset
[(tinstr
& 0x03C0) >> 6].otype
)
2158 *ainstr
|= ((tinstr
& 0x0007) << 16) /* Rn */
2159 | ((tinstr
& 0x0007) << 12) /* Rd */
2160 | ((tinstr
& 0x0038) >> 3); /* Rs */
2163 *ainstr
|= ((tinstr
& 0x0007) << 12) /* Rd */
2164 | ((tinstr
& 0x0007) >> 0) /* Rm */
2165 | ((tinstr
& 0x0038) << (8 - 3)); /* Rs */
2168 *ainstr
|= ((tinstr
& 0x0007) << 12) /* Rd */
2169 | ((tinstr
& 0x0038) << (16 - 3)); /* Rn */
2172 *ainstr
|= ((tinstr
& 0x0007) << 16) /* Rd */
2173 | ((tinstr
& 0x0007) << 8) /* Rs */
2174 | ((tinstr
& 0x0038) >> 3); /* Rm */
2181 ARMword Rd
= ((tinstr
& 0x0007) >> 0);
2182 ARMword Rs
= ((tinstr
& 0x0038) >> 3);
2183 if (tinstr
& (1 << 7))
2185 if (tinstr
& (1 << 6))
2187 switch ((tinstr
& 0x03C0) >> 6)
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 */
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 */
2205 case 0x9: /* MOV Rd,Hs */
2206 case 0xA: /* MOV Hd,Rs */
2207 case 0xB: /* MOV Hd,Hs */
2208 *ainstr
= 0xE1A00000 /* base */
2209 | (Rd
<< 12) /* Rd */
2210 | (Rs
<< 0); /* Rm */
2212 case 0xC: /* BX Rs */
2213 case 0xD: /* BX Hs */
2214 *ainstr
= 0xE12FFF10 /* base */
2215 | ((tinstr
& 0x0078) >> 3); /* Rd */
2217 case 0xE: /* UNDEFINED */
2218 case 0xF: /* UNDEFINED */
2221 /* BLX Rs; BLX Hs */
2222 *ainstr
= 0xE12FFF30 /* base */
2223 | ((tinstr
& 0x0078) >> 3); /* Rd */
2228 case 0x0: /* UNDEFINED */
2229 case 0x4: /* UNDEFINED */
2230 case 0x8: /* UNDEFINED */
2231 handle_v6_thumb_insn (state
, tinstr
, next_instr
, pc
, ainstr
, & valid
);
2236 case 9: /* LDR Rd,[PC,#imm8] */
2238 *ainstr
= 0xE59F0000 /* base */
2239 | ((tinstr
& 0x0700) << (12 - 8)) /* Rd */
2240 | ((tinstr
& 0x00FF) << (2 - 0)); /* off8 */
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)
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] */
2256 *ainstr
= subset
[(tinstr
& 0x0C00) >> 10] /* base */
2257 | ((tinstr
& 0x0007) << (12 - 0)) /* Rd */
2258 | ((tinstr
& 0x0038) << (16 - 3)) /* Rb */
2259 | ((tinstr
& 0x01C0) >> 6); /* Ro */
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] */
2270 *ainstr
= subset
[(tinstr
& 0x0C00) >> 10] /* base */
2271 | ((tinstr
& 0x0007) << (12 - 0)) /* Rd */
2272 | ((tinstr
& 0x0038) << (16 - 3)) /* Rb */
2273 | ((tinstr
& 0x01C0) >> 6); /* Ro */
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] */
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] */
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 */
2296 case 16: /* STRH Rd,[Rb,#imm5] */
2297 case 17: /* LDRH Rd,[Rb,#imm5] */
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 */
2307 case 18: /* STR Rd,[SP,#imm8] */
2308 case 19: /* LDR Rd,[SP,#imm8] */
2310 *ainstr
= ((tinstr
& (1 << 11)) /* base */
2311 ? 0xE59D0000 /* LDR */
2312 : 0xE58D0000) /* STR */
2313 | ((tinstr
& 0x0700) << (12 - 8)) /* Rd */
2314 | ((tinstr
& 0x00FF) << 2); /* off8 */
2316 case 20: /* ADD Rd,PC,#imm8 */
2317 case 21: /* ADD Rd,SP,#imm8 */
2319 if ((tinstr
& (1 << 11)) == 0)
2321 /* NOTE: The PC value used here should by word aligned */
2322 /* We encode shift-left-by-2 in the rotate immediate field,
2323 so no shift of off8 is needed. */
2324 *ainstr
= 0xE28F0F00 /* base */
2325 | ((tinstr
& 0x0700) << (12 - 8)) /* Rd */
2326 | (tinstr
& 0x00FF); /* off8 */
2330 /* We encode shift-left-by-2 in the rotate immediate field,
2331 so no shift of off8 is needed. */
2332 *ainstr
= 0xE28D0F00 /* base */
2333 | ((tinstr
& 0x0700) << (12 - 8)) /* Rd */
2334 | (tinstr
& 0x00FF); /* off8 */
2339 switch (tinstr
& 0x0F00)
2343 /* NOTE: The instruction contains a shift left of 2
2344 equivalent (implemented as ROR #30): */
2345 *ainstr
= ((tinstr
& (1 << 7)) /* base */
2346 ? 0xE24DDF00 /* SUB */
2347 : 0xE28DDF00) /* ADD */
2348 | (tinstr
& 0x007F); /* off7 */
2351 /* Format 14 - Push */
2352 * ainstr
= 0xE92D0000 | (tinstr
& 0x00FF);
2355 /* Format 14 - Push + LR */
2356 * ainstr
= 0xE92D4000 | (tinstr
& 0x00FF);
2359 /* Format 14 - Pop */
2360 * ainstr
= 0xE8BD0000 | (tinstr
& 0x00FF);
2363 /* Format 14 - Pop + PC */
2364 * ainstr
= 0xE8BD8000 | (tinstr
& 0x00FF);
2369 /* This is normally an undefined instruction. The v5t architecture
2370 defines this particular pattern as a BKPT instruction, for
2371 hardware assisted debugging. We map onto the arm BKPT
2374 // Map to the SVC instruction instead of the BKPT instruction.
2375 * ainstr
= 0xEF000000 | tBITS (0, 7);
2377 * ainstr
= 0xE1200070 | ((tinstr
& 0xf0) << 4) | (tinstr
& 0xf);
2382 /* Everything else is an undefined instruction. */
2383 handle_v6_thumb_insn (state
, tinstr
, next_instr
, pc
, ainstr
, & valid
);
2387 case 24: /* STMIA */
2388 case 25: /* LDMIA */
2390 *ainstr
= ((tinstr
& (1 << 11)) /* base */
2391 ? 0xE8B00000 /* LDMIA */
2392 : 0xE8A00000) /* STMIA */
2393 | ((tinstr
& 0x0700) << (16 - 8)) /* Rb */
2394 | (tinstr
& 0x00FF); /* mask8 */
2397 case 27: /* Bcc/SWI */
2398 if ((tinstr
& 0x0F00) == 0x0F00)
2400 /* Format 17 : SWI */
2401 *ainstr
= 0xEF000000;
2402 /* Breakpoint must be handled specially. */
2403 if ((tinstr
& 0x00FF) == 0x18)
2404 *ainstr
|= ((tinstr
& 0x00FF) << 16);
2405 /* New breakpoint value. See gdb/arm-tdep.c */
2406 else if ((tinstr
& 0x00FF) == 0xFE)
2407 *ainstr
|= SWI_Breakpoint
;
2409 *ainstr
|= (tinstr
& 0x00FF);
2411 else if ((tinstr
& 0x0F00) != 0x0E00)
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)
2445 doit
= (CFLAG
&& !ZFLAG
);
2448 doit
= (!CFLAG
|| ZFLAG
);
2451 doit
= ((!NFLAG
&& !VFLAG
) || (NFLAG
&& VFLAG
));
2454 doit
= ((NFLAG
&& !VFLAG
) || (!NFLAG
&& VFLAG
));
2457 doit
= ((!NFLAG
&& !VFLAG
&& !ZFLAG
)
2458 || (NFLAG
&& VFLAG
&& !ZFLAG
));
2461 doit
= ((NFLAG
&& !VFLAG
) || (!NFLAG
&& VFLAG
)) || ZFLAG
;
2466 state
->Reg
[15] = (pc
+ 4
2467 + (((tinstr
& 0x7F) << 1)
2468 | ((tinstr
& (1 << 7)) ? 0xFFFFFF00 : 0)));
2474 /* UNDEFINED : cc=1110(AL) uses different format. */
2475 handle_v6_thumb_insn (state
, tinstr
, next_instr
, pc
, ainstr
, & valid
);
2479 state
->Reg
[15] = (pc
+ 4
2480 + (((tinstr
& 0x3FF) << 1)
2481 | ((tinstr
& (1 << 10)) ? 0xFFFFF800 : 0)));
2485 case 29: /* UNDEFINED */
2488 handle_v6_thumb_insn (state
, tinstr
, next_instr
, pc
, ainstr
, & valid
);
2496 handle_v6_thumb_insn (state
, tinstr
, next_instr
, pc
, ainstr
, & valid
);
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. */
2508 ARMword tmp
= (pc
+ 2);
2510 state
->Reg
[15] = ((state
->Reg
[14] + ((tinstr
& 0x07FF) << 1))
2513 state
->Reg
[14] = (tmp
| 1);
2517 fprintf (stderr
, " pc changed to %x\n", state
->Reg
[15]);
2522 handle_v6_thumb_insn (state
, tinstr
, next_instr
, pc
, ainstr
, & valid
);
2525 case 30: /* BL instruction 1 */
2528 handle_T2_insn (state
, tinstr
, next_instr
, pc
, ainstr
, & valid
);
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
2538 state
->Reg
[14] = state
->Reg
[15] \
2539 + (((tinstr
& 0x07FF) << 12) \
2540 | ((tinstr
& (1 << 10)) ? 0xFF800000 : 0));
2542 valid
= t_branch
; /* in-case we don't have the 2nd half */
2543 tinstr
= next_instr
; /* move the instruction down */
2544 pc
+= 2; /* point the pc at the 2nd half */
2545 if (((tinstr
& 0xF800) >> 11) != 31)
2547 if (((tinstr
& 0xF800) >> 11) == 29)
2549 ARMword tmp
= (pc
+ 2);
2551 state
->Reg
[15] = ((state
->Reg
[14]
2552 + ((tinstr
& 0x07FE) << 1))
2555 state
->Reg
[14] = (tmp
| 1);
2560 /* Exit, since not correct instruction. */
2564 /* else we fall through to process the second half of the BL */
2565 pc
+= 2; /* point the pc at the 2nd half */
2566 case 31: /* BL instruction 2 */
2569 handle_T2_insn (state
, old_tinstr
, next_instr
, pc
, ainstr
, & valid
);
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
2578 r14 is not suitably initialised. */
2582 state
->Reg
[15] = (state
->Reg
[14] + ((tinstr
& 0x07FF) << 1));
2583 state
->Reg
[14] = (tmp
| 1);
2590 if (trace
&& valid
!= t_decoded
)
2591 fprintf (stderr
, "\n");