[src/erc32] Use ncurses instead of termcap on Cygwin too
[binutils-gdb.git] / sim / arm / thumbemu.c
blob72929c76b524803eadb49493f3875d4b1404218a
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 */
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
29 #include "armdefs.h"
30 #include "armemu.h"
31 #include "armos.h"
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)) )
39 static int
40 test_cond (int cond, ARMul_State * state)
42 switch (cond)
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;
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;
71 static void
72 handle_IT_block (ARMul_State * state,
73 ARMword tinstr,
74 tdstate * pvalid)
76 * pvalid = t_branch;
77 IT_block_mask = tBITS (0, 3);
79 if (IT_block_mask == 0)
80 // NOP or a HINT.
81 return;
83 IT_block_cond = tBITS (4, 7);
84 IT_block_first = TRUE;
87 static int
88 in_IT_block (void)
90 return IT_block_mask != 0;
93 static int
94 IT_block_allow (ARMul_State * state)
96 int cond;
98 if (IT_block_mask == 0)
99 return TRUE;
101 cond = IT_block_cond;
103 if (IT_block_first)
104 IT_block_first = FALSE;
105 else
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;
115 if (IT_block_mask == 0x8)
116 IT_block_mask = 0;
118 return test_cond (cond, state);
121 static ARMword
122 ThumbExpandImm (ARMword tinstr)
124 ARMword val;
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;
134 default: val = 0;
137 else
139 int ror = tBITS (7, 11);
141 val = (1 << 7) | tBITS (0, 6);
142 val = (val >> ror) | (val << (32 - ror));
145 return val;
148 #define tASSERT(truth) \
149 do \
151 if (! (truth)) \
153 fprintf (stderr, "unhandled T2 insn %04x|%04x detected at thumbemu.c:%d\n", \
154 tinstr, next_instr, __LINE__); \
155 return ; \
158 while (0)
161 /* Attempt to emulate a 32-bit ARMv7 Thumb instruction.
162 Stores t_branch into PVALUE upon success or t_undefined otherwise. */
164 static void
165 handle_T2_insn (ARMul_State * state,
166 ARMword tinstr,
167 ARMword next_instr,
168 ARMword pc,
169 ARMword * ainstr,
170 tdstate * pvalid)
172 * pvalid = t_undefined;
174 if (! state->is_v6)
175 return;
177 if (trace)
178 fprintf (stderr, "|%04x ", next_instr);
180 if (tBITS (11, 15) == 0x1E && ntBIT (15) == 1)
182 ARMsword simm32 = 0;
183 int S = tBIT (10);
185 * pvalid = t_branch;
186 switch ((ntBIT (14) << 1) | ntBIT (12))
188 case 0: /* B<c>.W */
190 ARMword cond = tBITS (6, 9);
191 ARMword imm6;
192 ARMword imm11;
193 ARMword J1;
194 ARMword J2;
196 tASSERT (cond != AL && cond != NV);
197 if (! test_cond (cond, state))
198 return;
200 imm6 = tBITS (0, 5);
201 imm11 = ntBITS (0, 10);
202 J1 = ntBIT (13);
203 J2 = ntBIT (11);
205 simm32 = (J1 << 19) | (J2 << 18) | (imm6 << 12) | (imm11 << 1);
206 if (S)
207 simm32 |= -(1 << 20);
208 break;
211 case 1: /* B.W */
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);
219 if (S)
220 simm32 |= -(1 << 24);
221 break;
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);
232 if (S)
233 simm32 |= -(1 << 24);
235 CLEART;
236 state->Reg[14] = (pc + 4) | 1;
237 break;
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);
248 if (S)
249 simm32 |= -(1 << 24);
250 state->Reg[14] = (pc + 4) | 1;
251 break;
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;
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);
275 * ainstr |= (Rm);
276 * ainstr |= (type << 5);
277 * ainstr |= (imm5 << 7);
278 * pvalid = t_decoded;
279 break;
282 case 0x46:
283 if (tBIT (4) && ntBITS (5, 15) == 0x780)
285 // Table Branch
286 ARMword Rn = tBITS (0, 3);
287 ARMword Rm = ntBITS (0, 3);
288 ARMword address, dest;
290 if (ntBIT (4))
292 // TBH
293 address = state->Reg[Rn] + state->Reg[Rm] * 2;
294 dest = ARMul_LoadHalfWord (state, address);
296 else
298 // TBB
299 address = state->Reg[Rn] + state->Reg[Rm];
300 dest = ARMul_LoadByte (state, address);
303 state->Reg[15] = (pc + 4 + dest * 2);
304 FLUSHPIPE;
305 * pvalid = t_branch;
306 break;
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
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);
326 imm8 <<= 2;
327 tASSERT (imm8 <= 255);
328 tASSERT (P != 0 || W != 0);
330 // Convert into an ARM A1 encoding.
331 if (Rn == 15)
333 tASSERT (tBIT (4) == 1);
334 // LDRD (literal)
335 // Ignore W even if 1.
336 * ainstr = 0xE14F00D0;
338 else
340 if (tBIT (4) == 1)
341 // LDRD (immediate)
342 * ainstr = 0xE04000D0;
343 else
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;
360 break;
363 case 0x44:
364 case 0x45: // LDMIA
366 ARMword Rn = tBITS (0, 3);
367 int W = tBIT (5);
368 ARMword list = (ntBIT (15) << 15) | (ntBIT (14) << 14) | ntBITS (0, 12);
370 if (Rn == 13)
371 * ainstr = 0xE8BD0000;
372 else
374 * ainstr = 0xE8900000;
375 * ainstr |= (W << 21);
376 * ainstr |= (Rn << 16);
378 * ainstr |= list;
379 * pvalid = t_decoded;
380 break;
383 case 0x48:
384 case 0x49: // STMDB
386 ARMword Rn = tBITS (0, 3);
387 int W = tBIT (5);
388 ARMword list = (ntBIT (14) << 14) | ntBITS (0, 12);
390 if (Rn == 13 && W)
391 * ainstr = 0xE92D0000;
392 else
394 * ainstr = 0xE9000000;
395 * ainstr |= (W << 21);
396 * ainstr |= (Rn << 16);
398 * ainstr |= list;
399 * pvalid = t_decoded;
400 break;
403 case 0x50:
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);
413 if (Rd == 15)
415 tASSERT (tBIT (4) == 1);
417 // TST<c>.W <Rn>,<Rm>{,<shift>}
418 * ainstr = 0xE1100000;
420 else
422 // AND{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
423 int S = tBIT (4);
425 * ainstr = 0xE0000000;
427 if (in_IT_block ())
428 S = 0;
429 * ainstr |= (S << 20);
432 * ainstr |= (Rn << 16);
433 * ainstr |= (imm5 << 7);
434 * ainstr |= (type << 5);
435 * ainstr |= (Rm << 0);
436 * pvalid = t_decoded;
437 break;
440 case 0x51: // BIC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
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);
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;
459 break;
462 case 0x52:
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);
471 tASSERT (Rd != 15);
473 if (in_IT_block ())
474 S = 0;
476 if (Rn == 15)
478 tASSERT (ntBIT (15) == 0);
480 switch (ntBITS (4, 5))
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;
503 else
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;
516 break;
519 case 0x53: // MVN{S}<c>.W <Rd>,<Rm>{,<shift>}
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);
527 tASSERT (ntBIT (15) == 0);
529 if (in_IT_block ())
530 S = 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;
539 break;
542 case 0x54:
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);
551 if (Rd == 15 && S)
553 // TEQ<c> <Rn>,<Rm>{,<shift>}
554 tASSERT (ntBIT (15) == 0);
556 * ainstr = 0xE1300000;
558 else
560 // EOR{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
561 if (in_IT_block ())
562 S = 0;
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;
574 break;
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);
582 int S = tBIT (4);
583 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
584 ARMword type = ntBITS (4, 5);
586 tASSERT (! (Rd == 15 && S));
588 if (in_IT_block ())
589 S = 0;
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;
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;
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);
620 int S = tBIT (4);
621 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
622 ARMword type = ntBITS (4, 5);
624 tASSERT (ntBIT (15) == 0);
626 if (in_IT_block ())
627 S = 0;
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;
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);
652 if (Rd == 15)
654 // CMP<c>.W <Rn>, <Rm> {,<shift>}
655 * ainstr = 0xE1500000;
656 Rd = 0;
658 else if (tBIT (5))
659 * ainstr = 0xE0400000;
660 else
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;
670 break;
673 case 0x9D: // NOP.W
674 tASSERT (tBITS (0, 15) == 0xF3AF);
675 tASSERT (ntBITS (0, 15) == 0x8000);
676 * pvalid = t_branch;
677 break;
679 case 0x80: // AND
680 case 0xA0: // TST
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);
688 imm12 = ThumbExpandImm (imm12);
689 val = state->Reg[Rn] & imm12;
691 if (Rd == 15)
693 // TST<c> <Rn>,#<const>
694 tASSERT (S == 1);
696 else
698 // AND{S}<c> <Rd>,<Rn>,#<const>
699 if (in_IT_block ())
700 S = 0;
702 state->Reg[Rd] = val;
705 if (S)
706 ARMul_NegZero (state, val);
707 * pvalid = t_branch;
708 break;
711 case 0xA1:
712 case 0x81: // BIC.W
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;
727 break;
730 case 0xA2:
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. */
742 * pvalid = t_branch;
743 break;
746 case 0xA3:
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);
753 val = ~ val;
754 state->Reg[Rd] = val;
756 if (tBIT (4) && ! in_IT_block ())
757 ARMul_NegZero (state, val);
758 * pvalid = t_resolved;
759 break;
762 case 0xA4: // EOR
763 case 0x84: // TEQ
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;
771 imm12 = ThumbExpandImm (imm12);
773 result = state->Reg[Rn] ^ imm12;
775 if (Rd == 15 && S)
776 // TEQ<c> <Rn>,#<const>
778 else
780 // EOR{S}<c> <Rd>,<Rn>,#<const>
781 state->Reg[Rd] = result;
783 if (in_IT_block ())
784 S = 0;
787 if (S)
788 ARMul_NegZero (state, result);
789 * pvalid = t_resolved;
790 break;
793 case 0xA8: // CMN
794 case 0x88: // ADD
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;
804 if (Rd == 15 && S)
806 // CMN<c> <Rn>,#<const>
807 res = lhs - rhs;
809 else
811 // ADD{S}<c>.W <Rd>,<Rn>,#<const>
812 res = lhs + rhs;
814 if (in_IT_block ())
815 S = 0;
817 state->Reg[Rd] = res;
820 if (S)
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);
830 else
832 CLEARC;
833 CLEARV;
837 * pvalid = t_branch;
838 break;
841 case 0xAA:
842 case 0x8A: // ADC{S}<c> <Rd>,<Rn>,#<const>
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;
852 tASSERT (ntBIT (15) == 0);
854 if (CFLAG)
855 rhs += 1;
857 res = lhs + rhs;
858 state->Reg[Rd] = res;
860 if (in_IT_block ())
861 S = 0;
863 if (S)
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);
872 else
874 CLEARC;
875 CLEARV;
879 * pvalid = t_branch;
880 break;
883 case 0xAB:
884 case 0x8B: // SBC{S}<c> <Rd>,<Rn>,#<const>
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;
894 tASSERT (ntBIT (15) == 0);
896 if (! CFLAG)
897 rhs += 1;
899 res = lhs - rhs;
900 state->Reg[Rd] = res;
902 if (in_IT_block ())
903 S = 0;
905 if (S)
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);
914 else
916 CLEARC;
917 CLEARV;
921 * pvalid = t_branch;
922 break;
925 case 0xAD:
926 case 0x8D: // SUB
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;
936 if (Rd == 15 && S)
938 // CMP<c>.W <Rn>,#<const>
939 tASSERT (S);
941 else
943 // SUB{S}<c>.W <Rd>,<Rn>,#<const>
944 if (in_IT_block ())
945 S = 0;
947 state->Reg[Rd] = res;
950 if (S)
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);
959 else
961 CLEARC;
962 CLEARV;
966 * pvalid = t_branch;
967 break;
970 case 0xAE:
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);
976 int S = tBIT (4);
977 ARMword lhs = imm12;
978 ARMword rhs = state->Reg[Rn];
979 ARMword res = lhs - rhs;
981 tASSERT (ntBIT (15) == 0);
983 state->Reg[Rd] = res;
985 if (S)
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);
994 else
996 CLEARC;
997 CLEARV;
1001 * pvalid = t_branch;
1002 break;
1005 case 0xB0:
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;
1017 break;
1020 case 0xB2:
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;
1029 break;
1032 case 0xb5:
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;
1048 break;
1051 case 0xB6:
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;
1060 break;
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;
1075 case 0x9B:
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);
1089 if (lsbit > msbit)
1090 ; // UNPREDICTABLE
1091 else if (Rn == 15)
1093 // BFC<c> <Rd>,#<lsb>,#<width>
1094 state->Reg[Rd] &= ~ mask;
1096 else
1098 // BFI<c> <Rd>,<Rn>,#<lsb>,#<width>
1099 ARMword val = state->Reg[Rn] & (mask >> lsbit);
1101 val <<= lsbit;
1102 state->Reg[Rd] &= ~ mask;
1103 state->Reg[Rd] |= val;
1106 * pvalid = t_resolved;
1107 break;
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;
1122 case 0xC0: // STRB
1123 case 0xC4: // LDRB
1125 ARMword Rn = tBITS (0, 3);
1126 ARMword Rt = ntBITS (12, 15);
1128 if (tBIT (4))
1130 if (Rn == 15)
1132 tASSERT (Rt != 15);
1134 /* LDRB<c> <Rt>,<label> => 1111 1000 U001 1111 */
1135 * ainstr = 0xE55F0000;
1136 * ainstr |= (tBIT (7) << 23);
1137 * ainstr |= ntBITS (0, 11);
1139 else if (tBIT (7))
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);
1152 else
1154 int P = ntBIT (10);
1155 int U = ntBIT (9);
1156 int W = ntBIT (8);
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);
1171 else
1173 if (tBIT (7) == 1)
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;
1180 break;
1182 else if (ntBIT (11))
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);
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);
1199 * ainstr |= imm8;
1201 else
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;
1215 break;
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);
1227 tASSERT (Rn != 15);
1229 if (tBIT (4))
1231 if (Rn == 15)
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>]!
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;
1254 else
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);
1265 else
1267 if (ntBIT (11))
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);
1279 Rt = Rn = 0;
1281 else
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;
1296 else
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;
1310 break;
1313 case 0xC1: // STRH
1314 case 0xC5: // LDRH
1316 ARMword Rn = tBITS (0, 3);
1317 ARMword Rt = ntBITS (12, 15);
1318 ARMword address;
1320 tASSERT (Rn != 15);
1322 if (tBIT (4) == 1)
1324 if (tBIT (7))
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);
1340 tASSERT (Rn != 15);
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;
1352 break;
1354 else
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);
1367 else
1369 if (tBIT (7))
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;
1397 break;
1399 else
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;
1413 break;
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];
1423 if (Rn == 15)
1425 // LDR<c>.W <Rt>,<label>
1426 tASSERT (tBIT (4) == 1);
1427 // tASSERT (tBIT (7) == 1)
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]);
1436 * pvalid = t_resolved;
1437 break;
1440 case 0xC8:
1441 case 0xCC: // LDRSB
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
1451 if (Rn == 15)
1453 // LDRSB<c> <Rt>,<label>
1454 ARMword imm12 = ntBITS (0, 11);
1455 address += (U ? imm12 : - imm12);
1457 else if (U)
1459 // LDRSB<c> <Rt>,[<Rn>,#<imm12>]
1460 ARMword imm12 = ntBITS (0, 11);
1461 address += imm12;
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;
1477 break;
1479 else
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;
1495 break;
1498 case 0xC9:
1499 case 0xCD:// LDRSH
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;
1530 break;
1532 else /* U == 0 */
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;
1548 break;
1551 case 0x0D0:
1553 ARMword Rm = ntBITS (0, 3);
1554 ARMword Rd = ntBITS (8, 11);
1556 tASSERT (ntBITS (12, 15) == 15);
1558 if (ntBIT (7) == 1)
1560 // SXTH<c>.W <Rd>,<Rm>{,<rotation>}
1561 ARMword ror = ntBITS (4, 5) << 3;
1562 ARMword val;
1564 val = state->Reg[Rm];
1565 val = (val >> ror) | (val << (32 - ror));
1566 if (val & 0x8000)
1567 val |= -(1 << 16);
1568 state->Reg[Rd] = val;
1570 else
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);
1578 if (tBIT (4))
1579 ARMul_NegZero (state, state->Reg[Rd]);
1581 * pvalid = t_branch;
1582 break;
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);
1595 if (tBIT (4))
1596 ARMul_NegZero (state, state->Reg[Rd]);
1597 * pvalid = t_resolved;
1598 break;
1601 case 0xD2:
1602 tASSERT (ntBITS (12, 15) == 15);
1603 if (ntBIT (7))
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
1611 else
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;
1624 break;
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;
1638 case 0xD4:
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];
1651 tASSERT (Rm == Rn);
1653 state->Reg [Rd] =
1654 (val >> 24)
1655 | ((val >> 8) & 0xFF00)
1656 | ((val << 8) & 0xFF0000)
1657 | (val << 24);
1658 * pvalid = t_resolved;
1660 else
1662 tASSERT (ntBITS (4, 7) == 4);
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;
1671 * ainstr |= (Rn << 16);
1672 * ainstr |= (Rd << 12);
1673 * ainstr |= (Rm << 0);
1674 * pvalid = t_decoded;
1676 break;
1679 case 0xD5:
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);
1688 if (tBIT (4))
1690 // CLZ<c> <Rd>,<Rm>
1691 tASSERT (Rm == Rn);
1692 * ainstr = 0xE16F0F10;
1694 else
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;
1704 break;
1707 case 0xD8: // MUL
1709 ARMword Rn = tBITS (0, 3);
1710 ARMword Rm = ntBITS (0, 3);
1711 ARMword Rd = ntBITS (8, 11);
1712 ARMword Ra = ntBITS (12, 15);
1714 if (tBIT (4))
1716 // SMLA<x><y><c> <Rd>,<Rn>,<Rm>,<Ra>
1717 ARMword nval = state->Reg[Rn];
1718 ARMword mval = state->Reg[Rm];
1719 ARMword res;
1721 tASSERT (ntBITS (6, 7) == 0);
1722 tASSERT (Ra != 15);
1724 if (ntBIT (5))
1725 nval >>= 16;
1726 else
1727 nval &= 0xFFFF;
1729 if (ntBIT (4))
1730 mval >>= 16;
1731 else
1732 mval &= 0xFFFF;
1734 res = nval * mval;
1735 res += state->Reg[Ra];
1736 // FIXME: Test and clear/set the Q bit.
1737 state->Reg[Rd] = res;
1739 else
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]);
1746 else
1748 tASSERT (ntBITS (4, 7) == 0);
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];
1758 * pvalid = t_resolved;
1759 break;
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;
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;
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;
1795 default:
1796 fprintf (stderr, "(op = %x) ", tBITS (5,12));
1797 tASSERT (0);
1798 return;
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. */
1809 static void
1810 handle_v6_thumb_insn (ARMul_State * state,
1811 ARMword tinstr,
1812 ARMword next_instr,
1813 ARMword pc,
1814 ARMword * ainstr,
1815 tdstate * pvalid)
1817 if (! state->is_v6)
1819 * pvalid = t_undefined;
1820 return;
1823 if (tBITS (12, 15) == 0xB
1824 && tBIT (10) == 0
1825 && tBIT (8) == 1)
1827 // Conditional branch forwards.
1828 ARMword Rn = tBITS (0, 2);
1829 ARMword imm5 = tBIT (9) << 5 | tBITS (3, 7);
1831 if (tBIT (11))
1833 if (state->Reg[Rn] != 0)
1835 state->Reg[15] = (pc + 4 + imm5 * 2);
1836 FLUSHPIPE;
1839 else
1841 if (state->Reg[Rn] == 0)
1843 state->Reg[15] = (pc + 4 + imm5 * 2);
1844 FLUSHPIPE;
1847 * pvalid = t_branch;
1848 return;
1851 switch (tinstr & 0xFFC0)
1853 case 0x4400:
1854 case 0x4480:
1855 case 0x4440:
1856 case 0x44C0: // ADD
1858 ARMword Rd = (tBIT (7) << 3) | tBITS (0, 2);
1859 ARMword Rm = tBITS (3, 6);
1860 state->Reg[Rd] += state->Reg[Rm];
1861 break;
1864 case 0x4600: // MOV<c> <Rd>,<Rm>
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;
1876 case 0xBF00:
1877 case 0xBF40:
1878 case 0xBF80:
1879 case 0xBFC0:
1880 handle_IT_block (state, tinstr, pvalid);
1881 return;
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;
1902 case 0xba00: /* rev */
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;
1913 case 0xba40: /* rev16 */
1915 ARMword val = state->Reg[tBITS (3, 5)];
1916 state->Reg [tBITS (0, 2)] = (val >> 16) | (val << 16);
1917 break;
1920 case 0xb660: /* cpsie */
1921 case 0xb670: /* cpsid */
1922 case 0xbac0: /* revsh */
1923 case 0xb650: /* setend */
1924 default:
1925 printf ("Unhandled v6 thumb insn: %04x\n", tinstr);
1926 * pvalid = t_undefined;
1927 return;
1929 case 0xb200: /* sxth */
1931 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1933 if (Rm & 0x8000)
1934 state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000;
1935 else
1936 state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1937 break;
1940 case 0xb240: /* sxtb */
1942 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1944 if (Rm & 0x80)
1945 state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00;
1946 else
1947 state->Reg [(tinstr & 0x7)] = Rm & 0xff;
1948 break;
1951 case 0xb280: /* uxth */
1953 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1955 state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1956 break;
1959 case 0xb2c0: /* uxtb */
1961 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1963 state->Reg [(tinstr & 0x7)] = Rm & 0xff;
1964 break;
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. */
1976 tdstate
1977 ARMul_ThumbDecode (ARMul_State * state,
1978 ARMword pc,
1979 ARMword tinstr,
1980 ARMword * ainstr)
1982 tdstate valid = t_decoded; /* default assumes a valid instruction */
1983 ARMword next_instr;
1984 ARMword old_tinstr = tinstr;
1986 if (skipping_32bit_thumb == pc)
1988 skipping_32bit_thumb = 0;
1989 return t_branch;
1991 skipping_32bit_thumb = 0;
1993 if (state->bigendSig)
1995 next_instr = tinstr & 0xFFFF;
1996 tinstr >>= 16;
1998 else
2000 next_instr = tinstr >> 16;
2001 tinstr &= 0xFFFF;
2004 if (! IT_block_allow (state))
2006 if ( tBITS (11, 15) == 0x1F
2007 || tBITS (11, 15) == 0x1E
2008 || tBITS (11, 15) == 0x1D)
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;
2015 else if (trace)
2016 fprintf (stderr, "pc: %x, SKIP instr: %04x\n", pc & ~1, tinstr);
2018 return t_branch;
2021 old_tinstr = tinstr;
2022 if (trace)
2023 fprintf (stderr, "pc: %x, Thumb instr: %x", pc & ~1, tinstr);
2025 #if 1 /* debugging to catch non updates */
2026 *ainstr = 0xDEADC0DE;
2027 #endif
2029 switch ((tinstr & 0xF800) >> 11)
2031 case 0: /* LSL */
2032 case 1: /* LSR */
2033 case 2: /* ASR */
2034 /* Format 1 */
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 */
2040 break;
2041 case 3: /* ADD/SUB */
2042 /* Format 2 */
2044 ARMword subset[4] =
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
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 */
2058 if (in_IT_block ())
2059 *ainstr &= ~ (1 << 20);
2061 break;
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);
2068 break;
2070 case 5:
2071 * ainstr = 0xE3500000; /* CMP Rd,#imm8 */
2072 * ainstr |= tBITS (8, 10) << 16;
2073 * ainstr |= tBITS (0, 7);
2074 break;
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;
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
2092 subset. */
2093 if ((tinstr & (1 << 10)) == 0)
2095 /* Format 4 */
2096 struct
2098 ARMword opcode;
2099 enum
2100 { t_norm, t_shift, t_neg, t_mul }
2101 otype;
2103 subset[16] =
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 */
2124 if (in_IT_block ())
2126 struct
2128 ARMword opcode;
2129 enum
2130 { t_norm, t_shift, t_neg, t_mul }
2131 otype;
2133 subset[16] =
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)
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;
2178 else
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)
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 */
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;
2217 case 0xE: /* UNDEFINED */
2218 case 0xF: /* UNDEFINED */
2219 if (state->is_v5)
2221 /* BLX Rs; BLX Hs */
2222 *ainstr = 0xE12FFF30 /* base */
2223 | ((tinstr & 0x0078) >> 3); /* Rd */
2224 break;
2226 /* Drop through. */
2227 default:
2228 case 0x0: /* UNDEFINED */
2229 case 0x4: /* UNDEFINED */
2230 case 0x8: /* UNDEFINED */
2231 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2232 break;
2235 break;
2236 case 9: /* LDR Rd,[PC,#imm8] */
2237 /* Format 6 */
2238 *ainstr = 0xE59F0000 /* base */
2239 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2240 | ((tinstr & 0x00FF) << (2 - 0)); /* off8 */
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)
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] */
2256 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2257 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2258 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2259 | ((tinstr & 0x01C0) >> 6); /* Ro */
2261 else
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] */
2270 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2271 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2272 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2273 | ((tinstr & 0x01C0) >> 6); /* Ro */
2275 break;
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] */
2280 /* Format 9 */
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 */
2295 break;
2296 case 16: /* STRH Rd,[Rb,#imm5] */
2297 case 17: /* LDRH Rd,[Rb,#imm5] */
2298 /* Format 10 */
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 */
2306 break;
2307 case 18: /* STR Rd,[SP,#imm8] */
2308 case 19: /* LDR Rd,[SP,#imm8] */
2309 /* Format 11 */
2310 *ainstr = ((tinstr & (1 << 11)) /* base */
2311 ? 0xE59D0000 /* LDR */
2312 : 0xE58D0000) /* STR */
2313 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2314 | ((tinstr & 0x00FF) << 2); /* off8 */
2315 break;
2316 case 20: /* ADD Rd,PC,#imm8 */
2317 case 21: /* ADD Rd,SP,#imm8 */
2318 /* Format 12 */
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 */
2328 else
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 */
2336 break;
2337 case 22:
2338 case 23:
2339 switch (tinstr & 0x0F00)
2341 case 0x0000:
2342 /* Format 13 */
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 */
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)
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
2372 instruction. */
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);
2378 break;
2380 /* Drop through. */
2381 default:
2382 /* Everything else is an undefined instruction. */
2383 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2384 break;
2386 break;
2387 case 24: /* STMIA */
2388 case 25: /* LDMIA */
2389 /* Format 15 */
2390 *ainstr = ((tinstr & (1 << 11)) /* base */
2391 ? 0xE8B00000 /* LDMIA */
2392 : 0xE8A00000) /* STMIA */
2393 | ((tinstr & 0x0700) << (16 - 8)) /* Rb */
2394 | (tinstr & 0x00FF); /* mask8 */
2395 break;
2396 case 26: /* Bcc */
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;
2408 else
2409 *ainstr |= (tinstr & 0x00FF);
2411 else if ((tinstr & 0x0F00) != 0x0E00)
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)
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;
2464 if (doit)
2466 state->Reg[15] = (pc + 4
2467 + (((tinstr & 0x7F) << 1)
2468 | ((tinstr & (1 << 7)) ? 0xFFFFFF00 : 0)));
2469 FLUSHPIPE;
2471 valid = t_branch;
2473 else
2474 /* UNDEFINED : cc=1110(AL) uses different format. */
2475 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2476 break;
2477 case 28: /* B */
2478 /* Format 18 */
2479 state->Reg[15] = (pc + 4
2480 + (((tinstr & 0x3FF) << 1)
2481 | ((tinstr & (1 << 10)) ? 0xFFFFF800 : 0)));
2482 FLUSHPIPE;
2483 valid = t_branch;
2484 break;
2485 case 29: /* UNDEFINED */
2486 if (state->is_v6)
2488 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2489 break;
2492 if (state->is_v5)
2494 if (tinstr & 1)
2496 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2497 break;
2499 /* Drop through. */
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. */
2508 ARMword tmp = (pc + 2);
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;
2516 if (trace_funcs)
2517 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
2518 break;
2522 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2523 break;
2525 case 30: /* BL instruction 1 */
2526 if (state->is_v6)
2528 handle_T2_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2529 break;
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
2537 immediately. */
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))
2553 & 0xFFFFFFFC);
2554 CLEART;
2555 state->Reg[14] = (tmp | 1);
2556 valid = t_branch;
2557 FLUSHPIPE;
2559 else
2560 /* Exit, since not correct instruction. */
2561 pc -= 2;
2562 break;
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 */
2567 if (state->is_v6)
2569 handle_T2_insn (state, old_tinstr, next_instr, pc, ainstr, & valid);
2570 break;
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
2578 r14 is not suitably initialised. */
2580 ARMword tmp = pc;
2582 state->Reg[15] = (state->Reg[14] + ((tinstr & 0x07FF) << 1));
2583 state->Reg[14] = (tmp | 1);
2584 valid = t_branch;
2585 FLUSHPIPE;
2587 break;
2590 if (trace && valid != t_decoded)
2591 fprintf (stderr, "\n");
2593 return valid;