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 18instruction into its corresponding ARM instruction, and using the 19existing 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 39static int 40test_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 65static ARMword skipping_32bit_thumb = 0; 66 67static int IT_block_cond = AL; 68static ARMword IT_block_mask = 0; 69static int IT_block_first = FALSE; 70 71static void 72handle_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 87static int 88in_IT_block (void) 89{ 90 return IT_block_mask != 0; 91} 92 93static int 94IT_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 121static ARMword 122ThumbExpandImm (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 164static void 165handle_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 1809static void 1810handle_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 1976tdstate 1977ARMul_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} 2595