Remove path name from test case
[binutils-gdb.git] / sim / arm / thumbemu.c
1 /* thumbemu.c -- Thumb instruction emulation.
2 Copyright (C) 1996, Cygnus Software Technologies Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>. */
16
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. */
20
21 /* This must come before any other includes. */
22 #include "defs.h"
23
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
31
32 #include "armdefs.h"
33 #include "armemu.h"
34 #include "armos.h"
35
36 #define tBIT(n) ( (ARMword)(tinstr >> (n)) & 1)
37 #define tBITS(m,n) ( (ARMword)(tinstr << (31 - (n))) >> ((31 - (n)) + (m)) )
38
39 #define ntBIT(n) ( (ARMword)(next_instr >> (n)) & 1)
40 #define ntBITS(m,n) ( (ARMword)(next_instr << (31 - (n))) >> ((31 - (n)) + (m)) )
41
42 static int
43 test_cond (int cond, ARMul_State * state)
44 {
45 switch (cond)
46 {
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;
65 }
66 }
67
68 static ARMword skipping_32bit_thumb = 0;
69
70 static int IT_block_cond = AL;
71 static ARMword IT_block_mask = 0;
72 static int IT_block_first = FALSE;
73
74 static void
75 handle_IT_block (ARMul_State * state,
76 ARMword tinstr,
77 tdstate * pvalid)
78 {
79 * pvalid = t_branch;
80 IT_block_mask = tBITS (0, 3);
81
82 if (IT_block_mask == 0)
83 // NOP or a HINT.
84 return;
85
86 IT_block_cond = tBITS (4, 7);
87 IT_block_first = TRUE;
88 }
89
90 static int
91 in_IT_block (void)
92 {
93 return IT_block_mask != 0;
94 }
95
96 static int
97 IT_block_allow (ARMul_State * state)
98 {
99 int cond;
100
101 if (IT_block_mask == 0)
102 return TRUE;
103
104 cond = IT_block_cond;
105
106 if (IT_block_first)
107 IT_block_first = FALSE;
108 else
109 {
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;
116 }
117
118 if (IT_block_mask == 0x8)
119 IT_block_mask = 0;
120
121 return test_cond (cond, state);
122 }
123
124 static ARMword
125 ThumbExpandImm (ARMword tinstr)
126 {
127 ARMword val;
128
129 if (tBITS (10, 11) == 0)
130 {
131 switch (tBITS (8, 9))
132 {
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;
138 }
139 }
140 else
141 {
142 int ror = tBITS (7, 11);
143
144 val = (1 << 7) | tBITS (0, 6);
145 val = (val >> ror) | (val << (32 - ror));
146 }
147
148 return val;
149 }
150
151 #define tASSERT(truth) \
152 do \
153 { \
154 if (! (truth)) \
155 { \
156 fprintf (stderr, "unhandled T2 insn %04x|%04x detected at thumbemu.c:%d\n", \
157 tinstr, next_instr, __LINE__); \
158 return ; \
159 } \
160 } \
161 while (0)
162
163
164 /* Attempt to emulate a 32-bit ARMv7 Thumb instruction.
165 Stores t_branch into PVALUE upon success or t_undefined otherwise. */
166
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)
174 {
175 * pvalid = t_undefined;
176
177 if (! state->is_v6)
178 return;
179
180 if (trace)
181 fprintf (stderr, "|%04x ", next_instr);
182
183 if (tBITS (11, 15) == 0x1E && ntBIT (15) == 1)
184 {
185 ARMsword simm32 = 0;
186 int S = tBIT (10);
187
188 * pvalid = t_branch;
189 switch ((ntBIT (14) << 1) | ntBIT (12))
190 {
191 case 0: /* B<c>.W */
192 {
193 ARMword cond = tBITS (6, 9);
194 ARMword imm6;
195 ARMword imm11;
196 ARMword J1;
197 ARMword J2;
198
199 tASSERT (cond != AL && cond != NV);
200 if (! test_cond (cond, state))
201 return;
202
203 imm6 = tBITS (0, 5);
204 imm11 = ntBITS (0, 10);
205 J1 = ntBIT (13);
206 J2 = ntBIT (11);
207
208 simm32 = (J1 << 19) | (J2 << 18) | (imm6 << 12) | (imm11 << 1);
209 if (S)
210 simm32 |= -(1 << 20);
211 break;
212 }
213
214 case 1: /* B.W */
215 {
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;
220
221 simm32 = (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
222 if (S)
223 simm32 |= -(1 << 24);
224 break;
225 }
226
227 case 2: /* BLX <label> */
228 {
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;
233
234 simm32 = (I1 << 23) | (I2 << 22) | (imm10h << 12) | (imm10l << 2);
235 if (S)
236 simm32 |= -(1 << 24);
237
238 CLEART;
239 state->Reg[14] = (pc + 4) | 1;
240 break;
241 }
242
243 case 3: /* BL <label> */
244 {
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;
249
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;
255 }
256 }
257
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;
263 }
264
265 switch (tBITS (5,12))
266 {
267 case 0x29: // TST<c>.W <Rn>,<Rm>{,<shift>}
268 {
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);
273
274 tASSERT (ntBITS (8, 11) == 0xF);
275
276 * ainstr = 0xE1100000;
277 * ainstr |= (Rn << 16);
278 * ainstr |= (Rm);
279 * ainstr |= (type << 5);
280 * ainstr |= (imm5 << 7);
281 * pvalid = t_decoded;
282 break;
283 }
284
285 case 0x46:
286 if (tBIT (4) && ntBITS (5, 15) == 0x780)
287 {
288 // Table Branch
289 ARMword Rn = tBITS (0, 3);
290 ARMword Rm = ntBITS (0, 3);
291 ARMword address, dest;
292
293 if (ntBIT (4))
294 {
295 // TBH
296 address = state->Reg[Rn] + state->Reg[Rm] * 2;
297 dest = ARMul_LoadHalfWord (state, address);
298 }
299 else
300 {
301 // TBB
302 address = state->Reg[Rn] + state->Reg[Rm];
303 dest = ARMul_LoadByte (state, address);
304 }
305
306 state->Reg[15] = (pc + 4 + dest * 2);
307 FLUSHPIPE;
308 * pvalid = t_branch;
309 break;
310 }
311 /* Fall through. */
312 case 0x42:
313 case 0x43:
314 case 0x47:
315 case 0x4A:
316 case 0x4B:
317 case 0x4E: // STRD
318 case 0x4F: // LDRD
319 {
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);
327
328 tASSERT (Rt2 == Rt + 1);
329 imm8 <<= 2;
330 tASSERT (imm8 <= 255);
331 tASSERT (P != 0 || W != 0);
332
333 // Convert into an ARM A1 encoding.
334 if (Rn == 15)
335 {
336 tASSERT (tBIT (4) == 1);
337 // LDRD (literal)
338 // Ignore W even if 1.
339 * ainstr = 0xE14F00D0;
340 }
341 else
342 {
343 if (tBIT (4) == 1)
344 // LDRD (immediate)
345 * ainstr = 0xE04000D0;
346 else
347 {
348 // STRD<c> <Rt>,<Rt2>,[<Rn>{,#+/-<imm8>}]
349 // STRD<c> <Rt>,<Rt2>,[<Rn>],#+/-<imm8>
350 // STRD<c> <Rt>,<Rt2>,[<Rn>,#+/-<imm8>]!
351 * ainstr = 0xE04000F0;
352 }
353 * ainstr |= (Rn << 16);
354 * ainstr |= (P << 24);
355 * ainstr |= (W << 21);
356 }
357
358 * ainstr |= (U << 23);
359 * ainstr |= (Rt << 12);
360 * ainstr |= ((imm8 << 4) & 0xF00);
361 * ainstr |= (imm8 & 0xF);
362 * pvalid = t_decoded;
363 break;
364 }
365
366 case 0x44:
367 case 0x45: // LDMIA
368 {
369 ARMword Rn = tBITS (0, 3);
370 int W = tBIT (5);
371 ARMword list = (ntBIT (15) << 15) | (ntBIT (14) << 14) | ntBITS (0, 12);
372
373 if (Rn == 13)
374 * ainstr = 0xE8BD0000;
375 else
376 {
377 * ainstr = 0xE8900000;
378 * ainstr |= (W << 21);
379 * ainstr |= (Rn << 16);
380 }
381 * ainstr |= list;
382 * pvalid = t_decoded;
383 break;
384 }
385
386 case 0x48:
387 case 0x49: // STMDB
388 {
389 ARMword Rn = tBITS (0, 3);
390 int W = tBIT (5);
391 ARMword list = (ntBIT (14) << 14) | ntBITS (0, 12);
392
393 if (Rn == 13 && W)
394 * ainstr = 0xE92D0000;
395 else
396 {
397 * ainstr = 0xE9000000;
398 * ainstr |= (W << 21);
399 * ainstr |= (Rn << 16);
400 }
401 * ainstr |= list;
402 * pvalid = t_decoded;
403 break;
404 }
405
406 case 0x50:
407 {
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);
413
414 tASSERT (ntBIT (15) == 0);
415
416 if (Rd == 15)
417 {
418 tASSERT (tBIT (4) == 1);
419
420 // TST<c>.W <Rn>,<Rm>{,<shift>}
421 * ainstr = 0xE1100000;
422 }
423 else
424 {
425 // AND{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
426 int S = tBIT (4);
427
428 * ainstr = 0xE0000000;
429
430 if (in_IT_block ())
431 S = 0;
432 * ainstr |= (S << 20);
433 }
434
435 * ainstr |= (Rn << 16);
436 * ainstr |= (imm5 << 7);
437 * ainstr |= (type << 5);
438 * ainstr |= (Rm << 0);
439 * pvalid = t_decoded;
440 break;
441 }
442
443 case 0x51: // BIC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
444 {
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);
451
452 tASSERT (ntBIT (15) == 0);
453
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;
463 }
464
465 case 0x52:
466 {
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);
473
474 tASSERT (Rd != 15);
475
476 if (in_IT_block ())
477 S = 0;
478
479 if (Rn == 15)
480 {
481 tASSERT (ntBIT (15) == 0);
482
483 switch (ntBITS (4, 5))
484 {
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;
504 }
505 }
506 else
507 {
508 // ORR{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
509 * ainstr = 0xE1800000;
510 * ainstr |= (Rn << 16);
511 * ainstr |= (type << 5);
512 }
513
514 * ainstr |= (Rd << 12);
515 * ainstr |= (S << 20);
516 * ainstr |= (imm5 << 7);
517 * ainstr |= (Rm << 0);
518 * pvalid = t_decoded;
519 break;
520 }
521
522 case 0x53: // MVN{S}<c>.W <Rd>,<Rm>{,<shift>}
523 {
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);
529
530 tASSERT (ntBIT (15) == 0);
531
532 if (in_IT_block ())
533 S = 0;
534
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;
543 }
544
545 case 0x54:
546 {
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);
553
554 if (Rd == 15 && S)
555 {
556 // TEQ<c> <Rn>,<Rm>{,<shift>}
557 tASSERT (ntBIT (15) == 0);
558
559 * ainstr = 0xE1300000;
560 }
561 else
562 {
563 // EOR{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
564 if (in_IT_block ())
565 S = 0;
566
567 * ainstr = 0xE0200000;
568 * ainstr |= (S << 20);
569 * ainstr |= (Rd << 8);
570 }
571
572 * ainstr |= (Rn << 16);
573 * ainstr |= (imm5 << 7);
574 * ainstr |= (type << 5);
575 * ainstr |= (Rm << 0);
576 * pvalid = t_decoded;
577 break;
578 }
579
580 case 0x58: // ADD{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
581 {
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);
588
589 tASSERT (! (Rd == 15 && S));
590
591 if (in_IT_block ())
592 S = 0;
593
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;
603 }
604
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;
617
618 case 0x5B: // SBC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
619 {
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);
626
627 tASSERT (ntBIT (15) == 0);
628
629 if (in_IT_block ())
630 S = 0;
631
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;
641 }
642
643 case 0x5E: // RSB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>}
644 case 0x5D: // SUB{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
645 {
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);
652
653 tASSERT (ntBIT(15) == 0);
654
655 if (Rd == 15)
656 {
657 // CMP<c>.W <Rn>, <Rm> {,<shift>}
658 * ainstr = 0xE1500000;
659 Rd = 0;
660 }
661 else if (tBIT (5))
662 * ainstr = 0xE0400000;
663 else
664 * ainstr = 0xE0600000;
665
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;
674 }
675
676 case 0x9D: // NOP.W
677 tASSERT (tBITS (0, 15) == 0xF3AF);
678 tASSERT (ntBITS (0, 15) == 0x8000);
679 * pvalid = t_branch;
680 break;
681
682 case 0x80: // AND
683 case 0xA0: // TST
684 {
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);
690
691 imm12 = ThumbExpandImm (imm12);
692 val = state->Reg[Rn] & imm12;
693
694 if (Rd == 15)
695 {
696 // TST<c> <Rn>,#<const>
697 tASSERT (S == 1);
698 }
699 else
700 {
701 // AND{S}<c> <Rd>,<Rn>,#<const>
702 if (in_IT_block ())
703 S = 0;
704
705 state->Reg[Rd] = val;
706 }
707
708 if (S)
709 ARMul_NegZero (state, val);
710 * pvalid = t_branch;
711 break;
712 }
713
714 case 0xA1:
715 case 0x81: // BIC.W
716 {
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);
721
722 tASSERT (ntBIT (15) == 0);
723
724 imm8 = ThumbExpandImm (imm8);
725 state->Reg[Rd] = state->Reg[Rn] & ~ imm8;
726
727 if (S && ! in_IT_block ())
728 ARMul_NegZero (state, state->Reg[Rd]);
729 * pvalid = t_resolved;
730 break;
731 }
732
733 case 0xA2:
734 case 0x82: // MOV{S}<c>.W <Rd>,#<const>
735 {
736 ARMword val = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
737 ARMword Rd = ntBITS (8, 11);
738
739 val = ThumbExpandImm (val);
740 state->Reg[Rd] = val;
741
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;
747 }
748
749 case 0xA3:
750 case 0x83: // MVN{S}<c> <Rd>,#<const>
751 {
752 ARMword val = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
753 ARMword Rd = ntBITS (8, 11);
754
755 val = ThumbExpandImm (val);
756 val = ~ val;
757 state->Reg[Rd] = val;
758
759 if (tBIT (4) && ! in_IT_block ())
760 ARMul_NegZero (state, val);
761 * pvalid = t_resolved;
762 break;
763 }
764
765 case 0xA4: // EOR
766 case 0x84: // TEQ
767 {
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;
773
774 imm12 = ThumbExpandImm (imm12);
775
776 result = state->Reg[Rn] ^ imm12;
777
778 if (Rd == 15 && S)
779 // TEQ<c> <Rn>,#<const>
780 ;
781 else
782 {
783 // EOR{S}<c> <Rd>,<Rn>,#<const>
784 state->Reg[Rd] = result;
785
786 if (in_IT_block ())
787 S = 0;
788 }
789
790 if (S)
791 ARMul_NegZero (state, result);
792 * pvalid = t_resolved;
793 break;
794 }
795
796 case 0xA8: // CMN
797 case 0x88: // ADD
798 {
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;
806
807 if (Rd == 15 && S)
808 {
809 // CMN<c> <Rn>,#<const>
810 res = lhs - rhs;
811 }
812 else
813 {
814 // ADD{S}<c>.W <Rd>,<Rn>,#<const>
815 res = lhs + rhs;
816
817 if (in_IT_block ())
818 S = 0;
819
820 state->Reg[Rd] = res;
821 }
822
823 if (S)
824 {
825 ARMul_NegZero (state, res);
826
827 if ((lhs | rhs) >> 30)
828 {
829 /* Possible C,V,N to set. */
830 ARMul_AddCarry (state, lhs, rhs, res);
831 ARMul_AddOverflow (state, lhs, rhs, res);
832 }
833 else
834 {
835 CLEARC;
836 CLEARV;
837 }
838 }
839
840 * pvalid = t_branch;
841 break;
842 }
843
844 case 0xAA:
845 case 0x8A: // ADC{S}<c> <Rd>,<Rn>,#<const>
846 {
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;
854
855 tASSERT (ntBIT (15) == 0);
856
857 if (CFLAG)
858 rhs += 1;
859
860 res = lhs + rhs;
861 state->Reg[Rd] = res;
862
863 if (in_IT_block ())
864 S = 0;
865
866 if (S)
867 {
868 ARMul_NegZero (state, res);
869
870 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
871 {
872 ARMul_AddCarry (state, lhs, rhs, res);
873 ARMul_AddOverflow (state, lhs, rhs, res);
874 }
875 else
876 {
877 CLEARC;
878 CLEARV;
879 }
880 }
881
882 * pvalid = t_branch;
883 break;
884 }
885
886 case 0xAB:
887 case 0x8B: // SBC{S}<c> <Rd>,<Rn>,#<const>
888 {
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;
896
897 tASSERT (ntBIT (15) == 0);
898
899 if (! CFLAG)
900 rhs += 1;
901
902 res = lhs - rhs;
903 state->Reg[Rd] = res;
904
905 if (in_IT_block ())
906 S = 0;
907
908 if (S)
909 {
910 ARMul_NegZero (state, res);
911
912 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
913 {
914 ARMul_SubCarry (state, lhs, rhs, res);
915 ARMul_SubOverflow (state, lhs, rhs, res);
916 }
917 else
918 {
919 CLEARC;
920 CLEARV;
921 }
922 }
923
924 * pvalid = t_branch;
925 break;
926 }
927
928 case 0xAD:
929 case 0x8D: // SUB
930 {
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;
938
939 if (Rd == 15 && S)
940 {
941 // CMP<c>.W <Rn>,#<const>
942 tASSERT (S);
943 }
944 else
945 {
946 // SUB{S}<c>.W <Rd>,<Rn>,#<const>
947 if (in_IT_block ())
948 S = 0;
949
950 state->Reg[Rd] = res;
951 }
952
953 if (S)
954 {
955 ARMul_NegZero (state, res);
956
957 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
958 {
959 ARMul_SubCarry (state, lhs, rhs, res);
960 ARMul_SubOverflow (state, lhs, rhs, res);
961 }
962 else
963 {
964 CLEARC;
965 CLEARV;
966 }
967 }
968
969 * pvalid = t_branch;
970 break;
971 }
972
973 case 0xAE:
974 case 0x8E: // RSB{S}<c>.W <Rd>,<Rn>,#<const>
975 {
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;
983
984 tASSERT (ntBIT (15) == 0);
985
986 state->Reg[Rd] = res;
987
988 if (S)
989 {
990 ARMul_NegZero (state, res);
991
992 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
993 {
994 ARMul_SubCarry (state, lhs, rhs, res);
995 ARMul_SubOverflow (state, lhs, rhs, res);
996 }
997 else
998 {
999 CLEARC;
1000 CLEARV;
1001 }
1002 }
1003
1004 * pvalid = t_branch;
1005 break;
1006 }
1007
1008 case 0xB0:
1009 case 0x90: // ADDW<c> <Rd>,<Rn>,#<imm12>
1010 {
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);
1014
1015 tASSERT (tBIT (4) == 0);
1016 tASSERT (ntBIT (15) == 0);
1017
1018 state->Reg[Rd] = state->Reg[Rn] + imm12;
1019 * pvalid = t_branch;
1020 break;
1021 }
1022
1023 case 0xB2:
1024 case 0x92: // MOVW<c> <Rd>,#<imm16>
1025 {
1026 ARMword Rd = ntBITS (8, 11);
1027 ARMword imm = (tBITS (0, 3) << 12) | (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1028
1029 state->Reg[Rd] = imm;
1030 /* Indicate that the instruction has been processed. */
1031 * pvalid = t_branch;
1032 break;
1033 }
1034
1035 case 0xb5:
1036 case 0x95:// SUBW<c> <Rd>,<Rn>,#<imm12>
1037 {
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);
1041
1042 tASSERT (tBIT (4) == 0);
1043 tASSERT (ntBIT (15) == 0);
1044
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;
1049
1050 * pvalid = t_resolved;
1051 break;
1052 }
1053
1054 case 0xB6:
1055 case 0x96: // MOVT<c> <Rd>,#<imm16>
1056 {
1057 ARMword Rd = ntBITS (8, 11);
1058 ARMword imm = (tBITS (0, 3) << 12) | (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1059
1060 state->Reg[Rd] &= 0xFFFF;
1061 state->Reg[Rd] |= (imm << 16);
1062 * pvalid = t_resolved;
1063 break;
1064 }
1065
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;
1077
1078 case 0x9B:
1079 {
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);
1085
1086 tASSERT (tBIT (4) == 0);
1087 tASSERT (ntBIT (15) == 0);
1088 tASSERT (ntBIT (5) == 0);
1089
1090 mask &= ((1 << (msbit + 1)) - 1);
1091
1092 if (lsbit > msbit)
1093 ; // UNPREDICTABLE
1094 else if (Rn == 15)
1095 {
1096 // BFC<c> <Rd>,#<lsb>,#<width>
1097 state->Reg[Rd] &= ~ mask;
1098 }
1099 else
1100 {
1101 // BFI<c> <Rd>,<Rn>,#<lsb>,#<width>
1102 ARMword val = state->Reg[Rn] & (mask >> lsbit);
1103
1104 val <<= lsbit;
1105 state->Reg[Rd] &= ~ mask;
1106 state->Reg[Rd] |= val;
1107 }
1108
1109 * pvalid = t_resolved;
1110 break;
1111 }
1112
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;
1124
1125 case 0xC0: // STRB
1126 case 0xC4: // LDRB
1127 {
1128 ARMword Rn = tBITS (0, 3);
1129 ARMword Rt = ntBITS (12, 15);
1130
1131 if (tBIT (4))
1132 {
1133 if (Rn == 15)
1134 {
1135 tASSERT (Rt != 15);
1136
1137 /* LDRB<c> <Rt>,<label> => 1111 1000 U001 1111 */
1138 * ainstr = 0xE55F0000;
1139 * ainstr |= (tBIT (7) << 23);
1140 * ainstr |= ntBITS (0, 11);
1141 }
1142 else if (tBIT (7))
1143 {
1144 /* LDRB<c>.W <Rt>,[<Rn>{,#<imm12>}] => 1111 1000 1001 rrrr */
1145 * ainstr = 0xE5D00000;
1146 * ainstr |= ntBITS (0, 11);
1147 }
1148 else if (ntBIT (11) == 0)
1149 {
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);
1154 }
1155 else
1156 {
1157 int P = ntBIT (10);
1158 int U = ntBIT (9);
1159 int W = ntBIT (8);
1160
1161 tASSERT (! (Rt == 15 && P && !U && !W));
1162 tASSERT (! (P && U && !W));
1163
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);
1172 }
1173 }
1174 else
1175 {
1176 if (tBIT (7) == 1)
1177 {
1178 // STRB<c>.W <Rt>,[<Rn>,#<imm12>]
1179 ARMword imm12 = ntBITS (0, 11);
1180
1181 ARMul_StoreByte (state, state->Reg[Rn] + imm12, state->Reg [Rt]);
1182 * pvalid = t_branch;
1183 break;
1184 }
1185 else if (ntBIT (11))
1186 {
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);
1194
1195 tASSERT (! (P && U && !W));
1196 tASSERT (! (Rn == 13 && P && !U && W && imm8 == 4));
1197
1198 * ainstr = 0xE4000000;
1199 * ainstr |= (P << 24);
1200 * ainstr |= (U << 23);
1201 * ainstr |= (W << 21);
1202 * ainstr |= imm8;
1203 }
1204 else
1205 {
1206 // STRB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1207 tASSERT (ntBITS (6, 11) == 0);
1208
1209 * ainstr = 0xE7C00000;
1210 * ainstr |= (ntBITS (4, 5) << 7);
1211 * ainstr |= ntBITS (0, 3);
1212 }
1213 }
1214
1215 * ainstr |= (Rn << 16);
1216 * ainstr |= (Rt << 12);
1217 * pvalid = t_decoded;
1218 break;
1219 }
1220
1221 case 0xC2: // LDR, STR
1222 {
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);
1229
1230 tASSERT (Rn != 15);
1231
1232 if (tBIT (4))
1233 {
1234 if (Rn == 15)
1235 {
1236 // LDR<c>.W <Rt>,<label>
1237 * ainstr = 0xE51F0000;
1238 * ainstr |= ntBITS (0, 11);
1239 }
1240 else if (ntBIT (11))
1241 {
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)));
1245
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;
1256 }
1257 else
1258 {
1259 // LDR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1260
1261 tASSERT (ntBITS (6, 11) == 0);
1262
1263 * ainstr = 0xE7900000;
1264 * ainstr |= ntBITS (4, 5) << 7;
1265 * ainstr |= ntBITS (0, 3);
1266 }
1267 }
1268 else
1269 {
1270 if (ntBIT (11))
1271 {
1272 tASSERT (! (P && U && ! W));
1273 if (Rn == 13 && P && !U && W && imm8 == 4)
1274 {
1275 // PUSH<c>.W <register>
1276 tASSERT (ntBITS (0, 11) == 0xD04);
1277 tASSERT (tBITS (0, 4) == 0x0D);
1278
1279 * ainstr = 0xE92D0000;
1280 * ainstr |= (1 << Rt);
1281
1282 Rt = Rn = 0;
1283 }
1284 else
1285 {
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;
1297 }
1298 }
1299 else
1300 {
1301 // STR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1302 tASSERT (ntBITS (6, 11) == 0);
1303
1304 * ainstr = 0xE7800000;
1305 * ainstr |= ntBITS (4, 5) << 7;
1306 * ainstr |= ntBITS (0, 3);
1307 }
1308 }
1309
1310 * ainstr |= (Rn << 16);
1311 * ainstr |= (Rt << 12);
1312 * pvalid = t_decoded;
1313 break;
1314 }
1315
1316 case 0xC1: // STRH
1317 case 0xC5: // LDRH
1318 {
1319 ARMword Rn = tBITS (0, 3);
1320 ARMword Rt = ntBITS (12, 15);
1321 ARMword address;
1322
1323 tASSERT (Rn != 15);
1324
1325 if (tBIT (4) == 1)
1326 {
1327 if (tBIT (7))
1328 {
1329 // LDRH<c>.W <Rt>,[<Rn>{,#<imm12>}]
1330 ARMword imm12 = ntBITS (0, 11);
1331 address = state->Reg[Rn] + imm12;
1332 }
1333 else if (ntBIT (11))
1334 {
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);
1342
1343 tASSERT (Rn != 15);
1344 tASSERT (! (P && U && !W));
1345
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;
1356 }
1357 else
1358 {
1359 // LDRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1360 ARMword Rm = ntBITS (0, 3);
1361 ARMword imm2 = ntBITS (4, 5);
1362
1363 tASSERT (ntBITS (6, 10) == 0);
1364
1365 address = state->Reg[Rn] + (state->Reg[Rm] << imm2);
1366 }
1367
1368 state->Reg[Rt] = ARMul_LoadHalfWord (state, address);
1369 }
1370 else
1371 {
1372 if (tBIT (7))
1373 {
1374 // STRH<c>.W <Rt>,[<Rn>{,#<imm12>}]
1375 ARMword imm12 = ntBITS (0, 11);
1376
1377 address = state->Reg[Rn] + imm12;
1378 }
1379 else if (ntBIT (11))
1380 {
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);
1388
1389 tASSERT (! (P && U && !W));
1390
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;
1401 }
1402 else
1403 {
1404 // STRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1405 ARMword Rm = ntBITS (0, 3);
1406 ARMword imm2 = ntBITS (4, 5);
1407
1408 tASSERT (ntBITS (6, 10) == 0);
1409
1410 address = state->Reg[Rn] + (state->Reg[Rm] << imm2);
1411 }
1412
1413 ARMul_StoreHalfWord (state, address, state->Reg [Rt]);
1414 }
1415 * pvalid = t_branch;
1416 break;
1417 }
1418
1419 case 0xC6: // LDR.W/STR.W
1420 {
1421 ARMword Rn = tBITS (0, 3);
1422 ARMword Rt = ntBITS (12, 15);
1423 ARMword imm12 = ntBITS (0, 11);
1424 ARMword address = state->Reg[Rn];
1425
1426 if (Rn == 15)
1427 {
1428 // LDR<c>.W <Rt>,<label>
1429 tASSERT (tBIT (4) == 1);
1430 // tASSERT (tBIT (7) == 1)
1431 }
1432
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]);
1438
1439 * pvalid = t_resolved;
1440 break;
1441 }
1442
1443 case 0xC8:
1444 case 0xCC: // LDRSB
1445 {
1446 ARMword Rt = ntBITS (12, 15);
1447 ARMword Rn = tBITS (0, 3);
1448 ARMword U = tBIT (7);
1449 ARMword address = state->Reg[Rn];
1450
1451 tASSERT (tBIT (4) == 1);
1452 tASSERT (Rt != 15); // PLI
1453
1454 if (Rn == 15)
1455 {
1456 // LDRSB<c> <Rt>,<label>
1457 ARMword imm12 = ntBITS (0, 11);
1458 address += (U ? imm12 : - imm12);
1459 }
1460 else if (U)
1461 {
1462 // LDRSB<c> <Rt>,[<Rn>,#<imm12>]
1463 ARMword imm12 = ntBITS (0, 11);
1464 address += imm12;
1465 }
1466 else if (ntBIT (11))
1467 {
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;
1481 }
1482 else
1483 {
1484 // LDRSB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1485 ARMword Rm = ntBITS (0, 3);
1486 ARMword imm2 = ntBITS (4,5);
1487
1488 tASSERT (ntBITS (6, 11) == 0);
1489
1490 address += (state->Reg[Rm] << imm2);
1491 }
1492
1493 state->Reg[Rt] = ARMul_LoadByte (state, address);
1494 if (state->Reg[Rt] & 0x80)
1495 state->Reg[Rt] |= -(1 << 8);
1496
1497 * pvalid = t_resolved;
1498 break;
1499 }
1500
1501 case 0xC9:
1502 case 0xCD:// LDRSH
1503 {
1504 ARMword Rt = ntBITS (12, 15);
1505 ARMword Rn = tBITS (0, 3);
1506 ARMword U = tBIT (7);
1507 ARMword address = state->Reg[Rn];
1508
1509 tASSERT (tBIT (4) == 1);
1510
1511 if (Rn == 15 || U == 1)
1512 {
1513 // Rn==15 => LDRSH<c> <Rt>,<label>
1514 // Rn!=15 => LDRSH<c> <Rt>,[<Rn>,#<imm12>]
1515 ARMword imm12 = ntBITS (0, 11);
1516
1517 address += (U ? imm12 : - imm12);
1518 }
1519 else if (ntBIT (11))
1520 {
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;
1534 }
1535 else /* U == 0 */
1536 {
1537 // LDRSH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1538 ARMword Rm = ntBITS (0, 3);
1539 ARMword imm2 = ntBITS (4,5);
1540
1541 tASSERT (ntBITS (6, 11) == 0);
1542
1543 address += (state->Reg[Rm] << imm2);
1544 }
1545
1546 state->Reg[Rt] = ARMul_LoadHalfWord (state, address);
1547 if (state->Reg[Rt] & 0x8000)
1548 state->Reg[Rt] |= -(1 << 16);
1549
1550 * pvalid = t_branch;
1551 break;
1552 }
1553
1554 case 0x0D0:
1555 {
1556 ARMword Rm = ntBITS (0, 3);
1557 ARMword Rd = ntBITS (8, 11);
1558
1559 tASSERT (ntBITS (12, 15) == 15);
1560
1561 if (ntBIT (7) == 1)
1562 {
1563 // SXTH<c>.W <Rd>,<Rm>{,<rotation>}
1564 ARMword ror = ntBITS (4, 5) << 3;
1565 ARMword val;
1566
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;
1572 }
1573 else
1574 {
1575 // LSL{S}<c>.W <Rd>,<Rn>,<Rm>
1576 ARMword Rn = tBITS (0, 3);
1577
1578 tASSERT (ntBITS (4, 6) == 0);
1579
1580 state->Reg[Rd] = state->Reg[Rn] << (state->Reg[Rm] & 0xFF);
1581 if (tBIT (4))
1582 ARMul_NegZero (state, state->Reg[Rd]);
1583 }
1584 * pvalid = t_branch;
1585 break;
1586 }
1587
1588 case 0x0D1: // LSR{S}<c>.W <Rd>,<Rn>,<Rm>
1589 {
1590 ARMword Rd = ntBITS (8, 11);
1591 ARMword Rn = tBITS (0, 3);
1592 ARMword Rm = ntBITS (0, 3);
1593
1594 tASSERT (ntBITS (12, 15) == 15);
1595 tASSERT (ntBITS (4, 7) == 0);
1596
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;
1602 }
1603
1604 case 0xD2:
1605 tASSERT (ntBITS (12, 15) == 15);
1606 if (ntBIT (7))
1607 {
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
1613 }
1614 else
1615 {
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
1623 }
1624
1625 * ainstr |= (ntBITS (8, 11) << 12); // Rd
1626 * pvalid = t_decoded;
1627 break;
1628
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;
1640
1641 case 0xD4:
1642 {
1643 ARMword Rn = tBITS (0, 3);
1644 ARMword Rd = ntBITS (8, 11);
1645 ARMword Rm = ntBITS (0, 3);
1646
1647 tASSERT (ntBITS (12, 15) == 15);
1648
1649 if (ntBITS (4, 7) == 8)
1650 {
1651 // REV<c>.W <Rd>,<Rm>
1652 ARMword val = state->Reg[Rm];
1653
1654 tASSERT (Rm == Rn);
1655
1656 state->Reg [Rd] =
1657 (val >> 24)
1658 | ((val >> 8) & 0xFF00)
1659 | ((val << 8) & 0xFF0000)
1660 | (val << 24);
1661 * pvalid = t_resolved;
1662 }
1663 else
1664 {
1665 tASSERT (ntBITS (4, 7) == 4);
1666
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;
1673
1674 * ainstr |= (Rn << 16);
1675 * ainstr |= (Rd << 12);
1676 * ainstr |= (Rm << 0);
1677 * pvalid = t_decoded;
1678 }
1679 break;
1680 }
1681
1682 case 0xD5:
1683 {
1684 ARMword Rn = tBITS (0, 3);
1685 ARMword Rd = ntBITS (8, 11);
1686 ARMword Rm = ntBITS (0, 3);
1687
1688 tASSERT (ntBITS (12, 15) == 15);
1689 tASSERT (ntBITS (4, 7) == 8);
1690
1691 if (tBIT (4))
1692 {
1693 // CLZ<c> <Rd>,<Rm>
1694 tASSERT (Rm == Rn);
1695 * ainstr = 0xE16F0F10;
1696 }
1697 else
1698 {
1699 // SEL<c> <Rd>,<Rn>,<Rm>
1700 * ainstr = 0xE6800FB0;
1701 * ainstr |= (Rn << 16);
1702 }
1703
1704 * ainstr |= (Rd << 12);
1705 * ainstr |= (Rm << 0);
1706 * pvalid = t_decoded;
1707 break;
1708 }
1709
1710 case 0xD8: // MUL
1711 {
1712 ARMword Rn = tBITS (0, 3);
1713 ARMword Rm = ntBITS (0, 3);
1714 ARMword Rd = ntBITS (8, 11);
1715 ARMword Ra = ntBITS (12, 15);
1716
1717 if (tBIT (4))
1718 {
1719 // SMLA<x><y><c> <Rd>,<Rn>,<Rm>,<Ra>
1720 ARMword nval = state->Reg[Rn];
1721 ARMword mval = state->Reg[Rm];
1722 ARMword res;
1723
1724 tASSERT (ntBITS (6, 7) == 0);
1725 tASSERT (Ra != 15);
1726
1727 if (ntBIT (5))
1728 nval >>= 16;
1729 else
1730 nval &= 0xFFFF;
1731
1732 if (ntBIT (4))
1733 mval >>= 16;
1734 else
1735 mval &= 0xFFFF;
1736
1737 res = nval * mval;
1738 res += state->Reg[Ra];
1739 // FIXME: Test and clear/set the Q bit.
1740 state->Reg[Rd] = res;
1741 }
1742 else
1743 {
1744 if (ntBITS (4, 7) == 1)
1745 {
1746 // MLS<c> <Rd>,<Rn>,<Rm>,<Ra>
1747 state->Reg[Rd] = state->Reg[Ra] - (state->Reg[Rn] * state->Reg[Rm]);
1748 }
1749 else
1750 {
1751 tASSERT (ntBITS (4, 7) == 0);
1752
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];
1759 }
1760 }
1761 * pvalid = t_resolved;
1762 break;
1763 }
1764
1765 case 0xDC:
1766 if (tBIT (4) == 0 && ntBITS (4, 7) == 0)
1767 {
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;
1775 }
1776 else if (tBIT (4) == 1 && ntBITS (4, 7) == 0xF)
1777 {
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;
1784 }
1785 else
1786 {
1787 fprintf (stderr, "(op = %x) ", tBITS (5,12));
1788 tASSERT (0);
1789 return;
1790 }
1791 break;
1792
1793 case 0xDD:
1794 if (tBIT (4) == 0 && ntBITS (4, 7) == 0)
1795 {
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;
1803 }
1804 else if (tBIT (4) == 1 && ntBITS (4, 7) == 0xF)
1805 {
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;
1812 }
1813 else
1814 {
1815 fprintf (stderr, "(op = %x) ", tBITS (5,12));
1816 tASSERT (0);
1817 return;
1818 }
1819 break;
1820
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;
1831
1832 default:
1833 fprintf (stderr, "(op = %x) ", tBITS (5,12));
1834 tASSERT (0);
1835 return;
1836 }
1837
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;
1841 }
1842
1843 /* Attempt to emulate an ARMv6 instruction.
1844 Stores t_branch into PVALUE upon success or t_undefined otherwise. */
1845
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)
1853 {
1854 if (! state->is_v6)
1855 {
1856 * pvalid = t_undefined;
1857 return;
1858 }
1859
1860 if (tBITS (12, 15) == 0xB
1861 && tBIT (10) == 0
1862 && tBIT (8) == 1)
1863 {
1864 // Conditional branch forwards.
1865 ARMword Rn = tBITS (0, 2);
1866 ARMword imm5 = tBIT (9) << 5 | tBITS (3, 7);
1867
1868 if (tBIT (11))
1869 {
1870 if (state->Reg[Rn] != 0)
1871 {
1872 state->Reg[15] = (pc + 4 + imm5 * 2);
1873 FLUSHPIPE;
1874 }
1875 }
1876 else
1877 {
1878 if (state->Reg[Rn] == 0)
1879 {
1880 state->Reg[15] = (pc + 4 + imm5 * 2);
1881 FLUSHPIPE;
1882 }
1883 }
1884 * pvalid = t_branch;
1885 return;
1886 }
1887
1888 switch (tinstr & 0xFFC0)
1889 {
1890 case 0x4400:
1891 case 0x4480:
1892 case 0x4440:
1893 case 0x44C0: // ADD
1894 {
1895 ARMword Rd = (tBIT (7) << 3) | tBITS (0, 2);
1896 ARMword Rm = tBITS (3, 6);
1897 state->Reg[Rd] += state->Reg[Rm];
1898 break;
1899 }
1900
1901 case 0x4600: // MOV<c> <Rd>,<Rm>
1902 {
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;
1911 }
1912
1913 case 0xBF00:
1914 case 0xBF40:
1915 case 0xBF80:
1916 case 0xBFC0:
1917 handle_IT_block (state, tinstr, pvalid);
1918 return;
1919
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;
1939
1940 case 0xba00: /* rev */
1941 {
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;
1949 }
1950
1951 case 0xba40: /* rev16 */
1952 {
1953 ARMword val = state->Reg[tBITS (3, 5)];
1954 state->Reg [tBITS (0, 2)] = (val >> 16) | (val << 16);
1955 break;
1956 }
1957
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;
1966
1967 case 0xb200: /* sxth */
1968 {
1969 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1970
1971 if (Rm & 0x8000)
1972 state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000;
1973 else
1974 state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1975 break;
1976 }
1977
1978 case 0xb240: /* sxtb */
1979 {
1980 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1981
1982 if (Rm & 0x80)
1983 state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00;
1984 else
1985 state->Reg [(tinstr & 0x7)] = Rm & 0xff;
1986 break;
1987 }
1988
1989 case 0xb280: /* uxth */
1990 {
1991 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1992
1993 state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1994 break;
1995 }
1996
1997 case 0xb2c0: /* uxtb */
1998 {
1999 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
2000
2001 state->Reg [(tinstr & 0x7)] = Rm & 0xff;
2002 break;
2003 }
2004 }
2005 /* Indicate that the instruction has been processed. */
2006 * pvalid = t_branch;
2007 }
2008
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. */
2013
2014 tdstate
2015 ARMul_ThumbDecode (ARMul_State * state,
2016 ARMword pc,
2017 ARMword tinstr,
2018 ARMword * ainstr)
2019 {
2020 tdstate valid = t_decoded; /* default assumes a valid instruction */
2021 ARMword next_instr;
2022 ARMword old_tinstr = tinstr;
2023
2024 if (skipping_32bit_thumb == pc)
2025 {
2026 skipping_32bit_thumb = 0;
2027 return t_branch;
2028 }
2029 skipping_32bit_thumb = 0;
2030
2031 if (state->bigendSig)
2032 {
2033 next_instr = tinstr & 0xFFFF;
2034 tinstr >>= 16;
2035 }
2036 else
2037 {
2038 next_instr = tinstr >> 16;
2039 tinstr &= 0xFFFF;
2040 }
2041
2042 if (! IT_block_allow (state))
2043 {
2044 if ( tBITS (11, 15) == 0x1F
2045 || tBITS (11, 15) == 0x1E
2046 || tBITS (11, 15) == 0x1D)
2047 {
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;
2052 }
2053 else if (trace)
2054 fprintf (stderr, "pc: %x, SKIP instr: %04x\n", pc & ~1, tinstr);
2055
2056 return t_branch;
2057 }
2058
2059 old_tinstr = tinstr;
2060 if (trace)
2061 fprintf (stderr, "pc: %x, Thumb instr: %x", pc & ~1, tinstr);
2062
2063 #if 1 /* debugging to catch non updates */
2064 *ainstr = 0xDEADC0DE;
2065 #endif
2066
2067 switch ((tinstr & 0xF800) >> 11)
2068 {
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 */
2081 {
2082 ARMword subset[4] =
2083 {
2084 0xE0900000, /* ADDS Rd,Rs,Rn */
2085 0xE0500000, /* SUBS Rd,Rs,Rn */
2086 0xE2900000, /* ADDS Rd,Rs,#imm3 */
2087 0xE2500000 /* SUBS Rd,Rs,#imm3 */
2088 };
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 */
2095
2096 if (in_IT_block ())
2097 *ainstr &= ~ (1 << 20);
2098 }
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;
2107
2108 case 5:
2109 * ainstr = 0xE3500000; /* CMP Rd,#imm8 */
2110 * ainstr |= tBITS (8, 10) << 16;
2111 * ainstr |= tBITS (0, 7);
2112 break;
2113
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;
2125
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)
2132 {
2133 /* Format 4 */
2134 struct
2135 {
2136 ARMword opcode;
2137 enum
2138 { t_norm, t_shift, t_neg, t_mul }
2139 otype;
2140 }
2141 subset[16] =
2142 {
2143 { 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */
2144 { 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */
2145 { 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */
2146 { 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */
2147 { 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */
2148 { 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */
2149 { 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */
2150 { 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */
2151 { 0xE1100000, t_norm}, /* TST Rd,Rs */
2152 { 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */
2153 { 0xE1500000, t_norm}, /* CMP Rd,Rs */
2154 { 0xE1700000, t_norm}, /* CMN Rd,Rs */
2155 { 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */
2156 { 0xE0100090, t_mul} , /* MULS Rd,Rd,Rs */
2157 { 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */
2158 { 0xE1F00000, t_norm} /* MVNS Rd,Rs */
2159 };
2160 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
2161
2162 if (in_IT_block ())
2163 {
2164 struct
2165 {
2166 ARMword opcode;
2167 enum
2168 { t_norm, t_shift, t_neg, t_mul }
2169 otype;
2170 }
2171 subset[16] =
2172 {
2173 { 0xE0000000, t_norm}, /* AND Rd,Rd,Rs */
2174 { 0xE0200000, t_norm}, /* EOR Rd,Rd,Rs */
2175 { 0xE1A00010, t_shift}, /* MOV Rd,Rd,LSL Rs */
2176 { 0xE1A00030, t_shift}, /* MOV Rd,Rd,LSR Rs */
2177 { 0xE1A00050, t_shift}, /* MOV Rd,Rd,ASR Rs */
2178 { 0xE0A00000, t_norm}, /* ADC Rd,Rd,Rs */
2179 { 0xE0C00000, t_norm}, /* SBC Rd,Rd,Rs */
2180 { 0xE1A00070, t_shift}, /* MOV Rd,Rd,ROR Rs */
2181 { 0xE1100000, t_norm}, /* TST Rd,Rs */
2182 { 0xE2600000, t_neg}, /* RSB Rd,Rs,#0 */
2183 { 0xE1500000, t_norm}, /* CMP Rd,Rs */
2184 { 0xE1700000, t_norm}, /* CMN Rd,Rs */
2185 { 0xE1800000, t_norm}, /* ORR Rd,Rd,Rs */
2186 { 0xE0000090, t_mul} , /* MUL Rd,Rd,Rs */
2187 { 0xE1C00000, t_norm}, /* BIC Rd,Rd,Rs */
2188 { 0xE1E00000, t_norm} /* MVN Rd,Rs */
2189 };
2190 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
2191 }
2192
2193 switch (subset[(tinstr & 0x03C0) >> 6].otype)
2194 {
2195 case t_norm:
2196 *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */
2197 | ((tinstr & 0x0007) << 12) /* Rd */
2198 | ((tinstr & 0x0038) >> 3); /* Rs */
2199 break;
2200 case t_shift:
2201 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
2202 | ((tinstr & 0x0007) >> 0) /* Rm */
2203 | ((tinstr & 0x0038) << (8 - 3)); /* Rs */
2204 break;
2205 case t_neg:
2206 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
2207 | ((tinstr & 0x0038) << (16 - 3)); /* Rn */
2208 break;
2209 case t_mul:
2210 *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */
2211 | ((tinstr & 0x0007) << 8) /* Rs */
2212 | ((tinstr & 0x0038) >> 3); /* Rm */
2213 break;
2214 }
2215 }
2216 else
2217 {
2218 /* Format 5 */
2219 ARMword Rd = ((tinstr & 0x0007) >> 0);
2220 ARMword Rs = ((tinstr & 0x0038) >> 3);
2221 if (tinstr & (1 << 7))
2222 Rd += 8;
2223 if (tinstr & (1 << 6))
2224 Rs += 8;
2225 switch ((tinstr & 0x03C0) >> 6)
2226 {
2227 case 0x1: /* ADD Rd,Rd,Hs */
2228 case 0x2: /* ADD Hd,Hd,Rs */
2229 case 0x3: /* ADD Hd,Hd,Hs */
2230 *ainstr = 0xE0800000 /* base */
2231 | (Rd << 16) /* Rn */
2232 | (Rd << 12) /* Rd */
2233 | (Rs << 0); /* Rm */
2234 break;
2235 case 0x5: /* CMP Rd,Hs */
2236 case 0x6: /* CMP Hd,Rs */
2237 case 0x7: /* CMP Hd,Hs */
2238 *ainstr = 0xE1500000 /* base */
2239 | (Rd << 16) /* Rn */
2240 | (Rd << 12) /* Rd */
2241 | (Rs << 0); /* Rm */
2242 break;
2243 case 0x9: /* MOV Rd,Hs */
2244 case 0xA: /* MOV Hd,Rs */
2245 case 0xB: /* MOV Hd,Hs */
2246 *ainstr = 0xE1A00000 /* base */
2247 | (Rd << 12) /* Rd */
2248 | (Rs << 0); /* Rm */
2249 break;
2250 case 0xC: /* BX Rs */
2251 case 0xD: /* BX Hs */
2252 *ainstr = 0xE12FFF10 /* base */
2253 | ((tinstr & 0x0078) >> 3); /* Rd */
2254 break;
2255 case 0xE: /* UNDEFINED */
2256 case 0xF: /* UNDEFINED */
2257 if (state->is_v5)
2258 {
2259 /* BLX Rs; BLX Hs */
2260 *ainstr = 0xE12FFF30 /* base */
2261 | ((tinstr & 0x0078) >> 3); /* Rd */
2262 break;
2263 }
2264 /* Drop through. */
2265 default:
2266 case 0x0: /* UNDEFINED */
2267 case 0x4: /* UNDEFINED */
2268 case 0x8: /* UNDEFINED */
2269 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2270 break;
2271 }
2272 }
2273 break;
2274 case 9: /* LDR Rd,[PC,#imm8] */
2275 /* Format 6 */
2276 *ainstr = 0xE59F0000 /* base */
2277 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2278 | ((tinstr & 0x00FF) << (2 - 0)); /* off8 */
2279 break;
2280 case 10:
2281 case 11:
2282 /* TODO: Format 7 and Format 8 perform the same ARM encoding, so
2283 the following could be merged into a single subset, saving on
2284 the following boolean: */
2285 if ((tinstr & (1 << 9)) == 0)
2286 {
2287 /* Format 7 */
2288 ARMword subset[4] = {
2289 0xE7800000, /* STR Rd,[Rb,Ro] */
2290 0xE7C00000, /* STRB Rd,[Rb,Ro] */
2291 0xE7900000, /* LDR Rd,[Rb,Ro] */
2292 0xE7D00000 /* LDRB Rd,[Rb,Ro] */
2293 };
2294 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2295 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2296 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2297 | ((tinstr & 0x01C0) >> 6); /* Ro */
2298 }
2299 else
2300 {
2301 /* Format 8 */
2302 ARMword subset[4] = {
2303 0xE18000B0, /* STRH Rd,[Rb,Ro] */
2304 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */
2305 0xE19000B0, /* LDRH Rd,[Rb,Ro] */
2306 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */
2307 };
2308 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2309 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2310 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2311 | ((tinstr & 0x01C0) >> 6); /* Ro */
2312 }
2313 break;
2314 case 12: /* STR Rd,[Rb,#imm5] */
2315 case 13: /* LDR Rd,[Rb,#imm5] */
2316 case 14: /* STRB Rd,[Rb,#imm5] */
2317 case 15: /* LDRB Rd,[Rb,#imm5] */
2318 /* Format 9 */
2319 {
2320 ARMword subset[4] = {
2321 0xE5800000, /* STR Rd,[Rb,#imm5] */
2322 0xE5900000, /* LDR Rd,[Rb,#imm5] */
2323 0xE5C00000, /* STRB Rd,[Rb,#imm5] */
2324 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */
2325 };
2326 /* The offset range defends on whether we are transferring a
2327 byte or word value: */
2328 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */
2329 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2330 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2331 | ((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */
2332 }
2333 break;
2334 case 16: /* STRH Rd,[Rb,#imm5] */
2335 case 17: /* LDRH Rd,[Rb,#imm5] */
2336 /* Format 10 */
2337 *ainstr = ((tinstr & (1 << 11)) /* base */
2338 ? 0xE1D000B0 /* LDRH */
2339 : 0xE1C000B0) /* STRH */
2340 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2341 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2342 | ((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */
2343 | ((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */
2344 break;
2345 case 18: /* STR Rd,[SP,#imm8] */
2346 case 19: /* LDR Rd,[SP,#imm8] */
2347 /* Format 11 */
2348 *ainstr = ((tinstr & (1 << 11)) /* base */
2349 ? 0xE59D0000 /* LDR */
2350 : 0xE58D0000) /* STR */
2351 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2352 | ((tinstr & 0x00FF) << 2); /* off8 */
2353 break;
2354 case 20: /* ADD Rd,PC,#imm8 */
2355 case 21: /* ADD Rd,SP,#imm8 */
2356 /* Format 12 */
2357 if ((tinstr & (1 << 11)) == 0)
2358 {
2359 /* NOTE: The PC value used here should by word aligned */
2360 /* We encode shift-left-by-2 in the rotate immediate field,
2361 so no shift of off8 is needed. */
2362 *ainstr = 0xE28F0F00 /* base */
2363 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2364 | (tinstr & 0x00FF); /* off8 */
2365 }
2366 else
2367 {
2368 /* We encode shift-left-by-2 in the rotate immediate field,
2369 so no shift of off8 is needed. */
2370 *ainstr = 0xE28D0F00 /* base */
2371 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2372 | (tinstr & 0x00FF); /* off8 */
2373 }
2374 break;
2375 case 22:
2376 case 23:
2377 switch (tinstr & 0x0F00)
2378 {
2379 case 0x0000:
2380 /* Format 13 */
2381 /* NOTE: The instruction contains a shift left of 2
2382 equivalent (implemented as ROR #30): */
2383 *ainstr = ((tinstr & (1 << 7)) /* base */
2384 ? 0xE24DDF00 /* SUB */
2385 : 0xE28DDF00) /* ADD */
2386 | (tinstr & 0x007F); /* off7 */
2387 break;
2388 case 0x0400:
2389 /* Format 14 - Push */
2390 * ainstr = 0xE92D0000 | (tinstr & 0x00FF);
2391 break;
2392 case 0x0500:
2393 /* Format 14 - Push + LR */
2394 * ainstr = 0xE92D4000 | (tinstr & 0x00FF);
2395 break;
2396 case 0x0c00:
2397 /* Format 14 - Pop */
2398 * ainstr = 0xE8BD0000 | (tinstr & 0x00FF);
2399 break;
2400 case 0x0d00:
2401 /* Format 14 - Pop + PC */
2402 * ainstr = 0xE8BD8000 | (tinstr & 0x00FF);
2403 break;
2404 case 0x0e00:
2405 if (state->is_v5)
2406 {
2407 /* This is normally an undefined instruction. The v5t architecture
2408 defines this particular pattern as a BKPT instruction, for
2409 hardware assisted debugging. We map onto the arm BKPT
2410 instruction. */
2411 if (state->is_v6)
2412 // Map to the SVC instruction instead of the BKPT instruction.
2413 * ainstr = 0xEF000000 | tBITS (0, 7);
2414 else
2415 * ainstr = 0xE1200070 | ((tinstr & 0xf0) << 4) | (tinstr & 0xf);
2416 break;
2417 }
2418 /* Drop through. */
2419 default:
2420 /* Everything else is an undefined instruction. */
2421 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2422 break;
2423 }
2424 break;
2425 case 24: /* STMIA */
2426 case 25: /* LDMIA */
2427 /* Format 15 */
2428 *ainstr = ((tinstr & (1 << 11)) /* base */
2429 ? 0xE8B00000 /* LDMIA */
2430 : 0xE8A00000) /* STMIA */
2431 | ((tinstr & 0x0700) << (16 - 8)) /* Rb */
2432 | (tinstr & 0x00FF); /* mask8 */
2433 break;
2434 case 26: /* Bcc */
2435 case 27: /* Bcc/SWI */
2436 if ((tinstr & 0x0F00) == 0x0F00)
2437 {
2438 /* Format 17 : SWI */
2439 *ainstr = 0xEF000000;
2440 /* Breakpoint must be handled specially. */
2441 if ((tinstr & 0x00FF) == 0x18)
2442 *ainstr |= ((tinstr & 0x00FF) << 16);
2443 /* New breakpoint value. See gdb/arm-tdep.c */
2444 else if ((tinstr & 0x00FF) == 0xFE)
2445 *ainstr |= SWI_Breakpoint;
2446 else
2447 *ainstr |= (tinstr & 0x00FF);
2448 }
2449 else if ((tinstr & 0x0F00) != 0x0E00)
2450 {
2451 /* Format 16 */
2452 int doit = FALSE;
2453 /* TODO: Since we are doing a switch here, we could just add
2454 the SWI and undefined instruction checks into this
2455 switch to same on a couple of conditionals: */
2456 switch ((tinstr & 0x0F00) >> 8)
2457 {
2458 case EQ:
2459 doit = ZFLAG;
2460 break;
2461 case NE:
2462 doit = !ZFLAG;
2463 break;
2464 case VS:
2465 doit = VFLAG;
2466 break;
2467 case VC:
2468 doit = !VFLAG;
2469 break;
2470 case MI:
2471 doit = NFLAG;
2472 break;
2473 case PL:
2474 doit = !NFLAG;
2475 break;
2476 case CS:
2477 doit = CFLAG;
2478 break;
2479 case CC:
2480 doit = !CFLAG;
2481 break;
2482 case HI:
2483 doit = (CFLAG && !ZFLAG);
2484 break;
2485 case LS:
2486 doit = (!CFLAG || ZFLAG);
2487 break;
2488 case GE:
2489 doit = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
2490 break;
2491 case LT:
2492 doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
2493 break;
2494 case GT:
2495 doit = ((!NFLAG && !VFLAG && !ZFLAG)
2496 || (NFLAG && VFLAG && !ZFLAG));
2497 break;
2498 case LE:
2499 doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
2500 break;
2501 }
2502 if (doit)
2503 {
2504 state->Reg[15] = (pc + 4
2505 + (((tinstr & 0x7F) << 1)
2506 | ((tinstr & (1 << 7)) ? 0xFFFFFF00 : 0)));
2507 FLUSHPIPE;
2508 }
2509 valid = t_branch;
2510 }
2511 else
2512 /* UNDEFINED : cc=1110(AL) uses different format. */
2513 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2514 break;
2515 case 28: /* B */
2516 /* Format 18 */
2517 state->Reg[15] = (pc + 4
2518 + (((tinstr & 0x3FF) << 1)
2519 | ((tinstr & (1 << 10)) ? 0xFFFFF800 : 0)));
2520 FLUSHPIPE;
2521 valid = t_branch;
2522 break;
2523 case 29: /* UNDEFINED */
2524 if (state->is_v6)
2525 {
2526 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2527 break;
2528 }
2529
2530 if (state->is_v5)
2531 {
2532 if (tinstr & 1)
2533 {
2534 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2535 break;
2536 }
2537 /* Drop through. */
2538
2539 /* Format 19 */
2540 /* There is no single ARM instruction equivalent for this
2541 instruction. Also, it should only ever be matched with the
2542 fmt19 "BL/BLX instruction 1" instruction. However, we do
2543 allow the simulation of it on its own, with undefined results
2544 if r14 is not suitably initialised. */
2545 {
2546 ARMword tmp = (pc + 2);
2547
2548 state->Reg[15] = ((state->Reg[14] + ((tinstr & 0x07FF) << 1))
2549 & 0xFFFFFFFC);
2550 CLEART;
2551 state->Reg[14] = (tmp | 1);
2552 valid = t_branch;
2553 FLUSHPIPE;
2554 if (trace_funcs)
2555 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
2556 break;
2557 }
2558 }
2559
2560 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2561 break;
2562
2563 case 30: /* BL instruction 1 */
2564 if (state->is_v6)
2565 {
2566 handle_T2_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2567 break;
2568 }
2569
2570 /* Format 19 */
2571 /* There is no single ARM instruction equivalent for this Thumb
2572 instruction. To keep the simulation simple (from the user
2573 perspective) we check if the following instruction is the
2574 second half of this BL, and if it is we simulate it
2575 immediately. */
2576 state->Reg[14] = state->Reg[15] \
2577 + (((tinstr & 0x07FF) << 12) \
2578 | ((tinstr & (1 << 10)) ? 0xFF800000 : 0));
2579
2580 valid = t_branch; /* in-case we don't have the 2nd half */
2581 tinstr = next_instr; /* move the instruction down */
2582 pc += 2; /* point the pc at the 2nd half */
2583 if (((tinstr & 0xF800) >> 11) != 31)
2584 {
2585 if (((tinstr & 0xF800) >> 11) == 29)
2586 {
2587 ARMword tmp = (pc + 2);
2588
2589 state->Reg[15] = ((state->Reg[14]
2590 + ((tinstr & 0x07FE) << 1))
2591 & 0xFFFFFFFC);
2592 CLEART;
2593 state->Reg[14] = (tmp | 1);
2594 valid = t_branch;
2595 FLUSHPIPE;
2596 }
2597 else
2598 /* Exit, since not correct instruction. */
2599 pc -= 2;
2600 break;
2601 }
2602 /* else we fall through to process the second half of the BL */
2603 pc += 2; /* point the pc at the 2nd half */
2604 case 31: /* BL instruction 2 */
2605 if (state->is_v6)
2606 {
2607 handle_T2_insn (state, old_tinstr, next_instr, pc, ainstr, & valid);
2608 break;
2609 }
2610
2611 /* Format 19 */
2612 /* There is no single ARM instruction equivalent for this
2613 instruction. Also, it should only ever be matched with the
2614 fmt19 "BL instruction 1" instruction. However, we do allow
2615 the simulation of it on its own, with undefined results if
2616 r14 is not suitably initialised. */
2617 {
2618 ARMword tmp = pc;
2619
2620 state->Reg[15] = (state->Reg[14] + ((tinstr & 0x07FF) << 1));
2621 state->Reg[14] = (tmp | 1);
2622 valid = t_branch;
2623 FLUSHPIPE;
2624 }
2625 break;
2626 }
2627
2628 if (trace && valid != t_decoded)
2629 fprintf (stderr, "\n");
2630
2631 return valid;
2632 }