]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/arm/thumbemu.c
Fix invalid left shift of negative value
[thirdparty/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: // SMULL
1763 tASSERT (tBIT (4) == 0);
1764 tASSERT (ntBITS (4, 7) == 0);
1765 * ainstr = 0xE0C00090;
1766 * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1767 * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1768 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1769 * ainstr |= tBITS (0, 3); // Rn
1770 * pvalid = t_decoded;
1771 break;
1772
1773 case 0xDD: // UMULL
1774 tASSERT (tBIT (4) == 0);
1775 tASSERT (ntBITS (4, 7) == 0);
1776 * ainstr = 0xE0800090;
1777 * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1778 * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1779 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1780 * ainstr |= tBITS (0, 3); // Rn
1781 * pvalid = t_decoded;
1782 break;
1783
1784 case 0xDF: // UMLAL
1785 tASSERT (tBIT (4) == 0);
1786 tASSERT (ntBITS (4, 7) == 0);
1787 * ainstr = 0xE0A00090;
1788 * ainstr |= (ntBITS (8, 11) << 16); // RdHi
1789 * ainstr |= (ntBITS (12, 15) << 12); // RdLo
1790 * ainstr |= (ntBITS (0, 3) << 8); // Rm
1791 * ainstr |= tBITS (0, 3); // Rn
1792 * pvalid = t_decoded;
1793 break;
1794
1795 default:
1796 fprintf (stderr, "(op = %x) ", tBITS (5,12));
1797 tASSERT (0);
1798 return;
1799 }
1800
1801 /* Tell the Thumb decoder to skip the next 16-bit insn - it was
1802 part of this insn - unless this insn has changed the PC. */
1803 skipping_32bit_thumb = pc + 2;
1804 }
1805
1806 /* Attempt to emulate an ARMv6 instruction.
1807 Stores t_branch into PVALUE upon success or t_undefined otherwise. */
1808
1809 static void
1810 handle_v6_thumb_insn (ARMul_State * state,
1811 ARMword tinstr,
1812 ARMword next_instr,
1813 ARMword pc,
1814 ARMword * ainstr,
1815 tdstate * pvalid)
1816 {
1817 if (! state->is_v6)
1818 {
1819 * pvalid = t_undefined;
1820 return;
1821 }
1822
1823 if (tBITS (12, 15) == 0xB
1824 && tBIT (10) == 0
1825 && tBIT (8) == 1)
1826 {
1827 // Conditional branch forwards.
1828 ARMword Rn = tBITS (0, 2);
1829 ARMword imm5 = tBIT (9) << 5 | tBITS (3, 7);
1830
1831 if (tBIT (11))
1832 {
1833 if (state->Reg[Rn] != 0)
1834 {
1835 state->Reg[15] = (pc + 4 + imm5 * 2);
1836 FLUSHPIPE;
1837 }
1838 }
1839 else
1840 {
1841 if (state->Reg[Rn] == 0)
1842 {
1843 state->Reg[15] = (pc + 4 + imm5 * 2);
1844 FLUSHPIPE;
1845 }
1846 }
1847 * pvalid = t_branch;
1848 return;
1849 }
1850
1851 switch (tinstr & 0xFFC0)
1852 {
1853 case 0x4400:
1854 case 0x4480:
1855 case 0x4440:
1856 case 0x44C0: // ADD
1857 {
1858 ARMword Rd = (tBIT (7) << 3) | tBITS (0, 2);
1859 ARMword Rm = tBITS (3, 6);
1860 state->Reg[Rd] += state->Reg[Rm];
1861 break;
1862 }
1863
1864 case 0x4600: // MOV<c> <Rd>,<Rm>
1865 {
1866 // instr [15, 8] = 0100 0110
1867 // instr [7] = Rd<high>
1868 // instr [6,3] = Rm
1869 // instr [2,0] = Rd<low>
1870 ARMword Rd = (tBIT(7) << 3) | tBITS (0, 2);
1871 // FIXME: Check for Rd == 15 and ITblock.
1872 state->Reg[Rd] = state->Reg[tBITS (3, 6)];
1873 break;
1874 }
1875
1876 case 0xBF00:
1877 case 0xBF40:
1878 case 0xBF80:
1879 case 0xBFC0:
1880 handle_IT_block (state, tinstr, pvalid);
1881 return;
1882
1883 case 0xE840:
1884 case 0xE880: // LDMIA
1885 case 0xE8C0:
1886 case 0xE900: // STM
1887 case 0xE940:
1888 case 0xE980:
1889 case 0xE9C0: // LDRD
1890 case 0xEA00: // BIC
1891 case 0xEA40: // ORR
1892 case 0xEA80: // EOR
1893 case 0xEAC0:
1894 case 0xEB00: // ADD
1895 case 0xEB40: // SBC
1896 case 0xEB80: // SUB
1897 case 0xEBC0: // RSB
1898 case 0xFA80: // UADD, SEL
1899 handle_T2_insn (state, tinstr, next_instr, pc, ainstr, pvalid);
1900 return;
1901
1902 case 0xba00: /* rev */
1903 {
1904 ARMword val = state->Reg[tBITS (3, 5)];
1905 state->Reg [tBITS (0, 2)] =
1906 (val >> 24)
1907 | ((val >> 8) & 0xFF00)
1908 | ((val << 8) & 0xFF0000)
1909 | (val << 24);
1910 break;
1911 }
1912
1913 case 0xba40: /* rev16 */
1914 {
1915 ARMword val = state->Reg[tBITS (3, 5)];
1916 state->Reg [tBITS (0, 2)] = (val >> 16) | (val << 16);
1917 break;
1918 }
1919
1920 case 0xb660: /* cpsie */
1921 case 0xb670: /* cpsid */
1922 case 0xbac0: /* revsh */
1923 case 0xb650: /* setend */
1924 default:
1925 printf ("Unhandled v6 thumb insn: %04x\n", tinstr);
1926 * pvalid = t_undefined;
1927 return;
1928
1929 case 0xb200: /* sxth */
1930 {
1931 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1932
1933 if (Rm & 0x8000)
1934 state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000;
1935 else
1936 state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1937 break;
1938 }
1939
1940 case 0xb240: /* sxtb */
1941 {
1942 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1943
1944 if (Rm & 0x80)
1945 state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00;
1946 else
1947 state->Reg [(tinstr & 0x7)] = Rm & 0xff;
1948 break;
1949 }
1950
1951 case 0xb280: /* uxth */
1952 {
1953 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1954
1955 state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
1956 break;
1957 }
1958
1959 case 0xb2c0: /* uxtb */
1960 {
1961 ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
1962
1963 state->Reg [(tinstr & 0x7)] = Rm & 0xff;
1964 break;
1965 }
1966 }
1967 /* Indicate that the instruction has been processed. */
1968 * pvalid = t_branch;
1969 }
1970
1971 /* Decode a 16bit Thumb instruction. The instruction is in the low
1972 16-bits of the tinstr field, with the following Thumb instruction
1973 held in the high 16-bits. Passing in two Thumb instructions allows
1974 easier simulation of the special dual BL instruction. */
1975
1976 tdstate
1977 ARMul_ThumbDecode (ARMul_State * state,
1978 ARMword pc,
1979 ARMword tinstr,
1980 ARMword * ainstr)
1981 {
1982 tdstate valid = t_decoded; /* default assumes a valid instruction */
1983 ARMword next_instr;
1984 ARMword old_tinstr = tinstr;
1985
1986 if (skipping_32bit_thumb == pc)
1987 {
1988 skipping_32bit_thumb = 0;
1989 return t_branch;
1990 }
1991 skipping_32bit_thumb = 0;
1992
1993 if (state->bigendSig)
1994 {
1995 next_instr = tinstr & 0xFFFF;
1996 tinstr >>= 16;
1997 }
1998 else
1999 {
2000 next_instr = tinstr >> 16;
2001 tinstr &= 0xFFFF;
2002 }
2003
2004 if (! IT_block_allow (state))
2005 {
2006 if ( tBITS (11, 15) == 0x1F
2007 || tBITS (11, 15) == 0x1E
2008 || tBITS (11, 15) == 0x1D)
2009 {
2010 if (trace)
2011 fprintf (stderr, "pc: %x, SKIP instr: %04x|%04x\n",
2012 pc & ~1, tinstr, next_instr);
2013 skipping_32bit_thumb = pc + 2;
2014 }
2015 else if (trace)
2016 fprintf (stderr, "pc: %x, SKIP instr: %04x\n", pc & ~1, tinstr);
2017
2018 return t_branch;
2019 }
2020
2021 old_tinstr = tinstr;
2022 if (trace)
2023 fprintf (stderr, "pc: %x, Thumb instr: %x", pc & ~1, tinstr);
2024
2025 #if 1 /* debugging to catch non updates */
2026 *ainstr = 0xDEADC0DE;
2027 #endif
2028
2029 switch ((tinstr & 0xF800) >> 11)
2030 {
2031 case 0: /* LSL */
2032 case 1: /* LSR */
2033 case 2: /* ASR */
2034 /* Format 1 */
2035 *ainstr = 0xE1B00000 /* base opcode */
2036 | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */
2037 | ((tinstr & 0x07C0) << (7 - 6)) /* imm5 */
2038 | ((tinstr & 0x0038) >> 3) /* Rs */
2039 | ((tinstr & 0x0007) << 12); /* Rd */
2040 break;
2041 case 3: /* ADD/SUB */
2042 /* Format 2 */
2043 {
2044 ARMword subset[4] =
2045 {
2046 0xE0900000, /* ADDS Rd,Rs,Rn */
2047 0xE0500000, /* SUBS Rd,Rs,Rn */
2048 0xE2900000, /* ADDS Rd,Rs,#imm3 */
2049 0xE2500000 /* SUBS Rd,Rs,#imm3 */
2050 };
2051 /* It is quicker indexing into a table, than performing switch
2052 or conditionals: */
2053 *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */
2054 | ((tinstr & 0x01C0) >> 6) /* Rn or imm3 */
2055 | ((tinstr & 0x0038) << (16 - 3)) /* Rs */
2056 | ((tinstr & 0x0007) << (12 - 0)); /* Rd */
2057
2058 if (in_IT_block ())
2059 *ainstr &= ~ (1 << 20);
2060 }
2061 break;
2062 case 4:
2063 * ainstr = 0xE3A00000; /* MOV Rd,#imm8 */
2064 if (! in_IT_block ())
2065 * ainstr |= (1 << 20);
2066 * ainstr |= tBITS (8, 10) << 12;
2067 * ainstr |= tBITS (0, 7);
2068 break;
2069
2070 case 5:
2071 * ainstr = 0xE3500000; /* CMP Rd,#imm8 */
2072 * ainstr |= tBITS (8, 10) << 16;
2073 * ainstr |= tBITS (0, 7);
2074 break;
2075
2076 case 6:
2077 case 7:
2078 * ainstr = tBIT (11)
2079 ? 0xE2400000 /* SUB Rd,Rd,#imm8 */
2080 : 0xE2800000; /* ADD Rd,Rd,#imm8 */
2081 if (! in_IT_block ())
2082 * ainstr |= (1 << 20);
2083 * ainstr |= tBITS (8, 10) << 12;
2084 * ainstr |= tBITS (8, 10) << 16;
2085 * ainstr |= tBITS (0, 7);
2086 break;
2087
2088 case 8: /* Arithmetic and high register transfers */
2089 /* TODO: Since the subsets for both Format 4 and Format 5
2090 instructions are made up of different ARM encodings, we could
2091 save the following conditional, and just have one large
2092 subset. */
2093 if ((tinstr & (1 << 10)) == 0)
2094 {
2095 /* Format 4 */
2096 struct
2097 {
2098 ARMword opcode;
2099 enum
2100 { t_norm, t_shift, t_neg, t_mul }
2101 otype;
2102 }
2103 subset[16] =
2104 {
2105 { 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */
2106 { 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */
2107 { 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */
2108 { 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */
2109 { 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */
2110 { 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */
2111 { 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */
2112 { 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */
2113 { 0xE1100000, t_norm}, /* TST Rd,Rs */
2114 { 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */
2115 { 0xE1500000, t_norm}, /* CMP Rd,Rs */
2116 { 0xE1700000, t_norm}, /* CMN Rd,Rs */
2117 { 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */
2118 { 0xE0100090, t_mul} , /* MULS Rd,Rd,Rs */
2119 { 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */
2120 { 0xE1F00000, t_norm} /* MVNS Rd,Rs */
2121 };
2122 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
2123
2124 if (in_IT_block ())
2125 {
2126 struct
2127 {
2128 ARMword opcode;
2129 enum
2130 { t_norm, t_shift, t_neg, t_mul }
2131 otype;
2132 }
2133 subset[16] =
2134 {
2135 { 0xE0000000, t_norm}, /* AND Rd,Rd,Rs */
2136 { 0xE0200000, t_norm}, /* EOR Rd,Rd,Rs */
2137 { 0xE1A00010, t_shift}, /* MOV Rd,Rd,LSL Rs */
2138 { 0xE1A00030, t_shift}, /* MOV Rd,Rd,LSR Rs */
2139 { 0xE1A00050, t_shift}, /* MOV Rd,Rd,ASR Rs */
2140 { 0xE0A00000, t_norm}, /* ADC Rd,Rd,Rs */
2141 { 0xE0C00000, t_norm}, /* SBC Rd,Rd,Rs */
2142 { 0xE1A00070, t_shift}, /* MOV Rd,Rd,ROR Rs */
2143 { 0xE1100000, t_norm}, /* TST Rd,Rs */
2144 { 0xE2600000, t_neg}, /* RSB Rd,Rs,#0 */
2145 { 0xE1500000, t_norm}, /* CMP Rd,Rs */
2146 { 0xE1700000, t_norm}, /* CMN Rd,Rs */
2147 { 0xE1800000, t_norm}, /* ORR Rd,Rd,Rs */
2148 { 0xE0000090, t_mul} , /* MUL Rd,Rd,Rs */
2149 { 0xE1C00000, t_norm}, /* BIC Rd,Rd,Rs */
2150 { 0xE1E00000, t_norm} /* MVN Rd,Rs */
2151 };
2152 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
2153 }
2154
2155 switch (subset[(tinstr & 0x03C0) >> 6].otype)
2156 {
2157 case t_norm:
2158 *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */
2159 | ((tinstr & 0x0007) << 12) /* Rd */
2160 | ((tinstr & 0x0038) >> 3); /* Rs */
2161 break;
2162 case t_shift:
2163 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
2164 | ((tinstr & 0x0007) >> 0) /* Rm */
2165 | ((tinstr & 0x0038) << (8 - 3)); /* Rs */
2166 break;
2167 case t_neg:
2168 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
2169 | ((tinstr & 0x0038) << (16 - 3)); /* Rn */
2170 break;
2171 case t_mul:
2172 *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */
2173 | ((tinstr & 0x0007) << 8) /* Rs */
2174 | ((tinstr & 0x0038) >> 3); /* Rm */
2175 break;
2176 }
2177 }
2178 else
2179 {
2180 /* Format 5 */
2181 ARMword Rd = ((tinstr & 0x0007) >> 0);
2182 ARMword Rs = ((tinstr & 0x0038) >> 3);
2183 if (tinstr & (1 << 7))
2184 Rd += 8;
2185 if (tinstr & (1 << 6))
2186 Rs += 8;
2187 switch ((tinstr & 0x03C0) >> 6)
2188 {
2189 case 0x1: /* ADD Rd,Rd,Hs */
2190 case 0x2: /* ADD Hd,Hd,Rs */
2191 case 0x3: /* ADD Hd,Hd,Hs */
2192 *ainstr = 0xE0800000 /* base */
2193 | (Rd << 16) /* Rn */
2194 | (Rd << 12) /* Rd */
2195 | (Rs << 0); /* Rm */
2196 break;
2197 case 0x5: /* CMP Rd,Hs */
2198 case 0x6: /* CMP Hd,Rs */
2199 case 0x7: /* CMP Hd,Hs */
2200 *ainstr = 0xE1500000 /* base */
2201 | (Rd << 16) /* Rn */
2202 | (Rd << 12) /* Rd */
2203 | (Rs << 0); /* Rm */
2204 break;
2205 case 0x9: /* MOV Rd,Hs */
2206 case 0xA: /* MOV Hd,Rs */
2207 case 0xB: /* MOV Hd,Hs */
2208 *ainstr = 0xE1A00000 /* base */
2209 | (Rd << 12) /* Rd */
2210 | (Rs << 0); /* Rm */
2211 break;
2212 case 0xC: /* BX Rs */
2213 case 0xD: /* BX Hs */
2214 *ainstr = 0xE12FFF10 /* base */
2215 | ((tinstr & 0x0078) >> 3); /* Rd */
2216 break;
2217 case 0xE: /* UNDEFINED */
2218 case 0xF: /* UNDEFINED */
2219 if (state->is_v5)
2220 {
2221 /* BLX Rs; BLX Hs */
2222 *ainstr = 0xE12FFF30 /* base */
2223 | ((tinstr & 0x0078) >> 3); /* Rd */
2224 break;
2225 }
2226 /* Drop through. */
2227 default:
2228 case 0x0: /* UNDEFINED */
2229 case 0x4: /* UNDEFINED */
2230 case 0x8: /* UNDEFINED */
2231 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2232 break;
2233 }
2234 }
2235 break;
2236 case 9: /* LDR Rd,[PC,#imm8] */
2237 /* Format 6 */
2238 *ainstr = 0xE59F0000 /* base */
2239 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2240 | ((tinstr & 0x00FF) << (2 - 0)); /* off8 */
2241 break;
2242 case 10:
2243 case 11:
2244 /* TODO: Format 7 and Format 8 perform the same ARM encoding, so
2245 the following could be merged into a single subset, saving on
2246 the following boolean: */
2247 if ((tinstr & (1 << 9)) == 0)
2248 {
2249 /* Format 7 */
2250 ARMword subset[4] = {
2251 0xE7800000, /* STR Rd,[Rb,Ro] */
2252 0xE7C00000, /* STRB Rd,[Rb,Ro] */
2253 0xE7900000, /* LDR Rd,[Rb,Ro] */
2254 0xE7D00000 /* LDRB Rd,[Rb,Ro] */
2255 };
2256 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2257 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2258 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2259 | ((tinstr & 0x01C0) >> 6); /* Ro */
2260 }
2261 else
2262 {
2263 /* Format 8 */
2264 ARMword subset[4] = {
2265 0xE18000B0, /* STRH Rd,[Rb,Ro] */
2266 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */
2267 0xE19000B0, /* LDRH Rd,[Rb,Ro] */
2268 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */
2269 };
2270 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
2271 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2272 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2273 | ((tinstr & 0x01C0) >> 6); /* Ro */
2274 }
2275 break;
2276 case 12: /* STR Rd,[Rb,#imm5] */
2277 case 13: /* LDR Rd,[Rb,#imm5] */
2278 case 14: /* STRB Rd,[Rb,#imm5] */
2279 case 15: /* LDRB Rd,[Rb,#imm5] */
2280 /* Format 9 */
2281 {
2282 ARMword subset[4] = {
2283 0xE5800000, /* STR Rd,[Rb,#imm5] */
2284 0xE5900000, /* LDR Rd,[Rb,#imm5] */
2285 0xE5C00000, /* STRB Rd,[Rb,#imm5] */
2286 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */
2287 };
2288 /* The offset range defends on whether we are transferring a
2289 byte or word value: */
2290 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */
2291 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2292 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2293 | ((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */
2294 }
2295 break;
2296 case 16: /* STRH Rd,[Rb,#imm5] */
2297 case 17: /* LDRH Rd,[Rb,#imm5] */
2298 /* Format 10 */
2299 *ainstr = ((tinstr & (1 << 11)) /* base */
2300 ? 0xE1D000B0 /* LDRH */
2301 : 0xE1C000B0) /* STRH */
2302 | ((tinstr & 0x0007) << (12 - 0)) /* Rd */
2303 | ((tinstr & 0x0038) << (16 - 3)) /* Rb */
2304 | ((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */
2305 | ((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */
2306 break;
2307 case 18: /* STR Rd,[SP,#imm8] */
2308 case 19: /* LDR Rd,[SP,#imm8] */
2309 /* Format 11 */
2310 *ainstr = ((tinstr & (1 << 11)) /* base */
2311 ? 0xE59D0000 /* LDR */
2312 : 0xE58D0000) /* STR */
2313 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2314 | ((tinstr & 0x00FF) << 2); /* off8 */
2315 break;
2316 case 20: /* ADD Rd,PC,#imm8 */
2317 case 21: /* ADD Rd,SP,#imm8 */
2318 /* Format 12 */
2319 if ((tinstr & (1 << 11)) == 0)
2320 {
2321 /* NOTE: The PC value used here should by word aligned */
2322 /* We encode shift-left-by-2 in the rotate immediate field,
2323 so no shift of off8 is needed. */
2324 *ainstr = 0xE28F0F00 /* base */
2325 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2326 | (tinstr & 0x00FF); /* off8 */
2327 }
2328 else
2329 {
2330 /* We encode shift-left-by-2 in the rotate immediate field,
2331 so no shift of off8 is needed. */
2332 *ainstr = 0xE28D0F00 /* base */
2333 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
2334 | (tinstr & 0x00FF); /* off8 */
2335 }
2336 break;
2337 case 22:
2338 case 23:
2339 switch (tinstr & 0x0F00)
2340 {
2341 case 0x0000:
2342 /* Format 13 */
2343 /* NOTE: The instruction contains a shift left of 2
2344 equivalent (implemented as ROR #30): */
2345 *ainstr = ((tinstr & (1 << 7)) /* base */
2346 ? 0xE24DDF00 /* SUB */
2347 : 0xE28DDF00) /* ADD */
2348 | (tinstr & 0x007F); /* off7 */
2349 break;
2350 case 0x0400:
2351 /* Format 14 - Push */
2352 * ainstr = 0xE92D0000 | (tinstr & 0x00FF);
2353 break;
2354 case 0x0500:
2355 /* Format 14 - Push + LR */
2356 * ainstr = 0xE92D4000 | (tinstr & 0x00FF);
2357 break;
2358 case 0x0c00:
2359 /* Format 14 - Pop */
2360 * ainstr = 0xE8BD0000 | (tinstr & 0x00FF);
2361 break;
2362 case 0x0d00:
2363 /* Format 14 - Pop + PC */
2364 * ainstr = 0xE8BD8000 | (tinstr & 0x00FF);
2365 break;
2366 case 0x0e00:
2367 if (state->is_v5)
2368 {
2369 /* This is normally an undefined instruction. The v5t architecture
2370 defines this particular pattern as a BKPT instruction, for
2371 hardware assisted debugging. We map onto the arm BKPT
2372 instruction. */
2373 if (state->is_v6)
2374 // Map to the SVC instruction instead of the BKPT instruction.
2375 * ainstr = 0xEF000000 | tBITS (0, 7);
2376 else
2377 * ainstr = 0xE1200070 | ((tinstr & 0xf0) << 4) | (tinstr & 0xf);
2378 break;
2379 }
2380 /* Drop through. */
2381 default:
2382 /* Everything else is an undefined instruction. */
2383 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2384 break;
2385 }
2386 break;
2387 case 24: /* STMIA */
2388 case 25: /* LDMIA */
2389 /* Format 15 */
2390 *ainstr = ((tinstr & (1 << 11)) /* base */
2391 ? 0xE8B00000 /* LDMIA */
2392 : 0xE8A00000) /* STMIA */
2393 | ((tinstr & 0x0700) << (16 - 8)) /* Rb */
2394 | (tinstr & 0x00FF); /* mask8 */
2395 break;
2396 case 26: /* Bcc */
2397 case 27: /* Bcc/SWI */
2398 if ((tinstr & 0x0F00) == 0x0F00)
2399 {
2400 /* Format 17 : SWI */
2401 *ainstr = 0xEF000000;
2402 /* Breakpoint must be handled specially. */
2403 if ((tinstr & 0x00FF) == 0x18)
2404 *ainstr |= ((tinstr & 0x00FF) << 16);
2405 /* New breakpoint value. See gdb/arm-tdep.c */
2406 else if ((tinstr & 0x00FF) == 0xFE)
2407 *ainstr |= SWI_Breakpoint;
2408 else
2409 *ainstr |= (tinstr & 0x00FF);
2410 }
2411 else if ((tinstr & 0x0F00) != 0x0E00)
2412 {
2413 /* Format 16 */
2414 int doit = FALSE;
2415 /* TODO: Since we are doing a switch here, we could just add
2416 the SWI and undefined instruction checks into this
2417 switch to same on a couple of conditionals: */
2418 switch ((tinstr & 0x0F00) >> 8)
2419 {
2420 case EQ:
2421 doit = ZFLAG;
2422 break;
2423 case NE:
2424 doit = !ZFLAG;
2425 break;
2426 case VS:
2427 doit = VFLAG;
2428 break;
2429 case VC:
2430 doit = !VFLAG;
2431 break;
2432 case MI:
2433 doit = NFLAG;
2434 break;
2435 case PL:
2436 doit = !NFLAG;
2437 break;
2438 case CS:
2439 doit = CFLAG;
2440 break;
2441 case CC:
2442 doit = !CFLAG;
2443 break;
2444 case HI:
2445 doit = (CFLAG && !ZFLAG);
2446 break;
2447 case LS:
2448 doit = (!CFLAG || ZFLAG);
2449 break;
2450 case GE:
2451 doit = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
2452 break;
2453 case LT:
2454 doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
2455 break;
2456 case GT:
2457 doit = ((!NFLAG && !VFLAG && !ZFLAG)
2458 || (NFLAG && VFLAG && !ZFLAG));
2459 break;
2460 case LE:
2461 doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
2462 break;
2463 }
2464 if (doit)
2465 {
2466 state->Reg[15] = (pc + 4
2467 + (((tinstr & 0x7F) << 1)
2468 | ((tinstr & (1 << 7)) ? 0xFFFFFF00 : 0)));
2469 FLUSHPIPE;
2470 }
2471 valid = t_branch;
2472 }
2473 else
2474 /* UNDEFINED : cc=1110(AL) uses different format. */
2475 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2476 break;
2477 case 28: /* B */
2478 /* Format 18 */
2479 state->Reg[15] = (pc + 4
2480 + (((tinstr & 0x3FF) << 1)
2481 | ((tinstr & (1 << 10)) ? 0xFFFFF800 : 0)));
2482 FLUSHPIPE;
2483 valid = t_branch;
2484 break;
2485 case 29: /* UNDEFINED */
2486 if (state->is_v6)
2487 {
2488 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2489 break;
2490 }
2491
2492 if (state->is_v5)
2493 {
2494 if (tinstr & 1)
2495 {
2496 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2497 break;
2498 }
2499 /* Drop through. */
2500
2501 /* Format 19 */
2502 /* There is no single ARM instruction equivalent for this
2503 instruction. Also, it should only ever be matched with the
2504 fmt19 "BL/BLX instruction 1" instruction. However, we do
2505 allow the simulation of it on its own, with undefined results
2506 if r14 is not suitably initialised. */
2507 {
2508 ARMword tmp = (pc + 2);
2509
2510 state->Reg[15] = ((state->Reg[14] + ((tinstr & 0x07FF) << 1))
2511 & 0xFFFFFFFC);
2512 CLEART;
2513 state->Reg[14] = (tmp | 1);
2514 valid = t_branch;
2515 FLUSHPIPE;
2516 if (trace_funcs)
2517 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
2518 break;
2519 }
2520 }
2521
2522 handle_v6_thumb_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2523 break;
2524
2525 case 30: /* BL instruction 1 */
2526 if (state->is_v6)
2527 {
2528 handle_T2_insn (state, tinstr, next_instr, pc, ainstr, & valid);
2529 break;
2530 }
2531
2532 /* Format 19 */
2533 /* There is no single ARM instruction equivalent for this Thumb
2534 instruction. To keep the simulation simple (from the user
2535 perspective) we check if the following instruction is the
2536 second half of this BL, and if it is we simulate it
2537 immediately. */
2538 state->Reg[14] = state->Reg[15] \
2539 + (((tinstr & 0x07FF) << 12) \
2540 | ((tinstr & (1 << 10)) ? 0xFF800000 : 0));
2541
2542 valid = t_branch; /* in-case we don't have the 2nd half */
2543 tinstr = next_instr; /* move the instruction down */
2544 pc += 2; /* point the pc at the 2nd half */
2545 if (((tinstr & 0xF800) >> 11) != 31)
2546 {
2547 if (((tinstr & 0xF800) >> 11) == 29)
2548 {
2549 ARMword tmp = (pc + 2);
2550
2551 state->Reg[15] = ((state->Reg[14]
2552 + ((tinstr & 0x07FE) << 1))
2553 & 0xFFFFFFFC);
2554 CLEART;
2555 state->Reg[14] = (tmp | 1);
2556 valid = t_branch;
2557 FLUSHPIPE;
2558 }
2559 else
2560 /* Exit, since not correct instruction. */
2561 pc -= 2;
2562 break;
2563 }
2564 /* else we fall through to process the second half of the BL */
2565 pc += 2; /* point the pc at the 2nd half */
2566 case 31: /* BL instruction 2 */
2567 if (state->is_v6)
2568 {
2569 handle_T2_insn (state, old_tinstr, next_instr, pc, ainstr, & valid);
2570 break;
2571 }
2572
2573 /* Format 19 */
2574 /* There is no single ARM instruction equivalent for this
2575 instruction. Also, it should only ever be matched with the
2576 fmt19 "BL instruction 1" instruction. However, we do allow
2577 the simulation of it on its own, with undefined results if
2578 r14 is not suitably initialised. */
2579 {
2580 ARMword tmp = pc;
2581
2582 state->Reg[15] = (state->Reg[14] + ((tinstr & 0x07FF) << 1));
2583 state->Reg[14] = (tmp | 1);
2584 valid = t_branch;
2585 FLUSHPIPE;
2586 }
2587 break;
2588 }
2589
2590 if (trace && valid != t_decoded)
2591 fprintf (stderr, "\n");
2592
2593 return valid;
2594 }