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