Automatic date update in version.in
[binutils-gdb.git] / sim / arm / thumbemu.c
bloba26a404fdf5ce24dca9d963212dddb772fd84001
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 /* This must come before any other includes. */
22 #include "defs.h"
24 #ifndef MODET /* required for the Thumb instruction support */
25 #if 1
26 #error "MODET needs to be defined for the Thumb world to work"
27 #else
28 #define MODET (1)
29 #endif
30 #endif
32 #include "armdefs.h"
33 #include "armemu.h"
34 #include "armos.h"
36 #define tBIT(n) ( (ARMword)(tinstr >> (n)) & 1)
37 #define tBITS(m,n) ( (ARMword)(tinstr << (31 - (n))) >> ((31 - (n)) + (m)) )
39 #define ntBIT(n) ( (ARMword)(next_instr >> (n)) & 1)
40 #define ntBITS(m,n) ( (ARMword)(next_instr << (31 - (n))) >> ((31 - (n)) + (m)) )
42 static int
43 test_cond (int cond, ARMul_State * state)
45 switch (cond)
47 case EQ: return ZFLAG;
48 case NE: return !ZFLAG;
49 case VS: return VFLAG;
50 case VC: return !VFLAG;
51 case MI: return NFLAG;
52 case PL: return !NFLAG;
53 case CS: return CFLAG;
54 case CC: return !CFLAG;
55 case HI: return (CFLAG && !ZFLAG);
56 case LS: return (!CFLAG || ZFLAG);
57 case GE: return ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
58 case LT: return ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
59 case GT: return ((!NFLAG && !VFLAG && !ZFLAG)
60 || (NFLAG && VFLAG && !ZFLAG));
61 case LE: return ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
62 case AL: return TRUE;
63 case NV:
64 default: return FALSE;
68 static ARMword skipping_32bit_thumb = 0;
70 static int IT_block_cond = AL;
71 static ARMword IT_block_mask = 0;
72 static int IT_block_first = FALSE;
74 static void
75 handle_IT_block (ARMul_State * state,
76 ARMword tinstr,
77 tdstate * pvalid)
79 * pvalid = t_branch;
80 IT_block_mask = tBITS (0, 3);
82 if (IT_block_mask == 0)
83 // NOP or a HINT.
84 return;
86 IT_block_cond = tBITS (4, 7);
87 IT_block_first = TRUE;
90 static int
91 in_IT_block (void)
93 return IT_block_mask != 0;
96 static int
97 IT_block_allow (ARMul_State * state)
99 int cond;
101 if (IT_block_mask == 0)
102 return TRUE;
104 cond = IT_block_cond;
106 if (IT_block_first)
107 IT_block_first = FALSE;
108 else
110 if ((IT_block_mask & 8) == 0)
111 cond &= 0xe;
112 else
113 cond |= 1;
114 IT_block_mask <<= 1;
115 IT_block_mask &= 0xF;
118 if (IT_block_mask == 0x8)
119 IT_block_mask = 0;
121 return test_cond (cond, state);
124 static ARMword
125 ThumbExpandImm (ARMword tinstr)
127 ARMword val;
129 if (tBITS (10, 11) == 0)
131 switch (tBITS (8, 9))
133 case 0: val = tBITS (0, 7); break;
134 case 1: val = tBITS (0, 7) << 8; break;
135 case 2: val = (tBITS (0, 7) << 8) | (tBITS (0, 7) << 24); break;
136 case 3: val = tBITS (0, 7) * 0x01010101; break;
137 default: val = 0;
140 else
142 int ror = tBITS (7, 11);
144 val = (1 << 7) | tBITS (0, 6);
145 val = (val >> ror) | (val << (32 - ror));
148 return val;
151 #define tASSERT(truth) \
152 do \
154 if (! (truth)) \
156 fprintf (stderr, "unhandled T2 insn %04x|%04x detected at thumbemu.c:%d\n", \
157 tinstr, next_instr, __LINE__); \
158 return ; \
161 while (0)
164 /* Attempt to emulate a 32-bit ARMv7 Thumb instruction.
165 Stores t_branch into PVALUE upon success or t_undefined otherwise. */
167 static void
168 handle_T2_insn (ARMul_State * state,
169 ARMword tinstr,
170 ARMword next_instr,
171 ARMword pc,
172 ARMword * ainstr,
173 tdstate * pvalid)
175 * pvalid = t_undefined;
177 if (! state->is_v6)
178 return;
180 if (trace)
181 fprintf (stderr, "|%04x ", next_instr);
183 if (tBITS (11, 15) == 0x1E && ntBIT (15) == 1)
185 ARMsword simm32 = 0;
186 int S = tBIT (10);
188 * pvalid = t_branch;
189 switch ((ntBIT (14) << 1) | ntBIT (12))
191 case 0: /* B<c>.W */
193 ARMword cond = tBITS (6, 9);
194 ARMword imm6;
195 ARMword imm11;
196 ARMword J1;
197 ARMword J2;
199 tASSERT (cond != AL && cond != NV);
200 if (! test_cond (cond, state))
201 return;
203 imm6 = tBITS (0, 5);
204 imm11 = ntBITS (0, 10);
205 J1 = ntBIT (13);
206 J2 = ntBIT (11);
208 simm32 = (J1 << 19) | (J2 << 18) | (imm6 << 12) | (imm11 << 1);
209 if (S)
210 simm32 |= -(1 << 20);
211 break;
214 case 1: /* B.W */
216 ARMword imm10 = tBITS (0, 9);
217 ARMword imm11 = ntBITS (0, 10);
218 ARMword I1 = (ntBIT (13) ^ S) ? 0 : 1;
219 ARMword I2 = (ntBIT (11) ^ S) ? 0 : 1;
221 simm32 = (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
222 if (S)
223 simm32 |= -(1 << 24);
224 break;
227 case 2: /* BLX <label> */
229 ARMword imm10h = tBITS (0, 9);
230 ARMword imm10l = ntBITS (1, 10);
231 ARMword I1 = (ntBIT (13) ^ S) ? 0 : 1;
232 ARMword I2 = (ntBIT (11) ^ S) ? 0 : 1;
234 simm32 = (I1 << 23) | (I2 << 22) | (imm10h << 12) | (imm10l << 2);
235 if (S)
236 simm32 |= -(1 << 24);
238 CLEART;
239 state->Reg[14] = (pc + 4) | 1;
240 break;
243 case 3: /* BL <label> */
245 ARMword imm10 = tBITS (0, 9);
246 ARMword imm11 = ntBITS (0, 10);
247 ARMword I1 = (ntBIT (13) ^ S) ? 0 : 1;
248 ARMword I2 = (ntBIT (11) ^ S) ? 0 : 1;
250 simm32 = (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
251 if (S)
252 simm32 |= -(1 << 24);
253 state->Reg[14] = (pc + 4) | 1;
254 break;
258 state->Reg[15] = (pc + 4 + simm32);
259 FLUSHPIPE;
260 if (trace_funcs)
261 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
262 return;
265 switch (tBITS (5,12))
267 case 0x29: // TST<c>.W <Rn>,<Rm>{,<shift>}
269 ARMword Rn = tBITS (0, 3);
270 ARMword Rm = ntBITS (0, 3);
271 ARMword type = ntBITS (4, 5);
272 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
274 tASSERT (ntBITS (8, 11) == 0xF);
276 * ainstr = 0xE1100000;
277 * ainstr |= (Rn << 16);
278 * ainstr |= (Rm);
279 * ainstr |= (type << 5);
280 * ainstr |= (imm5 << 7);
281 * pvalid = t_decoded;
282 break;
285 case 0x46:
286 if (tBIT (4) && ntBITS (5, 15) == 0x780)
288 // Table Branch
289 ARMword Rn = tBITS (0, 3);
290 ARMword Rm = ntBITS (0, 3);
291 ARMword address, dest;
293 if (ntBIT (4))
295 // TBH
296 address = state->Reg[Rn] + state->Reg[Rm] * 2;
297 dest = ARMul_LoadHalfWord (state, address);
299 else
301 // TBB
302 address = state->Reg[Rn] + state->Reg[Rm];
303 dest = ARMul_LoadByte (state, address);
306 state->Reg[15] = (pc + 4 + dest * 2);
307 FLUSHPIPE;
308 * pvalid = t_branch;
309 break;
311 ATTRIBUTE_FALLTHROUGH;
312 case 0x42:
313 case 0x43:
314 case 0x47:
315 case 0x4A:
316 case 0x4B:
317 case 0x4E: // STRD
318 case 0x4F: // LDRD
320 ARMword Rn = tBITS (0, 3);
321 ARMword Rt = ntBITS (12, 15);
322 ARMword Rt2 = ntBITS (8, 11);
323 ARMword imm8 = ntBITS (0, 7);
324 ARMword P = tBIT (8);
325 ARMword U = tBIT (7);
326 ARMword W = tBIT (5);
328 tASSERT (Rt2 == Rt + 1);
329 imm8 <<= 2;
330 tASSERT (imm8 <= 255);
331 tASSERT (P != 0 || W != 0);
333 // Convert into an ARM A1 encoding.
334 if (Rn == 15)
336 tASSERT (tBIT (4) == 1);
337 // LDRD (literal)
338 // Ignore W even if 1.
339 * ainstr = 0xE14F00D0;
341 else
343 if (tBIT (4) == 1)
344 // LDRD (immediate)
345 * ainstr = 0xE04000D0;
346 else
348 // STRD<c> <Rt>,<Rt2>,[<Rn>{,#+/-<imm8>}]
349 // STRD<c> <Rt>,<Rt2>,[<Rn>],#+/-<imm8>
350 // STRD<c> <Rt>,<Rt2>,[<Rn>,#+/-<imm8>]!
351 * ainstr = 0xE04000F0;
353 * ainstr |= (Rn << 16);
354 * ainstr |= (P << 24);
355 * ainstr |= (W << 21);
358 * ainstr |= (U << 23);
359 * ainstr |= (Rt << 12);
360 * ainstr |= ((imm8 << 4) & 0xF00);
361 * ainstr |= (imm8 & 0xF);
362 * pvalid = t_decoded;
363 break;
366 case 0x44:
367 case 0x45: // LDMIA
369 ARMword Rn = tBITS (0, 3);
370 int W = tBIT (5);
371 ARMword list = (ntBIT (15) << 15) | (ntBIT (14) << 14) | ntBITS (0, 12);
373 if (Rn == 13)
374 * ainstr = 0xE8BD0000;
375 else
377 * ainstr = 0xE8900000;
378 * ainstr |= (W << 21);
379 * ainstr |= (Rn << 16);
381 * ainstr |= list;
382 * pvalid = t_decoded;
383 break;
386 case 0x48:
387 case 0x49: // STMDB
389 ARMword Rn = tBITS (0, 3);
390 int W = tBIT (5);
391 ARMword list = (ntBIT (14) << 14) | ntBITS (0, 12);
393 if (Rn == 13 && W)
394 * ainstr = 0xE92D0000;
395 else
397 * ainstr = 0xE9000000;
398 * ainstr |= (W << 21);
399 * ainstr |= (Rn << 16);
401 * ainstr |= list;
402 * pvalid = t_decoded;
403 break;
406 case 0x50:
408 ARMword Rd = ntBITS (8, 11);
409 ARMword Rn = tBITS (0, 3);
410 ARMword Rm = ntBITS (0, 3);
411 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
412 ARMword type = ntBITS (4, 5);
414 tASSERT (ntBIT (15) == 0);
416 if (Rd == 15)
418 tASSERT (tBIT (4) == 1);
420 // TST<c>.W <Rn>,<Rm>{,<shift>}
421 * ainstr = 0xE1100000;
423 else
425 // AND{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
426 int S = tBIT (4);
428 * ainstr = 0xE0000000;
430 if (in_IT_block ())
431 S = 0;
432 * ainstr |= (S << 20);
435 * ainstr |= (Rn << 16);
436 * ainstr |= (imm5 << 7);
437 * ainstr |= (type << 5);
438 * ainstr |= (Rm << 0);
439 * pvalid = t_decoded;
440 break;
443 case 0x51: // BIC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
445 ARMword Rn = tBITS (0, 3);
446 ARMword S = tBIT(4);
447 ARMword Rm = ntBITS (0, 3);
448 ARMword Rd = ntBITS (8, 11);
449 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
450 ARMword type = ntBITS (4, 5);
452 tASSERT (ntBIT (15) == 0);
454 * ainstr = 0xE1C00000;
455 * ainstr |= (S << 20);
456 * ainstr |= (Rn << 16);
457 * ainstr |= (Rd << 12);
458 * ainstr |= (imm5 << 7);
459 * ainstr |= (type << 5);
460 * ainstr |= (Rm << 0);
461 * pvalid = t_decoded;
462 break;
465 case 0x52:
467 ARMword Rn = tBITS (0, 3);
468 ARMword Rd = ntBITS (8, 11);
469 ARMword Rm = ntBITS (0, 3);
470 int S = tBIT (4);
471 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
472 ARMword type = ntBITS (4, 5);
474 tASSERT (Rd != 15);
476 if (in_IT_block ())
477 S = 0;
479 if (Rn == 15)
481 tASSERT (ntBIT (15) == 0);
483 switch (ntBITS (4, 5))
485 case 0:
486 // LSL{S}<c>.W <Rd>,<Rm>,#<imm5>
487 * ainstr = 0xE1A00000;
488 break;
489 case 1:
490 // LSR{S}<c>.W <Rd>,<Rm>,#<imm>
491 * ainstr = 0xE1A00020;
492 break;
493 case 2:
494 // ASR{S}<c>.W <Rd>,<Rm>,#<imm>
495 * ainstr = 0xE1A00040;
496 break;
497 case 3:
498 // ROR{S}<c> <Rd>,<Rm>,#<imm>
499 * ainstr = 0xE1A00060;
500 break;
501 default:
502 tASSERT (0);
503 * ainstr = 0;
506 else
508 // ORR{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
509 * ainstr = 0xE1800000;
510 * ainstr |= (Rn << 16);
511 * ainstr |= (type << 5);
514 * ainstr |= (Rd << 12);
515 * ainstr |= (S << 20);
516 * ainstr |= (imm5 << 7);
517 * ainstr |= (Rm << 0);
518 * pvalid = t_decoded;
519 break;
522 case 0x53: // MVN{S}<c>.W <Rd>,<Rm>{,<shift>}
524 ARMword Rd = ntBITS (8, 11);
525 ARMword Rm = ntBITS (0, 3);
526 int S = tBIT (4);
527 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
528 ARMword type = ntBITS (4, 5);
530 tASSERT (ntBIT (15) == 0);
532 if (in_IT_block ())
533 S = 0;
535 * ainstr = 0xE1E00000;
536 * ainstr |= (S << 20);
537 * ainstr |= (Rd << 12);
538 * ainstr |= (imm5 << 7);
539 * ainstr |= (type << 5);
540 * ainstr |= (Rm << 0);
541 * pvalid = t_decoded;
542 break;
545 case 0x54:
547 ARMword Rn = tBITS (0, 3);
548 ARMword Rd = ntBITS (8, 11);
549 ARMword Rm = ntBITS (0, 3);
550 int S = tBIT (4);
551 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
552 ARMword type = ntBITS (4, 5);
554 if (Rd == 15 && S)
556 // TEQ<c> <Rn>,<Rm>{,<shift>}
557 tASSERT (ntBIT (15) == 0);
559 * ainstr = 0xE1300000;
561 else
563 // EOR{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
564 if (in_IT_block ())
565 S = 0;
567 * ainstr = 0xE0200000;
568 * ainstr |= (S << 20);
569 * ainstr |= (Rd << 8);
572 * ainstr |= (Rn << 16);
573 * ainstr |= (imm5 << 7);
574 * ainstr |= (type << 5);
575 * ainstr |= (Rm << 0);
576 * pvalid = t_decoded;
577 break;
580 case 0x58: // ADD{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
582 ARMword Rn = tBITS (0, 3);
583 ARMword Rd = ntBITS (8, 11);
584 ARMword Rm = ntBITS (0, 3);
585 int S = tBIT (4);
586 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
587 ARMword type = ntBITS (4, 5);
589 tASSERT (! (Rd == 15 && S));
591 if (in_IT_block ())
592 S = 0;
594 * ainstr = 0xE0800000;
595 * ainstr |= (S << 20);
596 * ainstr |= (Rn << 16);
597 * ainstr |= (Rd << 12);
598 * ainstr |= (imm5 << 7);
599 * ainstr |= (type << 5);
600 * ainstr |= Rm;
601 * pvalid = t_decoded;
602 break;
605 case 0x5A: // ADC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
606 tASSERT (ntBIT (15) == 0);
607 * ainstr = 0xE0A00000;
608 if (! in_IT_block ())
609 * ainstr |= (tBIT (4) << 20); // S
610 * ainstr |= (tBITS (0, 3) << 16); // Rn
611 * ainstr |= (ntBITS (8, 11) << 12); // Rd
612 * ainstr |= ((ntBITS (12, 14) << 2) | ntBITS (6, 7)) << 7; // imm5
613 * ainstr |= (ntBITS (4, 5) << 5); // type
614 * ainstr |= ntBITS (0, 3); // Rm
615 * pvalid = t_decoded;
616 break;
618 case 0x5B: // SBC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
620 ARMword Rn = tBITS (0, 3);
621 ARMword Rd = ntBITS (8, 11);
622 ARMword Rm = ntBITS (0, 3);
623 int S = tBIT (4);
624 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
625 ARMword type = ntBITS (4, 5);
627 tASSERT (ntBIT (15) == 0);
629 if (in_IT_block ())
630 S = 0;
632 * ainstr = 0xE0C00000;
633 * ainstr |= (S << 20);
634 * ainstr |= (Rn << 16);
635 * ainstr |= (Rd << 12);
636 * ainstr |= (imm5 << 7);
637 * ainstr |= (type << 5);
638 * ainstr |= Rm;
639 * pvalid = t_decoded;
640 break;
643 case 0x5E: // RSB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>}
644 case 0x5D: // SUB{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
646 ARMword Rn = tBITS (0, 3);
647 ARMword Rd = ntBITS (8, 11);
648 ARMword Rm = ntBITS (0, 3);
649 ARMword S = tBIT (4);
650 ARMword type = ntBITS (4, 5);
651 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
653 tASSERT (ntBIT(15) == 0);
655 if (Rd == 15)
657 // CMP<c>.W <Rn>, <Rm> {,<shift>}
658 * ainstr = 0xE1500000;
659 Rd = 0;
661 else if (tBIT (5))
662 * ainstr = 0xE0400000;
663 else
664 * ainstr = 0xE0600000;
666 * ainstr |= (S << 20);
667 * ainstr |= (Rn << 16);
668 * ainstr |= (Rd << 12);
669 * ainstr |= (imm5 << 7);
670 * ainstr |= (type << 5);
671 * ainstr |= (Rm << 0);
672 * pvalid = t_decoded;
673 break;
676 case 0x9D: // NOP.W
677 tASSERT (tBITS (0, 15) == 0xF3AF);
678 tASSERT (ntBITS (0, 15) == 0x8000);
679 * pvalid = t_branch;
680 break;
682 case 0x80: // AND
683 case 0xA0: // TST
685 ARMword Rn = tBITS (0, 3);
686 ARMword imm12 = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
687 ARMword Rd = ntBITS (8, 11);
688 ARMword val;
689 int S = tBIT (4);
691 imm12 = ThumbExpandImm (imm12);
692 val = state->Reg[Rn] & imm12;
694 if (Rd == 15)
696 // TST<c> <Rn>,#<const>
697 tASSERT (S == 1);
699 else
701 // AND{S}<c> <Rd>,<Rn>,#<const>
702 if (in_IT_block ())
703 S = 0;
705 state->Reg[Rd] = val;
708 if (S)
709 ARMul_NegZero (state, val);
710 * pvalid = t_branch;
711 break;
714 case 0xA1:
715 case 0x81: // BIC.W
717 ARMword Rn = tBITS (0, 3);
718 ARMword Rd = ntBITS (8, 11);
719 ARMword S = tBIT (4);
720 ARMword imm8 = (ntBITS (12, 14) << 8) | ntBITS (0, 7);
722 tASSERT (ntBIT (15) == 0);
724 imm8 = ThumbExpandImm (imm8);
725 state->Reg[Rd] = state->Reg[Rn] & ~ imm8;
727 if (S && ! in_IT_block ())
728 ARMul_NegZero (state, state->Reg[Rd]);
729 * pvalid = t_resolved;
730 break;
733 case 0xA2:
734 case 0x82: // MOV{S}<c>.W <Rd>,#<const>
736 ARMword val = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
737 ARMword Rd = ntBITS (8, 11);
739 val = ThumbExpandImm (val);
740 state->Reg[Rd] = val;
742 if (tBIT (4) && ! in_IT_block ())
743 ARMul_NegZero (state, val);
744 /* Indicate that the instruction has been processed. */
745 * pvalid = t_branch;
746 break;
749 case 0xA3:
750 case 0x83: // MVN{S}<c> <Rd>,#<const>
752 ARMword val = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
753 ARMword Rd = ntBITS (8, 11);
755 val = ThumbExpandImm (val);
756 val = ~ val;
757 state->Reg[Rd] = val;
759 if (tBIT (4) && ! in_IT_block ())
760 ARMul_NegZero (state, val);
761 * pvalid = t_resolved;
762 break;
765 case 0xA4: // EOR
766 case 0x84: // TEQ
768 ARMword Rn = tBITS (0, 3);
769 ARMword Rd = ntBITS (8, 11);
770 ARMword S = tBIT (4);
771 ARMword imm12 = ((tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7));
772 ARMword result;
774 imm12 = ThumbExpandImm (imm12);
776 result = state->Reg[Rn] ^ imm12;
778 if (Rd == 15 && S)
779 // TEQ<c> <Rn>,#<const>
781 else
783 // EOR{S}<c> <Rd>,<Rn>,#<const>
784 state->Reg[Rd] = result;
786 if (in_IT_block ())
787 S = 0;
790 if (S)
791 ARMul_NegZero (state, result);
792 * pvalid = t_resolved;
793 break;
796 case 0xA8: // CMN
797 case 0x88: // ADD
799 ARMword Rd = ntBITS (8, 11);
800 int S = tBIT (4);
801 ARMword Rn = tBITS (0, 3);
802 ARMword lhs = state->Reg[Rn];
803 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
804 ARMword rhs = ThumbExpandImm (imm12);
805 ARMword res = lhs + rhs;
807 if (Rd == 15 && S)
809 // CMN<c> <Rn>,#<const>
810 res = lhs - rhs;
812 else
814 // ADD{S}<c>.W <Rd>,<Rn>,#<const>
815 res = lhs + rhs;
817 if (in_IT_block ())
818 S = 0;
820 state->Reg[Rd] = res;
823 if (S)
825 ARMul_NegZero (state, res);
827 if ((lhs | rhs) >> 30)
829 /* Possible C,V,N to set. */
830 ARMul_AddCarry (state, lhs, rhs, res);
831 ARMul_AddOverflow (state, lhs, rhs, res);
833 else
835 CLEARC;
836 CLEARV;
840 * pvalid = t_branch;
841 break;
844 case 0xAA:
845 case 0x8A: // ADC{S}<c> <Rd>,<Rn>,#<const>
847 ARMword Rn = tBITS (0, 3);
848 ARMword Rd = ntBITS (8, 11);
849 int S = tBIT (4);
850 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
851 ARMword lhs = state->Reg[Rn];
852 ARMword rhs = ThumbExpandImm (imm12);
853 ARMword res;
855 tASSERT (ntBIT (15) == 0);
857 if (CFLAG)
858 rhs += 1;
860 res = lhs + rhs;
861 state->Reg[Rd] = res;
863 if (in_IT_block ())
864 S = 0;
866 if (S)
868 ARMul_NegZero (state, res);
870 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
872 ARMul_AddCarry (state, lhs, rhs, res);
873 ARMul_AddOverflow (state, lhs, rhs, res);
875 else
877 CLEARC;
878 CLEARV;
882 * pvalid = t_branch;
883 break;
886 case 0xAB:
887 case 0x8B: // SBC{S}<c> <Rd>,<Rn>,#<const>
889 ARMword Rn = tBITS (0, 3);
890 ARMword Rd = ntBITS (8, 11);
891 int S = tBIT (4);
892 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
893 ARMword lhs = state->Reg[Rn];
894 ARMword rhs = ThumbExpandImm (imm12);
895 ARMword res;
897 tASSERT (ntBIT (15) == 0);
899 if (! CFLAG)
900 rhs += 1;
902 res = lhs - rhs;
903 state->Reg[Rd] = res;
905 if (in_IT_block ())
906 S = 0;
908 if (S)
910 ARMul_NegZero (state, res);
912 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
914 ARMul_SubCarry (state, lhs, rhs, res);
915 ARMul_SubOverflow (state, lhs, rhs, res);
917 else
919 CLEARC;
920 CLEARV;
924 * pvalid = t_branch;
925 break;
928 case 0xAD:
929 case 0x8D: // SUB
931 ARMword Rn = tBITS (0, 3);
932 ARMword Rd = ntBITS (8, 11);
933 int S = tBIT (4);
934 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
935 ARMword lhs = state->Reg[Rn];
936 ARMword rhs = ThumbExpandImm (imm12);
937 ARMword res = lhs - rhs;
939 if (Rd == 15 && S)
941 // CMP<c>.W <Rn>,#<const>
942 tASSERT (S);
944 else
946 // SUB{S}<c>.W <Rd>,<Rn>,#<const>
947 if (in_IT_block ())
948 S = 0;
950 state->Reg[Rd] = res;
953 if (S)
955 ARMul_NegZero (state, res);
957 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
959 ARMul_SubCarry (state, lhs, rhs, res);
960 ARMul_SubOverflow (state, lhs, rhs, res);
962 else
964 CLEARC;
965 CLEARV;
969 * pvalid = t_branch;
970 break;
973 case 0xAE:
974 case 0x8E: // RSB{S}<c>.W <Rd>,<Rn>,#<const>
976 ARMword Rn = tBITS (0, 3);
977 ARMword Rd = ntBITS (8, 11);
978 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
979 int S = tBIT (4);
980 ARMword lhs = imm12;
981 ARMword rhs = state->Reg[Rn];
982 ARMword res = lhs - rhs;
984 tASSERT (ntBIT (15) == 0);
986 state->Reg[Rd] = res;
988 if (S)
990 ARMul_NegZero (state, res);
992 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
994 ARMul_SubCarry (state, lhs, rhs, res);
995 ARMul_SubOverflow (state, lhs, rhs, res);
997 else
999 CLEARC;
1000 CLEARV;
1004 * pvalid = t_branch;
1005 break;
1008 case 0xB0:
1009 case 0x90: // ADDW<c> <Rd>,<Rn>,#<imm12>
1011 ARMword Rn = tBITS (0, 3);
1012 ARMword Rd = ntBITS (8, 11);
1013 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1015 tASSERT (tBIT (4) == 0);
1016 tASSERT (ntBIT (15) == 0);
1018 state->Reg[Rd] = state->Reg[Rn] + imm12;
1019 * pvalid = t_branch;
1020 break;
1023 case 0xB2:
1024 case 0x92: // MOVW<c> <Rd>,#<imm16>
1026 ARMword Rd = ntBITS (8, 11);
1027 ARMword imm = (tBITS (0, 3) << 12) | (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1029 state->Reg[Rd] = imm;
1030 /* Indicate that the instruction has been processed. */
1031 * pvalid = t_branch;
1032 break;
1035 case 0xb5:
1036 case 0x95:// SUBW<c> <Rd>,<Rn>,#<imm12>
1038 ARMword Rd = ntBITS (8, 11);
1039 ARMword Rn = tBITS (0, 3);
1040 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1042 tASSERT (tBIT (4) == 0);
1043 tASSERT (ntBIT (15) == 0);
1045 /* Note the ARM ARM indicates special cases for Rn == 15 (ADR)
1046 and Rn == 13 (SUB SP minus immediate), but these are implemented
1047 in exactly the same way as the normal SUBW insn. */
1048 state->Reg[Rd] = state->Reg[Rn] - imm12;
1050 * pvalid = t_resolved;
1051 break;
1054 case 0xB6:
1055 case 0x96: // MOVT<c> <Rd>,#<imm16>
1057 ARMword Rd = ntBITS (8, 11);
1058 ARMword imm = (tBITS (0, 3) << 12) | (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1060 state->Reg[Rd] &= 0xFFFF;
1061 state->Reg[Rd] |= (imm << 16);
1062 * pvalid = t_resolved;
1063 break;
1066 case 0x9A: // SBFXc> <Rd>,<Rn>,#<lsb>,#<width>
1067 tASSERT (tBIT (4) == 0);
1068 tASSERT (ntBIT (15) == 0);
1069 tASSERT (ntBIT (5) == 0);
1070 * ainstr = 0xE7A00050;
1071 * ainstr |= (ntBITS (0, 4) << 16); // widthm1
1072 * ainstr |= (ntBITS (8, 11) << 12); // Rd
1073 * ainstr |= (((ntBITS (12, 14) << 2) | ntBITS (6, 7)) << 7); // lsb
1074 * ainstr |= tBITS (0, 3); // Rn
1075 * pvalid = t_decoded;
1076 break;
1078 case 0x9B:
1080 ARMword Rd = ntBITS (8, 11);
1081 ARMword Rn = tBITS (0, 3);
1082 ARMword msbit = ntBITS (0, 5);
1083 ARMword lsbit = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
1084 ARMword mask = -(1 << lsbit);
1086 tASSERT (tBIT (4) == 0);
1087 tASSERT (ntBIT (15) == 0);
1088 tASSERT (ntBIT (5) == 0);
1090 mask &= ((1 << (msbit + 1)) - 1);
1092 if (lsbit > msbit)
1093 ; // UNPREDICTABLE
1094 else if (Rn == 15)
1096 // BFC<c> <Rd>,#<lsb>,#<width>
1097 state->Reg[Rd] &= ~ mask;
1099 else
1101 // BFI<c> <Rd>,<Rn>,#<lsb>,#<width>
1102 ARMword val = state->Reg[Rn] & (mask >> lsbit);
1104 val <<= lsbit;
1105 state->Reg[Rd] &= ~ mask;
1106 state->Reg[Rd] |= val;
1109 * pvalid = t_resolved;
1110 break;
1113 case 0x9E: // UBFXc> <Rd>,<Rn>,#<lsb>,#<width>
1114 tASSERT (tBIT (4) == 0);
1115 tASSERT (ntBIT (15) == 0);
1116 tASSERT (ntBIT (5) == 0);
1117 * ainstr = 0xE7E00050;
1118 * ainstr |= (ntBITS (0, 4) << 16); // widthm1
1119 * ainstr |= (ntBITS (8, 11) << 12); // Rd
1120 * ainstr |= (((ntBITS (12, 14) << 2) | ntBITS (6, 7)) << 7); // lsb
1121 * ainstr |= tBITS (0, 3); // Rn
1122 * pvalid = t_decoded;
1123 break;
1125 case 0xC0: // STRB
1126 case 0xC4: // LDRB
1128 ARMword Rn = tBITS (0, 3);
1129 ARMword Rt = ntBITS (12, 15);
1131 if (tBIT (4))
1133 if (Rn == 15)
1135 tASSERT (Rt != 15);
1137 /* LDRB<c> <Rt>,<label> => 1111 1000 U001 1111 */
1138 * ainstr = 0xE55F0000;
1139 * ainstr |= (tBIT (7) << 23);
1140 * ainstr |= ntBITS (0, 11);
1142 else if (tBIT (7))
1144 /* LDRB<c>.W <Rt>,[<Rn>{,#<imm12>}] => 1111 1000 1001 rrrr */
1145 * ainstr = 0xE5D00000;
1146 * ainstr |= ntBITS (0, 11);
1148 else if (ntBIT (11) == 0)
1150 /* LDRB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}] => 1111 1000 0001 rrrr */
1151 * ainstr = 0xE7D00000;
1152 * ainstr |= (ntBITS (4, 5) << 7);
1153 * ainstr |= ntBITS (0, 3);
1155 else
1157 int P = ntBIT (10);
1158 int U = ntBIT (9);
1159 int W = ntBIT (8);
1161 tASSERT (! (Rt == 15 && P && !U && !W));
1162 tASSERT (! (P && U && !W));
1164 /* LDRB<c> <Rt>,[<Rn>,#-<imm8>] => 1111 1000 0001 rrrr
1165 LDRB<c> <Rt>,[<Rn>],#+/-<imm8> => 1111 1000 0001 rrrr
1166 LDRB<c> <Rt>,[<Rn>,#+/-<imm8>]! => 1111 1000 0001 rrrr */
1167 * ainstr = 0xE4500000;
1168 * ainstr |= (P << 24);
1169 * ainstr |= (U << 23);
1170 * ainstr |= (W << 21);
1171 * ainstr |= ntBITS (0, 7);
1174 else
1176 if (tBIT (7) == 1)
1178 // STRB<c>.W <Rt>,[<Rn>,#<imm12>]
1179 ARMword imm12 = ntBITS (0, 11);
1181 ARMul_StoreByte (state, state->Reg[Rn] + imm12, state->Reg [Rt]);
1182 * pvalid = t_branch;
1183 break;
1185 else if (ntBIT (11))
1187 // STRB<c> <Rt>,[<Rn>,#-<imm8>]
1188 // STRB<c> <Rt>,[<Rn>],#+/-<imm8>
1189 // STRB<c> <Rt>,[<Rn>,#+/-<imm8>]!
1190 int P = ntBIT (10);
1191 int U = ntBIT (9);
1192 int W = ntBIT (8);
1193 ARMword imm8 = ntBITS (0, 7);
1195 tASSERT (! (P && U && !W));
1196 tASSERT (! (Rn == 13 && P && !U && W && imm8 == 4));
1198 * ainstr = 0xE4000000;
1199 * ainstr |= (P << 24);
1200 * ainstr |= (U << 23);
1201 * ainstr |= (W << 21);
1202 * ainstr |= imm8;
1204 else
1206 // STRB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1207 tASSERT (ntBITS (6, 11) == 0);
1209 * ainstr = 0xE7C00000;
1210 * ainstr |= (ntBITS (4, 5) << 7);
1211 * ainstr |= ntBITS (0, 3);
1215 * ainstr |= (Rn << 16);
1216 * ainstr |= (Rt << 12);
1217 * pvalid = t_decoded;
1218 break;
1221 case 0xC2: // LDR, STR
1223 ARMword Rn = tBITS (0, 3);
1224 ARMword Rt = ntBITS (12, 15);
1225 ARMword imm8 = ntBITS (0, 7);
1226 ARMword P = ntBIT (10);
1227 ARMword U = ntBIT (9);
1228 ARMword W = ntBIT (8);
1230 tASSERT (Rn != 15);
1232 if (tBIT (4))
1234 if (Rn == 15)
1236 // LDR<c>.W <Rt>,<label>
1237 * ainstr = 0xE51F0000;
1238 * ainstr |= ntBITS (0, 11);
1240 else if (ntBIT (11))
1242 tASSERT (! (P && U && ! W));
1243 tASSERT (! (!P && U && W && Rn == 13 && imm8 == 4 && ntBIT (11) == 0));
1244 tASSERT (! (P && !U && W && Rn == 13 && imm8 == 4 && ntBIT (11)));
1246 // LDR<c> <Rt>,[<Rn>,#-<imm8>]
1247 // LDR<c> <Rt>,[<Rn>],#+/-<imm8>
1248 // LDR<c> <Rt>,[<Rn>,#+/-<imm8>]!
1249 if (!P && W)
1250 W = 0;
1251 * ainstr = 0xE4100000;
1252 * ainstr |= (P << 24);
1253 * ainstr |= (U << 23);
1254 * ainstr |= (W << 21);
1255 * ainstr |= imm8;
1257 else
1259 // LDR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1261 tASSERT (ntBITS (6, 11) == 0);
1263 * ainstr = 0xE7900000;
1264 * ainstr |= ntBITS (4, 5) << 7;
1265 * ainstr |= ntBITS (0, 3);
1268 else
1270 if (ntBIT (11))
1272 tASSERT (! (P && U && ! W));
1273 if (Rn == 13 && P && !U && W && imm8 == 4)
1275 // PUSH<c>.W <register>
1276 tASSERT (ntBITS (0, 11) == 0xD04);
1277 tASSERT (tBITS (0, 4) == 0x0D);
1279 * ainstr = 0xE92D0000;
1280 * ainstr |= (1 << Rt);
1282 Rt = Rn = 0;
1284 else
1286 tASSERT (! (P && U && !W));
1287 if (!P && W)
1288 W = 0;
1289 // STR<c> <Rt>,[<Rn>,#-<imm8>]
1290 // STR<c> <Rt>,[<Rn>],#+/-<imm8>
1291 // STR<c> <Rt>,[<Rn>,#+/-<imm8>]!
1292 * ainstr = 0xE4000000;
1293 * ainstr |= (P << 24);
1294 * ainstr |= (U << 23);
1295 * ainstr |= (W << 21);
1296 * ainstr |= imm8;
1299 else
1301 // STR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1302 tASSERT (ntBITS (6, 11) == 0);
1304 * ainstr = 0xE7800000;
1305 * ainstr |= ntBITS (4, 5) << 7;
1306 * ainstr |= ntBITS (0, 3);
1310 * ainstr |= (Rn << 16);
1311 * ainstr |= (Rt << 12);
1312 * pvalid = t_decoded;
1313 break;
1316 case 0xC1: // STRH
1317 case 0xC5: // LDRH
1319 ARMword Rn = tBITS (0, 3);
1320 ARMword Rt = ntBITS (12, 15);
1321 ARMword address;
1323 tASSERT (Rn != 15);
1325 if (tBIT (4) == 1)
1327 if (tBIT (7))
1329 // LDRH<c>.W <Rt>,[<Rn>{,#<imm12>}]
1330 ARMword imm12 = ntBITS (0, 11);
1331 address = state->Reg[Rn] + imm12;
1333 else if (ntBIT (11))
1335 // LDRH<c> <Rt>,[<Rn>,#-<imm8>]
1336 // LDRH<c> <Rt>,[<Rn>],#+/-<imm8>
1337 // LDRH<c> <Rt>,[<Rn>,#+/-<imm8>]!
1338 ARMword P = ntBIT (10);
1339 ARMword U = ntBIT (9);
1340 ARMword W = ntBIT (8);
1341 ARMword imm8 = ntBITS (0, 7);
1343 tASSERT (Rn != 15);
1344 tASSERT (! (P && U && !W));
1346 * ainstr = 0xE05000B0;
1347 * ainstr |= (P << 24);
1348 * ainstr |= (U << 23);
1349 * ainstr |= (W << 21);
1350 * ainstr |= (Rn << 16);
1351 * ainstr |= (Rt << 12);
1352 * ainstr |= ((imm8 & 0xF0) << 4);
1353 * ainstr |= (imm8 & 0xF);
1354 * pvalid = t_decoded;
1355 break;
1357 else
1359 // LDRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1360 ARMword Rm = ntBITS (0, 3);
1361 ARMword imm2 = ntBITS (4, 5);
1363 tASSERT (ntBITS (6, 10) == 0);
1365 address = state->Reg[Rn] + (state->Reg[Rm] << imm2);
1368 state->Reg[Rt] = ARMul_LoadHalfWord (state, address);
1370 else
1372 if (tBIT (7))
1374 // STRH<c>.W <Rt>,[<Rn>{,#<imm12>}]
1375 ARMword imm12 = ntBITS (0, 11);
1377 address = state->Reg[Rn] + imm12;
1379 else if (ntBIT (11))
1381 // STRH<c> <Rt>,[<Rn>,#-<imm8>]
1382 // STRH<c> <Rt>,[<Rn>],#+/-<imm8>
1383 // STRH<c> <Rt>,[<Rn>,#+/-<imm8>]!
1384 ARMword P = ntBIT (10);
1385 ARMword U = ntBIT (9);
1386 ARMword W = ntBIT (8);
1387 ARMword imm8 = ntBITS (0, 7);
1389 tASSERT (! (P && U && !W));
1391 * ainstr = 0xE04000B0;
1392 * ainstr |= (P << 24);
1393 * ainstr |= (U << 23);
1394 * ainstr |= (W << 21);
1395 * ainstr |= (Rn << 16);
1396 * ainstr |= (Rt << 12);
1397 * ainstr |= ((imm8 & 0xF0) << 4);
1398 * ainstr |= (imm8 & 0xF);
1399 * pvalid = t_decoded;
1400 break;
1402 else
1404 // STRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1405 ARMword Rm = ntBITS (0, 3);
1406 ARMword imm2 = ntBITS (4, 5);
1408 tASSERT (ntBITS (6, 10) == 0);
1410 address = state->Reg[Rn] + (state->Reg[Rm] << imm2);
1413 ARMul_StoreHalfWord (state, address, state->Reg [Rt]);
1415 * pvalid = t_branch;
1416 break;
1419 case 0xC6: // LDR.W/STR.W
1421 ARMword Rn = tBITS (0, 3);
1422 ARMword Rt = ntBITS (12, 15);
1423 ARMword imm12 = ntBITS (0, 11);
1424 ARMword address = state->Reg[Rn];
1426 if (Rn == 15)
1428 // LDR<c>.W <Rt>,<label>
1429 tASSERT (tBIT (4) == 1);
1430 // tASSERT (tBIT (7) == 1)
1433 address += imm12;
1434 if (tBIT (4) == 1)
1435 state->Reg[Rt] = ARMul_LoadWordN (state, address);
1436 else
1437 ARMul_StoreWordN (state, address, state->Reg [Rt]);
1439 * pvalid = t_resolved;
1440 break;
1443 case 0xC8:
1444 case 0xCC: // LDRSB
1446 ARMword Rt = ntBITS (12, 15);
1447 ARMword Rn = tBITS (0, 3);
1448 ARMword U = tBIT (7);
1449 ARMword address = state->Reg[Rn];
1451 tASSERT (tBIT (4) == 1);
1452 tASSERT (Rt != 15); // PLI
1454 if (Rn == 15)
1456 // LDRSB<c> <Rt>,<label>
1457 ARMword imm12 = ntBITS (0, 11);
1458 address += (U ? imm12 : - imm12);
1460 else if (U)
1462 // LDRSB<c> <Rt>,[<Rn>,#<imm12>]
1463 ARMword imm12 = ntBITS (0, 11);
1464 address += imm12;
1466 else if (ntBIT (11))
1468 // LDRSB<c> <Rt>,[<Rn>,#-<imm8>]
1469 // LDRSB<c> <Rt>,[<Rn>],#+/-<imm8>
1470 // LDRSB<c> <Rt>,[<Rn>,#+/-<imm8>]!
1471 * ainstr = 0xE05000D0;
1472 * ainstr |= ntBIT (10) << 24; // P
1473 * ainstr |= ntBIT (9) << 23; // U
1474 * ainstr |= ntBIT (8) << 21; // W
1475 * ainstr |= Rn << 16;
1476 * ainstr |= Rt << 12;
1477 * ainstr |= ntBITS (4, 7) << 8;
1478 * ainstr |= ntBITS (0, 3);
1479 * pvalid = t_decoded;
1480 break;
1482 else
1484 // LDRSB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1485 ARMword Rm = ntBITS (0, 3);
1486 ARMword imm2 = ntBITS (4,5);
1488 tASSERT (ntBITS (6, 11) == 0);
1490 address += (state->Reg[Rm] << imm2);
1493 state->Reg[Rt] = ARMul_LoadByte (state, address);
1494 if (state->Reg[Rt] & 0x80)
1495 state->Reg[Rt] |= -(1 << 8);
1497 * pvalid = t_resolved;
1498 break;
1501 case 0xC9:
1502 case 0xCD:// LDRSH
1504 ARMword Rt = ntBITS (12, 15);
1505 ARMword Rn = tBITS (0, 3);
1506 ARMword U = tBIT (7);
1507 ARMword address = state->Reg[Rn];
1509 tASSERT (tBIT (4) == 1);
1511 if (Rn == 15 || U == 1)
1513 // Rn==15 => LDRSH<c> <Rt>,<label>
1514 // Rn!=15 => LDRSH<c> <Rt>,[<Rn>,#<imm12>]
1515 ARMword imm12 = ntBITS (0, 11);
1517 address += (U ? imm12 : - imm12);
1519 else if (ntBIT (11))
1521 // LDRSH<c> <Rt>,[<Rn>,#-<imm8>]
1522 // LDRSH<c> <Rt>,[<Rn>],#+/-<imm8>
1523 // LDRSH<c> <Rt>,[<Rn>,#+/-<imm8>]!
1524 * ainstr = 0xE05000F0;
1525 * ainstr |= ntBIT (10) << 24; // P
1526 * ainstr |= ntBIT (9) << 23; // U
1527 * ainstr |= ntBIT (8) << 21; // W
1528 * ainstr |= Rn << 16;
1529 * ainstr |= Rt << 12;
1530 * ainstr |= ntBITS (4, 7) << 8;
1531 * ainstr |= ntBITS (0, 3);
1532 * pvalid = t_decoded;
1533 break;
1535 else /* U == 0 */
1537 // LDRSH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1538 ARMword Rm = ntBITS (0, 3);
1539 ARMword imm2 = ntBITS (4,5);
1541 tASSERT (ntBITS (6, 11) == 0);
1543 address += (state->Reg[Rm] << imm2);
1546 state->Reg[Rt] = ARMul_LoadHalfWord (state, address);
1547 if (state->Reg[Rt] & 0x8000)
1548 state->Reg[Rt] |= -(1 << 16);
1550 * pvalid = t_branch;
1551 break;
1554 case 0x0D0:
1556 ARMword Rm = ntBITS (0, 3);
1557 ARMword Rd = ntBITS (8, 11);
1559 tASSERT (ntBITS (12, 15) == 15);
1561 if (ntBIT (7) == 1)
1563 // SXTH<c>.W <Rd>,<Rm>{,<rotation>}
1564 ARMword ror = ntBITS (4, 5) << 3;
1565 ARMword val;
1567 val = state->Reg[Rm];
1568 val = (val >> ror) | (val << (32 - ror));
1569 if (val & 0x8000)
1570 val |= -(1 << 16);
1571 state->Reg[Rd] = val;
1573 else
1575 // LSL{S}<c>.W <Rd>,<Rn>,<Rm>
1576 ARMword Rn = tBITS (0, 3);
1578 tASSERT (ntBITS (4, 6) == 0);
1580 state->Reg[Rd] = state->Reg[Rn] << (state->Reg[Rm] & 0xFF);
1581 if (tBIT (4))
1582 ARMul_NegZero (state, state->Reg[Rd]);
1584 * pvalid = t_branch;
1585 break;
1588 case 0x0D1: // LSR{S}<c>.W <Rd>,<Rn>,<Rm>
1590 ARMword Rd = ntBITS (8, 11);
1591 ARMword Rn = tBITS (0, 3);
1592 ARMword Rm = ntBITS (0, 3);
1594 tASSERT (ntBITS (12, 15) == 15);
1595 tASSERT (ntBITS (4, 7) == 0);
1597 state->Reg[Rd] = state->Reg[Rn] >> (state->Reg[Rm] & 0xFF);
1598 if (tBIT (4))
1599 ARMul_NegZero (state, state->Reg[Rd]);
1600 * pvalid = t_resolved;
1601 break;
1604 case 0xD2:
1605 tASSERT (ntBITS (12, 15) == 15);
1606 if (ntBIT (7))
1608 tASSERT (ntBIT (6) == 0);
1609 // UXTB<c>.W <Rd>,<Rm>{,<rotation>}
1610 * ainstr = 0xE6EF0070;
1611 * ainstr |= (ntBITS (4, 5) << 10); // rotate
1612 * ainstr |= ntBITS (0, 3); // Rm
1614 else
1616 // ASR{S}<c>.W <Rd>,<Rn>,<Rm>
1617 tASSERT (ntBITS (4, 7) == 0);
1618 * ainstr = 0xE1A00050;
1619 if (! in_IT_block ())
1620 * ainstr |= (tBIT (4) << 20);
1621 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1622 * ainstr |= tBITS (0, 3); // Rn
1625 * ainstr |= (ntBITS (8, 11) << 12); // Rd
1626 * pvalid = t_decoded;
1627 break;
1629 case 0xD3: // ROR{S}<c>.W <Rd>,<Rn>,<Rm>
1630 tASSERT (ntBITS (12, 15) == 15);
1631 tASSERT (ntBITS (4, 7) == 0);
1632 * ainstr = 0xE1A00070;
1633 if (! in_IT_block ())
1634 * ainstr |= (tBIT (4) << 20);
1635 * ainstr |= (ntBITS (8, 11) << 12); // Rd
1636 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1637 * ainstr |= (tBITS (0, 3) << 0); // Rn
1638 * pvalid = t_decoded;
1639 break;
1641 case 0xD4:
1643 ARMword Rn = tBITS (0, 3);
1644 ARMword Rd = ntBITS (8, 11);
1645 ARMword Rm = ntBITS (0, 3);
1647 tASSERT (ntBITS (12, 15) == 15);
1649 if (ntBITS (4, 7) == 8)
1651 // REV<c>.W <Rd>,<Rm>
1652 ARMword val = state->Reg[Rm];
1654 tASSERT (Rm == Rn);
1656 state->Reg [Rd] =
1657 (val >> 24)
1658 | ((val >> 8) & 0xFF00)
1659 | ((val << 8) & 0xFF0000)
1660 | (val << 24);
1661 * pvalid = t_resolved;
1663 else
1665 tASSERT (ntBITS (4, 7) == 4);
1667 if (tBIT (4) == 1)
1668 // UADD8<c> <Rd>,<Rn>,<Rm>
1669 * ainstr = 0xE6500F10;
1670 else
1671 // UADD16<c> <Rd>,<Rn>,<Rm>
1672 * ainstr = 0xE6500F90;
1674 * ainstr |= (Rn << 16);
1675 * ainstr |= (Rd << 12);
1676 * ainstr |= (Rm << 0);
1677 * pvalid = t_decoded;
1679 break;
1682 case 0xD5:
1684 ARMword Rn = tBITS (0, 3);
1685 ARMword Rd = ntBITS (8, 11);
1686 ARMword Rm = ntBITS (0, 3);
1688 tASSERT (ntBITS (12, 15) == 15);
1689 tASSERT (ntBITS (4, 7) == 8);
1691 if (tBIT (4))
1693 // CLZ<c> <Rd>,<Rm>
1694 tASSERT (Rm == Rn);
1695 * ainstr = 0xE16F0F10;
1697 else
1699 // SEL<c> <Rd>,<Rn>,<Rm>
1700 * ainstr = 0xE6800FB0;
1701 * ainstr |= (Rn << 16);
1704 * ainstr |= (Rd << 12);
1705 * ainstr |= (Rm << 0);
1706 * pvalid = t_decoded;
1707 break;
1710 case 0xD8: // MUL
1712 ARMword Rn = tBITS (0, 3);
1713 ARMword Rm = ntBITS (0, 3);
1714 ARMword Rd = ntBITS (8, 11);
1715 ARMword Ra = ntBITS (12, 15);
1717 if (tBIT (4))
1719 // SMLA<x><y><c> <Rd>,<Rn>,<Rm>,<Ra>
1720 ARMword nval = state->Reg[Rn];
1721 ARMword mval = state->Reg[Rm];
1722 ARMword res;
1724 tASSERT (ntBITS (6, 7) == 0);
1725 tASSERT (Ra != 15);
1727 if (ntBIT (5))
1728 nval >>= 16;
1729 else
1730 nval &= 0xFFFF;
1732 if (ntBIT (4))
1733 mval >>= 16;
1734 else
1735 mval &= 0xFFFF;
1737 res = nval * mval;
1738 res += state->Reg[Ra];
1739 // FIXME: Test and clear/set the Q bit.
1740 state->Reg[Rd] = res;
1742 else
1744 if (ntBITS (4, 7) == 1)
1746 // MLS<c> <Rd>,<Rn>,<Rm>,<Ra>
1747 state->Reg[Rd] = state->Reg[Ra] - (state->Reg[Rn] * state->Reg[Rm]);
1749 else
1751 tASSERT (ntBITS (4, 7) == 0);
1753 if (Ra == 15)
1754 // MUL<c> <Rd>,<Rn>,<Rm>
1755 state->Reg[Rd] = state->Reg[Rn] * state->Reg[Rm];
1756 else
1757 // MLA<c> <Rd>,<Rn>,<Rm>,<Ra>
1758 state->Reg[Rd] = state->Reg[Rn] * state->Reg[Rm] + state->Reg[Ra];
1761 * pvalid = t_resolved;
1762 break;
1765 case 0xDC:
1766 if (tBIT (4) == 0 && ntBITS (4, 7) == 0)
1768 // SMULL
1769 * ainstr = 0xE0C00090;
1770 * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1771 * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1772 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1773 * ainstr |= tBITS (0, 3); // Rn
1774 * pvalid = t_decoded;
1776 else if (tBIT (4) == 1 && ntBITS (4, 7) == 0xF)
1778 // SDIV
1779 * ainstr = 0xE710F010;
1780 * ainstr |= (ntBITS (8, 11) << 16); // Rd
1781 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1782 * ainstr |= tBITS (0, 3); // Rn
1783 * pvalid = t_decoded;
1785 else
1787 fprintf (stderr, "(op = %x) ", tBITS (5,12));
1788 tASSERT (0);
1789 return;
1791 break;
1793 case 0xDD:
1794 if (tBIT (4) == 0 && ntBITS (4, 7) == 0)
1796 // UMULL
1797 * ainstr = 0xE0800090;
1798 * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1799 * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1800 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1801 * ainstr |= tBITS (0, 3); // Rn
1802 * pvalid = t_decoded;
1804 else if (tBIT (4) == 1 && ntBITS (4, 7) == 0xF)
1806 // UDIV
1807 * ainstr = 0xE730F010;
1808 * ainstr |= (ntBITS (8, 11) << 16); // Rd
1809 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1810 * ainstr |= tBITS (0, 3); // Rn
1811 * pvalid = t_decoded;
1813 else
1815 fprintf (stderr, "(op = %x) ", tBITS (5,12));
1816 tASSERT (0);
1817 return;
1819 break;
1821 case 0xDF: // UMLAL
1822 tASSERT (tBIT (4) == 0);
1823 tASSERT (ntBITS (4, 7) == 0);
1824 * ainstr = 0xE0A00090;
1825 * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1826 * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1827 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1828 * ainstr |= tBITS (0, 3); // Rn
1829 * pvalid = t_decoded;
1830 break;
1832 default:
1833 fprintf (stderr, "(op = %x) ", tBITS (5,12));
1834 tASSERT (0);
1835 return;
1838 /* Tell the Thumb decoder to skip the next 16-bit insn - it was
1839 part of this insn - unless this insn has changed the PC. */
1840 skipping_32bit_thumb = pc + 2;
1843 /* Attempt to emulate an ARMv6 instruction.
1844 Stores t_branch into PVALUE upon success or t_undefined otherwise. */
1846 static void
1847 handle_v6_thumb_insn (ARMul_State * state,
1848 ARMword tinstr,
1849 ARMword next_instr,
1850 ARMword pc,
1851 ARMword * ainstr,
1852 tdstate * pvalid)
1854 if (! state->is_v6)
1856 * pvalid = t_undefined;
1857 return;
1860 if (tBITS (12, 15) == 0xB
1861 && tBIT (10) == 0
1862 && tBIT (8) == 1)
1864 // Conditional branch forwards.
1865 ARMword Rn = tBITS (0, 2);
1866 ARMword imm5 = tBIT (9) << 5 | tBITS (3, 7);
1868 if (tBIT (11))
1870 if (state->Reg[Rn] != 0)
1872 state->Reg[15] = (pc + 4 + imm5 * 2);
1873 FLUSHPIPE;
1876 else
1878 if (state->Reg[Rn] == 0)
1880 state->Reg[15] = (pc + 4 + imm5 * 2);
1881 FLUSHPIPE;
1884 * pvalid = t_branch;
1885 return;
1888 switch (tinstr & 0xFFC0)
1890 case 0x4400:
1891 case 0x4480:
1892 case 0x4440:
1893 case 0x44C0: // ADD
1895 ARMword Rd = (tBIT (7) << 3) | tBITS (0, 2);
1896 ARMword Rm = tBITS (3, 6);
1897 state->Reg[Rd] += state->Reg[Rm];
1898 break;
1901 case 0x4600: // MOV<c> <Rd>,<Rm>
1903 // instr [15, 8] = 0100 0110
1904 // instr [7] = Rd<high>
1905 // instr [6,3] = Rm
1906 // instr [2,0] = Rd<low>
1907 ARMword Rd = (tBIT(7) << 3) | tBITS (0, 2);
1908 // FIXME: Check for Rd == 15 and ITblock.
1909 state->Reg[Rd] = state->Reg[tBITS (3, 6)];
1910 break;
1913 case 0xBF00:
1914 case 0xBF40:
1915 case 0xBF80:
1916 case 0xBFC0:
1917 handle_IT_block (state, tinstr, pvalid);
1918 return;
1920 case 0xE840:
1921 case 0xE880: // LDMIA
1922 case 0xE8C0:
1923 case 0xE900: // STM
1924 case 0xE940:
1925 case 0xE980:
1926 case 0xE9C0: // LDRD
1927 case 0xEA00: // BIC
1928 case 0xEA40: // ORR
1929 case 0xEA80: // EOR
1930 case 0xEAC0:
1931 case 0xEB00: // ADD
1932 case 0xEB40: // SBC
1933 case 0xEB80: // SUB
1934 case 0xEBC0: // RSB
1935 case 0xFA80: // UADD, SEL
1936 case 0xFBC0: // UMULL, SMULL, SDIV, UDIV
1937 handle_T2_insn (state, tinstr, next_instr, pc, ainstr, pvalid);
1938 return;
1940 case 0xba00: /* rev */
1942 ARMword val = state->Reg[tBITS (3, 5)];
1943 state->Reg [tBITS (0, 2)] =
1944 (val >> 24)
1945 | ((val >> 8) & 0xFF00)
1946 | ((val << 8) & 0xFF0000)
1947 | (val << 24);
1948 break;
1951 case 0xba40: /* rev16 */
1953 ARMword val = state->Reg[tBITS (3, 5)];
1954 state->Reg [tBITS (0, 2)] = (val >> 16) | (val << 16);
1955 break;
1958 case 0xb660: /* cpsie */
1959 case 0xb670: /* cpsid */
1960 case 0xbac0: /* revsh */
1961 case 0xb650: /* setend */
1962 default:
1963 printf ("Unhandled v6 thumb insn: %04x\n", tinstr);
1964 * pvalid = t_undefined;
1965 return;
1967 case 0xb200: /* sxth */
1969 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1971 if (Rm & 0x8000)
1972 state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000;
1973 else
1974 state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1975 break;
1978 case 0xb240: /* sxtb */
1980 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1982 if (Rm & 0x80)
1983 state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00;
1984 else
1985 state->Reg [(tinstr & 0x7)] = Rm & 0xff;
1986 break;
1989 case 0xb280: /* uxth */
1991 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1993 state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1994 break;
1997 case 0xb2c0: /* uxtb */
1999 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
2001 state->Reg [(tinstr & 0x7)] = Rm & 0xff;
2002 break;
2005 /* Indicate that the instruction has been processed. */
2006 * pvalid = t_branch;
2009 /* Decode a 16bit Thumb instruction. The instruction is in the low
2010 16-bits of the tinstr field, with the following Thumb instruction
2011 held in the high 16-bits. Passing in two Thumb instructions allows
2012 easier simulation of the special dual BL instruction. */
2014 tdstate
2015 ARMul_ThumbDecode (ARMul_State * state,
2016 ARMword pc,
2017 ARMword tinstr,
2018 ARMword * ainstr)
2020 tdstate valid = t_decoded; /* default assumes a valid instruction */
2021 ARMword next_instr;
2022 ARMword old_tinstr = tinstr;
2024 if (skipping_32bit_thumb == pc)
2026 skipping_32bit_thumb = 0;
2027 return t_branch;
2029 skipping_32bit_thumb = 0;
2031 if (state->bigendSig)
2033 next_instr = tinstr & 0xFFFF;
2034 tinstr >>= 16;
2036 else
2038 next_instr = tinstr >> 16;
2039 tinstr &= 0xFFFF;
2042 if (! IT_block_allow (state))
2044 if ( tBITS (11, 15) == 0x1F
2045 || tBITS (11, 15) == 0x1E
2046 || tBITS (11, 15) == 0x1D)
2048 if (trace)
2049 fprintf (stderr, "pc: %x, SKIP instr: %04x|%04x\n",
2050 pc & ~1, tinstr, next_instr);
2051 skipping_32bit_thumb = pc + 2;
2053 else if (trace)
2054 fprintf (stderr, "pc: %x, SKIP instr: %04x\n", pc & ~1, tinstr);
2056 return t_branch;
2059 old_tinstr = tinstr;
2060 if (trace)
2061 fprintf (stderr, "pc: %x, Thumb instr: %x", pc & ~1, tinstr);
2063 #if 1 /* debugging to catch non updates */
2064 *ainstr = 0xDEADC0DE;
2065 #endif
2067 switch ((tinstr & 0xF800) >> 11)
2069 case 0: /* LSL */
2070 case 1: /* LSR */
2071 case 2: /* ASR */
2072 /* Format 1 */
2073 *ainstr = 0xE1B00000 /* base opcode */
2074 | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */
2075 | ((tinstr & 0x07C0) << (7 - 6)) /* imm5 */
2076 | ((tinstr & 0x0038) >> 3) /* Rs */
2077 | ((tinstr & 0x0007) << 12); /* Rd */
2078 break;
2079 case 3: /* ADD/SUB */
2080 /* Format 2 */
2082 ARMword subset[4] =
2084 0xE0900000, /* ADDS Rd,Rs,Rn */
2085 0xE0500000, /* SUBS Rd,Rs,Rn */
2086 0xE2900000, /* ADDS Rd,Rs,#imm3 */
2087 0xE2500000 /* SUBS Rd,Rs,#imm3 */
2089 /* It is quicker indexing into a table, than performing switch
2090 or conditionals: */
2091 *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */
2092 | ((tinstr & 0x01C0) >> 6) /* Rn or imm3 */
2093 | ((tinstr & 0x0038) << (16 - 3)) /* Rs */
2094 | ((tinstr & 0x0007) << (12 - 0)); /* Rd */
2096 if (in_IT_block ())
2097 *ainstr &= ~ (1 << 20);
2099 break;
2100 case 4:
2101 * ainstr = 0xE3A00000; /* MOV Rd,#imm8 */
2102 if (! in_IT_block ())
2103 * ainstr |= (1 << 20);
2104 * ainstr |= tBITS (8, 10) << 12;
2105 * ainstr |= tBITS (0, 7);
2106 break;
2108 case 5:
2109 * ainstr = 0xE3500000; /* CMP Rd,#imm8 */
2110 * ainstr |= tBITS (8, 10) << 16;
2111 * ainstr |= tBITS (0, 7);
2112 break;
2114 case 6:
2115 case 7:
2116 * ainstr = tBIT (11)
2117 ? 0xE2400000 /* SUB Rd,Rd,#imm8 */
2118 : 0xE2800000; /* ADD Rd,Rd,#imm8 */
2119 if (! in_IT_block ())
2120 * ainstr |= (1 << 20);
2121 * ainstr |= tBITS (8, 10) << 12;
2122 * ainstr |= tBITS (8, 10) << 16;
2123 * ainstr |= tBITS (0, 7);
2124 break;
2126 case 8: /* Arithmetic and high register transfers */
2127 /* TODO: Since the subsets for both Format 4 and Format 5
2128 instructions are made up of different ARM encodings, we could
2129 save the following conditional, and just have one large
2130 subset. */
2131 if ((tinstr & (1 << 10)) == 0)
2133 /* Format 4 */
2134 struct insn_format {
2135 ARMword opcode;
2136 enum { t_norm, t_shift, t_neg, t_mul } otype;
2138 static const struct insn_format subset[16] =
2140 { 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */
2141 { 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */
2142 { 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */
2143 { 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */
2144 { 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */
2145 { 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */
2146 { 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */
2147 { 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */
2148 { 0xE1100000, t_norm}, /* TST Rd,Rs */
2149 { 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */
2150 { 0xE1500000, t_norm}, /* CMP Rd,Rs */
2151 { 0xE1700000, t_norm}, /* CMN Rd,Rs */
2152 { 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */
2153 { 0xE0100090, t_mul} , /* MULS Rd,Rd,Rs */
2154 { 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */
2155 { 0xE1F00000, t_norm} /* MVNS Rd,Rs */
2157 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
2159 if (in_IT_block ())
2161 static const struct insn_format it_subset[16] =
2163 { 0xE0000000, t_norm}, /* AND Rd,Rd,Rs */
2164 { 0xE0200000, t_norm}, /* EOR Rd,Rd,Rs */
2165 { 0xE1A00010, t_shift}, /* MOV Rd,Rd,LSL Rs */
2166 { 0xE1A00030, t_shift}, /* MOV Rd,Rd,LSR Rs */
2167 { 0xE1A00050, t_shift}, /* MOV Rd,Rd,ASR Rs */
2168 { 0xE0A00000, t_norm}, /* ADC Rd,Rd,Rs */
2169 { 0xE0C00000, t_norm}, /* SBC Rd,Rd,Rs */
2170 { 0xE1A00070, t_shift}, /* MOV Rd,Rd,ROR Rs */
2171 { 0xE1100000, t_norm}, /* TST Rd,Rs */
2172 { 0xE2600000, t_neg}, /* RSB Rd,Rs,#0 */
2173 { 0xE1500000, t_norm}, /* CMP Rd,Rs */
2174 { 0xE1700000, t_norm}, /* CMN Rd,Rs */
2175 { 0xE1800000, t_norm}, /* ORR Rd,Rd,Rs */
2176 { 0xE0000090, t_mul} , /* MUL Rd,Rd,Rs */
2177 { 0xE1C00000, t_norm}, /* BIC Rd,Rd,Rs */
2178 { 0xE1E00000, t_norm} /* MVN Rd,Rs */
2180 *ainstr = it_subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
2183 switch (subset[(tinstr & 0x03C0) >> 6].otype)
2185 case t_norm:
2186 *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */
2187 | ((tinstr & 0x0007) << 12) /* Rd */
2188 | ((tinstr & 0x0038) >> 3); /* Rs */
2189 break;
2190 case t_shift:
2191 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
2192 | ((tinstr & 0x0007) >> 0) /* Rm */
2193 | ((tinstr & 0x0038) << (8 - 3)); /* Rs */
2194 break;
2195 case t_neg:
2196 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
2197 | ((tinstr & 0x0038) << (16 - 3)); /* Rn */
2198 break;
2199 case t_mul:
2200 *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */
2201 | ((tinstr & 0x0007) << 8) /* Rs */
2202 | ((tinstr & 0x0038) >> 3); /* Rm */
2203 break;
2206 else
2208 /* Format 5 */
2209 ARMword Rd = ((tinstr & 0x0007) >> 0);
2210 ARMword Rs = ((tinstr & 0x0038) >> 3);
2211 if (tinstr & (1 << 7))
2212 Rd += 8;
2213 if (tinstr & (1 << 6))
2214 Rs += 8;
2215 switch ((tinstr & 0x03C0) >> 6)
2217 case 0x1: /* ADD Rd,Rd,Hs */
2218 case 0x2: /* ADD Hd,Hd,Rs */
2219 case 0x3: /* ADD Hd,Hd,Hs */
2220 *ainstr = 0xE0800000 /* base */
2221 | (Rd << 16) /* Rn */
2222 | (Rd << 12) /* Rd */
2223 | (Rs << 0); /* Rm */
2224 break;
2225 case 0x5: /* CMP Rd,Hs */
2226 case 0x6: /* CMP Hd,Rs */
2227 case 0x7: /* CMP Hd,Hs */
2228 *ainstr = 0xE1500000 /* base */
2229 | (Rd << 16) /* Rn */
2230 | (Rd << 12) /* Rd */
2231 | (Rs << 0); /* Rm */
2232 break;
2233 case 0x9: /* MOV Rd,Hs */
2234 case 0xA: /* MOV Hd,Rs */
2235 case 0xB: /* MOV Hd,Hs */
2236 *ainstr = 0xE1A00000 /* base */
2237 | (Rd << 12) /* Rd */
2238 | (Rs << 0); /* Rm */
2239 break;
2240 case 0xC: /* BX Rs */
2241 case 0xD: /* BX Hs */
2242 *ainstr = 0xE12FFF10 /* base */
2243 | ((tinstr & 0x0078) >> 3); /* Rd */
2244 break;
2245 case 0xE: /* UNDEFINED */
2246 case 0xF: /* UNDEFINED */
2247 if (state->is_v5)
2249 /* BLX Rs; BLX Hs */
2250 *ainstr = 0xE12FFF30 /* base */
2251 | ((tinstr & 0x0078) >> 3); /* Rd */
2252 break;
2254 ATTRIBUTE_FALLTHROUGH;
2255 default:
2256 case 0x0: /* UNDEFINED */
2257 case 0x4: /* UNDEFINED */
2258 case 0x8: /* UNDEFINED */
2259 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2260 break;
2263 break;
2264 case 9: /* LDR Rd,[PC,#imm8] */
2265 /* Format 6 */
2266 *ainstr = 0xE59F0000 /* base */
2267 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2268 | ((tinstr & 0x00FF) << (2 - 0)); /* off8 */
2269 break;
2270 case 10:
2271 case 11:
2272 /* TODO: Format 7 and Format 8 perform the same ARM encoding, so
2273 the following could be merged into a single subset, saving on
2274 the following boolean: */
2275 if ((tinstr & (1 << 9)) == 0)
2277 /* Format 7 */
2278 ARMword subset[4] = {
2279 0xE7800000, /* STR Rd,[Rb,Ro] */
2280 0xE7C00000, /* STRB Rd,[Rb,Ro] */
2281 0xE7900000, /* LDR Rd,[Rb,Ro] */
2282 0xE7D00000 /* LDRB Rd,[Rb,Ro] */
2284 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2285 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2286 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2287 | ((tinstr & 0x01C0) >> 6); /* Ro */
2289 else
2291 /* Format 8 */
2292 ARMword subset[4] = {
2293 0xE18000B0, /* STRH Rd,[Rb,Ro] */
2294 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */
2295 0xE19000B0, /* LDRH Rd,[Rb,Ro] */
2296 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */
2298 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2299 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2300 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2301 | ((tinstr & 0x01C0) >> 6); /* Ro */
2303 break;
2304 case 12: /* STR Rd,[Rb,#imm5] */
2305 case 13: /* LDR Rd,[Rb,#imm5] */
2306 case 14: /* STRB Rd,[Rb,#imm5] */
2307 case 15: /* LDRB Rd,[Rb,#imm5] */
2308 /* Format 9 */
2310 ARMword subset[4] = {
2311 0xE5800000, /* STR Rd,[Rb,#imm5] */
2312 0xE5900000, /* LDR Rd,[Rb,#imm5] */
2313 0xE5C00000, /* STRB Rd,[Rb,#imm5] */
2314 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */
2316 /* The offset range defends on whether we are transferring a
2317 byte or word value: */
2318 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */
2319 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2320 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2321 | ((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */
2323 break;
2324 case 16: /* STRH Rd,[Rb,#imm5] */
2325 case 17: /* LDRH Rd,[Rb,#imm5] */
2326 /* Format 10 */
2327 *ainstr = ((tinstr & (1 << 11)) /* base */
2328 ? 0xE1D000B0 /* LDRH */
2329 : 0xE1C000B0) /* STRH */
2330 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2331 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2332 | ((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */
2333 | ((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */
2334 break;
2335 case 18: /* STR Rd,[SP,#imm8] */
2336 case 19: /* LDR Rd,[SP,#imm8] */
2337 /* Format 11 */
2338 *ainstr = ((tinstr & (1 << 11)) /* base */
2339 ? 0xE59D0000 /* LDR */
2340 : 0xE58D0000) /* STR */
2341 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2342 | ((tinstr & 0x00FF) << 2); /* off8 */
2343 break;
2344 case 20: /* ADD Rd,PC,#imm8 */
2345 case 21: /* ADD Rd,SP,#imm8 */
2346 /* Format 12 */
2347 if ((tinstr & (1 << 11)) == 0)
2349 /* NOTE: The PC value used here should by word aligned */
2350 /* We encode shift-left-by-2 in the rotate immediate field,
2351 so no shift of off8 is needed. */
2352 *ainstr = 0xE28F0F00 /* base */
2353 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2354 | (tinstr & 0x00FF); /* off8 */
2356 else
2358 /* We encode shift-left-by-2 in the rotate immediate field,
2359 so no shift of off8 is needed. */
2360 *ainstr = 0xE28D0F00 /* base */
2361 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2362 | (tinstr & 0x00FF); /* off8 */
2364 break;
2365 case 22:
2366 case 23:
2367 switch (tinstr & 0x0F00)
2369 case 0x0000:
2370 /* Format 13 */
2371 /* NOTE: The instruction contains a shift left of 2
2372 equivalent (implemented as ROR #30): */
2373 *ainstr = ((tinstr & (1 << 7)) /* base */
2374 ? 0xE24DDF00 /* SUB */
2375 : 0xE28DDF00) /* ADD */
2376 | (tinstr & 0x007F); /* off7 */
2377 break;
2378 case 0x0400:
2379 /* Format 14 - Push */
2380 * ainstr = 0xE92D0000 | (tinstr & 0x00FF);
2381 break;
2382 case 0x0500:
2383 /* Format 14 - Push + LR */
2384 * ainstr = 0xE92D4000 | (tinstr & 0x00FF);
2385 break;
2386 case 0x0c00:
2387 /* Format 14 - Pop */
2388 * ainstr = 0xE8BD0000 | (tinstr & 0x00FF);
2389 break;
2390 case 0x0d00:
2391 /* Format 14 - Pop + PC */
2392 * ainstr = 0xE8BD8000 | (tinstr & 0x00FF);
2393 break;
2394 case 0x0e00:
2395 if (state->is_v5)
2397 /* This is normally an undefined instruction. The v5t architecture
2398 defines this particular pattern as a BKPT instruction, for
2399 hardware assisted debugging. We map onto the arm BKPT
2400 instruction. */
2401 if (state->is_v6)
2402 // Map to the SVC instruction instead of the BKPT instruction.
2403 * ainstr = 0xEF000000 | tBITS (0, 7);
2404 else
2405 * ainstr = 0xE1200070 | ((tinstr & 0xf0) << 4) | (tinstr & 0xf);
2406 break;
2408 ATTRIBUTE_FALLTHROUGH;
2409 default:
2410 /* Everything else is an undefined instruction. */
2411 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2412 break;
2414 break;
2415 case 24: /* STMIA */
2416 case 25: /* LDMIA */
2417 /* Format 15 */
2418 *ainstr = ((tinstr & (1 << 11)) /* base */
2419 ? 0xE8B00000 /* LDMIA */
2420 : 0xE8A00000) /* STMIA */
2421 | ((tinstr & 0x0700) << (16 - 8)) /* Rb */
2422 | (tinstr & 0x00FF); /* mask8 */
2423 break;
2424 case 26: /* Bcc */
2425 case 27: /* Bcc/SWI */
2426 if ((tinstr & 0x0F00) == 0x0F00)
2428 /* Format 17 : SWI */
2429 *ainstr = 0xEF000000;
2430 /* Breakpoint must be handled specially. */
2431 if ((tinstr & 0x00FF) == 0x18)
2432 *ainstr |= ((tinstr & 0x00FF) << 16);
2433 /* New breakpoint value. See gdb/arm-tdep.c */
2434 else if ((tinstr & 0x00FF) == 0xFE)
2435 *ainstr |= SWI_Breakpoint;
2436 else
2437 *ainstr |= (tinstr & 0x00FF);
2439 else if ((tinstr & 0x0F00) != 0x0E00)
2441 /* Format 16 */
2442 int doit = FALSE;
2443 /* TODO: Since we are doing a switch here, we could just add
2444 the SWI and undefined instruction checks into this
2445 switch to same on a couple of conditionals: */
2446 switch ((tinstr & 0x0F00) >> 8)
2448 case EQ:
2449 doit = ZFLAG;
2450 break;
2451 case NE:
2452 doit = !ZFLAG;
2453 break;
2454 case VS:
2455 doit = VFLAG;
2456 break;
2457 case VC:
2458 doit = !VFLAG;
2459 break;
2460 case MI:
2461 doit = NFLAG;
2462 break;
2463 case PL:
2464 doit = !NFLAG;
2465 break;
2466 case CS:
2467 doit = CFLAG;
2468 break;
2469 case CC:
2470 doit = !CFLAG;
2471 break;
2472 case HI:
2473 doit = (CFLAG && !ZFLAG);
2474 break;
2475 case LS:
2476 doit = (!CFLAG || ZFLAG);
2477 break;
2478 case GE:
2479 doit = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
2480 break;
2481 case LT:
2482 doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
2483 break;
2484 case GT:
2485 doit = ((!NFLAG && !VFLAG && !ZFLAG)
2486 || (NFLAG && VFLAG && !ZFLAG));
2487 break;
2488 case LE:
2489 doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
2490 break;
2492 if (doit)
2494 state->Reg[15] = (pc + 4
2495 + (((tinstr & 0x7F) << 1)
2496 | ((tinstr & (1 << 7)) ? 0xFFFFFF00 : 0)));
2497 FLUSHPIPE;
2499 valid = t_branch;
2501 else
2502 /* UNDEFINED : cc=1110(AL) uses different format. */
2503 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2504 break;
2505 case 28: /* B */
2506 /* Format 18 */
2507 state->Reg[15] = (pc + 4
2508 + (((tinstr & 0x3FF) << 1)
2509 | ((tinstr & (1 << 10)) ? 0xFFFFF800 : 0)));
2510 FLUSHPIPE;
2511 valid = t_branch;
2512 break;
2513 case 29: /* UNDEFINED */
2514 if (state->is_v6)
2516 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2517 break;
2520 if (state->is_v5)
2522 if (tinstr & 1)
2524 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2525 break;
2527 /* Drop through. */
2529 /* Format 19 */
2530 /* There is no single ARM instruction equivalent for this
2531 instruction. Also, it should only ever be matched with the
2532 fmt19 "BL/BLX instruction 1" instruction. However, we do
2533 allow the simulation of it on its own, with undefined results
2534 if r14 is not suitably initialised. */
2536 ARMword tmp = (pc + 2);
2538 state->Reg[15] = ((state->Reg[14] + ((tinstr & 0x07FF) << 1))
2539 & 0xFFFFFFFC);
2540 CLEART;
2541 state->Reg[14] = (tmp | 1);
2542 valid = t_branch;
2543 FLUSHPIPE;
2544 if (trace_funcs)
2545 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
2546 break;
2550 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2551 break;
2553 case 30: /* BL instruction 1 */
2554 if (state->is_v6)
2556 handle_T2_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2557 break;
2560 /* Format 19 */
2561 /* There is no single ARM instruction equivalent for this Thumb
2562 instruction. To keep the simulation simple (from the user
2563 perspective) we check if the following instruction is the
2564 second half of this BL, and if it is we simulate it
2565 immediately. */
2566 state->Reg[14] = state->Reg[15] \
2567 + (((tinstr & 0x07FF) << 12) \
2568 | ((tinstr & (1 << 10)) ? 0xFF800000 : 0));
2570 valid = t_branch; /* in-case we don't have the 2nd half */
2571 tinstr = next_instr; /* move the instruction down */
2572 pc += 2; /* point the pc at the 2nd half */
2573 if (((tinstr & 0xF800) >> 11) != 31)
2575 if (((tinstr & 0xF800) >> 11) == 29)
2577 ARMword tmp = (pc + 2);
2579 state->Reg[15] = ((state->Reg[14]
2580 + ((tinstr & 0x07FE) << 1))
2581 & 0xFFFFFFFC);
2582 CLEART;
2583 state->Reg[14] = (tmp | 1);
2584 valid = t_branch;
2585 FLUSHPIPE;
2587 else
2588 /* Exit, since not correct instruction. */
2589 pc -= 2;
2590 break;
2592 /* else we fall through to process the second half of the BL */
2593 pc += 2; /* point the pc at the 2nd half */
2594 ATTRIBUTE_FALLTHROUGH;
2595 case 31: /* BL instruction 2 */
2596 if (state->is_v6)
2598 handle_T2_insn (state, old_tinstr, next_instr, pc, ainstr, & valid);
2599 break;
2602 /* Format 19 */
2603 /* There is no single ARM instruction equivalent for this
2604 instruction. Also, it should only ever be matched with the
2605 fmt19 "BL instruction 1" instruction. However, we do allow
2606 the simulation of it on its own, with undefined results if
2607 r14 is not suitably initialised. */
2609 ARMword tmp = pc;
2611 state->Reg[15] = (state->Reg[14] + ((tinstr & 0x07FF) << 1));
2612 state->Reg[14] = (tmp | 1);
2613 valid = t_branch;
2614 FLUSHPIPE;
2616 break;
2619 if (trace && valid != t_decoded)
2620 fprintf (stderr, "\n");
2622 return valid;