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
test_cond(int cond,ARMul_State * state)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
handle_IT_block(ARMul_State * state,ARMword tinstr,tdstate * pvalid)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
in_IT_block(void)91 in_IT_block (void)
92 {
93 return IT_block_mask != 0;
94 }
95
96 static int
IT_block_allow(ARMul_State * state)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
ThumbExpandImm(ARMword tinstr)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
handle_T2_insn(ARMul_State * state,ARMword tinstr,ARMword next_instr,ARMword pc,ARMword * ainstr,tdstate * pvalid)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 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
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
handle_v6_thumb_insn(ARMul_State * state,ARMword tinstr,ARMword next_instr,ARMword pc,ARMword * ainstr,tdstate * pvalid)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
ARMul_ThumbDecode(ARMul_State * state,ARMword pc,ARMword tinstr,ARMword * ainstr)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 insn_format {
2135 ARMword opcode;
2136 enum { t_norm, t_shift, t_neg, t_mul } otype;
2137 };
2138 static const struct insn_format subset[16] =
2139 {
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 */
2156 };
2157 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
2158
2159 if (in_IT_block ())
2160 {
2161 static const struct insn_format it_subset[16] =
2162 {
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 */
2179 };
2180 *ainstr = it_subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
2181 }
2182
2183 switch (subset[(tinstr & 0x03C0) >> 6].otype)
2184 {
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;
2204 }
2205 }
2206 else
2207 {
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)
2216 {
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)
2248 {
2249 /* BLX Rs; BLX Hs */
2250 *ainstr = 0xE12FFF30 /* base */
2251 | ((tinstr & 0x0078) >> 3); /* Rd */
2252 break;
2253 }
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;
2261 }
2262 }
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)
2276 {
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] */
2283 };
2284 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2285 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2286 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2287 | ((tinstr & 0x01C0) >> 6); /* Ro */
2288 }
2289 else
2290 {
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] */
2297 };
2298 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2299 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2300 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2301 | ((tinstr & 0x01C0) >> 6); /* Ro */
2302 }
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 */
2309 {
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] */
2315 };
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 */
2322 }
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)
2348 {
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 */
2355 }
2356 else
2357 {
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 */
2363 }
2364 break;
2365 case 22:
2366 case 23:
2367 switch (tinstr & 0x0F00)
2368 {
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)
2396 {
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;
2407 }
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;
2413 }
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)
2427 {
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);
2438 }
2439 else if ((tinstr & 0x0F00) != 0x0E00)
2440 {
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)
2447 {
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;
2491 }
2492 if (doit)
2493 {
2494 state->Reg[15] = (pc + 4
2495 + (((tinstr & 0x7F) << 1)
2496 | ((tinstr & (1 << 7)) ? 0xFFFFFF00 : 0)));
2497 FLUSHPIPE;
2498 }
2499 valid = t_branch;
2500 }
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)
2515 {
2516 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2517 break;
2518 }
2519
2520 if (state->is_v5)
2521 {
2522 if (tinstr & 1)
2523 {
2524 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2525 break;
2526 }
2527 /* Drop through. */
2528
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. */
2535 {
2536 ARMword tmp = (pc + 2);
2537
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;
2547 }
2548 }
2549
2550 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2551 break;
2552
2553 case 30: /* BL instruction 1 */
2554 if (state->is_v6)
2555 {
2556 handle_T2_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2557 break;
2558 }
2559
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));
2569
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)
2574 {
2575 if (((tinstr & 0xF800) >> 11) == 29)
2576 {
2577 ARMword tmp = (pc + 2);
2578
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;
2586 }
2587 else
2588 /* Exit, since not correct instruction. */
2589 pc -= 2;
2590 break;
2591 }
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)
2597 {
2598 handle_T2_insn (state, old_tinstr, next_instr, pc, ainstr, & valid);
2599 break;
2600 }
2601
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. */
2608 {
2609 ARMword tmp = pc;
2610
2611 state->Reg[15] = (state->Reg[14] + ((tinstr & 0x07FF) << 1));
2612 state->Reg[14] = (tmp | 1);
2613 valid = t_branch;
2614 FLUSHPIPE;
2615 }
2616 break;
2617 }
2618
2619 if (trace && valid != t_decoded)
2620 fprintf (stderr, "\n");
2621
2622 return valid;
2623 }
2624