sim: replace custom attributes with ansidecl.h
[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 #ifndef MODET /* required for the Thumb instruction support */
22 #if 1
23 #error "MODET needs to be defined for the Thumb world to work"
24 #else
25 #define MODET (1)
26 #endif
27 #endif
28
29 #include "armdefs.h"
30 #include "armemu.h"
31 #include "armos.h"
32
33 #define tBIT(n) ( (ARMword)(tinstr >> (n)) & 1)
34 #define tBITS(m,n) ( (ARMword)(tinstr << (31 - (n))) >> ((31 - (n)) + (m)) )
35
36 #define ntBIT(n) ( (ARMword)(next_instr >> (n)) & 1)
37 #define ntBITS(m,n) ( (ARMword)(next_instr << (31 - (n))) >> ((31 - (n)) + (m)) )
38
39 static int
40 test_cond (int cond, ARMul_State * state)
41 {
42 switch (cond)
43 {
44 case EQ: return ZFLAG;
45 case NE: return !ZFLAG;
46 case VS: return VFLAG;
47 case VC: return !VFLAG;
48 case MI: return NFLAG;
49 case PL: return !NFLAG;
50 case CS: return CFLAG;
51 case CC: return !CFLAG;
52 case HI: return (CFLAG && !ZFLAG);
53 case LS: return (!CFLAG || ZFLAG);
54 case GE: return ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
55 case LT: return ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
56 case GT: return ((!NFLAG && !VFLAG && !ZFLAG)
57 || (NFLAG && VFLAG && !ZFLAG));
58 case LE: return ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
59 case AL: return TRUE;
60 case NV:
61 default: return FALSE;
62 }
63 }
64
65 static ARMword skipping_32bit_thumb = 0;
66
67 static int IT_block_cond = AL;
68 static ARMword IT_block_mask = 0;
69 static int IT_block_first = FALSE;
70
71 static void
72 handle_IT_block (ARMul_State * state,
73 ARMword tinstr,
74 tdstate * pvalid)
75 {
76 * pvalid = t_branch;
77 IT_block_mask = tBITS (0, 3);
78
79 if (IT_block_mask == 0)
80 // NOP or a HINT.
81 return;
82
83 IT_block_cond = tBITS (4, 7);
84 IT_block_first = TRUE;
85 }
86
87 static int
88 in_IT_block (void)
89 {
90 return IT_block_mask != 0;
91 }
92
93 static int
94 IT_block_allow (ARMul_State * state)
95 {
96 int cond;
97
98 if (IT_block_mask == 0)
99 return TRUE;
100
101 cond = IT_block_cond;
102
103 if (IT_block_first)
104 IT_block_first = FALSE;
105 else
106 {
107 if ((IT_block_mask & 8) == 0)
108 cond &= 0xe;
109 else
110 cond |= 1;
111 IT_block_mask <<= 1;
112 IT_block_mask &= 0xF;
113 }
114
115 if (IT_block_mask == 0x8)
116 IT_block_mask = 0;
117
118 return test_cond (cond, state);
119 }
120
121 static ARMword
122 ThumbExpandImm (ARMword tinstr)
123 {
124 ARMword val;
125
126 if (tBITS (10, 11) == 0)
127 {
128 switch (tBITS (8, 9))
129 {
130 case 0: val = tBITS (0, 7); break;
131 case 1: val = tBITS (0, 7) << 8; break;
132 case 2: val = (tBITS (0, 7) << 8) | (tBITS (0, 7) << 24); break;
133 case 3: val = tBITS (0, 7) * 0x01010101; break;
134 default: val = 0;
135 }
136 }
137 else
138 {
139 int ror = tBITS (7, 11);
140
141 val = (1 << 7) | tBITS (0, 6);
142 val = (val >> ror) | (val << (32 - ror));
143 }
144
145 return val;
146 }
147
148 #define tASSERT(truth) \
149 do \
150 { \
151 if (! (truth)) \
152 { \
153 fprintf (stderr, "unhandled T2 insn %04x|%04x detected at thumbemu.c:%d\n", \
154 tinstr, next_instr, __LINE__); \
155 return ; \
156 } \
157 } \
158 while (0)
159
160
161 /* Attempt to emulate a 32-bit ARMv7 Thumb instruction.
162 Stores t_branch into PVALUE upon success or t_undefined otherwise. */
163
164 static void
165 handle_T2_insn (ARMul_State * state,
166 ARMword tinstr,
167 ARMword next_instr,
168 ARMword pc,
169 ARMword * ainstr,
170 tdstate * pvalid)
171 {
172 * pvalid = t_undefined;
173
174 if (! state->is_v6)
175 return;
176
177 if (trace)
178 fprintf (stderr, "|%04x ", next_instr);
179
180 if (tBITS (11, 15) == 0x1E && ntBIT (15) == 1)
181 {
182 ARMsword simm32 = 0;
183 int S = tBIT (10);
184
185 * pvalid = t_branch;
186 switch ((ntBIT (14) << 1) | ntBIT (12))
187 {
188 case 0: /* B<c>.W */
189 {
190 ARMword cond = tBITS (6, 9);
191 ARMword imm6;
192 ARMword imm11;
193 ARMword J1;
194 ARMword J2;
195
196 tASSERT (cond != AL && cond != NV);
197 if (! test_cond (cond, state))
198 return;
199
200 imm6 = tBITS (0, 5);
201 imm11 = ntBITS (0, 10);
202 J1 = ntBIT (13);
203 J2 = ntBIT (11);
204
205 simm32 = (J1 << 19) | (J2 << 18) | (imm6 << 12) | (imm11 << 1);
206 if (S)
207 simm32 |= -(1 << 20);
208 break;
209 }
210
211 case 1: /* B.W */
212 {
213 ARMword imm10 = tBITS (0, 9);
214 ARMword imm11 = ntBITS (0, 10);
215 ARMword I1 = (ntBIT (13) ^ S) ? 0 : 1;
216 ARMword I2 = (ntBIT (11) ^ S) ? 0 : 1;
217
218 simm32 = (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
219 if (S)
220 simm32 |= -(1 << 24);
221 break;
222 }
223
224 case 2: /* BLX <label> */
225 {
226 ARMword imm10h = tBITS (0, 9);
227 ARMword imm10l = ntBITS (1, 10);
228 ARMword I1 = (ntBIT (13) ^ S) ? 0 : 1;
229 ARMword I2 = (ntBIT (11) ^ S) ? 0 : 1;
230
231 simm32 = (I1 << 23) | (I2 << 22) | (imm10h << 12) | (imm10l << 2);
232 if (S)
233 simm32 |= -(1 << 24);
234
235 CLEART;
236 state->Reg[14] = (pc + 4) | 1;
237 break;
238 }
239
240 case 3: /* BL <label> */
241 {
242 ARMword imm10 = tBITS (0, 9);
243 ARMword imm11 = ntBITS (0, 10);
244 ARMword I1 = (ntBIT (13) ^ S) ? 0 : 1;
245 ARMword I2 = (ntBIT (11) ^ S) ? 0 : 1;
246
247 simm32 = (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
248 if (S)
249 simm32 |= -(1 << 24);
250 state->Reg[14] = (pc + 4) | 1;
251 break;
252 }
253 }
254
255 state->Reg[15] = (pc + 4 + simm32);
256 FLUSHPIPE;
257 if (trace_funcs)
258 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
259 return;
260 }
261
262 switch (tBITS (5,12))
263 {
264 case 0x29: // TST<c>.W <Rn>,<Rm>{,<shift>}
265 {
266 ARMword Rn = tBITS (0, 3);
267 ARMword Rm = ntBITS (0, 3);
268 ARMword type = ntBITS (4, 5);
269 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
270
271 tASSERT (ntBITS (8, 11) == 0xF);
272
273 * ainstr = 0xE1100000;
274 * ainstr |= (Rn << 16);
275 * ainstr |= (Rm);
276 * ainstr |= (type << 5);
277 * ainstr |= (imm5 << 7);
278 * pvalid = t_decoded;
279 break;
280 }
281
282 case 0x46:
283 if (tBIT (4) && ntBITS (5, 15) == 0x780)
284 {
285 // Table Branch
286 ARMword Rn = tBITS (0, 3);
287 ARMword Rm = ntBITS (0, 3);
288 ARMword address, dest;
289
290 if (ntBIT (4))
291 {
292 // TBH
293 address = state->Reg[Rn] + state->Reg[Rm] * 2;
294 dest = ARMul_LoadHalfWord (state, address);
295 }
296 else
297 {
298 // TBB
299 address = state->Reg[Rn] + state->Reg[Rm];
300 dest = ARMul_LoadByte (state, address);
301 }
302
303 state->Reg[15] = (pc + 4 + dest * 2);
304 FLUSHPIPE;
305 * pvalid = t_branch;
306 break;
307 }
308 /* Fall through. */
309 case 0x42:
310 case 0x43:
311 case 0x47:
312 case 0x4A:
313 case 0x4B:
314 case 0x4E: // STRD
315 case 0x4F: // LDRD
316 {
317 ARMword Rn = tBITS (0, 3);
318 ARMword Rt = ntBITS (12, 15);
319 ARMword Rt2 = ntBITS (8, 11);
320 ARMword imm8 = ntBITS (0, 7);
321 ARMword P = tBIT (8);
322 ARMword U = tBIT (7);
323 ARMword W = tBIT (5);
324
325 tASSERT (Rt2 == Rt + 1);
326 imm8 <<= 2;
327 tASSERT (imm8 <= 255);
328 tASSERT (P != 0 || W != 0);
329
330 // Convert into an ARM A1 encoding.
331 if (Rn == 15)
332 {
333 tASSERT (tBIT (4) == 1);
334 // LDRD (literal)
335 // Ignore W even if 1.
336 * ainstr = 0xE14F00D0;
337 }
338 else
339 {
340 if (tBIT (4) == 1)
341 // LDRD (immediate)
342 * ainstr = 0xE04000D0;
343 else
344 {
345 // STRD<c> <Rt>,<Rt2>,[<Rn>{,#+/-<imm8>}]
346 // STRD<c> <Rt>,<Rt2>,[<Rn>],#+/-<imm8>
347 // STRD<c> <Rt>,<Rt2>,[<Rn>,#+/-<imm8>]!
348 * ainstr = 0xE04000F0;
349 }
350 * ainstr |= (Rn << 16);
351 * ainstr |= (P << 24);
352 * ainstr |= (W << 21);
353 }
354
355 * ainstr |= (U << 23);
356 * ainstr |= (Rt << 12);
357 * ainstr |= ((imm8 << 4) & 0xF00);
358 * ainstr |= (imm8 & 0xF);
359 * pvalid = t_decoded;
360 break;
361 }
362
363 case 0x44:
364 case 0x45: // LDMIA
365 {
366 ARMword Rn = tBITS (0, 3);
367 int W = tBIT (5);
368 ARMword list = (ntBIT (15) << 15) | (ntBIT (14) << 14) | ntBITS (0, 12);
369
370 if (Rn == 13)
371 * ainstr = 0xE8BD0000;
372 else
373 {
374 * ainstr = 0xE8900000;
375 * ainstr |= (W << 21);
376 * ainstr |= (Rn << 16);
377 }
378 * ainstr |= list;
379 * pvalid = t_decoded;
380 break;
381 }
382
383 case 0x48:
384 case 0x49: // STMDB
385 {
386 ARMword Rn = tBITS (0, 3);
387 int W = tBIT (5);
388 ARMword list = (ntBIT (14) << 14) | ntBITS (0, 12);
389
390 if (Rn == 13 && W)
391 * ainstr = 0xE92D0000;
392 else
393 {
394 * ainstr = 0xE9000000;
395 * ainstr |= (W << 21);
396 * ainstr |= (Rn << 16);
397 }
398 * ainstr |= list;
399 * pvalid = t_decoded;
400 break;
401 }
402
403 case 0x50:
404 {
405 ARMword Rd = ntBITS (8, 11);
406 ARMword Rn = tBITS (0, 3);
407 ARMword Rm = ntBITS (0, 3);
408 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
409 ARMword type = ntBITS (4, 5);
410
411 tASSERT (ntBIT (15) == 0);
412
413 if (Rd == 15)
414 {
415 tASSERT (tBIT (4) == 1);
416
417 // TST<c>.W <Rn>,<Rm>{,<shift>}
418 * ainstr = 0xE1100000;
419 }
420 else
421 {
422 // AND{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
423 int S = tBIT (4);
424
425 * ainstr = 0xE0000000;
426
427 if (in_IT_block ())
428 S = 0;
429 * ainstr |= (S << 20);
430 }
431
432 * ainstr |= (Rn << 16);
433 * ainstr |= (imm5 << 7);
434 * ainstr |= (type << 5);
435 * ainstr |= (Rm << 0);
436 * pvalid = t_decoded;
437 break;
438 }
439
440 case 0x51: // BIC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
441 {
442 ARMword Rn = tBITS (0, 3);
443 ARMword S = tBIT(4);
444 ARMword Rm = ntBITS (0, 3);
445 ARMword Rd = ntBITS (8, 11);
446 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
447 ARMword type = ntBITS (4, 5);
448
449 tASSERT (ntBIT (15) == 0);
450
451 * ainstr = 0xE1C00000;
452 * ainstr |= (S << 20);
453 * ainstr |= (Rn << 16);
454 * ainstr |= (Rd << 12);
455 * ainstr |= (imm5 << 7);
456 * ainstr |= (type << 5);
457 * ainstr |= (Rm << 0);
458 * pvalid = t_decoded;
459 break;
460 }
461
462 case 0x52:
463 {
464 ARMword Rn = tBITS (0, 3);
465 ARMword Rd = ntBITS (8, 11);
466 ARMword Rm = ntBITS (0, 3);
467 int S = tBIT (4);
468 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
469 ARMword type = ntBITS (4, 5);
470
471 tASSERT (Rd != 15);
472
473 if (in_IT_block ())
474 S = 0;
475
476 if (Rn == 15)
477 {
478 tASSERT (ntBIT (15) == 0);
479
480 switch (ntBITS (4, 5))
481 {
482 case 0:
483 // LSL{S}<c>.W <Rd>,<Rm>,#<imm5>
484 * ainstr = 0xE1A00000;
485 break;
486 case 1:
487 // LSR{S}<c>.W <Rd>,<Rm>,#<imm>
488 * ainstr = 0xE1A00020;
489 break;
490 case 2:
491 // ASR{S}<c>.W <Rd>,<Rm>,#<imm>
492 * ainstr = 0xE1A00040;
493 break;
494 case 3:
495 // ROR{S}<c> <Rd>,<Rm>,#<imm>
496 * ainstr = 0xE1A00060;
497 break;
498 default:
499 tASSERT (0);
500 * ainstr = 0;
501 }
502 }
503 else
504 {
505 // ORR{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
506 * ainstr = 0xE1800000;
507 * ainstr |= (Rn << 16);
508 * ainstr |= (type << 5);
509 }
510
511 * ainstr |= (Rd << 12);
512 * ainstr |= (S << 20);
513 * ainstr |= (imm5 << 7);
514 * ainstr |= (Rm << 0);
515 * pvalid = t_decoded;
516 break;
517 }
518
519 case 0x53: // MVN{S}<c>.W <Rd>,<Rm>{,<shift>}
520 {
521 ARMword Rd = ntBITS (8, 11);
522 ARMword Rm = ntBITS (0, 3);
523 int S = tBIT (4);
524 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
525 ARMword type = ntBITS (4, 5);
526
527 tASSERT (ntBIT (15) == 0);
528
529 if (in_IT_block ())
530 S = 0;
531
532 * ainstr = 0xE1E00000;
533 * ainstr |= (S << 20);
534 * ainstr |= (Rd << 12);
535 * ainstr |= (imm5 << 7);
536 * ainstr |= (type << 5);
537 * ainstr |= (Rm << 0);
538 * pvalid = t_decoded;
539 break;
540 }
541
542 case 0x54:
543 {
544 ARMword Rn = tBITS (0, 3);
545 ARMword Rd = ntBITS (8, 11);
546 ARMword Rm = ntBITS (0, 3);
547 int S = tBIT (4);
548 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
549 ARMword type = ntBITS (4, 5);
550
551 if (Rd == 15 && S)
552 {
553 // TEQ<c> <Rn>,<Rm>{,<shift>}
554 tASSERT (ntBIT (15) == 0);
555
556 * ainstr = 0xE1300000;
557 }
558 else
559 {
560 // EOR{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
561 if (in_IT_block ())
562 S = 0;
563
564 * ainstr = 0xE0200000;
565 * ainstr |= (S << 20);
566 * ainstr |= (Rd << 8);
567 }
568
569 * ainstr |= (Rn << 16);
570 * ainstr |= (imm5 << 7);
571 * ainstr |= (type << 5);
572 * ainstr |= (Rm << 0);
573 * pvalid = t_decoded;
574 break;
575 }
576
577 case 0x58: // ADD{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
578 {
579 ARMword Rn = tBITS (0, 3);
580 ARMword Rd = ntBITS (8, 11);
581 ARMword Rm = ntBITS (0, 3);
582 int S = tBIT (4);
583 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
584 ARMword type = ntBITS (4, 5);
585
586 tASSERT (! (Rd == 15 && S));
587
588 if (in_IT_block ())
589 S = 0;
590
591 * ainstr = 0xE0800000;
592 * ainstr |= (S << 20);
593 * ainstr |= (Rn << 16);
594 * ainstr |= (Rd << 12);
595 * ainstr |= (imm5 << 7);
596 * ainstr |= (type << 5);
597 * ainstr |= Rm;
598 * pvalid = t_decoded;
599 break;
600 }
601
602 case 0x5A: // ADC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
603 tASSERT (ntBIT (15) == 0);
604 * ainstr = 0xE0A00000;
605 if (! in_IT_block ())
606 * ainstr |= (tBIT (4) << 20); // S
607 * ainstr |= (tBITS (0, 3) << 16); // Rn
608 * ainstr |= (ntBITS (8, 11) << 12); // Rd
609 * ainstr |= ((ntBITS (12, 14) << 2) | ntBITS (6, 7)) << 7; // imm5
610 * ainstr |= (ntBITS (4, 5) << 5); // type
611 * ainstr |= ntBITS (0, 3); // Rm
612 * pvalid = t_decoded;
613 break;
614
615 case 0x5B: // SBC{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
616 {
617 ARMword Rn = tBITS (0, 3);
618 ARMword Rd = ntBITS (8, 11);
619 ARMword Rm = ntBITS (0, 3);
620 int S = tBIT (4);
621 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
622 ARMword type = ntBITS (4, 5);
623
624 tASSERT (ntBIT (15) == 0);
625
626 if (in_IT_block ())
627 S = 0;
628
629 * ainstr = 0xE0C00000;
630 * ainstr |= (S << 20);
631 * ainstr |= (Rn << 16);
632 * ainstr |= (Rd << 12);
633 * ainstr |= (imm5 << 7);
634 * ainstr |= (type << 5);
635 * ainstr |= Rm;
636 * pvalid = t_decoded;
637 break;
638 }
639
640 case 0x5E: // RSB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>}
641 case 0x5D: // SUB{S}<c>.W <Rd>,<Rn>,<Rm>{,<shift>}
642 {
643 ARMword Rn = tBITS (0, 3);
644 ARMword Rd = ntBITS (8, 11);
645 ARMword Rm = ntBITS (0, 3);
646 ARMword S = tBIT (4);
647 ARMword type = ntBITS (4, 5);
648 ARMword imm5 = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
649
650 tASSERT (ntBIT(15) == 0);
651
652 if (Rd == 15)
653 {
654 // CMP<c>.W <Rn>, <Rm> {,<shift>}
655 * ainstr = 0xE1500000;
656 Rd = 0;
657 }
658 else if (tBIT (5))
659 * ainstr = 0xE0400000;
660 else
661 * ainstr = 0xE0600000;
662
663 * ainstr |= (S << 20);
664 * ainstr |= (Rn << 16);
665 * ainstr |= (Rd << 12);
666 * ainstr |= (imm5 << 7);
667 * ainstr |= (type << 5);
668 * ainstr |= (Rm << 0);
669 * pvalid = t_decoded;
670 break;
671 }
672
673 case 0x9D: // NOP.W
674 tASSERT (tBITS (0, 15) == 0xF3AF);
675 tASSERT (ntBITS (0, 15) == 0x8000);
676 * pvalid = t_branch;
677 break;
678
679 case 0x80: // AND
680 case 0xA0: // TST
681 {
682 ARMword Rn = tBITS (0, 3);
683 ARMword imm12 = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
684 ARMword Rd = ntBITS (8, 11);
685 ARMword val;
686 int S = tBIT (4);
687
688 imm12 = ThumbExpandImm (imm12);
689 val = state->Reg[Rn] & imm12;
690
691 if (Rd == 15)
692 {
693 // TST<c> <Rn>,#<const>
694 tASSERT (S == 1);
695 }
696 else
697 {
698 // AND{S}<c> <Rd>,<Rn>,#<const>
699 if (in_IT_block ())
700 S = 0;
701
702 state->Reg[Rd] = val;
703 }
704
705 if (S)
706 ARMul_NegZero (state, val);
707 * pvalid = t_branch;
708 break;
709 }
710
711 case 0xA1:
712 case 0x81: // BIC.W
713 {
714 ARMword Rn = tBITS (0, 3);
715 ARMword Rd = ntBITS (8, 11);
716 ARMword S = tBIT (4);
717 ARMword imm8 = (ntBITS (12, 14) << 8) | ntBITS (0, 7);
718
719 tASSERT (ntBIT (15) == 0);
720
721 imm8 = ThumbExpandImm (imm8);
722 state->Reg[Rd] = state->Reg[Rn] & ~ imm8;
723
724 if (S && ! in_IT_block ())
725 ARMul_NegZero (state, state->Reg[Rd]);
726 * pvalid = t_resolved;
727 break;
728 }
729
730 case 0xA2:
731 case 0x82: // MOV{S}<c>.W <Rd>,#<const>
732 {
733 ARMword val = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
734 ARMword Rd = ntBITS (8, 11);
735
736 val = ThumbExpandImm (val);
737 state->Reg[Rd] = val;
738
739 if (tBIT (4) && ! in_IT_block ())
740 ARMul_NegZero (state, val);
741 /* Indicate that the instruction has been processed. */
742 * pvalid = t_branch;
743 break;
744 }
745
746 case 0xA3:
747 case 0x83: // MVN{S}<c> <Rd>,#<const>
748 {
749 ARMword val = (tBIT(10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
750 ARMword Rd = ntBITS (8, 11);
751
752 val = ThumbExpandImm (val);
753 val = ~ val;
754 state->Reg[Rd] = val;
755
756 if (tBIT (4) && ! in_IT_block ())
757 ARMul_NegZero (state, val);
758 * pvalid = t_resolved;
759 break;
760 }
761
762 case 0xA4: // EOR
763 case 0x84: // TEQ
764 {
765 ARMword Rn = tBITS (0, 3);
766 ARMword Rd = ntBITS (8, 11);
767 ARMword S = tBIT (4);
768 ARMword imm12 = ((tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7));
769 ARMword result;
770
771 imm12 = ThumbExpandImm (imm12);
772
773 result = state->Reg[Rn] ^ imm12;
774
775 if (Rd == 15 && S)
776 // TEQ<c> <Rn>,#<const>
777 ;
778 else
779 {
780 // EOR{S}<c> <Rd>,<Rn>,#<const>
781 state->Reg[Rd] = result;
782
783 if (in_IT_block ())
784 S = 0;
785 }
786
787 if (S)
788 ARMul_NegZero (state, result);
789 * pvalid = t_resolved;
790 break;
791 }
792
793 case 0xA8: // CMN
794 case 0x88: // ADD
795 {
796 ARMword Rd = ntBITS (8, 11);
797 int S = tBIT (4);
798 ARMword Rn = tBITS (0, 3);
799 ARMword lhs = state->Reg[Rn];
800 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
801 ARMword rhs = ThumbExpandImm (imm12);
802 ARMword res = lhs + rhs;
803
804 if (Rd == 15 && S)
805 {
806 // CMN<c> <Rn>,#<const>
807 res = lhs - rhs;
808 }
809 else
810 {
811 // ADD{S}<c>.W <Rd>,<Rn>,#<const>
812 res = lhs + rhs;
813
814 if (in_IT_block ())
815 S = 0;
816
817 state->Reg[Rd] = res;
818 }
819
820 if (S)
821 {
822 ARMul_NegZero (state, res);
823
824 if ((lhs | rhs) >> 30)
825 {
826 /* Possible C,V,N to set. */
827 ARMul_AddCarry (state, lhs, rhs, res);
828 ARMul_AddOverflow (state, lhs, rhs, res);
829 }
830 else
831 {
832 CLEARC;
833 CLEARV;
834 }
835 }
836
837 * pvalid = t_branch;
838 break;
839 }
840
841 case 0xAA:
842 case 0x8A: // ADC{S}<c> <Rd>,<Rn>,#<const>
843 {
844 ARMword Rn = tBITS (0, 3);
845 ARMword Rd = ntBITS (8, 11);
846 int S = tBIT (4);
847 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
848 ARMword lhs = state->Reg[Rn];
849 ARMword rhs = ThumbExpandImm (imm12);
850 ARMword res;
851
852 tASSERT (ntBIT (15) == 0);
853
854 if (CFLAG)
855 rhs += 1;
856
857 res = lhs + rhs;
858 state->Reg[Rd] = res;
859
860 if (in_IT_block ())
861 S = 0;
862
863 if (S)
864 {
865 ARMul_NegZero (state, res);
866
867 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
868 {
869 ARMul_AddCarry (state, lhs, rhs, res);
870 ARMul_AddOverflow (state, lhs, rhs, res);
871 }
872 else
873 {
874 CLEARC;
875 CLEARV;
876 }
877 }
878
879 * pvalid = t_branch;
880 break;
881 }
882
883 case 0xAB:
884 case 0x8B: // SBC{S}<c> <Rd>,<Rn>,#<const>
885 {
886 ARMword Rn = tBITS (0, 3);
887 ARMword Rd = ntBITS (8, 11);
888 int S = tBIT (4);
889 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
890 ARMword lhs = state->Reg[Rn];
891 ARMword rhs = ThumbExpandImm (imm12);
892 ARMword res;
893
894 tASSERT (ntBIT (15) == 0);
895
896 if (! CFLAG)
897 rhs += 1;
898
899 res = lhs - rhs;
900 state->Reg[Rd] = res;
901
902 if (in_IT_block ())
903 S = 0;
904
905 if (S)
906 {
907 ARMul_NegZero (state, res);
908
909 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
910 {
911 ARMul_SubCarry (state, lhs, rhs, res);
912 ARMul_SubOverflow (state, lhs, rhs, res);
913 }
914 else
915 {
916 CLEARC;
917 CLEARV;
918 }
919 }
920
921 * pvalid = t_branch;
922 break;
923 }
924
925 case 0xAD:
926 case 0x8D: // SUB
927 {
928 ARMword Rn = tBITS (0, 3);
929 ARMword Rd = ntBITS (8, 11);
930 int S = tBIT (4);
931 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
932 ARMword lhs = state->Reg[Rn];
933 ARMword rhs = ThumbExpandImm (imm12);
934 ARMword res = lhs - rhs;
935
936 if (Rd == 15 && S)
937 {
938 // CMP<c>.W <Rn>,#<const>
939 tASSERT (S);
940 }
941 else
942 {
943 // SUB{S}<c>.W <Rd>,<Rn>,#<const>
944 if (in_IT_block ())
945 S = 0;
946
947 state->Reg[Rd] = res;
948 }
949
950 if (S)
951 {
952 ARMul_NegZero (state, res);
953
954 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
955 {
956 ARMul_SubCarry (state, lhs, rhs, res);
957 ARMul_SubOverflow (state, lhs, rhs, res);
958 }
959 else
960 {
961 CLEARC;
962 CLEARV;
963 }
964 }
965
966 * pvalid = t_branch;
967 break;
968 }
969
970 case 0xAE:
971 case 0x8E: // RSB{S}<c>.W <Rd>,<Rn>,#<const>
972 {
973 ARMword Rn = tBITS (0, 3);
974 ARMword Rd = ntBITS (8, 11);
975 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
976 int S = tBIT (4);
977 ARMword lhs = imm12;
978 ARMword rhs = state->Reg[Rn];
979 ARMword res = lhs - rhs;
980
981 tASSERT (ntBIT (15) == 0);
982
983 state->Reg[Rd] = res;
984
985 if (S)
986 {
987 ARMul_NegZero (state, res);
988
989 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
990 {
991 ARMul_SubCarry (state, lhs, rhs, res);
992 ARMul_SubOverflow (state, lhs, rhs, res);
993 }
994 else
995 {
996 CLEARC;
997 CLEARV;
998 }
999 }
1000
1001 * pvalid = t_branch;
1002 break;
1003 }
1004
1005 case 0xB0:
1006 case 0x90: // ADDW<c> <Rd>,<Rn>,#<imm12>
1007 {
1008 ARMword Rn = tBITS (0, 3);
1009 ARMword Rd = ntBITS (8, 11);
1010 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1011
1012 tASSERT (tBIT (4) == 0);
1013 tASSERT (ntBIT (15) == 0);
1014
1015 state->Reg[Rd] = state->Reg[Rn] + imm12;
1016 * pvalid = t_branch;
1017 break;
1018 }
1019
1020 case 0xB2:
1021 case 0x92: // MOVW<c> <Rd>,#<imm16>
1022 {
1023 ARMword Rd = ntBITS (8, 11);
1024 ARMword imm = (tBITS (0, 3) << 12) | (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1025
1026 state->Reg[Rd] = imm;
1027 /* Indicate that the instruction has been processed. */
1028 * pvalid = t_branch;
1029 break;
1030 }
1031
1032 case 0xb5:
1033 case 0x95:// SUBW<c> <Rd>,<Rn>,#<imm12>
1034 {
1035 ARMword Rd = ntBITS (8, 11);
1036 ARMword Rn = tBITS (0, 3);
1037 ARMword imm12 = (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1038
1039 tASSERT (tBIT (4) == 0);
1040 tASSERT (ntBIT (15) == 0);
1041
1042 /* Note the ARM ARM indicates special cases for Rn == 15 (ADR)
1043 and Rn == 13 (SUB SP minus immediate), but these are implemented
1044 in exactly the same way as the normal SUBW insn. */
1045 state->Reg[Rd] = state->Reg[Rn] - imm12;
1046
1047 * pvalid = t_resolved;
1048 break;
1049 }
1050
1051 case 0xB6:
1052 case 0x96: // MOVT<c> <Rd>,#<imm16>
1053 {
1054 ARMword Rd = ntBITS (8, 11);
1055 ARMword imm = (tBITS (0, 3) << 12) | (tBIT (10) << 11) | (ntBITS (12, 14) << 8) | ntBITS (0, 7);
1056
1057 state->Reg[Rd] &= 0xFFFF;
1058 state->Reg[Rd] |= (imm << 16);
1059 * pvalid = t_resolved;
1060 break;
1061 }
1062
1063 case 0x9A: // SBFXc> <Rd>,<Rn>,#<lsb>,#<width>
1064 tASSERT (tBIT (4) == 0);
1065 tASSERT (ntBIT (15) == 0);
1066 tASSERT (ntBIT (5) == 0);
1067 * ainstr = 0xE7A00050;
1068 * ainstr |= (ntBITS (0, 4) << 16); // widthm1
1069 * ainstr |= (ntBITS (8, 11) << 12); // Rd
1070 * ainstr |= (((ntBITS (12, 14) << 2) | ntBITS (6, 7)) << 7); // lsb
1071 * ainstr |= tBITS (0, 3); // Rn
1072 * pvalid = t_decoded;
1073 break;
1074
1075 case 0x9B:
1076 {
1077 ARMword Rd = ntBITS (8, 11);
1078 ARMword Rn = tBITS (0, 3);
1079 ARMword msbit = ntBITS (0, 5);
1080 ARMword lsbit = (ntBITS (12, 14) << 2) | ntBITS (6, 7);
1081 ARMword mask = -(1 << lsbit);
1082
1083 tASSERT (tBIT (4) == 0);
1084 tASSERT (ntBIT (15) == 0);
1085 tASSERT (ntBIT (5) == 0);
1086
1087 mask &= ((1 << (msbit + 1)) - 1);
1088
1089 if (lsbit > msbit)
1090 ; // UNPREDICTABLE
1091 else if (Rn == 15)
1092 {
1093 // BFC<c> <Rd>,#<lsb>,#<width>
1094 state->Reg[Rd] &= ~ mask;
1095 }
1096 else
1097 {
1098 // BFI<c> <Rd>,<Rn>,#<lsb>,#<width>
1099 ARMword val = state->Reg[Rn] & (mask >> lsbit);
1100
1101 val <<= lsbit;
1102 state->Reg[Rd] &= ~ mask;
1103 state->Reg[Rd] |= val;
1104 }
1105
1106 * pvalid = t_resolved;
1107 break;
1108 }
1109
1110 case 0x9E: // UBFXc> <Rd>,<Rn>,#<lsb>,#<width>
1111 tASSERT (tBIT (4) == 0);
1112 tASSERT (ntBIT (15) == 0);
1113 tASSERT (ntBIT (5) == 0);
1114 * ainstr = 0xE7E00050;
1115 * ainstr |= (ntBITS (0, 4) << 16); // widthm1
1116 * ainstr |= (ntBITS (8, 11) << 12); // Rd
1117 * ainstr |= (((ntBITS (12, 14) << 2) | ntBITS (6, 7)) << 7); // lsb
1118 * ainstr |= tBITS (0, 3); // Rn
1119 * pvalid = t_decoded;
1120 break;
1121
1122 case 0xC0: // STRB
1123 case 0xC4: // LDRB
1124 {
1125 ARMword Rn = tBITS (0, 3);
1126 ARMword Rt = ntBITS (12, 15);
1127
1128 if (tBIT (4))
1129 {
1130 if (Rn == 15)
1131 {
1132 tASSERT (Rt != 15);
1133
1134 /* LDRB<c> <Rt>,<label> => 1111 1000 U001 1111 */
1135 * ainstr = 0xE55F0000;
1136 * ainstr |= (tBIT (7) << 23);
1137 * ainstr |= ntBITS (0, 11);
1138 }
1139 else if (tBIT (7))
1140 {
1141 /* LDRB<c>.W <Rt>,[<Rn>{,#<imm12>}] => 1111 1000 1001 rrrr */
1142 * ainstr = 0xE5D00000;
1143 * ainstr |= ntBITS (0, 11);
1144 }
1145 else if (ntBIT (11) == 0)
1146 {
1147 /* LDRB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}] => 1111 1000 0001 rrrr */
1148 * ainstr = 0xE7D00000;
1149 * ainstr |= (ntBITS (4, 5) << 7);
1150 * ainstr |= ntBITS (0, 3);
1151 }
1152 else
1153 {
1154 int P = ntBIT (10);
1155 int U = ntBIT (9);
1156 int W = ntBIT (8);
1157
1158 tASSERT (! (Rt == 15 && P && !U && !W));
1159 tASSERT (! (P && U && !W));
1160
1161 /* LDRB<c> <Rt>,[<Rn>,#-<imm8>] => 1111 1000 0001 rrrr
1162 LDRB<c> <Rt>,[<Rn>],#+/-<imm8> => 1111 1000 0001 rrrr
1163 LDRB<c> <Rt>,[<Rn>,#+/-<imm8>]! => 1111 1000 0001 rrrr */
1164 * ainstr = 0xE4500000;
1165 * ainstr |= (P << 24);
1166 * ainstr |= (U << 23);
1167 * ainstr |= (W << 21);
1168 * ainstr |= ntBITS (0, 7);
1169 }
1170 }
1171 else
1172 {
1173 if (tBIT (7) == 1)
1174 {
1175 // STRB<c>.W <Rt>,[<Rn>,#<imm12>]
1176 ARMword imm12 = ntBITS (0, 11);
1177
1178 ARMul_StoreByte (state, state->Reg[Rn] + imm12, state->Reg [Rt]);
1179 * pvalid = t_branch;
1180 break;
1181 }
1182 else if (ntBIT (11))
1183 {
1184 // STRB<c> <Rt>,[<Rn>,#-<imm8>]
1185 // STRB<c> <Rt>,[<Rn>],#+/-<imm8>
1186 // STRB<c> <Rt>,[<Rn>,#+/-<imm8>]!
1187 int P = ntBIT (10);
1188 int U = ntBIT (9);
1189 int W = ntBIT (8);
1190 ARMword imm8 = ntBITS (0, 7);
1191
1192 tASSERT (! (P && U && !W));
1193 tASSERT (! (Rn == 13 && P && !U && W && imm8 == 4));
1194
1195 * ainstr = 0xE4000000;
1196 * ainstr |= (P << 24);
1197 * ainstr |= (U << 23);
1198 * ainstr |= (W << 21);
1199 * ainstr |= imm8;
1200 }
1201 else
1202 {
1203 // STRB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1204 tASSERT (ntBITS (6, 11) == 0);
1205
1206 * ainstr = 0xE7C00000;
1207 * ainstr |= (ntBITS (4, 5) << 7);
1208 * ainstr |= ntBITS (0, 3);
1209 }
1210 }
1211
1212 * ainstr |= (Rn << 16);
1213 * ainstr |= (Rt << 12);
1214 * pvalid = t_decoded;
1215 break;
1216 }
1217
1218 case 0xC2: // LDR, STR
1219 {
1220 ARMword Rn = tBITS (0, 3);
1221 ARMword Rt = ntBITS (12, 15);
1222 ARMword imm8 = ntBITS (0, 7);
1223 ARMword P = ntBIT (10);
1224 ARMword U = ntBIT (9);
1225 ARMword W = ntBIT (8);
1226
1227 tASSERT (Rn != 15);
1228
1229 if (tBIT (4))
1230 {
1231 if (Rn == 15)
1232 {
1233 // LDR<c>.W <Rt>,<label>
1234 * ainstr = 0xE51F0000;
1235 * ainstr |= ntBITS (0, 11);
1236 }
1237 else if (ntBIT (11))
1238 {
1239 tASSERT (! (P && U && ! W));
1240 tASSERT (! (!P && U && W && Rn == 13 && imm8 == 4 && ntBIT (11) == 0));
1241 tASSERT (! (P && !U && W && Rn == 13 && imm8 == 4 && ntBIT (11)));
1242
1243 // LDR<c> <Rt>,[<Rn>,#-<imm8>]
1244 // LDR<c> <Rt>,[<Rn>],#+/-<imm8>
1245 // LDR<c> <Rt>,[<Rn>,#+/-<imm8>]!
1246 if (!P && W)
1247 W = 0;
1248 * ainstr = 0xE4100000;
1249 * ainstr |= (P << 24);
1250 * ainstr |= (U << 23);
1251 * ainstr |= (W << 21);
1252 * ainstr |= imm8;
1253 }
1254 else
1255 {
1256 // LDR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1257
1258 tASSERT (ntBITS (6, 11) == 0);
1259
1260 * ainstr = 0xE7900000;
1261 * ainstr |= ntBITS (4, 5) << 7;
1262 * ainstr |= ntBITS (0, 3);
1263 }
1264 }
1265 else
1266 {
1267 if (ntBIT (11))
1268 {
1269 tASSERT (! (P && U && ! W));
1270 if (Rn == 13 && P && !U && W && imm8 == 4)
1271 {
1272 // PUSH<c>.W <register>
1273 tASSERT (ntBITS (0, 11) == 0xD04);
1274 tASSERT (tBITS (0, 4) == 0x0D);
1275
1276 * ainstr = 0xE92D0000;
1277 * ainstr |= (1 << Rt);
1278
1279 Rt = Rn = 0;
1280 }
1281 else
1282 {
1283 tASSERT (! (P && U && !W));
1284 if (!P && W)
1285 W = 0;
1286 // STR<c> <Rt>,[<Rn>,#-<imm8>]
1287 // STR<c> <Rt>,[<Rn>],#+/-<imm8>
1288 // STR<c> <Rt>,[<Rn>,#+/-<imm8>]!
1289 * ainstr = 0xE4000000;
1290 * ainstr |= (P << 24);
1291 * ainstr |= (U << 23);
1292 * ainstr |= (W << 21);
1293 * ainstr |= imm8;
1294 }
1295 }
1296 else
1297 {
1298 // STR<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1299 tASSERT (ntBITS (6, 11) == 0);
1300
1301 * ainstr = 0xE7800000;
1302 * ainstr |= ntBITS (4, 5) << 7;
1303 * ainstr |= ntBITS (0, 3);
1304 }
1305 }
1306
1307 * ainstr |= (Rn << 16);
1308 * ainstr |= (Rt << 12);
1309 * pvalid = t_decoded;
1310 break;
1311 }
1312
1313 case 0xC1: // STRH
1314 case 0xC5: // LDRH
1315 {
1316 ARMword Rn = tBITS (0, 3);
1317 ARMword Rt = ntBITS (12, 15);
1318 ARMword address;
1319
1320 tASSERT (Rn != 15);
1321
1322 if (tBIT (4) == 1)
1323 {
1324 if (tBIT (7))
1325 {
1326 // LDRH<c>.W <Rt>,[<Rn>{,#<imm12>}]
1327 ARMword imm12 = ntBITS (0, 11);
1328 address = state->Reg[Rn] + imm12;
1329 }
1330 else if (ntBIT (11))
1331 {
1332 // LDRH<c> <Rt>,[<Rn>,#-<imm8>]
1333 // LDRH<c> <Rt>,[<Rn>],#+/-<imm8>
1334 // LDRH<c> <Rt>,[<Rn>,#+/-<imm8>]!
1335 ARMword P = ntBIT (10);
1336 ARMword U = ntBIT (9);
1337 ARMword W = ntBIT (8);
1338 ARMword imm8 = ntBITS (0, 7);
1339
1340 tASSERT (Rn != 15);
1341 tASSERT (! (P && U && !W));
1342
1343 * ainstr = 0xE05000B0;
1344 * ainstr |= (P << 24);
1345 * ainstr |= (U << 23);
1346 * ainstr |= (W << 21);
1347 * ainstr |= (Rn << 16);
1348 * ainstr |= (Rt << 12);
1349 * ainstr |= ((imm8 & 0xF0) << 4);
1350 * ainstr |= (imm8 & 0xF);
1351 * pvalid = t_decoded;
1352 break;
1353 }
1354 else
1355 {
1356 // LDRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1357 ARMword Rm = ntBITS (0, 3);
1358 ARMword imm2 = ntBITS (4, 5);
1359
1360 tASSERT (ntBITS (6, 10) == 0);
1361
1362 address = state->Reg[Rn] + (state->Reg[Rm] << imm2);
1363 }
1364
1365 state->Reg[Rt] = ARMul_LoadHalfWord (state, address);
1366 }
1367 else
1368 {
1369 if (tBIT (7))
1370 {
1371 // STRH<c>.W <Rt>,[<Rn>{,#<imm12>}]
1372 ARMword imm12 = ntBITS (0, 11);
1373
1374 address = state->Reg[Rn] + imm12;
1375 }
1376 else if (ntBIT (11))
1377 {
1378 // STRH<c> <Rt>,[<Rn>,#-<imm8>]
1379 // STRH<c> <Rt>,[<Rn>],#+/-<imm8>
1380 // STRH<c> <Rt>,[<Rn>,#+/-<imm8>]!
1381 ARMword P = ntBIT (10);
1382 ARMword U = ntBIT (9);
1383 ARMword W = ntBIT (8);
1384 ARMword imm8 = ntBITS (0, 7);
1385
1386 tASSERT (! (P && U && !W));
1387
1388 * ainstr = 0xE04000B0;
1389 * ainstr |= (P << 24);
1390 * ainstr |= (U << 23);
1391 * ainstr |= (W << 21);
1392 * ainstr |= (Rn << 16);
1393 * ainstr |= (Rt << 12);
1394 * ainstr |= ((imm8 & 0xF0) << 4);
1395 * ainstr |= (imm8 & 0xF);
1396 * pvalid = t_decoded;
1397 break;
1398 }
1399 else
1400 {
1401 // STRH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1402 ARMword Rm = ntBITS (0, 3);
1403 ARMword imm2 = ntBITS (4, 5);
1404
1405 tASSERT (ntBITS (6, 10) == 0);
1406
1407 address = state->Reg[Rn] + (state->Reg[Rm] << imm2);
1408 }
1409
1410 ARMul_StoreHalfWord (state, address, state->Reg [Rt]);
1411 }
1412 * pvalid = t_branch;
1413 break;
1414 }
1415
1416 case 0xC6: // LDR.W/STR.W
1417 {
1418 ARMword Rn = tBITS (0, 3);
1419 ARMword Rt = ntBITS (12, 15);
1420 ARMword imm12 = ntBITS (0, 11);
1421 ARMword address = state->Reg[Rn];
1422
1423 if (Rn == 15)
1424 {
1425 // LDR<c>.W <Rt>,<label>
1426 tASSERT (tBIT (4) == 1);
1427 // tASSERT (tBIT (7) == 1)
1428 }
1429
1430 address += imm12;
1431 if (tBIT (4) == 1)
1432 state->Reg[Rt] = ARMul_LoadWordN (state, address);
1433 else
1434 ARMul_StoreWordN (state, address, state->Reg [Rt]);
1435
1436 * pvalid = t_resolved;
1437 break;
1438 }
1439
1440 case 0xC8:
1441 case 0xCC: // LDRSB
1442 {
1443 ARMword Rt = ntBITS (12, 15);
1444 ARMword Rn = tBITS (0, 3);
1445 ARMword U = tBIT (7);
1446 ARMword address = state->Reg[Rn];
1447
1448 tASSERT (tBIT (4) == 1);
1449 tASSERT (Rt != 15); // PLI
1450
1451 if (Rn == 15)
1452 {
1453 // LDRSB<c> <Rt>,<label>
1454 ARMword imm12 = ntBITS (0, 11);
1455 address += (U ? imm12 : - imm12);
1456 }
1457 else if (U)
1458 {
1459 // LDRSB<c> <Rt>,[<Rn>,#<imm12>]
1460 ARMword imm12 = ntBITS (0, 11);
1461 address += imm12;
1462 }
1463 else if (ntBIT (11))
1464 {
1465 // LDRSB<c> <Rt>,[<Rn>,#-<imm8>]
1466 // LDRSB<c> <Rt>,[<Rn>],#+/-<imm8>
1467 // LDRSB<c> <Rt>,[<Rn>,#+/-<imm8>]!
1468 * ainstr = 0xE05000D0;
1469 * ainstr |= ntBIT (10) << 24; // P
1470 * ainstr |= ntBIT (9) << 23; // U
1471 * ainstr |= ntBIT (8) << 21; // W
1472 * ainstr |= Rn << 16;
1473 * ainstr |= Rt << 12;
1474 * ainstr |= ntBITS (4, 7) << 8;
1475 * ainstr |= ntBITS (0, 3);
1476 * pvalid = t_decoded;
1477 break;
1478 }
1479 else
1480 {
1481 // LDRSB<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1482 ARMword Rm = ntBITS (0, 3);
1483 ARMword imm2 = ntBITS (4,5);
1484
1485 tASSERT (ntBITS (6, 11) == 0);
1486
1487 address += (state->Reg[Rm] << imm2);
1488 }
1489
1490 state->Reg[Rt] = ARMul_LoadByte (state, address);
1491 if (state->Reg[Rt] & 0x80)
1492 state->Reg[Rt] |= -(1 << 8);
1493
1494 * pvalid = t_resolved;
1495 break;
1496 }
1497
1498 case 0xC9:
1499 case 0xCD:// LDRSH
1500 {
1501 ARMword Rt = ntBITS (12, 15);
1502 ARMword Rn = tBITS (0, 3);
1503 ARMword U = tBIT (7);
1504 ARMword address = state->Reg[Rn];
1505
1506 tASSERT (tBIT (4) == 1);
1507
1508 if (Rn == 15 || U == 1)
1509 {
1510 // Rn==15 => LDRSH<c> <Rt>,<label>
1511 // Rn!=15 => LDRSH<c> <Rt>,[<Rn>,#<imm12>]
1512 ARMword imm12 = ntBITS (0, 11);
1513
1514 address += (U ? imm12 : - imm12);
1515 }
1516 else if (ntBIT (11))
1517 {
1518 // LDRSH<c> <Rt>,[<Rn>,#-<imm8>]
1519 // LDRSH<c> <Rt>,[<Rn>],#+/-<imm8>
1520 // LDRSH<c> <Rt>,[<Rn>,#+/-<imm8>]!
1521 * ainstr = 0xE05000F0;
1522 * ainstr |= ntBIT (10) << 24; // P
1523 * ainstr |= ntBIT (9) << 23; // U
1524 * ainstr |= ntBIT (8) << 21; // W
1525 * ainstr |= Rn << 16;
1526 * ainstr |= Rt << 12;
1527 * ainstr |= ntBITS (4, 7) << 8;
1528 * ainstr |= ntBITS (0, 3);
1529 * pvalid = t_decoded;
1530 break;
1531 }
1532 else /* U == 0 */
1533 {
1534 // LDRSH<c>.W <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]
1535 ARMword Rm = ntBITS (0, 3);
1536 ARMword imm2 = ntBITS (4,5);
1537
1538 tASSERT (ntBITS (6, 11) == 0);
1539
1540 address += (state->Reg[Rm] << imm2);
1541 }
1542
1543 state->Reg[Rt] = ARMul_LoadHalfWord (state, address);
1544 if (state->Reg[Rt] & 0x8000)
1545 state->Reg[Rt] |= -(1 << 16);
1546
1547 * pvalid = t_branch;
1548 break;
1549 }
1550
1551 case 0x0D0:
1552 {
1553 ARMword Rm = ntBITS (0, 3);
1554 ARMword Rd = ntBITS (8, 11);
1555
1556 tASSERT (ntBITS (12, 15) == 15);
1557
1558 if (ntBIT (7) == 1)
1559 {
1560 // SXTH<c>.W <Rd>,<Rm>{,<rotation>}
1561 ARMword ror = ntBITS (4, 5) << 3;
1562 ARMword val;
1563
1564 val = state->Reg[Rm];
1565 val = (val >> ror) | (val << (32 - ror));
1566 if (val & 0x8000)
1567 val |= -(1 << 16);
1568 state->Reg[Rd] = val;
1569 }
1570 else
1571 {
1572 // LSL{S}<c>.W <Rd>,<Rn>,<Rm>
1573 ARMword Rn = tBITS (0, 3);
1574
1575 tASSERT (ntBITS (4, 6) == 0);
1576
1577 state->Reg[Rd] = state->Reg[Rn] << (state->Reg[Rm] & 0xFF);
1578 if (tBIT (4))
1579 ARMul_NegZero (state, state->Reg[Rd]);
1580 }
1581 * pvalid = t_branch;
1582 break;
1583 }
1584
1585 case 0x0D1: // LSR{S}<c>.W <Rd>,<Rn>,<Rm>
1586 {
1587 ARMword Rd = ntBITS (8, 11);
1588 ARMword Rn = tBITS (0, 3);
1589 ARMword Rm = ntBITS (0, 3);
1590
1591 tASSERT (ntBITS (12, 15) == 15);
1592 tASSERT (ntBITS (4, 7) == 0);
1593
1594 state->Reg[Rd] = state->Reg[Rn] >> (state->Reg[Rm] & 0xFF);
1595 if (tBIT (4))
1596 ARMul_NegZero (state, state->Reg[Rd]);
1597 * pvalid = t_resolved;
1598 break;
1599 }
1600
1601 case 0xD2:
1602 tASSERT (ntBITS (12, 15) == 15);
1603 if (ntBIT (7))
1604 {
1605 tASSERT (ntBIT (6) == 0);
1606 // UXTB<c>.W <Rd>,<Rm>{,<rotation>}
1607 * ainstr = 0xE6EF0070;
1608 * ainstr |= (ntBITS (4, 5) << 10); // rotate
1609 * ainstr |= ntBITS (0, 3); // Rm
1610 }
1611 else
1612 {
1613 // ASR{S}<c>.W <Rd>,<Rn>,<Rm>
1614 tASSERT (ntBITS (4, 7) == 0);
1615 * ainstr = 0xE1A00050;
1616 if (! in_IT_block ())
1617 * ainstr |= (tBIT (4) << 20);
1618 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1619 * ainstr |= tBITS (0, 3); // Rn
1620 }
1621
1622 * ainstr |= (ntBITS (8, 11) << 12); // Rd
1623 * pvalid = t_decoded;
1624 break;
1625
1626 case 0xD3: // ROR{S}<c>.W <Rd>,<Rn>,<Rm>
1627 tASSERT (ntBITS (12, 15) == 15);
1628 tASSERT (ntBITS (4, 7) == 0);
1629 * ainstr = 0xE1A00070;
1630 if (! in_IT_block ())
1631 * ainstr |= (tBIT (4) << 20);
1632 * ainstr |= (ntBITS (8, 11) << 12); // Rd
1633 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1634 * ainstr |= (tBITS (0, 3) << 0); // Rn
1635 * pvalid = t_decoded;
1636 break;
1637
1638 case 0xD4:
1639 {
1640 ARMword Rn = tBITS (0, 3);
1641 ARMword Rd = ntBITS (8, 11);
1642 ARMword Rm = ntBITS (0, 3);
1643
1644 tASSERT (ntBITS (12, 15) == 15);
1645
1646 if (ntBITS (4, 7) == 8)
1647 {
1648 // REV<c>.W <Rd>,<Rm>
1649 ARMword val = state->Reg[Rm];
1650
1651 tASSERT (Rm == Rn);
1652
1653 state->Reg [Rd] =
1654 (val >> 24)
1655 | ((val >> 8) & 0xFF00)
1656 | ((val << 8) & 0xFF0000)
1657 | (val << 24);
1658 * pvalid = t_resolved;
1659 }
1660 else
1661 {
1662 tASSERT (ntBITS (4, 7) == 4);
1663
1664 if (tBIT (4) == 1)
1665 // UADD8<c> <Rd>,<Rn>,<Rm>
1666 * ainstr = 0xE6500F10;
1667 else
1668 // UADD16<c> <Rd>,<Rn>,<Rm>
1669 * ainstr = 0xE6500F90;
1670
1671 * ainstr |= (Rn << 16);
1672 * ainstr |= (Rd << 12);
1673 * ainstr |= (Rm << 0);
1674 * pvalid = t_decoded;
1675 }
1676 break;
1677 }
1678
1679 case 0xD5:
1680 {
1681 ARMword Rn = tBITS (0, 3);
1682 ARMword Rd = ntBITS (8, 11);
1683 ARMword Rm = ntBITS (0, 3);
1684
1685 tASSERT (ntBITS (12, 15) == 15);
1686 tASSERT (ntBITS (4, 7) == 8);
1687
1688 if (tBIT (4))
1689 {
1690 // CLZ<c> <Rd>,<Rm>
1691 tASSERT (Rm == Rn);
1692 * ainstr = 0xE16F0F10;
1693 }
1694 else
1695 {
1696 // SEL<c> <Rd>,<Rn>,<Rm>
1697 * ainstr = 0xE6800FB0;
1698 * ainstr |= (Rn << 16);
1699 }
1700
1701 * ainstr |= (Rd << 12);
1702 * ainstr |= (Rm << 0);
1703 * pvalid = t_decoded;
1704 break;
1705 }
1706
1707 case 0xD8: // MUL
1708 {
1709 ARMword Rn = tBITS (0, 3);
1710 ARMword Rm = ntBITS (0, 3);
1711 ARMword Rd = ntBITS (8, 11);
1712 ARMword Ra = ntBITS (12, 15);
1713
1714 if (tBIT (4))
1715 {
1716 // SMLA<x><y><c> <Rd>,<Rn>,<Rm>,<Ra>
1717 ARMword nval = state->Reg[Rn];
1718 ARMword mval = state->Reg[Rm];
1719 ARMword res;
1720
1721 tASSERT (ntBITS (6, 7) == 0);
1722 tASSERT (Ra != 15);
1723
1724 if (ntBIT (5))
1725 nval >>= 16;
1726 else
1727 nval &= 0xFFFF;
1728
1729 if (ntBIT (4))
1730 mval >>= 16;
1731 else
1732 mval &= 0xFFFF;
1733
1734 res = nval * mval;
1735 res += state->Reg[Ra];
1736 // FIXME: Test and clear/set the Q bit.
1737 state->Reg[Rd] = res;
1738 }
1739 else
1740 {
1741 if (ntBITS (4, 7) == 1)
1742 {
1743 // MLS<c> <Rd>,<Rn>,<Rm>,<Ra>
1744 state->Reg[Rd] = state->Reg[Ra] - (state->Reg[Rn] * state->Reg[Rm]);
1745 }
1746 else
1747 {
1748 tASSERT (ntBITS (4, 7) == 0);
1749
1750 if (Ra == 15)
1751 // MUL<c> <Rd>,<Rn>,<Rm>
1752 state->Reg[Rd] = state->Reg[Rn] * state->Reg[Rm];
1753 else
1754 // MLA<c> <Rd>,<Rn>,<Rm>,<Ra>
1755 state->Reg[Rd] = state->Reg[Rn] * state->Reg[Rm] + state->Reg[Ra];
1756 }
1757 }
1758 * pvalid = t_resolved;
1759 break;
1760 }
1761
1762 case 0xDC:
1763 if (tBIT (4) == 0 && ntBITS (4, 7) == 0)
1764 {
1765 // SMULL
1766 * ainstr = 0xE0C00090;
1767 * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1768 * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1769 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1770 * ainstr |= tBITS (0, 3); // Rn
1771 * pvalid = t_decoded;
1772 }
1773 else if (tBIT (4) == 1 && ntBITS (4, 7) == 0xF)
1774 {
1775 // SDIV
1776 * ainstr = 0xE710F010;
1777 * ainstr |= (ntBITS (8, 11) << 16); // Rd
1778 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1779 * ainstr |= tBITS (0, 3); // Rn
1780 * pvalid = t_decoded;
1781 }
1782 else
1783 {
1784 fprintf (stderr, "(op = %x) ", tBITS (5,12));
1785 tASSERT (0);
1786 return;
1787 }
1788 break;
1789
1790 case 0xDD:
1791 if (tBIT (4) == 0 && ntBITS (4, 7) == 0)
1792 {
1793 // UMULL
1794 * ainstr = 0xE0800090;
1795 * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1796 * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1797 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1798 * ainstr |= tBITS (0, 3); // Rn
1799 * pvalid = t_decoded;
1800 }
1801 else if (tBIT (4) == 1 && ntBITS (4, 7) == 0xF)
1802 {
1803 // UDIV
1804 * ainstr = 0xE730F010;
1805 * ainstr |= (ntBITS (8, 11) << 16); // Rd
1806 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1807 * ainstr |= tBITS (0, 3); // Rn
1808 * pvalid = t_decoded;
1809 }
1810 else
1811 {
1812 fprintf (stderr, "(op = %x) ", tBITS (5,12));
1813 tASSERT (0);
1814 return;
1815 }
1816 break;
1817
1818 case 0xDF: // UMLAL
1819 tASSERT (tBIT (4) == 0);
1820 tASSERT (ntBITS (4, 7) == 0);
1821 * ainstr = 0xE0A00090;
1822 * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1823 * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1824 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1825 * ainstr |= tBITS (0, 3); // Rn
1826 * pvalid = t_decoded;
1827 break;
1828
1829 default:
1830 fprintf (stderr, "(op = %x) ", tBITS (5,12));
1831 tASSERT (0);
1832 return;
1833 }
1834
1835 /* Tell the Thumb decoder to skip the next 16-bit insn - it was
1836 part of this insn - unless this insn has changed the PC. */
1837 skipping_32bit_thumb = pc + 2;
1838 }
1839
1840 /* Attempt to emulate an ARMv6 instruction.
1841 Stores t_branch into PVALUE upon success or t_undefined otherwise. */
1842
1843 static void
1844 handle_v6_thumb_insn (ARMul_State * state,
1845 ARMword tinstr,
1846 ARMword next_instr,
1847 ARMword pc,
1848 ARMword * ainstr,
1849 tdstate * pvalid)
1850 {
1851 if (! state->is_v6)
1852 {
1853 * pvalid = t_undefined;
1854 return;
1855 }
1856
1857 if (tBITS (12, 15) == 0xB
1858 && tBIT (10) == 0
1859 && tBIT (8) == 1)
1860 {
1861 // Conditional branch forwards.
1862 ARMword Rn = tBITS (0, 2);
1863 ARMword imm5 = tBIT (9) << 5 | tBITS (3, 7);
1864
1865 if (tBIT (11))
1866 {
1867 if (state->Reg[Rn] != 0)
1868 {
1869 state->Reg[15] = (pc + 4 + imm5 * 2);
1870 FLUSHPIPE;
1871 }
1872 }
1873 else
1874 {
1875 if (state->Reg[Rn] == 0)
1876 {
1877 state->Reg[15] = (pc + 4 + imm5 * 2);
1878 FLUSHPIPE;
1879 }
1880 }
1881 * pvalid = t_branch;
1882 return;
1883 }
1884
1885 switch (tinstr & 0xFFC0)
1886 {
1887 case 0x4400:
1888 case 0x4480:
1889 case 0x4440:
1890 case 0x44C0: // ADD
1891 {
1892 ARMword Rd = (tBIT (7) << 3) | tBITS (0, 2);
1893 ARMword Rm = tBITS (3, 6);
1894 state->Reg[Rd] += state->Reg[Rm];
1895 break;
1896 }
1897
1898 case 0x4600: // MOV<c> <Rd>,<Rm>
1899 {
1900 // instr [15, 8] = 0100 0110
1901 // instr [7] = Rd<high>
1902 // instr [6,3] = Rm
1903 // instr [2,0] = Rd<low>
1904 ARMword Rd = (tBIT(7) << 3) | tBITS (0, 2);
1905 // FIXME: Check for Rd == 15 and ITblock.
1906 state->Reg[Rd] = state->Reg[tBITS (3, 6)];
1907 break;
1908 }
1909
1910 case 0xBF00:
1911 case 0xBF40:
1912 case 0xBF80:
1913 case 0xBFC0:
1914 handle_IT_block (state, tinstr, pvalid);
1915 return;
1916
1917 case 0xE840:
1918 case 0xE880: // LDMIA
1919 case 0xE8C0:
1920 case 0xE900: // STM
1921 case 0xE940:
1922 case 0xE980:
1923 case 0xE9C0: // LDRD
1924 case 0xEA00: // BIC
1925 case 0xEA40: // ORR
1926 case 0xEA80: // EOR
1927 case 0xEAC0:
1928 case 0xEB00: // ADD
1929 case 0xEB40: // SBC
1930 case 0xEB80: // SUB
1931 case 0xEBC0: // RSB
1932 case 0xFA80: // UADD, SEL
1933 case 0xFBC0: // UMULL, SMULL, SDIV, UDIV
1934 handle_T2_insn (state, tinstr, next_instr, pc, ainstr, pvalid);
1935 return;
1936
1937 case 0xba00: /* rev */
1938 {
1939 ARMword val = state->Reg[tBITS (3, 5)];
1940 state->Reg [tBITS (0, 2)] =
1941 (val >> 24)
1942 | ((val >> 8) & 0xFF00)
1943 | ((val << 8) & 0xFF0000)
1944 | (val << 24);
1945 break;
1946 }
1947
1948 case 0xba40: /* rev16 */
1949 {
1950 ARMword val = state->Reg[tBITS (3, 5)];
1951 state->Reg [tBITS (0, 2)] = (val >> 16) | (val << 16);
1952 break;
1953 }
1954
1955 case 0xb660: /* cpsie */
1956 case 0xb670: /* cpsid */
1957 case 0xbac0: /* revsh */
1958 case 0xb650: /* setend */
1959 default:
1960 printf ("Unhandled v6 thumb insn: %04x\n", tinstr);
1961 * pvalid = t_undefined;
1962 return;
1963
1964 case 0xb200: /* sxth */
1965 {
1966 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1967
1968 if (Rm & 0x8000)
1969 state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000;
1970 else
1971 state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1972 break;
1973 }
1974
1975 case 0xb240: /* sxtb */
1976 {
1977 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1978
1979 if (Rm & 0x80)
1980 state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00;
1981 else
1982 state->Reg [(tinstr & 0x7)] = Rm & 0xff;
1983 break;
1984 }
1985
1986 case 0xb280: /* uxth */
1987 {
1988 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1989
1990 state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1991 break;
1992 }
1993
1994 case 0xb2c0: /* uxtb */
1995 {
1996 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1997
1998 state->Reg [(tinstr & 0x7)] = Rm & 0xff;
1999 break;
2000 }
2001 }
2002 /* Indicate that the instruction has been processed. */
2003 * pvalid = t_branch;
2004 }
2005
2006 /* Decode a 16bit Thumb instruction. The instruction is in the low
2007 16-bits of the tinstr field, with the following Thumb instruction
2008 held in the high 16-bits. Passing in two Thumb instructions allows
2009 easier simulation of the special dual BL instruction. */
2010
2011 tdstate
2012 ARMul_ThumbDecode (ARMul_State * state,
2013 ARMword pc,
2014 ARMword tinstr,
2015 ARMword * ainstr)
2016 {
2017 tdstate valid = t_decoded; /* default assumes a valid instruction */
2018 ARMword next_instr;
2019 ARMword old_tinstr = tinstr;
2020
2021 if (skipping_32bit_thumb == pc)
2022 {
2023 skipping_32bit_thumb = 0;
2024 return t_branch;
2025 }
2026 skipping_32bit_thumb = 0;
2027
2028 if (state->bigendSig)
2029 {
2030 next_instr = tinstr & 0xFFFF;
2031 tinstr >>= 16;
2032 }
2033 else
2034 {
2035 next_instr = tinstr >> 16;
2036 tinstr &= 0xFFFF;
2037 }
2038
2039 if (! IT_block_allow (state))
2040 {
2041 if ( tBITS (11, 15) == 0x1F
2042 || tBITS (11, 15) == 0x1E
2043 || tBITS (11, 15) == 0x1D)
2044 {
2045 if (trace)
2046 fprintf (stderr, "pc: %x, SKIP instr: %04x|%04x\n",
2047 pc & ~1, tinstr, next_instr);
2048 skipping_32bit_thumb = pc + 2;
2049 }
2050 else if (trace)
2051 fprintf (stderr, "pc: %x, SKIP instr: %04x\n", pc & ~1, tinstr);
2052
2053 return t_branch;
2054 }
2055
2056 old_tinstr = tinstr;
2057 if (trace)
2058 fprintf (stderr, "pc: %x, Thumb instr: %x", pc & ~1, tinstr);
2059
2060 #if 1 /* debugging to catch non updates */
2061 *ainstr = 0xDEADC0DE;
2062 #endif
2063
2064 switch ((tinstr & 0xF800) >> 11)
2065 {
2066 case 0: /* LSL */
2067 case 1: /* LSR */
2068 case 2: /* ASR */
2069 /* Format 1 */
2070 *ainstr = 0xE1B00000 /* base opcode */
2071 | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */
2072 | ((tinstr & 0x07C0) << (7 - 6)) /* imm5 */
2073 | ((tinstr & 0x0038) >> 3) /* Rs */
2074 | ((tinstr & 0x0007) << 12); /* Rd */
2075 break;
2076 case 3: /* ADD/SUB */
2077 /* Format 2 */
2078 {
2079 ARMword subset[4] =
2080 {
2081 0xE0900000, /* ADDS Rd,Rs,Rn */
2082 0xE0500000, /* SUBS Rd,Rs,Rn */
2083 0xE2900000, /* ADDS Rd,Rs,#imm3 */
2084 0xE2500000 /* SUBS Rd,Rs,#imm3 */
2085 };
2086 /* It is quicker indexing into a table, than performing switch
2087 or conditionals: */
2088 *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */
2089 | ((tinstr & 0x01C0) >> 6) /* Rn or imm3 */
2090 | ((tinstr & 0x0038) << (16 - 3)) /* Rs */
2091 | ((tinstr & 0x0007) << (12 - 0)); /* Rd */
2092
2093 if (in_IT_block ())
2094 *ainstr &= ~ (1 << 20);
2095 }
2096 break;
2097 case 4:
2098 * ainstr = 0xE3A00000; /* MOV Rd,#imm8 */
2099 if (! in_IT_block ())
2100 * ainstr |= (1 << 20);
2101 * ainstr |= tBITS (8, 10) << 12;
2102 * ainstr |= tBITS (0, 7);
2103 break;
2104
2105 case 5:
2106 * ainstr = 0xE3500000; /* CMP Rd,#imm8 */
2107 * ainstr |= tBITS (8, 10) << 16;
2108 * ainstr |= tBITS (0, 7);
2109 break;
2110
2111 case 6:
2112 case 7:
2113 * ainstr = tBIT (11)
2114 ? 0xE2400000 /* SUB Rd,Rd,#imm8 */
2115 : 0xE2800000; /* ADD Rd,Rd,#imm8 */
2116 if (! in_IT_block ())
2117 * ainstr |= (1 << 20);
2118 * ainstr |= tBITS (8, 10) << 12;
2119 * ainstr |= tBITS (8, 10) << 16;
2120 * ainstr |= tBITS (0, 7);
2121 break;
2122
2123 case 8: /* Arithmetic and high register transfers */
2124 /* TODO: Since the subsets for both Format 4 and Format 5
2125 instructions are made up of different ARM encodings, we could
2126 save the following conditional, and just have one large
2127 subset. */
2128 if ((tinstr & (1 << 10)) == 0)
2129 {
2130 /* Format 4 */
2131 struct
2132 {
2133 ARMword opcode;
2134 enum
2135 { t_norm, t_shift, t_neg, t_mul }
2136 otype;
2137 }
2138 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 struct
2162 {
2163 ARMword opcode;
2164 enum
2165 { t_norm, t_shift, t_neg, t_mul }
2166 otype;
2167 }
2168 subset[16] =
2169 {
2170 { 0xE0000000, t_norm}, /* AND Rd,Rd,Rs */
2171 { 0xE0200000, t_norm}, /* EOR Rd,Rd,Rs */
2172 { 0xE1A00010, t_shift}, /* MOV Rd,Rd,LSL Rs */
2173 { 0xE1A00030, t_shift}, /* MOV Rd,Rd,LSR Rs */
2174 { 0xE1A00050, t_shift}, /* MOV Rd,Rd,ASR Rs */
2175 { 0xE0A00000, t_norm}, /* ADC Rd,Rd,Rs */
2176 { 0xE0C00000, t_norm}, /* SBC Rd,Rd,Rs */
2177 { 0xE1A00070, t_shift}, /* MOV Rd,Rd,ROR Rs */
2178 { 0xE1100000, t_norm}, /* TST Rd,Rs */
2179 { 0xE2600000, t_neg}, /* RSB Rd,Rs,#0 */
2180 { 0xE1500000, t_norm}, /* CMP Rd,Rs */
2181 { 0xE1700000, t_norm}, /* CMN Rd,Rs */
2182 { 0xE1800000, t_norm}, /* ORR Rd,Rd,Rs */
2183 { 0xE0000090, t_mul} , /* MUL Rd,Rd,Rs */
2184 { 0xE1C00000, t_norm}, /* BIC Rd,Rd,Rs */
2185 { 0xE1E00000, t_norm} /* MVN Rd,Rs */
2186 };
2187 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
2188 }
2189
2190 switch (subset[(tinstr & 0x03C0) >> 6].otype)
2191 {
2192 case t_norm:
2193 *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */
2194 | ((tinstr & 0x0007) << 12) /* Rd */
2195 | ((tinstr & 0x0038) >> 3); /* Rs */
2196 break;
2197 case t_shift:
2198 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
2199 | ((tinstr & 0x0007) >> 0) /* Rm */
2200 | ((tinstr & 0x0038) << (8 - 3)); /* Rs */
2201 break;
2202 case t_neg:
2203 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
2204 | ((tinstr & 0x0038) << (16 - 3)); /* Rn */
2205 break;
2206 case t_mul:
2207 *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */
2208 | ((tinstr & 0x0007) << 8) /* Rs */
2209 | ((tinstr & 0x0038) >> 3); /* Rm */
2210 break;
2211 }
2212 }
2213 else
2214 {
2215 /* Format 5 */
2216 ARMword Rd = ((tinstr & 0x0007) >> 0);
2217 ARMword Rs = ((tinstr & 0x0038) >> 3);
2218 if (tinstr & (1 << 7))
2219 Rd += 8;
2220 if (tinstr & (1 << 6))
2221 Rs += 8;
2222 switch ((tinstr & 0x03C0) >> 6)
2223 {
2224 case 0x1: /* ADD Rd,Rd,Hs */
2225 case 0x2: /* ADD Hd,Hd,Rs */
2226 case 0x3: /* ADD Hd,Hd,Hs */
2227 *ainstr = 0xE0800000 /* base */
2228 | (Rd << 16) /* Rn */
2229 | (Rd << 12) /* Rd */
2230 | (Rs << 0); /* Rm */
2231 break;
2232 case 0x5: /* CMP Rd,Hs */
2233 case 0x6: /* CMP Hd,Rs */
2234 case 0x7: /* CMP Hd,Hs */
2235 *ainstr = 0xE1500000 /* base */
2236 | (Rd << 16) /* Rn */
2237 | (Rd << 12) /* Rd */
2238 | (Rs << 0); /* Rm */
2239 break;
2240 case 0x9: /* MOV Rd,Hs */
2241 case 0xA: /* MOV Hd,Rs */
2242 case 0xB: /* MOV Hd,Hs */
2243 *ainstr = 0xE1A00000 /* base */
2244 | (Rd << 12) /* Rd */
2245 | (Rs << 0); /* Rm */
2246 break;
2247 case 0xC: /* BX Rs */
2248 case 0xD: /* BX Hs */
2249 *ainstr = 0xE12FFF10 /* base */
2250 | ((tinstr & 0x0078) >> 3); /* Rd */
2251 break;
2252 case 0xE: /* UNDEFINED */
2253 case 0xF: /* UNDEFINED */
2254 if (state->is_v5)
2255 {
2256 /* BLX Rs; BLX Hs */
2257 *ainstr = 0xE12FFF30 /* base */
2258 | ((tinstr & 0x0078) >> 3); /* Rd */
2259 break;
2260 }
2261 /* Drop through. */
2262 default:
2263 case 0x0: /* UNDEFINED */
2264 case 0x4: /* UNDEFINED */
2265 case 0x8: /* UNDEFINED */
2266 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2267 break;
2268 }
2269 }
2270 break;
2271 case 9: /* LDR Rd,[PC,#imm8] */
2272 /* Format 6 */
2273 *ainstr = 0xE59F0000 /* base */
2274 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2275 | ((tinstr & 0x00FF) << (2 - 0)); /* off8 */
2276 break;
2277 case 10:
2278 case 11:
2279 /* TODO: Format 7 and Format 8 perform the same ARM encoding, so
2280 the following could be merged into a single subset, saving on
2281 the following boolean: */
2282 if ((tinstr & (1 << 9)) == 0)
2283 {
2284 /* Format 7 */
2285 ARMword subset[4] = {
2286 0xE7800000, /* STR Rd,[Rb,Ro] */
2287 0xE7C00000, /* STRB Rd,[Rb,Ro] */
2288 0xE7900000, /* LDR Rd,[Rb,Ro] */
2289 0xE7D00000 /* LDRB Rd,[Rb,Ro] */
2290 };
2291 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2292 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2293 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2294 | ((tinstr & 0x01C0) >> 6); /* Ro */
2295 }
2296 else
2297 {
2298 /* Format 8 */
2299 ARMword subset[4] = {
2300 0xE18000B0, /* STRH Rd,[Rb,Ro] */
2301 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */
2302 0xE19000B0, /* LDRH Rd,[Rb,Ro] */
2303 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */
2304 };
2305 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2306 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2307 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2308 | ((tinstr & 0x01C0) >> 6); /* Ro */
2309 }
2310 break;
2311 case 12: /* STR Rd,[Rb,#imm5] */
2312 case 13: /* LDR Rd,[Rb,#imm5] */
2313 case 14: /* STRB Rd,[Rb,#imm5] */
2314 case 15: /* LDRB Rd,[Rb,#imm5] */
2315 /* Format 9 */
2316 {
2317 ARMword subset[4] = {
2318 0xE5800000, /* STR Rd,[Rb,#imm5] */
2319 0xE5900000, /* LDR Rd,[Rb,#imm5] */
2320 0xE5C00000, /* STRB Rd,[Rb,#imm5] */
2321 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */
2322 };
2323 /* The offset range defends on whether we are transferring a
2324 byte or word value: */
2325 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */
2326 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2327 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2328 | ((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */
2329 }
2330 break;
2331 case 16: /* STRH Rd,[Rb,#imm5] */
2332 case 17: /* LDRH Rd,[Rb,#imm5] */
2333 /* Format 10 */
2334 *ainstr = ((tinstr & (1 << 11)) /* base */
2335 ? 0xE1D000B0 /* LDRH */
2336 : 0xE1C000B0) /* STRH */
2337 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2338 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2339 | ((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */
2340 | ((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */
2341 break;
2342 case 18: /* STR Rd,[SP,#imm8] */
2343 case 19: /* LDR Rd,[SP,#imm8] */
2344 /* Format 11 */
2345 *ainstr = ((tinstr & (1 << 11)) /* base */
2346 ? 0xE59D0000 /* LDR */
2347 : 0xE58D0000) /* STR */
2348 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2349 | ((tinstr & 0x00FF) << 2); /* off8 */
2350 break;
2351 case 20: /* ADD Rd,PC,#imm8 */
2352 case 21: /* ADD Rd,SP,#imm8 */
2353 /* Format 12 */
2354 if ((tinstr & (1 << 11)) == 0)
2355 {
2356 /* NOTE: The PC value used here should by word aligned */
2357 /* We encode shift-left-by-2 in the rotate immediate field,
2358 so no shift of off8 is needed. */
2359 *ainstr = 0xE28F0F00 /* base */
2360 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2361 | (tinstr & 0x00FF); /* off8 */
2362 }
2363 else
2364 {
2365 /* We encode shift-left-by-2 in the rotate immediate field,
2366 so no shift of off8 is needed. */
2367 *ainstr = 0xE28D0F00 /* base */
2368 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2369 | (tinstr & 0x00FF); /* off8 */
2370 }
2371 break;
2372 case 22:
2373 case 23:
2374 switch (tinstr & 0x0F00)
2375 {
2376 case 0x0000:
2377 /* Format 13 */
2378 /* NOTE: The instruction contains a shift left of 2
2379 equivalent (implemented as ROR #30): */
2380 *ainstr = ((tinstr & (1 << 7)) /* base */
2381 ? 0xE24DDF00 /* SUB */
2382 : 0xE28DDF00) /* ADD */
2383 | (tinstr & 0x007F); /* off7 */
2384 break;
2385 case 0x0400:
2386 /* Format 14 - Push */
2387 * ainstr = 0xE92D0000 | (tinstr & 0x00FF);
2388 break;
2389 case 0x0500:
2390 /* Format 14 - Push + LR */
2391 * ainstr = 0xE92D4000 | (tinstr & 0x00FF);
2392 break;
2393 case 0x0c00:
2394 /* Format 14 - Pop */
2395 * ainstr = 0xE8BD0000 | (tinstr & 0x00FF);
2396 break;
2397 case 0x0d00:
2398 /* Format 14 - Pop + PC */
2399 * ainstr = 0xE8BD8000 | (tinstr & 0x00FF);
2400 break;
2401 case 0x0e00:
2402 if (state->is_v5)
2403 {
2404 /* This is normally an undefined instruction. The v5t architecture
2405 defines this particular pattern as a BKPT instruction, for
2406 hardware assisted debugging. We map onto the arm BKPT
2407 instruction. */
2408 if (state->is_v6)
2409 // Map to the SVC instruction instead of the BKPT instruction.
2410 * ainstr = 0xEF000000 | tBITS (0, 7);
2411 else
2412 * ainstr = 0xE1200070 | ((tinstr & 0xf0) << 4) | (tinstr & 0xf);
2413 break;
2414 }
2415 /* Drop through. */
2416 default:
2417 /* Everything else is an undefined instruction. */
2418 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2419 break;
2420 }
2421 break;
2422 case 24: /* STMIA */
2423 case 25: /* LDMIA */
2424 /* Format 15 */
2425 *ainstr = ((tinstr & (1 << 11)) /* base */
2426 ? 0xE8B00000 /* LDMIA */
2427 : 0xE8A00000) /* STMIA */
2428 | ((tinstr & 0x0700) << (16 - 8)) /* Rb */
2429 | (tinstr & 0x00FF); /* mask8 */
2430 break;
2431 case 26: /* Bcc */
2432 case 27: /* Bcc/SWI */
2433 if ((tinstr & 0x0F00) == 0x0F00)
2434 {
2435 /* Format 17 : SWI */
2436 *ainstr = 0xEF000000;
2437 /* Breakpoint must be handled specially. */
2438 if ((tinstr & 0x00FF) == 0x18)
2439 *ainstr |= ((tinstr & 0x00FF) << 16);
2440 /* New breakpoint value. See gdb/arm-tdep.c */
2441 else if ((tinstr & 0x00FF) == 0xFE)
2442 *ainstr |= SWI_Breakpoint;
2443 else
2444 *ainstr |= (tinstr & 0x00FF);
2445 }
2446 else if ((tinstr & 0x0F00) != 0x0E00)
2447 {
2448 /* Format 16 */
2449 int doit = FALSE;
2450 /* TODO: Since we are doing a switch here, we could just add
2451 the SWI and undefined instruction checks into this
2452 switch to same on a couple of conditionals: */
2453 switch ((tinstr & 0x0F00) >> 8)
2454 {
2455 case EQ:
2456 doit = ZFLAG;
2457 break;
2458 case NE:
2459 doit = !ZFLAG;
2460 break;
2461 case VS:
2462 doit = VFLAG;
2463 break;
2464 case VC:
2465 doit = !VFLAG;
2466 break;
2467 case MI:
2468 doit = NFLAG;
2469 break;
2470 case PL:
2471 doit = !NFLAG;
2472 break;
2473 case CS:
2474 doit = CFLAG;
2475 break;
2476 case CC:
2477 doit = !CFLAG;
2478 break;
2479 case HI:
2480 doit = (CFLAG && !ZFLAG);
2481 break;
2482 case LS:
2483 doit = (!CFLAG || ZFLAG);
2484 break;
2485 case GE:
2486 doit = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
2487 break;
2488 case LT:
2489 doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
2490 break;
2491 case GT:
2492 doit = ((!NFLAG && !VFLAG && !ZFLAG)
2493 || (NFLAG && VFLAG && !ZFLAG));
2494 break;
2495 case LE:
2496 doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
2497 break;
2498 }
2499 if (doit)
2500 {
2501 state->Reg[15] = (pc + 4
2502 + (((tinstr & 0x7F) << 1)
2503 | ((tinstr & (1 << 7)) ? 0xFFFFFF00 : 0)));
2504 FLUSHPIPE;
2505 }
2506 valid = t_branch;
2507 }
2508 else
2509 /* UNDEFINED : cc=1110(AL) uses different format. */
2510 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2511 break;
2512 case 28: /* B */
2513 /* Format 18 */
2514 state->Reg[15] = (pc + 4
2515 + (((tinstr & 0x3FF) << 1)
2516 | ((tinstr & (1 << 10)) ? 0xFFFFF800 : 0)));
2517 FLUSHPIPE;
2518 valid = t_branch;
2519 break;
2520 case 29: /* UNDEFINED */
2521 if (state->is_v6)
2522 {
2523 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2524 break;
2525 }
2526
2527 if (state->is_v5)
2528 {
2529 if (tinstr & 1)
2530 {
2531 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2532 break;
2533 }
2534 /* Drop through. */
2535
2536 /* Format 19 */
2537 /* There is no single ARM instruction equivalent for this
2538 instruction. Also, it should only ever be matched with the
2539 fmt19 "BL/BLX instruction 1" instruction. However, we do
2540 allow the simulation of it on its own, with undefined results
2541 if r14 is not suitably initialised. */
2542 {
2543 ARMword tmp = (pc + 2);
2544
2545 state->Reg[15] = ((state->Reg[14] + ((tinstr & 0x07FF) << 1))
2546 & 0xFFFFFFFC);
2547 CLEART;
2548 state->Reg[14] = (tmp | 1);
2549 valid = t_branch;
2550 FLUSHPIPE;
2551 if (trace_funcs)
2552 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
2553 break;
2554 }
2555 }
2556
2557 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2558 break;
2559
2560 case 30: /* BL instruction 1 */
2561 if (state->is_v6)
2562 {
2563 handle_T2_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2564 break;
2565 }
2566
2567 /* Format 19 */
2568 /* There is no single ARM instruction equivalent for this Thumb
2569 instruction. To keep the simulation simple (from the user
2570 perspective) we check if the following instruction is the
2571 second half of this BL, and if it is we simulate it
2572 immediately. */
2573 state->Reg[14] = state->Reg[15] \
2574 + (((tinstr & 0x07FF) << 12) \
2575 | ((tinstr & (1 << 10)) ? 0xFF800000 : 0));
2576
2577 valid = t_branch; /* in-case we don't have the 2nd half */
2578 tinstr = next_instr; /* move the instruction down */
2579 pc += 2; /* point the pc at the 2nd half */
2580 if (((tinstr & 0xF800) >> 11) != 31)
2581 {
2582 if (((tinstr & 0xF800) >> 11) == 29)
2583 {
2584 ARMword tmp = (pc + 2);
2585
2586 state->Reg[15] = ((state->Reg[14]
2587 + ((tinstr & 0x07FE) << 1))
2588 & 0xFFFFFFFC);
2589 CLEART;
2590 state->Reg[14] = (tmp | 1);
2591 valid = t_branch;
2592 FLUSHPIPE;
2593 }
2594 else
2595 /* Exit, since not correct instruction. */
2596 pc -= 2;
2597 break;
2598 }
2599 /* else we fall through to process the second half of the BL */
2600 pc += 2; /* point the pc at the 2nd half */
2601 case 31: /* BL instruction 2 */
2602 if (state->is_v6)
2603 {
2604 handle_T2_insn (state, old_tinstr, next_instr, pc, ainstr, & valid);
2605 break;
2606 }
2607
2608 /* Format 19 */
2609 /* There is no single ARM instruction equivalent for this
2610 instruction. Also, it should only ever be matched with the
2611 fmt19 "BL instruction 1" instruction. However, we do allow
2612 the simulation of it on its own, with undefined results if
2613 r14 is not suitably initialised. */
2614 {
2615 ARMword tmp = pc;
2616
2617 state->Reg[15] = (state->Reg[14] + ((tinstr & 0x07FF) << 1));
2618 state->Reg[14] = (tmp | 1);
2619 valid = t_branch;
2620 FLUSHPIPE;
2621 }
2622 break;
2623 }
2624
2625 if (trace && valid != t_decoded)
2626 fprintf (stderr, "\n");
2627
2628 return valid;
2629 }