1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include <stdlib.h> 11 12 #include "EmulateInstructionARM.h" 13 #include "EmulationStateARM.h" 14 #include "lldb/Core/Address.h" 15 #include "lldb/Core/ArchSpec.h" 16 #include "lldb/Core/PluginManager.h" 17 #include "lldb/Host/PosixApi.h" 18 #include "lldb/Interpreter/OptionValueArray.h" 19 #include "lldb/Interpreter/OptionValueDictionary.h" 20 #include "lldb/Symbol/UnwindPlan.h" 21 #include "lldb/Utility/ConstString.h" 22 #include "lldb/Utility/Stream.h" 23 24 #include "Plugins/Process/Utility/ARMDefines.h" 25 #include "Plugins/Process/Utility/ARMUtils.h" 26 #include "Utility/ARM_DWARF_Registers.h" 27 28 #include "llvm/ADT/STLExtras.h" 29 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function 30 // and countTrailingZeros function 31 32 using namespace lldb; 33 using namespace lldb_private; 34 35 // Convenient macro definitions. 36 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 37 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 38 39 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 40 41 //---------------------------------------------------------------------- 42 // 43 // ITSession implementation 44 // 45 //---------------------------------------------------------------------- 46 47 static const char *GetARMDWARFRegisterName(unsigned reg_num) { 48 switch (reg_num) { 49 case dwarf_r0: 50 return "r0"; 51 case dwarf_r1: 52 return "r1"; 53 case dwarf_r2: 54 return "r2"; 55 case dwarf_r3: 56 return "r3"; 57 case dwarf_r4: 58 return "r4"; 59 case dwarf_r5: 60 return "r5"; 61 case dwarf_r6: 62 return "r6"; 63 case dwarf_r7: 64 return "r7"; 65 case dwarf_r8: 66 return "r8"; 67 case dwarf_r9: 68 return "r9"; 69 case dwarf_r10: 70 return "r10"; 71 case dwarf_r11: 72 return "r11"; 73 case dwarf_r12: 74 return "r12"; 75 case dwarf_sp: 76 return "sp"; 77 case dwarf_lr: 78 return "lr"; 79 case dwarf_pc: 80 return "pc"; 81 case dwarf_cpsr: 82 return "cpsr"; 83 84 case dwarf_s0: 85 return "s0"; 86 case dwarf_s1: 87 return "s1"; 88 case dwarf_s2: 89 return "s2"; 90 case dwarf_s3: 91 return "s3"; 92 case dwarf_s4: 93 return "s4"; 94 case dwarf_s5: 95 return "s5"; 96 case dwarf_s6: 97 return "s6"; 98 case dwarf_s7: 99 return "s7"; 100 case dwarf_s8: 101 return "s8"; 102 case dwarf_s9: 103 return "s9"; 104 case dwarf_s10: 105 return "s10"; 106 case dwarf_s11: 107 return "s11"; 108 case dwarf_s12: 109 return "s12"; 110 case dwarf_s13: 111 return "s13"; 112 case dwarf_s14: 113 return "s14"; 114 case dwarf_s15: 115 return "s15"; 116 case dwarf_s16: 117 return "s16"; 118 case dwarf_s17: 119 return "s17"; 120 case dwarf_s18: 121 return "s18"; 122 case dwarf_s19: 123 return "s19"; 124 case dwarf_s20: 125 return "s20"; 126 case dwarf_s21: 127 return "s21"; 128 case dwarf_s22: 129 return "s22"; 130 case dwarf_s23: 131 return "s23"; 132 case dwarf_s24: 133 return "s24"; 134 case dwarf_s25: 135 return "s25"; 136 case dwarf_s26: 137 return "s26"; 138 case dwarf_s27: 139 return "s27"; 140 case dwarf_s28: 141 return "s28"; 142 case dwarf_s29: 143 return "s29"; 144 case dwarf_s30: 145 return "s30"; 146 case dwarf_s31: 147 return "s31"; 148 149 // FPA Registers 0-7 150 case dwarf_f0: 151 return "f0"; 152 case dwarf_f1: 153 return "f1"; 154 case dwarf_f2: 155 return "f2"; 156 case dwarf_f3: 157 return "f3"; 158 case dwarf_f4: 159 return "f4"; 160 case dwarf_f5: 161 return "f5"; 162 case dwarf_f6: 163 return "f6"; 164 case dwarf_f7: 165 return "f7"; 166 167 // Intel wireless MMX general purpose registers 0 - 7 168 // XScale accumulator register 0 - 7 (they do overlap with wCGR0 - wCGR7) 169 case dwarf_wCGR0: 170 return "wCGR0/ACC0"; 171 case dwarf_wCGR1: 172 return "wCGR1/ACC1"; 173 case dwarf_wCGR2: 174 return "wCGR2/ACC2"; 175 case dwarf_wCGR3: 176 return "wCGR3/ACC3"; 177 case dwarf_wCGR4: 178 return "wCGR4/ACC4"; 179 case dwarf_wCGR5: 180 return "wCGR5/ACC5"; 181 case dwarf_wCGR6: 182 return "wCGR6/ACC6"; 183 case dwarf_wCGR7: 184 return "wCGR7/ACC7"; 185 186 // Intel wireless MMX data registers 0 - 15 187 case dwarf_wR0: 188 return "wR0"; 189 case dwarf_wR1: 190 return "wR1"; 191 case dwarf_wR2: 192 return "wR2"; 193 case dwarf_wR3: 194 return "wR3"; 195 case dwarf_wR4: 196 return "wR4"; 197 case dwarf_wR5: 198 return "wR5"; 199 case dwarf_wR6: 200 return "wR6"; 201 case dwarf_wR7: 202 return "wR7"; 203 case dwarf_wR8: 204 return "wR8"; 205 case dwarf_wR9: 206 return "wR9"; 207 case dwarf_wR10: 208 return "wR10"; 209 case dwarf_wR11: 210 return "wR11"; 211 case dwarf_wR12: 212 return "wR12"; 213 case dwarf_wR13: 214 return "wR13"; 215 case dwarf_wR14: 216 return "wR14"; 217 case dwarf_wR15: 218 return "wR15"; 219 220 case dwarf_spsr: 221 return "spsr"; 222 case dwarf_spsr_fiq: 223 return "spsr_fiq"; 224 case dwarf_spsr_irq: 225 return "spsr_irq"; 226 case dwarf_spsr_abt: 227 return "spsr_abt"; 228 case dwarf_spsr_und: 229 return "spsr_und"; 230 case dwarf_spsr_svc: 231 return "spsr_svc"; 232 233 case dwarf_r8_usr: 234 return "r8_usr"; 235 case dwarf_r9_usr: 236 return "r9_usr"; 237 case dwarf_r10_usr: 238 return "r10_usr"; 239 case dwarf_r11_usr: 240 return "r11_usr"; 241 case dwarf_r12_usr: 242 return "r12_usr"; 243 case dwarf_r13_usr: 244 return "r13_usr"; 245 case dwarf_r14_usr: 246 return "r14_usr"; 247 case dwarf_r8_fiq: 248 return "r8_fiq"; 249 case dwarf_r9_fiq: 250 return "r9_fiq"; 251 case dwarf_r10_fiq: 252 return "r10_fiq"; 253 case dwarf_r11_fiq: 254 return "r11_fiq"; 255 case dwarf_r12_fiq: 256 return "r12_fiq"; 257 case dwarf_r13_fiq: 258 return "r13_fiq"; 259 case dwarf_r14_fiq: 260 return "r14_fiq"; 261 case dwarf_r13_irq: 262 return "r13_irq"; 263 case dwarf_r14_irq: 264 return "r14_irq"; 265 case dwarf_r13_abt: 266 return "r13_abt"; 267 case dwarf_r14_abt: 268 return "r14_abt"; 269 case dwarf_r13_und: 270 return "r13_und"; 271 case dwarf_r14_und: 272 return "r14_und"; 273 case dwarf_r13_svc: 274 return "r13_svc"; 275 case dwarf_r14_svc: 276 return "r14_svc"; 277 278 // Intel wireless MMX control register in co-processor 0 - 7 279 case dwarf_wC0: 280 return "wC0"; 281 case dwarf_wC1: 282 return "wC1"; 283 case dwarf_wC2: 284 return "wC2"; 285 case dwarf_wC3: 286 return "wC3"; 287 case dwarf_wC4: 288 return "wC4"; 289 case dwarf_wC5: 290 return "wC5"; 291 case dwarf_wC6: 292 return "wC6"; 293 case dwarf_wC7: 294 return "wC7"; 295 296 // VFP-v3/Neon 297 case dwarf_d0: 298 return "d0"; 299 case dwarf_d1: 300 return "d1"; 301 case dwarf_d2: 302 return "d2"; 303 case dwarf_d3: 304 return "d3"; 305 case dwarf_d4: 306 return "d4"; 307 case dwarf_d5: 308 return "d5"; 309 case dwarf_d6: 310 return "d6"; 311 case dwarf_d7: 312 return "d7"; 313 case dwarf_d8: 314 return "d8"; 315 case dwarf_d9: 316 return "d9"; 317 case dwarf_d10: 318 return "d10"; 319 case dwarf_d11: 320 return "d11"; 321 case dwarf_d12: 322 return "d12"; 323 case dwarf_d13: 324 return "d13"; 325 case dwarf_d14: 326 return "d14"; 327 case dwarf_d15: 328 return "d15"; 329 case dwarf_d16: 330 return "d16"; 331 case dwarf_d17: 332 return "d17"; 333 case dwarf_d18: 334 return "d18"; 335 case dwarf_d19: 336 return "d19"; 337 case dwarf_d20: 338 return "d20"; 339 case dwarf_d21: 340 return "d21"; 341 case dwarf_d22: 342 return "d22"; 343 case dwarf_d23: 344 return "d23"; 345 case dwarf_d24: 346 return "d24"; 347 case dwarf_d25: 348 return "d25"; 349 case dwarf_d26: 350 return "d26"; 351 case dwarf_d27: 352 return "d27"; 353 case dwarf_d28: 354 return "d28"; 355 case dwarf_d29: 356 return "d29"; 357 case dwarf_d30: 358 return "d30"; 359 case dwarf_d31: 360 return "d31"; 361 362 // NEON 128-bit vector registers (overlays the d registers) 363 case dwarf_q0: 364 return "q0"; 365 case dwarf_q1: 366 return "q1"; 367 case dwarf_q2: 368 return "q2"; 369 case dwarf_q3: 370 return "q3"; 371 case dwarf_q4: 372 return "q4"; 373 case dwarf_q5: 374 return "q5"; 375 case dwarf_q6: 376 return "q6"; 377 case dwarf_q7: 378 return "q7"; 379 case dwarf_q8: 380 return "q8"; 381 case dwarf_q9: 382 return "q9"; 383 case dwarf_q10: 384 return "q10"; 385 case dwarf_q11: 386 return "q11"; 387 case dwarf_q12: 388 return "q12"; 389 case dwarf_q13: 390 return "q13"; 391 case dwarf_q14: 392 return "q14"; 393 case dwarf_q15: 394 return "q15"; 395 } 396 return nullptr; 397 } 398 399 static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo ®_info) { 400 ::memset(®_info, 0, sizeof(RegisterInfo)); 401 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); 402 403 if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) { 404 reg_info.byte_size = 16; 405 reg_info.format = eFormatVectorOfUInt8; 406 reg_info.encoding = eEncodingVector; 407 } 408 409 if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) { 410 reg_info.byte_size = 8; 411 reg_info.format = eFormatFloat; 412 reg_info.encoding = eEncodingIEEE754; 413 } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) { 414 reg_info.byte_size = 4; 415 reg_info.format = eFormatFloat; 416 reg_info.encoding = eEncodingIEEE754; 417 } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) { 418 reg_info.byte_size = 12; 419 reg_info.format = eFormatFloat; 420 reg_info.encoding = eEncodingIEEE754; 421 } else { 422 reg_info.byte_size = 4; 423 reg_info.format = eFormatHex; 424 reg_info.encoding = eEncodingUint; 425 } 426 427 reg_info.kinds[eRegisterKindDWARF] = reg_num; 428 429 switch (reg_num) { 430 case dwarf_r0: 431 reg_info.name = "r0"; 432 break; 433 case dwarf_r1: 434 reg_info.name = "r1"; 435 break; 436 case dwarf_r2: 437 reg_info.name = "r2"; 438 break; 439 case dwarf_r3: 440 reg_info.name = "r3"; 441 break; 442 case dwarf_r4: 443 reg_info.name = "r4"; 444 break; 445 case dwarf_r5: 446 reg_info.name = "r5"; 447 break; 448 case dwarf_r6: 449 reg_info.name = "r6"; 450 break; 451 case dwarf_r7: 452 reg_info.name = "r7"; 453 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; 454 break; 455 case dwarf_r8: 456 reg_info.name = "r8"; 457 break; 458 case dwarf_r9: 459 reg_info.name = "r9"; 460 break; 461 case dwarf_r10: 462 reg_info.name = "r10"; 463 break; 464 case dwarf_r11: 465 reg_info.name = "r11"; 466 break; 467 case dwarf_r12: 468 reg_info.name = "r12"; 469 break; 470 case dwarf_sp: 471 reg_info.name = "sp"; 472 reg_info.alt_name = "r13"; 473 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; 474 break; 475 case dwarf_lr: 476 reg_info.name = "lr"; 477 reg_info.alt_name = "r14"; 478 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; 479 break; 480 case dwarf_pc: 481 reg_info.name = "pc"; 482 reg_info.alt_name = "r15"; 483 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; 484 break; 485 case dwarf_cpsr: 486 reg_info.name = "cpsr"; 487 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; 488 break; 489 490 case dwarf_s0: 491 reg_info.name = "s0"; 492 break; 493 case dwarf_s1: 494 reg_info.name = "s1"; 495 break; 496 case dwarf_s2: 497 reg_info.name = "s2"; 498 break; 499 case dwarf_s3: 500 reg_info.name = "s3"; 501 break; 502 case dwarf_s4: 503 reg_info.name = "s4"; 504 break; 505 case dwarf_s5: 506 reg_info.name = "s5"; 507 break; 508 case dwarf_s6: 509 reg_info.name = "s6"; 510 break; 511 case dwarf_s7: 512 reg_info.name = "s7"; 513 break; 514 case dwarf_s8: 515 reg_info.name = "s8"; 516 break; 517 case dwarf_s9: 518 reg_info.name = "s9"; 519 break; 520 case dwarf_s10: 521 reg_info.name = "s10"; 522 break; 523 case dwarf_s11: 524 reg_info.name = "s11"; 525 break; 526 case dwarf_s12: 527 reg_info.name = "s12"; 528 break; 529 case dwarf_s13: 530 reg_info.name = "s13"; 531 break; 532 case dwarf_s14: 533 reg_info.name = "s14"; 534 break; 535 case dwarf_s15: 536 reg_info.name = "s15"; 537 break; 538 case dwarf_s16: 539 reg_info.name = "s16"; 540 break; 541 case dwarf_s17: 542 reg_info.name = "s17"; 543 break; 544 case dwarf_s18: 545 reg_info.name = "s18"; 546 break; 547 case dwarf_s19: 548 reg_info.name = "s19"; 549 break; 550 case dwarf_s20: 551 reg_info.name = "s20"; 552 break; 553 case dwarf_s21: 554 reg_info.name = "s21"; 555 break; 556 case dwarf_s22: 557 reg_info.name = "s22"; 558 break; 559 case dwarf_s23: 560 reg_info.name = "s23"; 561 break; 562 case dwarf_s24: 563 reg_info.name = "s24"; 564 break; 565 case dwarf_s25: 566 reg_info.name = "s25"; 567 break; 568 case dwarf_s26: 569 reg_info.name = "s26"; 570 break; 571 case dwarf_s27: 572 reg_info.name = "s27"; 573 break; 574 case dwarf_s28: 575 reg_info.name = "s28"; 576 break; 577 case dwarf_s29: 578 reg_info.name = "s29"; 579 break; 580 case dwarf_s30: 581 reg_info.name = "s30"; 582 break; 583 case dwarf_s31: 584 reg_info.name = "s31"; 585 break; 586 587 // FPA Registers 0-7 588 case dwarf_f0: 589 reg_info.name = "f0"; 590 break; 591 case dwarf_f1: 592 reg_info.name = "f1"; 593 break; 594 case dwarf_f2: 595 reg_info.name = "f2"; 596 break; 597 case dwarf_f3: 598 reg_info.name = "f3"; 599 break; 600 case dwarf_f4: 601 reg_info.name = "f4"; 602 break; 603 case dwarf_f5: 604 reg_info.name = "f5"; 605 break; 606 case dwarf_f6: 607 reg_info.name = "f6"; 608 break; 609 case dwarf_f7: 610 reg_info.name = "f7"; 611 break; 612 613 // Intel wireless MMX general purpose registers 0 - 7 614 // XScale accumulator register 0 - 7 (they do overlap with wCGR0 - wCGR7) 615 case dwarf_wCGR0: 616 reg_info.name = "wCGR0/ACC0"; 617 break; 618 case dwarf_wCGR1: 619 reg_info.name = "wCGR1/ACC1"; 620 break; 621 case dwarf_wCGR2: 622 reg_info.name = "wCGR2/ACC2"; 623 break; 624 case dwarf_wCGR3: 625 reg_info.name = "wCGR3/ACC3"; 626 break; 627 case dwarf_wCGR4: 628 reg_info.name = "wCGR4/ACC4"; 629 break; 630 case dwarf_wCGR5: 631 reg_info.name = "wCGR5/ACC5"; 632 break; 633 case dwarf_wCGR6: 634 reg_info.name = "wCGR6/ACC6"; 635 break; 636 case dwarf_wCGR7: 637 reg_info.name = "wCGR7/ACC7"; 638 break; 639 640 // Intel wireless MMX data registers 0 - 15 641 case dwarf_wR0: 642 reg_info.name = "wR0"; 643 break; 644 case dwarf_wR1: 645 reg_info.name = "wR1"; 646 break; 647 case dwarf_wR2: 648 reg_info.name = "wR2"; 649 break; 650 case dwarf_wR3: 651 reg_info.name = "wR3"; 652 break; 653 case dwarf_wR4: 654 reg_info.name = "wR4"; 655 break; 656 case dwarf_wR5: 657 reg_info.name = "wR5"; 658 break; 659 case dwarf_wR6: 660 reg_info.name = "wR6"; 661 break; 662 case dwarf_wR7: 663 reg_info.name = "wR7"; 664 break; 665 case dwarf_wR8: 666 reg_info.name = "wR8"; 667 break; 668 case dwarf_wR9: 669 reg_info.name = "wR9"; 670 break; 671 case dwarf_wR10: 672 reg_info.name = "wR10"; 673 break; 674 case dwarf_wR11: 675 reg_info.name = "wR11"; 676 break; 677 case dwarf_wR12: 678 reg_info.name = "wR12"; 679 break; 680 case dwarf_wR13: 681 reg_info.name = "wR13"; 682 break; 683 case dwarf_wR14: 684 reg_info.name = "wR14"; 685 break; 686 case dwarf_wR15: 687 reg_info.name = "wR15"; 688 break; 689 690 case dwarf_spsr: 691 reg_info.name = "spsr"; 692 break; 693 case dwarf_spsr_fiq: 694 reg_info.name = "spsr_fiq"; 695 break; 696 case dwarf_spsr_irq: 697 reg_info.name = "spsr_irq"; 698 break; 699 case dwarf_spsr_abt: 700 reg_info.name = "spsr_abt"; 701 break; 702 case dwarf_spsr_und: 703 reg_info.name = "spsr_und"; 704 break; 705 case dwarf_spsr_svc: 706 reg_info.name = "spsr_svc"; 707 break; 708 709 case dwarf_r8_usr: 710 reg_info.name = "r8_usr"; 711 break; 712 case dwarf_r9_usr: 713 reg_info.name = "r9_usr"; 714 break; 715 case dwarf_r10_usr: 716 reg_info.name = "r10_usr"; 717 break; 718 case dwarf_r11_usr: 719 reg_info.name = "r11_usr"; 720 break; 721 case dwarf_r12_usr: 722 reg_info.name = "r12_usr"; 723 break; 724 case dwarf_r13_usr: 725 reg_info.name = "r13_usr"; 726 break; 727 case dwarf_r14_usr: 728 reg_info.name = "r14_usr"; 729 break; 730 case dwarf_r8_fiq: 731 reg_info.name = "r8_fiq"; 732 break; 733 case dwarf_r9_fiq: 734 reg_info.name = "r9_fiq"; 735 break; 736 case dwarf_r10_fiq: 737 reg_info.name = "r10_fiq"; 738 break; 739 case dwarf_r11_fiq: 740 reg_info.name = "r11_fiq"; 741 break; 742 case dwarf_r12_fiq: 743 reg_info.name = "r12_fiq"; 744 break; 745 case dwarf_r13_fiq: 746 reg_info.name = "r13_fiq"; 747 break; 748 case dwarf_r14_fiq: 749 reg_info.name = "r14_fiq"; 750 break; 751 case dwarf_r13_irq: 752 reg_info.name = "r13_irq"; 753 break; 754 case dwarf_r14_irq: 755 reg_info.name = "r14_irq"; 756 break; 757 case dwarf_r13_abt: 758 reg_info.name = "r13_abt"; 759 break; 760 case dwarf_r14_abt: 761 reg_info.name = "r14_abt"; 762 break; 763 case dwarf_r13_und: 764 reg_info.name = "r13_und"; 765 break; 766 case dwarf_r14_und: 767 reg_info.name = "r14_und"; 768 break; 769 case dwarf_r13_svc: 770 reg_info.name = "r13_svc"; 771 break; 772 case dwarf_r14_svc: 773 reg_info.name = "r14_svc"; 774 break; 775 776 // Intel wireless MMX control register in co-processor 0 - 7 777 case dwarf_wC0: 778 reg_info.name = "wC0"; 779 break; 780 case dwarf_wC1: 781 reg_info.name = "wC1"; 782 break; 783 case dwarf_wC2: 784 reg_info.name = "wC2"; 785 break; 786 case dwarf_wC3: 787 reg_info.name = "wC3"; 788 break; 789 case dwarf_wC4: 790 reg_info.name = "wC4"; 791 break; 792 case dwarf_wC5: 793 reg_info.name = "wC5"; 794 break; 795 case dwarf_wC6: 796 reg_info.name = "wC6"; 797 break; 798 case dwarf_wC7: 799 reg_info.name = "wC7"; 800 break; 801 802 // VFP-v3/Neon 803 case dwarf_d0: 804 reg_info.name = "d0"; 805 break; 806 case dwarf_d1: 807 reg_info.name = "d1"; 808 break; 809 case dwarf_d2: 810 reg_info.name = "d2"; 811 break; 812 case dwarf_d3: 813 reg_info.name = "d3"; 814 break; 815 case dwarf_d4: 816 reg_info.name = "d4"; 817 break; 818 case dwarf_d5: 819 reg_info.name = "d5"; 820 break; 821 case dwarf_d6: 822 reg_info.name = "d6"; 823 break; 824 case dwarf_d7: 825 reg_info.name = "d7"; 826 break; 827 case dwarf_d8: 828 reg_info.name = "d8"; 829 break; 830 case dwarf_d9: 831 reg_info.name = "d9"; 832 break; 833 case dwarf_d10: 834 reg_info.name = "d10"; 835 break; 836 case dwarf_d11: 837 reg_info.name = "d11"; 838 break; 839 case dwarf_d12: 840 reg_info.name = "d12"; 841 break; 842 case dwarf_d13: 843 reg_info.name = "d13"; 844 break; 845 case dwarf_d14: 846 reg_info.name = "d14"; 847 break; 848 case dwarf_d15: 849 reg_info.name = "d15"; 850 break; 851 case dwarf_d16: 852 reg_info.name = "d16"; 853 break; 854 case dwarf_d17: 855 reg_info.name = "d17"; 856 break; 857 case dwarf_d18: 858 reg_info.name = "d18"; 859 break; 860 case dwarf_d19: 861 reg_info.name = "d19"; 862 break; 863 case dwarf_d20: 864 reg_info.name = "d20"; 865 break; 866 case dwarf_d21: 867 reg_info.name = "d21"; 868 break; 869 case dwarf_d22: 870 reg_info.name = "d22"; 871 break; 872 case dwarf_d23: 873 reg_info.name = "d23"; 874 break; 875 case dwarf_d24: 876 reg_info.name = "d24"; 877 break; 878 case dwarf_d25: 879 reg_info.name = "d25"; 880 break; 881 case dwarf_d26: 882 reg_info.name = "d26"; 883 break; 884 case dwarf_d27: 885 reg_info.name = "d27"; 886 break; 887 case dwarf_d28: 888 reg_info.name = "d28"; 889 break; 890 case dwarf_d29: 891 reg_info.name = "d29"; 892 break; 893 case dwarf_d30: 894 reg_info.name = "d30"; 895 break; 896 case dwarf_d31: 897 reg_info.name = "d31"; 898 break; 899 900 // NEON 128-bit vector registers (overlays the d registers) 901 case dwarf_q0: 902 reg_info.name = "q0"; 903 break; 904 case dwarf_q1: 905 reg_info.name = "q1"; 906 break; 907 case dwarf_q2: 908 reg_info.name = "q2"; 909 break; 910 case dwarf_q3: 911 reg_info.name = "q3"; 912 break; 913 case dwarf_q4: 914 reg_info.name = "q4"; 915 break; 916 case dwarf_q5: 917 reg_info.name = "q5"; 918 break; 919 case dwarf_q6: 920 reg_info.name = "q6"; 921 break; 922 case dwarf_q7: 923 reg_info.name = "q7"; 924 break; 925 case dwarf_q8: 926 reg_info.name = "q8"; 927 break; 928 case dwarf_q9: 929 reg_info.name = "q9"; 930 break; 931 case dwarf_q10: 932 reg_info.name = "q10"; 933 break; 934 case dwarf_q11: 935 reg_info.name = "q11"; 936 break; 937 case dwarf_q12: 938 reg_info.name = "q12"; 939 break; 940 case dwarf_q13: 941 reg_info.name = "q13"; 942 break; 943 case dwarf_q14: 944 reg_info.name = "q14"; 945 break; 946 case dwarf_q15: 947 reg_info.name = "q15"; 948 break; 949 950 default: 951 return false; 952 } 953 return true; 954 } 955 956 // A8.6.50 957 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 958 static uint32_t CountITSize(uint32_t ITMask) { 959 // First count the trailing zeros of the IT mask. 960 uint32_t TZ = llvm::countTrailingZeros(ITMask); 961 if (TZ > 3) { 962 #ifdef LLDB_CONFIGURATION_DEBUG 963 printf("Encoding error: IT Mask '0000'\n"); 964 #endif 965 return 0; 966 } 967 return (4 - TZ); 968 } 969 970 // Init ITState. Note that at least one bit is always 1 in mask. 971 bool ITSession::InitIT(uint32_t bits7_0) { 972 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 973 if (ITCounter == 0) 974 return false; 975 976 // A8.6.50 IT 977 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 978 if (FirstCond == 0xF) { 979 #ifdef LLDB_CONFIGURATION_DEBUG 980 printf("Encoding error: IT FirstCond '1111'\n"); 981 #endif 982 return false; 983 } 984 if (FirstCond == 0xE && ITCounter != 1) { 985 #ifdef LLDB_CONFIGURATION_DEBUG 986 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 987 #endif 988 return false; 989 } 990 991 ITState = bits7_0; 992 return true; 993 } 994 995 // Update ITState if necessary. 996 void ITSession::ITAdvance() { 997 // assert(ITCounter); 998 --ITCounter; 999 if (ITCounter == 0) 1000 ITState = 0; 1001 else { 1002 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 1003 SetBits32(ITState, 4, 0, NewITState4_0); 1004 } 1005 } 1006 1007 // Return true if we're inside an IT Block. 1008 bool ITSession::InITBlock() { return ITCounter != 0; } 1009 1010 // Return true if we're the last instruction inside an IT Block. 1011 bool ITSession::LastInITBlock() { return ITCounter == 1; } 1012 1013 // Get condition bits for the current thumb instruction. 1014 uint32_t ITSession::GetCond() { 1015 if (InITBlock()) 1016 return Bits32(ITState, 7, 4); 1017 else 1018 return COND_AL; 1019 } 1020 1021 // ARM constants used during decoding 1022 #define REG_RD 0 1023 #define LDM_REGLIST 1 1024 #define SP_REG 13 1025 #define LR_REG 14 1026 #define PC_REG 15 1027 #define PC_REGLIST_BIT 0x8000 1028 1029 #define ARMv4 (1u << 0) 1030 #define ARMv4T (1u << 1) 1031 #define ARMv5T (1u << 2) 1032 #define ARMv5TE (1u << 3) 1033 #define ARMv5TEJ (1u << 4) 1034 #define ARMv6 (1u << 5) 1035 #define ARMv6K (1u << 6) 1036 #define ARMv6T2 (1u << 7) 1037 #define ARMv7 (1u << 8) 1038 #define ARMv7S (1u << 9) 1039 #define ARMv8 (1u << 10) 1040 #define ARMvAll (0xffffffffu) 1041 1042 #define ARMV4T_ABOVE \ 1043 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \ 1044 ARMv7S | ARMv8) 1045 #define ARMV5_ABOVE \ 1046 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \ 1047 ARMv8) 1048 #define ARMV5TE_ABOVE \ 1049 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 1050 #define ARMV5J_ABOVE \ 1051 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 1052 #define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 1053 #define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 1054 #define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8) 1055 1056 #define No_VFP 0 1057 #define VFPv1 (1u << 1) 1058 #define VFPv2 (1u << 2) 1059 #define VFPv3 (1u << 3) 1060 #define AdvancedSIMD (1u << 4) 1061 1062 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 1063 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 1064 #define VFPv2v3 (VFPv2 | VFPv3) 1065 1066 //---------------------------------------------------------------------- 1067 // 1068 // EmulateInstructionARM implementation 1069 // 1070 //---------------------------------------------------------------------- 1071 1072 void EmulateInstructionARM::Initialize() { 1073 PluginManager::RegisterPlugin(GetPluginNameStatic(), 1074 GetPluginDescriptionStatic(), CreateInstance); 1075 } 1076 1077 void EmulateInstructionARM::Terminate() { 1078 PluginManager::UnregisterPlugin(CreateInstance); 1079 } 1080 1081 ConstString EmulateInstructionARM::GetPluginNameStatic() { 1082 static ConstString g_name("arm"); 1083 return g_name; 1084 } 1085 1086 const char *EmulateInstructionARM::GetPluginDescriptionStatic() { 1087 return "Emulate instructions for the ARM architecture."; 1088 } 1089 1090 EmulateInstruction * 1091 EmulateInstructionARM::CreateInstance(const ArchSpec &arch, 1092 InstructionType inst_type) { 1093 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic( 1094 inst_type)) { 1095 if (arch.GetTriple().getArch() == llvm::Triple::arm) { 1096 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap( 1097 new EmulateInstructionARM(arch)); 1098 1099 if (emulate_insn_ap.get()) 1100 return emulate_insn_ap.release(); 1101 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) { 1102 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap( 1103 new EmulateInstructionARM(arch)); 1104 1105 if (emulate_insn_ap.get()) 1106 return emulate_insn_ap.release(); 1107 } 1108 } 1109 1110 return NULL; 1111 } 1112 1113 bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) { 1114 if (arch.GetTriple().getArch() == llvm::Triple::arm) 1115 return true; 1116 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 1117 return true; 1118 1119 return false; 1120 } 1121 1122 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for 1123 // many ARM instructions. 1124 bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) { 1125 EmulateInstruction::Context context; 1126 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 1127 context.SetNoArgs(); 1128 1129 uint32_t random_data = rand(); 1130 const uint32_t addr_byte_size = GetAddressByteSize(); 1131 1132 if (!MemAWrite(context, address, random_data, addr_byte_size)) 1133 return false; 1134 1135 return true; 1136 } 1137 1138 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM 1139 // instructions. 1140 bool EmulateInstructionARM::WriteBits32Unknown(int n) { 1141 EmulateInstruction::Context context; 1142 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 1143 context.SetNoArgs(); 1144 1145 bool success; 1146 uint32_t data = 1147 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1148 1149 if (!success) 1150 return false; 1151 1152 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data)) 1153 return false; 1154 1155 return true; 1156 } 1157 1158 bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind, 1159 uint32_t reg_num, 1160 RegisterInfo ®_info) { 1161 if (reg_kind == eRegisterKindGeneric) { 1162 switch (reg_num) { 1163 case LLDB_REGNUM_GENERIC_PC: 1164 reg_kind = eRegisterKindDWARF; 1165 reg_num = dwarf_pc; 1166 break; 1167 case LLDB_REGNUM_GENERIC_SP: 1168 reg_kind = eRegisterKindDWARF; 1169 reg_num = dwarf_sp; 1170 break; 1171 case LLDB_REGNUM_GENERIC_FP: 1172 reg_kind = eRegisterKindDWARF; 1173 reg_num = dwarf_r7; 1174 break; 1175 case LLDB_REGNUM_GENERIC_RA: 1176 reg_kind = eRegisterKindDWARF; 1177 reg_num = dwarf_lr; 1178 break; 1179 case LLDB_REGNUM_GENERIC_FLAGS: 1180 reg_kind = eRegisterKindDWARF; 1181 reg_num = dwarf_cpsr; 1182 break; 1183 default: 1184 return false; 1185 } 1186 } 1187 1188 if (reg_kind == eRegisterKindDWARF) 1189 return GetARMDWARFRegisterInfo(reg_num, reg_info); 1190 return false; 1191 } 1192 1193 uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const { 1194 if (m_arch.GetTriple().isAndroid()) 1195 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android 1196 bool is_apple = false; 1197 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 1198 is_apple = true; 1199 switch (m_arch.GetTriple().getOS()) { 1200 case llvm::Triple::Darwin: 1201 case llvm::Triple::MacOSX: 1202 case llvm::Triple::IOS: 1203 case llvm::Triple::TvOS: 1204 case llvm::Triple::WatchOS: 1205 is_apple = true; 1206 break; 1207 default: 1208 break; 1209 } 1210 1211 /* On Apple iOS et al, the frame pointer register is always r7. 1212 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 1213 */ 1214 1215 uint32_t fp_regnum = 11; 1216 1217 if (is_apple) 1218 fp_regnum = 7; 1219 1220 if (m_opcode_mode == eModeThumb) 1221 fp_regnum = 7; 1222 1223 return fp_regnum; 1224 } 1225 1226 uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const { 1227 bool is_apple = false; 1228 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 1229 is_apple = true; 1230 switch (m_arch.GetTriple().getOS()) { 1231 case llvm::Triple::Darwin: 1232 case llvm::Triple::MacOSX: 1233 case llvm::Triple::IOS: 1234 is_apple = true; 1235 break; 1236 default: 1237 break; 1238 } 1239 1240 /* On Apple iOS et al, the frame pointer register is always r7. 1241 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 1242 */ 1243 1244 uint32_t fp_regnum = dwarf_r11; 1245 1246 if (is_apple) 1247 fp_regnum = dwarf_r7; 1248 1249 if (m_opcode_mode == eModeThumb) 1250 fp_regnum = dwarf_r7; 1251 1252 return fp_regnum; 1253 } 1254 1255 // Push Multiple Registers stores multiple registers to the stack, storing to 1256 // consecutive memory locations ending just below the address in SP, and updates 1257 // SP to point to the start of the stored data. 1258 bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode, 1259 const ARMEncoding encoding) { 1260 #if 0 1261 // ARM pseudo code... 1262 if (ConditionPassed()) 1263 { 1264 EncodingSpecificOperations(); 1265 NullCheckIfThumbEE(13); 1266 address = SP - 4*BitCount(registers); 1267 1268 for (i = 0 to 14) 1269 { 1270 if (registers<i> == '1') 1271 { 1272 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 1273 MemA[address,4] = bits(32) UNKNOWN; 1274 else 1275 MemA[address,4] = R[i]; 1276 address = address + 4; 1277 } 1278 } 1279 1280 if (registers<15> == '1') // Only possible for encoding A1 or A2 1281 MemA[address,4] = PCStoreValue(); 1282 1283 SP = SP - 4*BitCount(registers); 1284 } 1285 #endif 1286 1287 bool success = false; 1288 if (ConditionPassed(opcode)) { 1289 const uint32_t addr_byte_size = GetAddressByteSize(); 1290 const addr_t sp = ReadCoreReg(SP_REG, &success); 1291 if (!success) 1292 return false; 1293 uint32_t registers = 0; 1294 uint32_t Rt; // the source register 1295 switch (encoding) { 1296 case eEncodingT1: 1297 registers = Bits32(opcode, 7, 0); 1298 // The M bit represents LR. 1299 if (Bit32(opcode, 8)) 1300 registers |= (1u << 14); 1301 // if BitCount(registers) < 1 then UNPREDICTABLE; 1302 if (BitCount(registers) < 1) 1303 return false; 1304 break; 1305 case eEncodingT2: 1306 // Ignore bits 15 & 13. 1307 registers = Bits32(opcode, 15, 0) & ~0xa000; 1308 // if BitCount(registers) < 2 then UNPREDICTABLE; 1309 if (BitCount(registers) < 2) 1310 return false; 1311 break; 1312 case eEncodingT3: 1313 Rt = Bits32(opcode, 15, 12); 1314 // if BadReg(t) then UNPREDICTABLE; 1315 if (BadReg(Rt)) 1316 return false; 1317 registers = (1u << Rt); 1318 break; 1319 case eEncodingA1: 1320 registers = Bits32(opcode, 15, 0); 1321 // Instead of return false, let's handle the following case as well, 1322 // which amounts to pushing one reg onto the full descending stacks. 1323 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 1324 break; 1325 case eEncodingA2: 1326 Rt = Bits32(opcode, 15, 12); 1327 // if t == 13 then UNPREDICTABLE; 1328 if (Rt == dwarf_sp) 1329 return false; 1330 registers = (1u << Rt); 1331 break; 1332 default: 1333 return false; 1334 } 1335 addr_t sp_offset = addr_byte_size * BitCount(registers); 1336 addr_t addr = sp - sp_offset; 1337 uint32_t i; 1338 1339 EmulateInstruction::Context context; 1340 context.type = EmulateInstruction::eContextPushRegisterOnStack; 1341 RegisterInfo reg_info; 1342 RegisterInfo sp_reg; 1343 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1344 for (i = 0; i < 15; ++i) { 1345 if (BitIsSet(registers, i)) { 1346 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info); 1347 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 1348 uint32_t reg_value = ReadCoreReg(i, &success); 1349 if (!success) 1350 return false; 1351 if (!MemAWrite(context, addr, reg_value, addr_byte_size)) 1352 return false; 1353 addr += addr_byte_size; 1354 } 1355 } 1356 1357 if (BitIsSet(registers, 15)) { 1358 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info); 1359 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 1360 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1361 if (!success) 1362 return false; 1363 if (!MemAWrite(context, addr, pc, addr_byte_size)) 1364 return false; 1365 } 1366 1367 context.type = EmulateInstruction::eContextAdjustStackPointer; 1368 context.SetImmediateSigned(-sp_offset); 1369 1370 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1371 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1372 return false; 1373 } 1374 return true; 1375 } 1376 1377 // Pop Multiple Registers loads multiple registers from the stack, loading from 1378 // consecutive memory locations staring at the address in SP, and updates 1379 // SP to point just above the loaded data. 1380 bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode, 1381 const ARMEncoding encoding) { 1382 #if 0 1383 // ARM pseudo code... 1384 if (ConditionPassed()) 1385 { 1386 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 1387 address = SP; 1388 for i = 0 to 14 1389 if registers<i> == '1' then 1390 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 1391 if registers<15> == '1' then 1392 if UnalignedAllowed then 1393 LoadWritePC(MemU[address,4]); 1394 else 1395 LoadWritePC(MemA[address,4]); 1396 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 1397 if registers<13> == '1' then SP = bits(32) UNKNOWN; 1398 } 1399 #endif 1400 1401 bool success = false; 1402 1403 if (ConditionPassed(opcode)) { 1404 const uint32_t addr_byte_size = GetAddressByteSize(); 1405 const addr_t sp = ReadCoreReg(SP_REG, &success); 1406 if (!success) 1407 return false; 1408 uint32_t registers = 0; 1409 uint32_t Rt; // the destination register 1410 switch (encoding) { 1411 case eEncodingT1: 1412 registers = Bits32(opcode, 7, 0); 1413 // The P bit represents PC. 1414 if (Bit32(opcode, 8)) 1415 registers |= (1u << 15); 1416 // if BitCount(registers) < 1 then UNPREDICTABLE; 1417 if (BitCount(registers) < 1) 1418 return false; 1419 break; 1420 case eEncodingT2: 1421 // Ignore bit 13. 1422 registers = Bits32(opcode, 15, 0) & ~0x2000; 1423 // if BitCount(registers) < 2 || (P == '1' && M == '1') then 1424 // UNPREDICTABLE; 1425 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 1426 return false; 1427 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 1428 // UNPREDICTABLE; 1429 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 1430 return false; 1431 break; 1432 case eEncodingT3: 1433 Rt = Bits32(opcode, 15, 12); 1434 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then 1435 // UNPREDICTABLE; 1436 if (Rt == 13) 1437 return false; 1438 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1439 return false; 1440 registers = (1u << Rt); 1441 break; 1442 case eEncodingA1: 1443 registers = Bits32(opcode, 15, 0); 1444 // Instead of return false, let's handle the following case as well, 1445 // which amounts to popping one reg from the full descending stacks. 1446 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 1447 1448 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 1449 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 1450 return false; 1451 break; 1452 case eEncodingA2: 1453 Rt = Bits32(opcode, 15, 12); 1454 // if t == 13 then UNPREDICTABLE; 1455 if (Rt == dwarf_sp) 1456 return false; 1457 registers = (1u << Rt); 1458 break; 1459 default: 1460 return false; 1461 } 1462 addr_t sp_offset = addr_byte_size * BitCount(registers); 1463 addr_t addr = sp; 1464 uint32_t i, data; 1465 1466 EmulateInstruction::Context context; 1467 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1468 1469 RegisterInfo sp_reg; 1470 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1471 1472 for (i = 0; i < 15; ++i) { 1473 if (BitIsSet(registers, i)) { 1474 context.SetAddress(addr); 1475 data = MemARead(context, addr, 4, 0, &success); 1476 if (!success) 1477 return false; 1478 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 1479 data)) 1480 return false; 1481 addr += addr_byte_size; 1482 } 1483 } 1484 1485 if (BitIsSet(registers, 15)) { 1486 context.SetRegisterPlusOffset(sp_reg, addr - sp); 1487 data = MemARead(context, addr, 4, 0, &success); 1488 if (!success) 1489 return false; 1490 // In ARMv5T and above, this is an interworking branch. 1491 if (!LoadWritePC(context, data)) 1492 return false; 1493 // addr += addr_byte_size; 1494 } 1495 1496 context.type = EmulateInstruction::eContextAdjustStackPointer; 1497 context.SetImmediateSigned(sp_offset); 1498 1499 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1500 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1501 return false; 1502 } 1503 return true; 1504 } 1505 1506 // Set r7 or ip to point to saved value residing within the stack. 1507 // ADD (SP plus immediate) 1508 bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode, 1509 const ARMEncoding encoding) { 1510 #if 0 1511 // ARM pseudo code... 1512 if (ConditionPassed()) 1513 { 1514 EncodingSpecificOperations(); 1515 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1516 if d == 15 then 1517 ALUWritePC(result); // setflags is always FALSE here 1518 else 1519 R[d] = result; 1520 if setflags then 1521 APSR.N = result<31>; 1522 APSR.Z = IsZeroBit(result); 1523 APSR.C = carry; 1524 APSR.V = overflow; 1525 } 1526 #endif 1527 1528 bool success = false; 1529 1530 if (ConditionPassed(opcode)) { 1531 const addr_t sp = ReadCoreReg(SP_REG, &success); 1532 if (!success) 1533 return false; 1534 uint32_t Rd; // the destination register 1535 uint32_t imm32; 1536 switch (encoding) { 1537 case eEncodingT1: 1538 Rd = 7; 1539 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 1540 break; 1541 case eEncodingA1: 1542 Rd = Bits32(opcode, 15, 12); 1543 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1544 break; 1545 default: 1546 return false; 1547 } 1548 addr_t sp_offset = imm32; 1549 addr_t addr = sp + sp_offset; // a pointer to the stack area 1550 1551 EmulateInstruction::Context context; 1552 if (Rd == GetFramePointerRegisterNumber()) 1553 context.type = eContextSetFramePointer; 1554 else 1555 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1556 RegisterInfo sp_reg; 1557 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1558 context.SetRegisterPlusOffset(sp_reg, sp_offset); 1559 1560 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, 1561 addr)) 1562 return false; 1563 } 1564 return true; 1565 } 1566 1567 // Set r7 or ip to the current stack pointer. 1568 // MOV (register) 1569 bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode, 1570 const ARMEncoding encoding) { 1571 #if 0 1572 // ARM pseudo code... 1573 if (ConditionPassed()) 1574 { 1575 EncodingSpecificOperations(); 1576 result = R[m]; 1577 if d == 15 then 1578 ALUWritePC(result); // setflags is always FALSE here 1579 else 1580 R[d] = result; 1581 if setflags then 1582 APSR.N = result<31>; 1583 APSR.Z = IsZeroBit(result); 1584 // APSR.C unchanged 1585 // APSR.V unchanged 1586 } 1587 #endif 1588 1589 bool success = false; 1590 1591 if (ConditionPassed(opcode)) { 1592 const addr_t sp = ReadCoreReg(SP_REG, &success); 1593 if (!success) 1594 return false; 1595 uint32_t Rd; // the destination register 1596 switch (encoding) { 1597 case eEncodingT1: 1598 Rd = 7; 1599 break; 1600 case eEncodingA1: 1601 Rd = 12; 1602 break; 1603 default: 1604 return false; 1605 } 1606 1607 EmulateInstruction::Context context; 1608 if (Rd == GetFramePointerRegisterNumber()) 1609 context.type = EmulateInstruction::eContextSetFramePointer; 1610 else 1611 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1612 RegisterInfo sp_reg; 1613 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1614 context.SetRegisterPlusOffset(sp_reg, 0); 1615 1616 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 1617 return false; 1618 } 1619 return true; 1620 } 1621 1622 // Move from high register (r8-r15) to low register (r0-r7). 1623 // MOV (register) 1624 bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode, 1625 const ARMEncoding encoding) { 1626 return EmulateMOVRdRm(opcode, encoding); 1627 } 1628 1629 // Move from register to register. 1630 // MOV (register) 1631 bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode, 1632 const ARMEncoding encoding) { 1633 #if 0 1634 // ARM pseudo code... 1635 if (ConditionPassed()) 1636 { 1637 EncodingSpecificOperations(); 1638 result = R[m]; 1639 if d == 15 then 1640 ALUWritePC(result); // setflags is always FALSE here 1641 else 1642 R[d] = result; 1643 if setflags then 1644 APSR.N = result<31>; 1645 APSR.Z = IsZeroBit(result); 1646 // APSR.C unchanged 1647 // APSR.V unchanged 1648 } 1649 #endif 1650 1651 bool success = false; 1652 1653 if (ConditionPassed(opcode)) { 1654 uint32_t Rm; // the source register 1655 uint32_t Rd; // the destination register 1656 bool setflags; 1657 switch (encoding) { 1658 case eEncodingT1: 1659 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1660 Rm = Bits32(opcode, 6, 3); 1661 setflags = false; 1662 if (Rd == 15 && InITBlock() && !LastInITBlock()) 1663 return false; 1664 break; 1665 case eEncodingT2: 1666 Rd = Bits32(opcode, 2, 0); 1667 Rm = Bits32(opcode, 5, 3); 1668 setflags = true; 1669 if (InITBlock()) 1670 return false; 1671 break; 1672 case eEncodingT3: 1673 Rd = Bits32(opcode, 11, 8); 1674 Rm = Bits32(opcode, 3, 0); 1675 setflags = BitIsSet(opcode, 20); 1676 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1677 if (setflags && (BadReg(Rd) || BadReg(Rm))) 1678 return false; 1679 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then 1680 // UNPREDICTABLE; 1681 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 1682 return false; 1683 break; 1684 case eEncodingA1: 1685 Rd = Bits32(opcode, 15, 12); 1686 Rm = Bits32(opcode, 3, 0); 1687 setflags = BitIsSet(opcode, 20); 1688 1689 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1690 // instructions; 1691 if (Rd == 15 && setflags) 1692 return EmulateSUBSPcLrEtc(opcode, encoding); 1693 break; 1694 default: 1695 return false; 1696 } 1697 uint32_t result = ReadCoreReg(Rm, &success); 1698 if (!success) 1699 return false; 1700 1701 // The context specifies that Rm is to be moved into Rd. 1702 EmulateInstruction::Context context; 1703 if (Rd == 13) 1704 context.type = EmulateInstruction::eContextAdjustStackPointer; 1705 else 1706 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1707 RegisterInfo dwarf_reg; 1708 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1709 context.SetRegisterPlusOffset(dwarf_reg, 0); 1710 1711 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 1712 return false; 1713 } 1714 return true; 1715 } 1716 1717 // Move (immediate) writes an immediate value to the destination register. It 1718 // can optionally update the condition flags based on the value. 1719 // MOV (immediate) 1720 bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode, 1721 const ARMEncoding encoding) { 1722 #if 0 1723 // ARM pseudo code... 1724 if (ConditionPassed()) 1725 { 1726 EncodingSpecificOperations(); 1727 result = imm32; 1728 if d == 15 then // Can only occur for ARM encoding 1729 ALUWritePC(result); // setflags is always FALSE here 1730 else 1731 R[d] = result; 1732 if setflags then 1733 APSR.N = result<31>; 1734 APSR.Z = IsZeroBit(result); 1735 APSR.C = carry; 1736 // APSR.V unchanged 1737 } 1738 #endif 1739 1740 if (ConditionPassed(opcode)) { 1741 uint32_t Rd; // the destination register 1742 uint32_t imm32; // the immediate value to be written to Rd 1743 uint32_t carry = 1744 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 1745 // for setflags == false, this value is a don't care 1746 // initialized to 0 to silence the static analyzer 1747 bool setflags; 1748 switch (encoding) { 1749 case eEncodingT1: 1750 Rd = Bits32(opcode, 10, 8); 1751 setflags = !InITBlock(); 1752 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 1753 carry = APSR_C; 1754 1755 break; 1756 1757 case eEncodingT2: 1758 Rd = Bits32(opcode, 11, 8); 1759 setflags = BitIsSet(opcode, 20); 1760 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1761 if (BadReg(Rd)) 1762 return false; 1763 1764 break; 1765 1766 case eEncodingT3: { 1767 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 1768 // 32); 1769 Rd = Bits32(opcode, 11, 8); 1770 setflags = false; 1771 uint32_t imm4 = Bits32(opcode, 19, 16); 1772 uint32_t imm3 = Bits32(opcode, 14, 12); 1773 uint32_t i = Bit32(opcode, 26); 1774 uint32_t imm8 = Bits32(opcode, 7, 0); 1775 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 1776 1777 // if BadReg(d) then UNPREDICTABLE; 1778 if (BadReg(Rd)) 1779 return false; 1780 } break; 1781 1782 case eEncodingA1: 1783 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = 1784 // ARMExpandImm_C(imm12, APSR.C); 1785 Rd = Bits32(opcode, 15, 12); 1786 setflags = BitIsSet(opcode, 20); 1787 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1788 1789 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1790 // instructions; 1791 if ((Rd == 15) && setflags) 1792 return EmulateSUBSPcLrEtc(opcode, encoding); 1793 1794 break; 1795 1796 case eEncodingA2: { 1797 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 1798 Rd = Bits32(opcode, 15, 12); 1799 setflags = false; 1800 uint32_t imm4 = Bits32(opcode, 19, 16); 1801 uint32_t imm12 = Bits32(opcode, 11, 0); 1802 imm32 = (imm4 << 12) | imm12; 1803 1804 // if d == 15 then UNPREDICTABLE; 1805 if (Rd == 15) 1806 return false; 1807 } break; 1808 1809 default: 1810 return false; 1811 } 1812 uint32_t result = imm32; 1813 1814 // The context specifies that an immediate is to be moved into Rd. 1815 EmulateInstruction::Context context; 1816 context.type = EmulateInstruction::eContextImmediate; 1817 context.SetNoArgs(); 1818 1819 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1820 return false; 1821 } 1822 return true; 1823 } 1824 1825 // MUL multiplies two register values. The least significant 32 bits of the 1826 // result are written to the destination 1827 // register. These 32 bits do not depend on whether the source register values 1828 // are considered to be signed values or 1829 // unsigned values. 1830 // 1831 // Optionally, it can update the condition flags based on the result. In the 1832 // Thumb instruction set, this option is 1833 // limited to only a few forms of the instruction. 1834 bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode, 1835 const ARMEncoding encoding) { 1836 #if 0 1837 if ConditionPassed() then 1838 EncodingSpecificOperations(); 1839 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1840 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1841 result = operand1 * operand2; 1842 R[d] = result<31:0>; 1843 if setflags then 1844 APSR.N = result<31>; 1845 APSR.Z = IsZeroBit(result); 1846 if ArchVersion() == 4 then 1847 APSR.C = bit UNKNOWN; 1848 // else APSR.C unchanged 1849 // APSR.V always unchanged 1850 #endif 1851 1852 if (ConditionPassed(opcode)) { 1853 uint32_t d; 1854 uint32_t n; 1855 uint32_t m; 1856 bool setflags; 1857 1858 // EncodingSpecificOperations(); 1859 switch (encoding) { 1860 case eEncodingT1: 1861 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 1862 d = Bits32(opcode, 2, 0); 1863 n = Bits32(opcode, 5, 3); 1864 m = Bits32(opcode, 2, 0); 1865 setflags = !InITBlock(); 1866 1867 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1868 if ((ArchVersion() < ARMv6) && (d == n)) 1869 return false; 1870 1871 break; 1872 1873 case eEncodingT2: 1874 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 1875 d = Bits32(opcode, 11, 8); 1876 n = Bits32(opcode, 19, 16); 1877 m = Bits32(opcode, 3, 0); 1878 setflags = false; 1879 1880 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 1881 if (BadReg(d) || BadReg(n) || BadReg(m)) 1882 return false; 1883 1884 break; 1885 1886 case eEncodingA1: 1887 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 1888 d = Bits32(opcode, 19, 16); 1889 n = Bits32(opcode, 3, 0); 1890 m = Bits32(opcode, 11, 8); 1891 setflags = BitIsSet(opcode, 20); 1892 1893 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1894 if ((d == 15) || (n == 15) || (m == 15)) 1895 return false; 1896 1897 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1898 if ((ArchVersion() < ARMv6) && (d == n)) 1899 return false; 1900 1901 break; 1902 1903 default: 1904 return false; 1905 } 1906 1907 bool success = false; 1908 1909 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final 1910 // results 1911 uint64_t operand1 = 1912 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1913 if (!success) 1914 return false; 1915 1916 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final 1917 // results 1918 uint64_t operand2 = 1919 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1920 if (!success) 1921 return false; 1922 1923 // result = operand1 * operand2; 1924 uint64_t result = operand1 * operand2; 1925 1926 // R[d] = result<31:0>; 1927 RegisterInfo op1_reg; 1928 RegisterInfo op2_reg; 1929 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1930 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1931 1932 EmulateInstruction::Context context; 1933 context.type = eContextArithmetic; 1934 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 1935 1936 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 1937 (0x0000ffff & result))) 1938 return false; 1939 1940 // if setflags then 1941 if (setflags) { 1942 // APSR.N = result<31>; 1943 // APSR.Z = IsZeroBit(result); 1944 m_new_inst_cpsr = m_opcode_cpsr; 1945 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31)); 1946 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1947 if (m_new_inst_cpsr != m_opcode_cpsr) { 1948 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1949 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1950 return false; 1951 } 1952 1953 // if ArchVersion() == 4 then 1954 // APSR.C = bit UNKNOWN; 1955 } 1956 } 1957 return true; 1958 } 1959 1960 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to 1961 // the destination register. 1962 // It can optionally update the condition flags based on the value. 1963 bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode, 1964 const ARMEncoding encoding) { 1965 #if 0 1966 // ARM pseudo code... 1967 if (ConditionPassed()) 1968 { 1969 EncodingSpecificOperations(); 1970 result = NOT(imm32); 1971 if d == 15 then // Can only occur for ARM encoding 1972 ALUWritePC(result); // setflags is always FALSE here 1973 else 1974 R[d] = result; 1975 if setflags then 1976 APSR.N = result<31>; 1977 APSR.Z = IsZeroBit(result); 1978 APSR.C = carry; 1979 // APSR.V unchanged 1980 } 1981 #endif 1982 1983 if (ConditionPassed(opcode)) { 1984 uint32_t Rd; // the destination register 1985 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1986 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1987 bool setflags; 1988 switch (encoding) { 1989 case eEncodingT1: 1990 Rd = Bits32(opcode, 11, 8); 1991 setflags = BitIsSet(opcode, 20); 1992 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1993 break; 1994 case eEncodingA1: 1995 Rd = Bits32(opcode, 15, 12); 1996 setflags = BitIsSet(opcode, 20); 1997 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1998 1999 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 2000 // instructions; 2001 if (Rd == 15 && setflags) 2002 return EmulateSUBSPcLrEtc(opcode, encoding); 2003 break; 2004 default: 2005 return false; 2006 } 2007 uint32_t result = ~imm32; 2008 2009 // The context specifies that an immediate is to be moved into Rd. 2010 EmulateInstruction::Context context; 2011 context.type = EmulateInstruction::eContextImmediate; 2012 context.SetNoArgs(); 2013 2014 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 2015 return false; 2016 } 2017 return true; 2018 } 2019 2020 // Bitwise NOT (register) writes the bitwise inverse of a register value to the 2021 // destination register. 2022 // It can optionally update the condition flags based on the result. 2023 bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode, 2024 const ARMEncoding encoding) { 2025 #if 0 2026 // ARM pseudo code... 2027 if (ConditionPassed()) 2028 { 2029 EncodingSpecificOperations(); 2030 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 2031 result = NOT(shifted); 2032 if d == 15 then // Can only occur for ARM encoding 2033 ALUWritePC(result); // setflags is always FALSE here 2034 else 2035 R[d] = result; 2036 if setflags then 2037 APSR.N = result<31>; 2038 APSR.Z = IsZeroBit(result); 2039 APSR.C = carry; 2040 // APSR.V unchanged 2041 } 2042 #endif 2043 2044 if (ConditionPassed(opcode)) { 2045 uint32_t Rm; // the source register 2046 uint32_t Rd; // the destination register 2047 ARM_ShifterType shift_t; 2048 uint32_t shift_n; // the shift applied to the value read from Rm 2049 bool setflags; 2050 uint32_t carry; // the carry bit after the shift operation 2051 switch (encoding) { 2052 case eEncodingT1: 2053 Rd = Bits32(opcode, 2, 0); 2054 Rm = Bits32(opcode, 5, 3); 2055 setflags = !InITBlock(); 2056 shift_t = SRType_LSL; 2057 shift_n = 0; 2058 if (InITBlock()) 2059 return false; 2060 break; 2061 case eEncodingT2: 2062 Rd = Bits32(opcode, 11, 8); 2063 Rm = Bits32(opcode, 3, 0); 2064 setflags = BitIsSet(opcode, 20); 2065 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2066 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 2067 if (BadReg(Rd) || BadReg(Rm)) 2068 return false; 2069 break; 2070 case eEncodingA1: 2071 Rd = Bits32(opcode, 15, 12); 2072 Rm = Bits32(opcode, 3, 0); 2073 setflags = BitIsSet(opcode, 20); 2074 shift_n = DecodeImmShiftARM(opcode, shift_t); 2075 break; 2076 default: 2077 return false; 2078 } 2079 bool success = false; 2080 uint32_t value = ReadCoreReg(Rm, &success); 2081 if (!success) 2082 return false; 2083 2084 uint32_t shifted = 2085 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 2086 if (!success) 2087 return false; 2088 uint32_t result = ~shifted; 2089 2090 // The context specifies that an immediate is to be moved into Rd. 2091 EmulateInstruction::Context context; 2092 context.type = EmulateInstruction::eContextImmediate; 2093 context.SetNoArgs(); 2094 2095 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 2096 return false; 2097 } 2098 return true; 2099 } 2100 2101 // PC relative immediate load into register, possibly followed by ADD (SP plus 2102 // register). 2103 // LDR (literal) 2104 bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode, 2105 const ARMEncoding encoding) { 2106 #if 0 2107 // ARM pseudo code... 2108 if (ConditionPassed()) 2109 { 2110 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 2111 base = Align(PC,4); 2112 address = if add then (base + imm32) else (base - imm32); 2113 data = MemU[address,4]; 2114 if t == 15 then 2115 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 2116 elsif UnalignedSupport() || address<1:0> = '00' then 2117 R[t] = data; 2118 else // Can only apply before ARMv7 2119 if CurrentInstrSet() == InstrSet_ARM then 2120 R[t] = ROR(data, 8*UInt(address<1:0>)); 2121 else 2122 R[t] = bits(32) UNKNOWN; 2123 } 2124 #endif 2125 2126 if (ConditionPassed(opcode)) { 2127 bool success = false; 2128 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2129 if (!success) 2130 return false; 2131 2132 // PC relative immediate load context 2133 EmulateInstruction::Context context; 2134 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2135 RegisterInfo pc_reg; 2136 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 2137 context.SetRegisterPlusOffset(pc_reg, 0); 2138 2139 uint32_t Rt; // the destination register 2140 uint32_t imm32; // immediate offset from the PC 2141 bool add; // +imm32 or -imm32? 2142 addr_t base; // the base address 2143 addr_t address; // the PC relative address 2144 uint32_t data; // the literal data value from the PC relative load 2145 switch (encoding) { 2146 case eEncodingT1: 2147 Rt = Bits32(opcode, 10, 8); 2148 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 2149 add = true; 2150 break; 2151 case eEncodingT2: 2152 Rt = Bits32(opcode, 15, 12); 2153 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 2154 add = BitIsSet(opcode, 23); 2155 if (Rt == 15 && InITBlock() && !LastInITBlock()) 2156 return false; 2157 break; 2158 default: 2159 return false; 2160 } 2161 2162 base = Align(pc, 4); 2163 if (add) 2164 address = base + imm32; 2165 else 2166 address = base - imm32; 2167 2168 context.SetRegisterPlusOffset(pc_reg, address - base); 2169 data = MemURead(context, address, 4, 0, &success); 2170 if (!success) 2171 return false; 2172 2173 if (Rt == 15) { 2174 if (Bits32(address, 1, 0) == 0) { 2175 // In ARMv5T and above, this is an interworking branch. 2176 if (!LoadWritePC(context, data)) 2177 return false; 2178 } else 2179 return false; 2180 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 2181 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 2182 data)) 2183 return false; 2184 } else // We don't handle ARM for now. 2185 return false; 2186 } 2187 return true; 2188 } 2189 2190 // An add operation to adjust the SP. 2191 // ADD (SP plus immediate) 2192 bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode, 2193 const ARMEncoding encoding) { 2194 #if 0 2195 // ARM pseudo code... 2196 if (ConditionPassed()) 2197 { 2198 EncodingSpecificOperations(); 2199 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 2200 if d == 15 then // Can only occur for ARM encoding 2201 ALUWritePC(result); // setflags is always FALSE here 2202 else 2203 R[d] = result; 2204 if setflags then 2205 APSR.N = result<31>; 2206 APSR.Z = IsZeroBit(result); 2207 APSR.C = carry; 2208 APSR.V = overflow; 2209 } 2210 #endif 2211 2212 bool success = false; 2213 2214 if (ConditionPassed(opcode)) { 2215 const addr_t sp = ReadCoreReg(SP_REG, &success); 2216 if (!success) 2217 return false; 2218 uint32_t imm32; // the immediate operand 2219 uint32_t d; 2220 bool setflags; 2221 switch (encoding) { 2222 case eEncodingT1: 2223 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 2224 d = Bits32(opcode, 10, 8); 2225 imm32 = (Bits32(opcode, 7, 0) << 2); 2226 setflags = false; 2227 break; 2228 2229 case eEncodingT2: 2230 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 2231 d = 13; 2232 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 2233 setflags = false; 2234 break; 2235 2236 case eEncodingT3: 2237 // d = UInt(Rd); setflags = (S == "1"); imm32 = 2238 // ThumbExpandImm(i:imm3:imm8); 2239 d = Bits32(opcode, 11, 8); 2240 imm32 = ThumbExpandImm(opcode); 2241 setflags = Bit32(opcode, 20); 2242 2243 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 2244 if (d == 15 && setflags == 1) 2245 return false; // CMN (immediate) not yet supported 2246 2247 // if d == 15 && S == "0" then UNPREDICTABLE; 2248 if (d == 15 && setflags == 0) 2249 return false; 2250 break; 2251 2252 case eEncodingT4: { 2253 // if Rn == '1111' then SEE ADR; 2254 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2255 d = Bits32(opcode, 11, 8); 2256 setflags = false; 2257 uint32_t i = Bit32(opcode, 26); 2258 uint32_t imm3 = Bits32(opcode, 14, 12); 2259 uint32_t imm8 = Bits32(opcode, 7, 0); 2260 imm32 = (i << 11) | (imm3 << 8) | imm8; 2261 2262 // if d == 15 then UNPREDICTABLE; 2263 if (d == 15) 2264 return false; 2265 } break; 2266 2267 default: 2268 return false; 2269 } 2270 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2271 AddWithCarryResult res = AddWithCarry(sp, imm32, 0); 2272 2273 EmulateInstruction::Context context; 2274 if (d == 13) 2275 context.type = EmulateInstruction::eContextAdjustStackPointer; 2276 else 2277 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2278 2279 RegisterInfo sp_reg; 2280 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2281 context.SetRegisterPlusOffset(sp_reg, res.result - sp); 2282 2283 if (d == 15) { 2284 if (!ALUWritePC(context, res.result)) 2285 return false; 2286 } else { 2287 // R[d] = result; 2288 // if setflags then 2289 // APSR.N = result<31>; 2290 // APSR.Z = IsZeroBit(result); 2291 // APSR.C = carry; 2292 // APSR.V = overflow; 2293 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 2294 res.carry_out, res.overflow)) 2295 return false; 2296 } 2297 } 2298 return true; 2299 } 2300 2301 // An add operation to adjust the SP. 2302 // ADD (SP plus register) 2303 bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode, 2304 const ARMEncoding encoding) { 2305 #if 0 2306 // ARM pseudo code... 2307 if (ConditionPassed()) 2308 { 2309 EncodingSpecificOperations(); 2310 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2311 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 2312 if d == 15 then 2313 ALUWritePC(result); // setflags is always FALSE here 2314 else 2315 R[d] = result; 2316 if setflags then 2317 APSR.N = result<31>; 2318 APSR.Z = IsZeroBit(result); 2319 APSR.C = carry; 2320 APSR.V = overflow; 2321 } 2322 #endif 2323 2324 bool success = false; 2325 2326 if (ConditionPassed(opcode)) { 2327 const addr_t sp = ReadCoreReg(SP_REG, &success); 2328 if (!success) 2329 return false; 2330 uint32_t Rm; // the second operand 2331 switch (encoding) { 2332 case eEncodingT2: 2333 Rm = Bits32(opcode, 6, 3); 2334 break; 2335 default: 2336 return false; 2337 } 2338 int32_t reg_value = ReadCoreReg(Rm, &success); 2339 if (!success) 2340 return false; 2341 2342 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 2343 2344 EmulateInstruction::Context context; 2345 context.type = eContextArithmetic; 2346 RegisterInfo sp_reg; 2347 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2348 2349 RegisterInfo other_reg; 2350 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 2351 context.SetRegisterRegisterOperands(sp_reg, other_reg); 2352 2353 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2354 LLDB_REGNUM_GENERIC_SP, addr)) 2355 return false; 2356 } 2357 return true; 2358 } 2359 2360 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 2361 // at a PC-relative address, and changes instruction set from ARM to Thumb, or 2362 // from Thumb to ARM. 2363 // BLX (immediate) 2364 bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode, 2365 const ARMEncoding encoding) { 2366 #if 0 2367 // ARM pseudo code... 2368 if (ConditionPassed()) 2369 { 2370 EncodingSpecificOperations(); 2371 if CurrentInstrSet() == InstrSet_ARM then 2372 LR = PC - 4; 2373 else 2374 LR = PC<31:1> : '1'; 2375 if targetInstrSet == InstrSet_ARM then 2376 targetAddress = Align(PC,4) + imm32; 2377 else 2378 targetAddress = PC + imm32; 2379 SelectInstrSet(targetInstrSet); 2380 BranchWritePC(targetAddress); 2381 } 2382 #endif 2383 2384 bool success = true; 2385 2386 if (ConditionPassed(opcode)) { 2387 EmulateInstruction::Context context; 2388 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2389 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2390 if (!success) 2391 return false; 2392 addr_t lr; // next instruction address 2393 addr_t target; // target address 2394 int32_t imm32; // PC-relative offset 2395 switch (encoding) { 2396 case eEncodingT1: { 2397 lr = pc | 1u; // return address 2398 uint32_t S = Bit32(opcode, 26); 2399 uint32_t imm10 = Bits32(opcode, 25, 16); 2400 uint32_t J1 = Bit32(opcode, 13); 2401 uint32_t J2 = Bit32(opcode, 11); 2402 uint32_t imm11 = Bits32(opcode, 10, 0); 2403 uint32_t I1 = !(J1 ^ S); 2404 uint32_t I2 = !(J2 ^ S); 2405 uint32_t imm25 = 2406 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2407 imm32 = llvm::SignExtend32<25>(imm25); 2408 target = pc + imm32; 2409 SelectInstrSet(eModeThumb); 2410 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2411 if (InITBlock() && !LastInITBlock()) 2412 return false; 2413 break; 2414 } 2415 case eEncodingT2: { 2416 lr = pc | 1u; // return address 2417 uint32_t S = Bit32(opcode, 26); 2418 uint32_t imm10H = Bits32(opcode, 25, 16); 2419 uint32_t J1 = Bit32(opcode, 13); 2420 uint32_t J2 = Bit32(opcode, 11); 2421 uint32_t imm10L = Bits32(opcode, 10, 1); 2422 uint32_t I1 = !(J1 ^ S); 2423 uint32_t I2 = !(J2 ^ S); 2424 uint32_t imm25 = 2425 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 2426 imm32 = llvm::SignExtend32<25>(imm25); 2427 target = Align(pc, 4) + imm32; 2428 SelectInstrSet(eModeARM); 2429 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32); 2430 if (InITBlock() && !LastInITBlock()) 2431 return false; 2432 break; 2433 } 2434 case eEncodingA1: 2435 lr = pc - 4; // return address 2436 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2437 target = Align(pc, 4) + imm32; 2438 SelectInstrSet(eModeARM); 2439 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2440 break; 2441 case eEncodingA2: 2442 lr = pc - 4; // return address 2443 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | 2444 Bits32(opcode, 24, 24) << 1); 2445 target = pc + imm32; 2446 SelectInstrSet(eModeThumb); 2447 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32); 2448 break; 2449 default: 2450 return false; 2451 } 2452 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2453 LLDB_REGNUM_GENERIC_RA, lr)) 2454 return false; 2455 if (!BranchWritePC(context, target)) 2456 return false; 2457 if (m_opcode_cpsr != m_new_inst_cpsr) 2458 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2459 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2460 return false; 2461 } 2462 return true; 2463 } 2464 2465 // Branch with Link and Exchange (register) calls a subroutine at an address and 2466 // instruction set specified by a register. 2467 // BLX (register) 2468 bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode, 2469 const ARMEncoding encoding) { 2470 #if 0 2471 // ARM pseudo code... 2472 if (ConditionPassed()) 2473 { 2474 EncodingSpecificOperations(); 2475 target = R[m]; 2476 if CurrentInstrSet() == InstrSet_ARM then 2477 next_instr_addr = PC - 4; 2478 LR = next_instr_addr; 2479 else 2480 next_instr_addr = PC - 2; 2481 LR = next_instr_addr<31:1> : '1'; 2482 BXWritePC(target); 2483 } 2484 #endif 2485 2486 bool success = false; 2487 2488 if (ConditionPassed(opcode)) { 2489 EmulateInstruction::Context context; 2490 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2491 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2492 addr_t lr; // next instruction address 2493 if (!success) 2494 return false; 2495 uint32_t Rm; // the register with the target address 2496 switch (encoding) { 2497 case eEncodingT1: 2498 lr = (pc - 2) | 1u; // return address 2499 Rm = Bits32(opcode, 6, 3); 2500 // if m == 15 then UNPREDICTABLE; 2501 if (Rm == 15) 2502 return false; 2503 if (InITBlock() && !LastInITBlock()) 2504 return false; 2505 break; 2506 case eEncodingA1: 2507 lr = pc - 4; // return address 2508 Rm = Bits32(opcode, 3, 0); 2509 // if m == 15 then UNPREDICTABLE; 2510 if (Rm == 15) 2511 return false; 2512 break; 2513 default: 2514 return false; 2515 } 2516 addr_t target = ReadCoreReg(Rm, &success); 2517 if (!success) 2518 return false; 2519 RegisterInfo dwarf_reg; 2520 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2521 context.SetRegister(dwarf_reg); 2522 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2523 LLDB_REGNUM_GENERIC_RA, lr)) 2524 return false; 2525 if (!BXWritePC(context, target)) 2526 return false; 2527 } 2528 return true; 2529 } 2530 2531 // Branch and Exchange causes a branch to an address and instruction set 2532 // specified by a register. 2533 bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode, 2534 const ARMEncoding encoding) { 2535 #if 0 2536 // ARM pseudo code... 2537 if (ConditionPassed()) 2538 { 2539 EncodingSpecificOperations(); 2540 BXWritePC(R[m]); 2541 } 2542 #endif 2543 2544 if (ConditionPassed(opcode)) { 2545 EmulateInstruction::Context context; 2546 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2547 uint32_t Rm; // the register with the target address 2548 switch (encoding) { 2549 case eEncodingT1: 2550 Rm = Bits32(opcode, 6, 3); 2551 if (InITBlock() && !LastInITBlock()) 2552 return false; 2553 break; 2554 case eEncodingA1: 2555 Rm = Bits32(opcode, 3, 0); 2556 break; 2557 default: 2558 return false; 2559 } 2560 bool success = false; 2561 addr_t target = ReadCoreReg(Rm, &success); 2562 if (!success) 2563 return false; 2564 2565 RegisterInfo dwarf_reg; 2566 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2567 context.SetRegister(dwarf_reg); 2568 if (!BXWritePC(context, target)) 2569 return false; 2570 } 2571 return true; 2572 } 2573 2574 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the 2575 // attempt fails, it branches to an 2576 // address and instruction set specified by a register as though it were a BX 2577 // instruction. 2578 // 2579 // TODO: Emulate Jazelle architecture? 2580 // We currently assume that switching to Jazelle state fails, thus 2581 // treating BXJ as a BX operation. 2582 bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode, 2583 const ARMEncoding encoding) { 2584 #if 0 2585 // ARM pseudo code... 2586 if (ConditionPassed()) 2587 { 2588 EncodingSpecificOperations(); 2589 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 2590 BXWritePC(R[m]); 2591 else 2592 if JazelleAcceptsExecution() then 2593 SwitchToJazelleExecution(); 2594 else 2595 SUBARCHITECTURE_DEFINED handler call; 2596 } 2597 #endif 2598 2599 if (ConditionPassed(opcode)) { 2600 EmulateInstruction::Context context; 2601 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2602 uint32_t Rm; // the register with the target address 2603 switch (encoding) { 2604 case eEncodingT1: 2605 Rm = Bits32(opcode, 19, 16); 2606 if (BadReg(Rm)) 2607 return false; 2608 if (InITBlock() && !LastInITBlock()) 2609 return false; 2610 break; 2611 case eEncodingA1: 2612 Rm = Bits32(opcode, 3, 0); 2613 if (Rm == 15) 2614 return false; 2615 break; 2616 default: 2617 return false; 2618 } 2619 bool success = false; 2620 addr_t target = ReadCoreReg(Rm, &success); 2621 if (!success) 2622 return false; 2623 2624 RegisterInfo dwarf_reg; 2625 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2626 context.SetRegister(dwarf_reg); 2627 if (!BXWritePC(context, target)) 2628 return false; 2629 } 2630 return true; 2631 } 2632 2633 // Set r7 to point to some ip offset. 2634 // SUB (immediate) 2635 bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode, 2636 const ARMEncoding encoding) { 2637 #if 0 2638 // ARM pseudo code... 2639 if (ConditionPassed()) 2640 { 2641 EncodingSpecificOperations(); 2642 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2643 if d == 15 then // Can only occur for ARM encoding 2644 ALUWritePC(result); // setflags is always FALSE here 2645 else 2646 R[d] = result; 2647 if setflags then 2648 APSR.N = result<31>; 2649 APSR.Z = IsZeroBit(result); 2650 APSR.C = carry; 2651 APSR.V = overflow; 2652 } 2653 #endif 2654 2655 if (ConditionPassed(opcode)) { 2656 bool success = false; 2657 const addr_t ip = ReadCoreReg(12, &success); 2658 if (!success) 2659 return false; 2660 uint32_t imm32; 2661 switch (encoding) { 2662 case eEncodingA1: 2663 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2664 break; 2665 default: 2666 return false; 2667 } 2668 addr_t ip_offset = imm32; 2669 addr_t addr = ip - ip_offset; // the adjusted ip value 2670 2671 EmulateInstruction::Context context; 2672 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2673 RegisterInfo dwarf_reg; 2674 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg); 2675 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset); 2676 2677 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr)) 2678 return false; 2679 } 2680 return true; 2681 } 2682 2683 // Set ip to point to some stack offset. 2684 // SUB (SP minus immediate) 2685 bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode, 2686 const ARMEncoding encoding) { 2687 #if 0 2688 // ARM pseudo code... 2689 if (ConditionPassed()) 2690 { 2691 EncodingSpecificOperations(); 2692 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2693 if d == 15 then // Can only occur for ARM encoding 2694 ALUWritePC(result); // setflags is always FALSE here 2695 else 2696 R[d] = result; 2697 if setflags then 2698 APSR.N = result<31>; 2699 APSR.Z = IsZeroBit(result); 2700 APSR.C = carry; 2701 APSR.V = overflow; 2702 } 2703 #endif 2704 2705 if (ConditionPassed(opcode)) { 2706 bool success = false; 2707 const addr_t sp = ReadCoreReg(SP_REG, &success); 2708 if (!success) 2709 return false; 2710 uint32_t imm32; 2711 switch (encoding) { 2712 case eEncodingA1: 2713 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2714 break; 2715 default: 2716 return false; 2717 } 2718 addr_t sp_offset = imm32; 2719 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 2720 2721 EmulateInstruction::Context context; 2722 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2723 RegisterInfo dwarf_reg; 2724 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 2725 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset); 2726 2727 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr)) 2728 return false; 2729 } 2730 return true; 2731 } 2732 2733 // This instruction subtracts an immediate value from the SP value, and writes 2734 // the result to the destination register. 2735 // 2736 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local 2737 // storage. 2738 bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode, 2739 const ARMEncoding encoding) { 2740 #if 0 2741 // ARM pseudo code... 2742 if (ConditionPassed()) 2743 { 2744 EncodingSpecificOperations(); 2745 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2746 if d == 15 then // Can only occur for ARM encoding 2747 ALUWritePC(result); // setflags is always FALSE here 2748 else 2749 R[d] = result; 2750 if setflags then 2751 APSR.N = result<31>; 2752 APSR.Z = IsZeroBit(result); 2753 APSR.C = carry; 2754 APSR.V = overflow; 2755 } 2756 #endif 2757 2758 bool success = false; 2759 if (ConditionPassed(opcode)) { 2760 const addr_t sp = ReadCoreReg(SP_REG, &success); 2761 if (!success) 2762 return false; 2763 2764 uint32_t Rd; 2765 bool setflags; 2766 uint32_t imm32; 2767 switch (encoding) { 2768 case eEncodingT1: 2769 Rd = 13; 2770 setflags = false; 2771 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 2772 break; 2773 case eEncodingT2: 2774 Rd = Bits32(opcode, 11, 8); 2775 setflags = BitIsSet(opcode, 20); 2776 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2777 if (Rd == 15 && setflags) 2778 return EmulateCMPImm(opcode, eEncodingT2); 2779 if (Rd == 15 && !setflags) 2780 return false; 2781 break; 2782 case eEncodingT3: 2783 Rd = Bits32(opcode, 11, 8); 2784 setflags = false; 2785 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 2786 if (Rd == 15) 2787 return false; 2788 break; 2789 case eEncodingA1: 2790 Rd = Bits32(opcode, 15, 12); 2791 setflags = BitIsSet(opcode, 20); 2792 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2793 2794 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 2795 // instructions; 2796 if (Rd == 15 && setflags) 2797 return EmulateSUBSPcLrEtc(opcode, encoding); 2798 break; 2799 default: 2800 return false; 2801 } 2802 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 2803 2804 EmulateInstruction::Context context; 2805 if (Rd == 13) { 2806 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting 2807 // to negate it, or the wrong 2808 // value gets passed down to context.SetImmediateSigned. 2809 context.type = EmulateInstruction::eContextAdjustStackPointer; 2810 context.SetImmediateSigned(-imm64); // the stack pointer offset 2811 } else { 2812 context.type = EmulateInstruction::eContextImmediate; 2813 context.SetNoArgs(); 2814 } 2815 2816 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 2817 res.carry_out, res.overflow)) 2818 return false; 2819 } 2820 return true; 2821 } 2822 2823 // A store operation to the stack that also updates the SP. 2824 bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode, 2825 const ARMEncoding encoding) { 2826 #if 0 2827 // ARM pseudo code... 2828 if (ConditionPassed()) 2829 { 2830 EncodingSpecificOperations(); 2831 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2832 address = if index then offset_addr else R[n]; 2833 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 2834 if wback then R[n] = offset_addr; 2835 } 2836 #endif 2837 2838 bool success = false; 2839 if (ConditionPassed(opcode)) { 2840 const uint32_t addr_byte_size = GetAddressByteSize(); 2841 const addr_t sp = ReadCoreReg(SP_REG, &success); 2842 if (!success) 2843 return false; 2844 uint32_t Rt; // the source register 2845 uint32_t imm12; 2846 uint32_t 2847 Rn; // This function assumes Rn is the SP, but we should verify that. 2848 2849 bool index; 2850 bool add; 2851 bool wback; 2852 switch (encoding) { 2853 case eEncodingA1: 2854 Rt = Bits32(opcode, 15, 12); 2855 imm12 = Bits32(opcode, 11, 0); 2856 Rn = Bits32(opcode, 19, 16); 2857 2858 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 2859 return false; 2860 2861 index = BitIsSet(opcode, 24); 2862 add = BitIsSet(opcode, 23); 2863 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 2864 2865 if (wback && ((Rn == 15) || (Rn == Rt))) 2866 return false; 2867 break; 2868 default: 2869 return false; 2870 } 2871 addr_t offset_addr; 2872 if (add) 2873 offset_addr = sp + imm12; 2874 else 2875 offset_addr = sp - imm12; 2876 2877 addr_t addr; 2878 if (index) 2879 addr = offset_addr; 2880 else 2881 addr = sp; 2882 2883 EmulateInstruction::Context context; 2884 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2885 RegisterInfo sp_reg; 2886 RegisterInfo dwarf_reg; 2887 2888 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2889 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2890 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2891 if (Rt != 15) { 2892 uint32_t reg_value = ReadCoreReg(Rt, &success); 2893 if (!success) 2894 return false; 2895 if (!MemUWrite(context, addr, reg_value, addr_byte_size)) 2896 return false; 2897 } else { 2898 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2899 if (!success) 2900 return false; 2901 if (!MemUWrite(context, addr, pc, addr_byte_size)) 2902 return false; 2903 } 2904 2905 if (wback) { 2906 context.type = EmulateInstruction::eContextAdjustStackPointer; 2907 context.SetImmediateSigned(addr - sp); 2908 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2909 LLDB_REGNUM_GENERIC_SP, offset_addr)) 2910 return false; 2911 } 2912 } 2913 return true; 2914 } 2915 2916 // Vector Push stores multiple extension registers to the stack. 2917 // It also updates SP to point to the start of the stored data. 2918 bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode, 2919 const ARMEncoding encoding) { 2920 #if 0 2921 // ARM pseudo code... 2922 if (ConditionPassed()) 2923 { 2924 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2925 address = SP - imm32; 2926 SP = SP - imm32; 2927 if single_regs then 2928 for r = 0 to regs-1 2929 MemA[address,4] = S[d+r]; address = address+4; 2930 else 2931 for r = 0 to regs-1 2932 // Store as two word-aligned words in the correct order for current endianness. 2933 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2934 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2935 address = address+8; 2936 } 2937 #endif 2938 2939 bool success = false; 2940 if (ConditionPassed(opcode)) { 2941 const uint32_t addr_byte_size = GetAddressByteSize(); 2942 const addr_t sp = ReadCoreReg(SP_REG, &success); 2943 if (!success) 2944 return false; 2945 bool single_regs; 2946 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2947 uint32_t imm32; // stack offset 2948 uint32_t regs; // number of registers 2949 switch (encoding) { 2950 case eEncodingT1: 2951 case eEncodingA1: 2952 single_regs = false; 2953 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2954 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2955 // If UInt(imm8) is odd, see "FSTMX". 2956 regs = Bits32(opcode, 7, 0) / 2; 2957 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2958 if (regs == 0 || regs > 16 || (d + regs) > 32) 2959 return false; 2960 break; 2961 case eEncodingT2: 2962 case eEncodingA2: 2963 single_regs = true; 2964 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2965 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2966 regs = Bits32(opcode, 7, 0); 2967 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2968 if (regs == 0 || regs > 16 || (d + regs) > 32) 2969 return false; 2970 break; 2971 default: 2972 return false; 2973 } 2974 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2975 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2976 addr_t sp_offset = imm32; 2977 addr_t addr = sp - sp_offset; 2978 uint32_t i; 2979 2980 EmulateInstruction::Context context; 2981 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2982 2983 RegisterInfo dwarf_reg; 2984 RegisterInfo sp_reg; 2985 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2986 for (i = 0; i < regs; ++i) { 2987 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2988 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2989 // uint64_t to accommodate 64-bit registers. 2990 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success); 2991 if (!success) 2992 return false; 2993 if (!MemAWrite(context, addr, reg_value, reg_byte_size)) 2994 return false; 2995 addr += reg_byte_size; 2996 } 2997 2998 context.type = EmulateInstruction::eContextAdjustStackPointer; 2999 context.SetImmediateSigned(-sp_offset); 3000 3001 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 3002 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 3003 return false; 3004 } 3005 return true; 3006 } 3007 3008 // Vector Pop loads multiple extension registers from the stack. 3009 // It also updates SP to point just above the loaded data. 3010 bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode, 3011 const ARMEncoding encoding) { 3012 #if 0 3013 // ARM pseudo code... 3014 if (ConditionPassed()) 3015 { 3016 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 3017 address = SP; 3018 SP = SP + imm32; 3019 if single_regs then 3020 for r = 0 to regs-1 3021 S[d+r] = MemA[address,4]; address = address+4; 3022 else 3023 for r = 0 to regs-1 3024 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 3025 // Combine the word-aligned words in the correct order for current endianness. 3026 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 3027 } 3028 #endif 3029 3030 bool success = false; 3031 if (ConditionPassed(opcode)) { 3032 const uint32_t addr_byte_size = GetAddressByteSize(); 3033 const addr_t sp = ReadCoreReg(SP_REG, &success); 3034 if (!success) 3035 return false; 3036 bool single_regs; 3037 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 3038 uint32_t imm32; // stack offset 3039 uint32_t regs; // number of registers 3040 switch (encoding) { 3041 case eEncodingT1: 3042 case eEncodingA1: 3043 single_regs = false; 3044 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 3045 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 3046 // If UInt(imm8) is odd, see "FLDMX". 3047 regs = Bits32(opcode, 7, 0) / 2; 3048 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 3049 if (regs == 0 || regs > 16 || (d + regs) > 32) 3050 return false; 3051 break; 3052 case eEncodingT2: 3053 case eEncodingA2: 3054 single_regs = true; 3055 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 3056 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 3057 regs = Bits32(opcode, 7, 0); 3058 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 3059 if (regs == 0 || regs > 16 || (d + regs) > 32) 3060 return false; 3061 break; 3062 default: 3063 return false; 3064 } 3065 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 3066 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 3067 addr_t sp_offset = imm32; 3068 addr_t addr = sp; 3069 uint32_t i; 3070 uint64_t data; // uint64_t to accommodate 64-bit registers. 3071 3072 EmulateInstruction::Context context; 3073 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3074 3075 RegisterInfo dwarf_reg; 3076 RegisterInfo sp_reg; 3077 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 3078 for (i = 0; i < regs; ++i) { 3079 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 3080 context.SetAddress(addr); 3081 data = MemARead(context, addr, reg_byte_size, 0, &success); 3082 if (!success) 3083 return false; 3084 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 3085 return false; 3086 addr += reg_byte_size; 3087 } 3088 3089 context.type = EmulateInstruction::eContextAdjustStackPointer; 3090 context.SetImmediateSigned(sp_offset); 3091 3092 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 3093 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 3094 return false; 3095 } 3096 return true; 3097 } 3098 3099 // SVC (previously SWI) 3100 bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode, 3101 const ARMEncoding encoding) { 3102 #if 0 3103 // ARM pseudo code... 3104 if (ConditionPassed()) 3105 { 3106 EncodingSpecificOperations(); 3107 CallSupervisor(); 3108 } 3109 #endif 3110 3111 bool success = false; 3112 3113 if (ConditionPassed(opcode)) { 3114 const uint32_t pc = ReadCoreReg(PC_REG, &success); 3115 addr_t lr; // next instruction address 3116 if (!success) 3117 return false; 3118 uint32_t imm32; // the immediate constant 3119 uint32_t mode; // ARM or Thumb mode 3120 switch (encoding) { 3121 case eEncodingT1: 3122 lr = (pc + 2) | 1u; // return address 3123 imm32 = Bits32(opcode, 7, 0); 3124 mode = eModeThumb; 3125 break; 3126 case eEncodingA1: 3127 lr = pc + 4; // return address 3128 imm32 = Bits32(opcode, 23, 0); 3129 mode = eModeARM; 3130 break; 3131 default: 3132 return false; 3133 } 3134 3135 EmulateInstruction::Context context; 3136 context.type = EmulateInstruction::eContextSupervisorCall; 3137 context.SetISAAndImmediate(mode, imm32); 3138 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 3139 LLDB_REGNUM_GENERIC_RA, lr)) 3140 return false; 3141 } 3142 return true; 3143 } 3144 3145 // If Then makes up to four following instructions (the IT block) conditional. 3146 bool EmulateInstructionARM::EmulateIT(const uint32_t opcode, 3147 const ARMEncoding encoding) { 3148 #if 0 3149 // ARM pseudo code... 3150 EncodingSpecificOperations(); 3151 ITSTATE.IT<7:0> = firstcond:mask; 3152 #endif 3153 3154 m_it_session.InitIT(Bits32(opcode, 7, 0)); 3155 return true; 3156 } 3157 3158 bool EmulateInstructionARM::EmulateNop(const uint32_t opcode, 3159 const ARMEncoding encoding) { 3160 // NOP, nothing to do... 3161 return true; 3162 } 3163 3164 // Branch causes a branch to a target address. 3165 bool EmulateInstructionARM::EmulateB(const uint32_t opcode, 3166 const ARMEncoding encoding) { 3167 #if 0 3168 // ARM pseudo code... 3169 if (ConditionPassed()) 3170 { 3171 EncodingSpecificOperations(); 3172 BranchWritePC(PC + imm32); 3173 } 3174 #endif 3175 3176 bool success = false; 3177 3178 if (ConditionPassed(opcode)) { 3179 EmulateInstruction::Context context; 3180 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 3181 const uint32_t pc = ReadCoreReg(PC_REG, &success); 3182 if (!success) 3183 return false; 3184 addr_t target; // target address 3185 int32_t imm32; // PC-relative offset 3186 switch (encoding) { 3187 case eEncodingT1: 3188 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 3189 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 3190 target = pc + imm32; 3191 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 3192 break; 3193 case eEncodingT2: 3194 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 3195 target = pc + imm32; 3196 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 3197 break; 3198 case eEncodingT3: 3199 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 3200 { 3201 if (Bits32(opcode, 25, 23) == 7) 3202 return false; // See Branches and miscellaneous control on page 3203 // A6-235. 3204 3205 uint32_t S = Bit32(opcode, 26); 3206 uint32_t imm6 = Bits32(opcode, 21, 16); 3207 uint32_t J1 = Bit32(opcode, 13); 3208 uint32_t J2 = Bit32(opcode, 11); 3209 uint32_t imm11 = Bits32(opcode, 10, 0); 3210 uint32_t imm21 = 3211 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 3212 imm32 = llvm::SignExtend32<21>(imm21); 3213 target = pc + imm32; 3214 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 3215 break; 3216 } 3217 case eEncodingT4: { 3218 uint32_t S = Bit32(opcode, 26); 3219 uint32_t imm10 = Bits32(opcode, 25, 16); 3220 uint32_t J1 = Bit32(opcode, 13); 3221 uint32_t J2 = Bit32(opcode, 11); 3222 uint32_t imm11 = Bits32(opcode, 10, 0); 3223 uint32_t I1 = !(J1 ^ S); 3224 uint32_t I2 = !(J2 ^ S); 3225 uint32_t imm25 = 3226 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 3227 imm32 = llvm::SignExtend32<25>(imm25); 3228 target = pc + imm32; 3229 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 3230 break; 3231 } 3232 case eEncodingA1: 3233 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 3234 target = pc + imm32; 3235 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 3236 break; 3237 default: 3238 return false; 3239 } 3240 if (!BranchWritePC(context, target)) 3241 return false; 3242 } 3243 return true; 3244 } 3245 3246 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the 3247 // value in a register with 3248 // zero and conditionally branch forward a constant value. They do not affect 3249 // the condition flags. 3250 // CBNZ, CBZ 3251 bool EmulateInstructionARM::EmulateCB(const uint32_t opcode, 3252 const ARMEncoding encoding) { 3253 #if 0 3254 // ARM pseudo code... 3255 EncodingSpecificOperations(); 3256 if nonzero ^ IsZero(R[n]) then 3257 BranchWritePC(PC + imm32); 3258 #endif 3259 3260 bool success = false; 3261 3262 // Read the register value from the operand register Rn. 3263 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 3264 if (!success) 3265 return false; 3266 3267 EmulateInstruction::Context context; 3268 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 3269 const uint32_t pc = ReadCoreReg(PC_REG, &success); 3270 if (!success) 3271 return false; 3272 3273 addr_t target; // target address 3274 uint32_t imm32; // PC-relative offset to branch forward 3275 bool nonzero; 3276 switch (encoding) { 3277 case eEncodingT1: 3278 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 3279 nonzero = BitIsSet(opcode, 11); 3280 target = pc + imm32; 3281 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 3282 break; 3283 default: 3284 return false; 3285 } 3286 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 3287 if (!BranchWritePC(context, target)) 3288 return false; 3289 3290 return true; 3291 } 3292 3293 // Table Branch Byte causes a PC-relative forward branch using a table of single 3294 // byte offsets. 3295 // A base register provides a pointer to the table, and a second register 3296 // supplies an index into the table. 3297 // The branch length is twice the value of the byte returned from the table. 3298 // 3299 // Table Branch Halfword causes a PC-relative forward branch using a table of 3300 // single halfword offsets. 3301 // A base register provides a pointer to the table, and a second register 3302 // supplies an index into the table. 3303 // The branch length is twice the value of the halfword returned from the table. 3304 // TBB, TBH 3305 bool EmulateInstructionARM::EmulateTB(const uint32_t opcode, 3306 const ARMEncoding encoding) { 3307 #if 0 3308 // ARM pseudo code... 3309 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3310 if is_tbh then 3311 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 3312 else 3313 halfwords = UInt(MemU[R[n]+R[m], 1]); 3314 BranchWritePC(PC + 2*halfwords); 3315 #endif 3316 3317 bool success = false; 3318 3319 if (ConditionPassed(opcode)) { 3320 uint32_t Rn; // the base register which contains the address of the table of 3321 // branch lengths 3322 uint32_t Rm; // the index register which contains an integer pointing to a 3323 // byte/halfword in the table 3324 bool is_tbh; // true if table branch halfword 3325 switch (encoding) { 3326 case eEncodingT1: 3327 Rn = Bits32(opcode, 19, 16); 3328 Rm = Bits32(opcode, 3, 0); 3329 is_tbh = BitIsSet(opcode, 4); 3330 if (Rn == 13 || BadReg(Rm)) 3331 return false; 3332 if (InITBlock() && !LastInITBlock()) 3333 return false; 3334 break; 3335 default: 3336 return false; 3337 } 3338 3339 // Read the address of the table from the operand register Rn. 3340 // The PC can be used, in which case the table immediately follows this 3341 // instruction. 3342 uint32_t base = ReadCoreReg(Rn, &success); 3343 if (!success) 3344 return false; 3345 3346 // the table index 3347 uint32_t index = ReadCoreReg(Rm, &success); 3348 if (!success) 3349 return false; 3350 3351 // the offsetted table address 3352 addr_t addr = base + (is_tbh ? index * 2 : index); 3353 3354 // PC-relative offset to branch forward 3355 EmulateInstruction::Context context; 3356 context.type = EmulateInstruction::eContextTableBranchReadMemory; 3357 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 3358 if (!success) 3359 return false; 3360 3361 const uint32_t pc = ReadCoreReg(PC_REG, &success); 3362 if (!success) 3363 return false; 3364 3365 // target address 3366 addr_t target = pc + offset; 3367 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 3368 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset); 3369 3370 if (!BranchWritePC(context, target)) 3371 return false; 3372 } 3373 3374 return true; 3375 } 3376 3377 // This instruction adds an immediate value to a register value, and writes the 3378 // result to the destination register. 3379 // It can optionally update the condition flags based on the result. 3380 bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode, 3381 const ARMEncoding encoding) { 3382 #if 0 3383 if ConditionPassed() then 3384 EncodingSpecificOperations(); 3385 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3386 R[d] = result; 3387 if setflags then 3388 APSR.N = result<31>; 3389 APSR.Z = IsZeroBit(result); 3390 APSR.C = carry; 3391 APSR.V = overflow; 3392 #endif 3393 3394 bool success = false; 3395 3396 if (ConditionPassed(opcode)) { 3397 uint32_t d; 3398 uint32_t n; 3399 bool setflags; 3400 uint32_t imm32; 3401 uint32_t carry_out; 3402 3403 // EncodingSpecificOperations(); 3404 switch (encoding) { 3405 case eEncodingT1: 3406 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = 3407 // ZeroExtend(imm3, 32); 3408 d = Bits32(opcode, 2, 0); 3409 n = Bits32(opcode, 5, 3); 3410 setflags = !InITBlock(); 3411 imm32 = Bits32(opcode, 8, 6); 3412 3413 break; 3414 3415 case eEncodingT2: 3416 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = 3417 // ZeroExtend(imm8, 32); 3418 d = Bits32(opcode, 10, 8); 3419 n = Bits32(opcode, 10, 8); 3420 setflags = !InITBlock(); 3421 imm32 = Bits32(opcode, 7, 0); 3422 3423 break; 3424 3425 case eEncodingT3: 3426 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 3427 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = 3428 // ThumbExpandImm(i:imm3:imm8); 3429 d = Bits32(opcode, 11, 8); 3430 n = Bits32(opcode, 19, 16); 3431 setflags = BitIsSet(opcode, 20); 3432 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out); 3433 3434 // if Rn == '1101' then SEE ADD (SP plus immediate); 3435 if (n == 13) 3436 return EmulateADDSPImm(opcode, eEncodingT3); 3437 3438 // if BadReg(d) || n == 15 then UNPREDICTABLE; 3439 if (BadReg(d) || (n == 15)) 3440 return false; 3441 3442 break; 3443 3444 case eEncodingT4: { 3445 // if Rn == '1111' then SEE ADR; 3446 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = 3447 // ZeroExtend(i:imm3:imm8, 32); 3448 d = Bits32(opcode, 11, 8); 3449 n = Bits32(opcode, 19, 16); 3450 setflags = false; 3451 uint32_t i = Bit32(opcode, 26); 3452 uint32_t imm3 = Bits32(opcode, 14, 12); 3453 uint32_t imm8 = Bits32(opcode, 7, 0); 3454 imm32 = (i << 11) | (imm3 << 8) | imm8; 3455 3456 // if Rn == '1101' then SEE ADD (SP plus immediate); 3457 if (n == 13) 3458 return EmulateADDSPImm(opcode, eEncodingT4); 3459 3460 // if BadReg(d) then UNPREDICTABLE; 3461 if (BadReg(d)) 3462 return false; 3463 3464 break; 3465 } 3466 3467 default: 3468 return false; 3469 } 3470 3471 uint64_t Rn = 3472 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3473 if (!success) 3474 return false; 3475 3476 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3477 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0); 3478 3479 RegisterInfo reg_n; 3480 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 3481 3482 EmulateInstruction::Context context; 3483 context.type = eContextArithmetic; 3484 context.SetRegisterPlusOffset(reg_n, imm32); 3485 3486 // R[d] = result; 3487 // if setflags then 3488 // APSR.N = result<31>; 3489 // APSR.Z = IsZeroBit(result); 3490 // APSR.C = carry; 3491 // APSR.V = overflow; 3492 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 3493 res.carry_out, res.overflow)) 3494 return false; 3495 } 3496 return true; 3497 } 3498 3499 // This instruction adds an immediate value to a register value, and writes the 3500 // result to the destination 3501 // register. It can optionally update the condition flags based on the result. 3502 bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode, 3503 const ARMEncoding encoding) { 3504 #if 0 3505 // ARM pseudo code... 3506 if ConditionPassed() then 3507 EncodingSpecificOperations(); 3508 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3509 if d == 15 then 3510 ALUWritePC(result); // setflags is always FALSE here 3511 else 3512 R[d] = result; 3513 if setflags then 3514 APSR.N = result<31>; 3515 APSR.Z = IsZeroBit(result); 3516 APSR.C = carry; 3517 APSR.V = overflow; 3518 #endif 3519 3520 bool success = false; 3521 3522 if (ConditionPassed(opcode)) { 3523 uint32_t Rd, Rn; 3524 uint32_t 3525 imm32; // the immediate value to be added to the value obtained from Rn 3526 bool setflags; 3527 switch (encoding) { 3528 case eEncodingA1: 3529 Rd = Bits32(opcode, 15, 12); 3530 Rn = Bits32(opcode, 19, 16); 3531 setflags = BitIsSet(opcode, 20); 3532 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3533 break; 3534 default: 3535 return false; 3536 } 3537 3538 // Read the first operand. 3539 uint32_t val1 = ReadCoreReg(Rn, &success); 3540 if (!success) 3541 return false; 3542 3543 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 3544 3545 EmulateInstruction::Context context; 3546 if (Rd == 13) 3547 context.type = EmulateInstruction::eContextAdjustStackPointer; 3548 else if (Rd == GetFramePointerRegisterNumber()) 3549 context.type = EmulateInstruction::eContextSetFramePointer; 3550 else 3551 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3552 3553 RegisterInfo dwarf_reg; 3554 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 3555 context.SetRegisterPlusOffset(dwarf_reg, imm32); 3556 3557 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3558 res.carry_out, res.overflow)) 3559 return false; 3560 } 3561 return true; 3562 } 3563 3564 // This instruction adds a register value and an optionally-shifted register 3565 // value, and writes the result 3566 // to the destination register. It can optionally update the condition flags 3567 // based on the result. 3568 bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode, 3569 const ARMEncoding encoding) { 3570 #if 0 3571 // ARM pseudo code... 3572 if ConditionPassed() then 3573 EncodingSpecificOperations(); 3574 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3575 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3576 if d == 15 then 3577 ALUWritePC(result); // setflags is always FALSE here 3578 else 3579 R[d] = result; 3580 if setflags then 3581 APSR.N = result<31>; 3582 APSR.Z = IsZeroBit(result); 3583 APSR.C = carry; 3584 APSR.V = overflow; 3585 #endif 3586 3587 bool success = false; 3588 3589 if (ConditionPassed(opcode)) { 3590 uint32_t Rd, Rn, Rm; 3591 ARM_ShifterType shift_t; 3592 uint32_t shift_n; // the shift applied to the value read from Rm 3593 bool setflags; 3594 switch (encoding) { 3595 case eEncodingT1: 3596 Rd = Bits32(opcode, 2, 0); 3597 Rn = Bits32(opcode, 5, 3); 3598 Rm = Bits32(opcode, 8, 6); 3599 setflags = !InITBlock(); 3600 shift_t = SRType_LSL; 3601 shift_n = 0; 3602 break; 3603 case eEncodingT2: 3604 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3605 Rm = Bits32(opcode, 6, 3); 3606 setflags = false; 3607 shift_t = SRType_LSL; 3608 shift_n = 0; 3609 if (Rn == 15 && Rm == 15) 3610 return false; 3611 if (Rd == 15 && InITBlock() && !LastInITBlock()) 3612 return false; 3613 break; 3614 case eEncodingA1: 3615 Rd = Bits32(opcode, 15, 12); 3616 Rn = Bits32(opcode, 19, 16); 3617 Rm = Bits32(opcode, 3, 0); 3618 setflags = BitIsSet(opcode, 20); 3619 shift_n = DecodeImmShiftARM(opcode, shift_t); 3620 break; 3621 default: 3622 return false; 3623 } 3624 3625 // Read the first operand. 3626 uint32_t val1 = ReadCoreReg(Rn, &success); 3627 if (!success) 3628 return false; 3629 3630 // Read the second operand. 3631 uint32_t val2 = ReadCoreReg(Rm, &success); 3632 if (!success) 3633 return false; 3634 3635 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3636 if (!success) 3637 return false; 3638 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3639 3640 EmulateInstruction::Context context; 3641 context.type = eContextArithmetic; 3642 RegisterInfo op1_reg; 3643 RegisterInfo op2_reg; 3644 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 3645 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 3646 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 3647 3648 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3649 res.carry_out, res.overflow)) 3650 return false; 3651 } 3652 return true; 3653 } 3654 3655 // Compare Negative (immediate) adds a register value and an immediate value. 3656 // It updates the condition flags based on the result, and discards the result. 3657 bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode, 3658 const ARMEncoding encoding) { 3659 #if 0 3660 // ARM pseudo code... 3661 if ConditionPassed() then 3662 EncodingSpecificOperations(); 3663 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3664 APSR.N = result<31>; 3665 APSR.Z = IsZeroBit(result); 3666 APSR.C = carry; 3667 APSR.V = overflow; 3668 #endif 3669 3670 bool success = false; 3671 3672 uint32_t Rn; // the first operand 3673 uint32_t imm32; // the immediate value to be compared with 3674 switch (encoding) { 3675 case eEncodingT1: 3676 Rn = Bits32(opcode, 19, 16); 3677 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3678 if (Rn == 15) 3679 return false; 3680 break; 3681 case eEncodingA1: 3682 Rn = Bits32(opcode, 19, 16); 3683 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3684 break; 3685 default: 3686 return false; 3687 } 3688 // Read the register value from the operand register Rn. 3689 uint32_t reg_val = ReadCoreReg(Rn, &success); 3690 if (!success) 3691 return false; 3692 3693 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 3694 3695 EmulateInstruction::Context context; 3696 context.type = EmulateInstruction::eContextImmediate; 3697 context.SetNoArgs(); 3698 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3699 return false; 3700 3701 return true; 3702 } 3703 3704 // Compare Negative (register) adds a register value and an optionally-shifted 3705 // register value. 3706 // It updates the condition flags based on the result, and discards the result. 3707 bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode, 3708 const ARMEncoding encoding) { 3709 #if 0 3710 // ARM pseudo code... 3711 if ConditionPassed() then 3712 EncodingSpecificOperations(); 3713 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3714 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3715 APSR.N = result<31>; 3716 APSR.Z = IsZeroBit(result); 3717 APSR.C = carry; 3718 APSR.V = overflow; 3719 #endif 3720 3721 bool success = false; 3722 3723 uint32_t Rn; // the first operand 3724 uint32_t Rm; // the second operand 3725 ARM_ShifterType shift_t; 3726 uint32_t shift_n; // the shift applied to the value read from Rm 3727 switch (encoding) { 3728 case eEncodingT1: 3729 Rn = Bits32(opcode, 2, 0); 3730 Rm = Bits32(opcode, 5, 3); 3731 shift_t = SRType_LSL; 3732 shift_n = 0; 3733 break; 3734 case eEncodingT2: 3735 Rn = Bits32(opcode, 19, 16); 3736 Rm = Bits32(opcode, 3, 0); 3737 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3738 // if n == 15 || BadReg(m) then UNPREDICTABLE; 3739 if (Rn == 15 || BadReg(Rm)) 3740 return false; 3741 break; 3742 case eEncodingA1: 3743 Rn = Bits32(opcode, 19, 16); 3744 Rm = Bits32(opcode, 3, 0); 3745 shift_n = DecodeImmShiftARM(opcode, shift_t); 3746 break; 3747 default: 3748 return false; 3749 } 3750 // Read the register value from register Rn. 3751 uint32_t val1 = ReadCoreReg(Rn, &success); 3752 if (!success) 3753 return false; 3754 3755 // Read the register value from register Rm. 3756 uint32_t val2 = ReadCoreReg(Rm, &success); 3757 if (!success) 3758 return false; 3759 3760 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3761 if (!success) 3762 return false; 3763 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3764 3765 EmulateInstruction::Context context; 3766 context.type = EmulateInstruction::eContextImmediate; 3767 context.SetNoArgs(); 3768 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3769 return false; 3770 3771 return true; 3772 } 3773 3774 // Compare (immediate) subtracts an immediate value from a register value. 3775 // It updates the condition flags based on the result, and discards the result. 3776 bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode, 3777 const ARMEncoding encoding) { 3778 #if 0 3779 // ARM pseudo code... 3780 if ConditionPassed() then 3781 EncodingSpecificOperations(); 3782 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 3783 APSR.N = result<31>; 3784 APSR.Z = IsZeroBit(result); 3785 APSR.C = carry; 3786 APSR.V = overflow; 3787 #endif 3788 3789 bool success = false; 3790 3791 uint32_t Rn; // the first operand 3792 uint32_t imm32; // the immediate value to be compared with 3793 switch (encoding) { 3794 case eEncodingT1: 3795 Rn = Bits32(opcode, 10, 8); 3796 imm32 = Bits32(opcode, 7, 0); 3797 break; 3798 case eEncodingT2: 3799 Rn = Bits32(opcode, 19, 16); 3800 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3801 if (Rn == 15) 3802 return false; 3803 break; 3804 case eEncodingA1: 3805 Rn = Bits32(opcode, 19, 16); 3806 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3807 break; 3808 default: 3809 return false; 3810 } 3811 // Read the register value from the operand register Rn. 3812 uint32_t reg_val = ReadCoreReg(Rn, &success); 3813 if (!success) 3814 return false; 3815 3816 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 3817 3818 EmulateInstruction::Context context; 3819 context.type = EmulateInstruction::eContextImmediate; 3820 context.SetNoArgs(); 3821 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3822 return false; 3823 3824 return true; 3825 } 3826 3827 // Compare (register) subtracts an optionally-shifted register value from a 3828 // register value. 3829 // It updates the condition flags based on the result, and discards the result. 3830 bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode, 3831 const ARMEncoding encoding) { 3832 #if 0 3833 // ARM pseudo code... 3834 if ConditionPassed() then 3835 EncodingSpecificOperations(); 3836 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3837 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 3838 APSR.N = result<31>; 3839 APSR.Z = IsZeroBit(result); 3840 APSR.C = carry; 3841 APSR.V = overflow; 3842 #endif 3843 3844 bool success = false; 3845 3846 uint32_t Rn; // the first operand 3847 uint32_t Rm; // the second operand 3848 ARM_ShifterType shift_t; 3849 uint32_t shift_n; // the shift applied to the value read from Rm 3850 switch (encoding) { 3851 case eEncodingT1: 3852 Rn = Bits32(opcode, 2, 0); 3853 Rm = Bits32(opcode, 5, 3); 3854 shift_t = SRType_LSL; 3855 shift_n = 0; 3856 break; 3857 case eEncodingT2: 3858 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3859 Rm = Bits32(opcode, 6, 3); 3860 shift_t = SRType_LSL; 3861 shift_n = 0; 3862 if (Rn < 8 && Rm < 8) 3863 return false; 3864 if (Rn == 15 || Rm == 15) 3865 return false; 3866 break; 3867 case eEncodingT3: 3868 Rn = Bits32(opcode, 19, 16); 3869 Rm = Bits32(opcode, 3, 0); 3870 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3871 if (Rn == 15 || BadReg(Rm)) 3872 return false; 3873 break; 3874 case eEncodingA1: 3875 Rn = Bits32(opcode, 19, 16); 3876 Rm = Bits32(opcode, 3, 0); 3877 shift_n = DecodeImmShiftARM(opcode, shift_t); 3878 break; 3879 default: 3880 return false; 3881 } 3882 // Read the register value from register Rn. 3883 uint32_t val1 = ReadCoreReg(Rn, &success); 3884 if (!success) 3885 return false; 3886 3887 // Read the register value from register Rm. 3888 uint32_t val2 = ReadCoreReg(Rm, &success); 3889 if (!success) 3890 return false; 3891 3892 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3893 if (!success) 3894 return false; 3895 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3896 3897 EmulateInstruction::Context context; 3898 context.type = EmulateInstruction::eContextImmediate; 3899 context.SetNoArgs(); 3900 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3901 return false; 3902 3903 return true; 3904 } 3905 3906 // Arithmetic Shift Right (immediate) shifts a register value right by an 3907 // immediate number of bits, 3908 // shifting in copies of its sign bit, and writes the result to the destination 3909 // register. It can 3910 // optionally update the condition flags based on the result. 3911 bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode, 3912 const ARMEncoding encoding) { 3913 #if 0 3914 // ARM pseudo code... 3915 if ConditionPassed() then 3916 EncodingSpecificOperations(); 3917 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3918 if d == 15 then // Can only occur for ARM encoding 3919 ALUWritePC(result); // setflags is always FALSE here 3920 else 3921 R[d] = result; 3922 if setflags then 3923 APSR.N = result<31>; 3924 APSR.Z = IsZeroBit(result); 3925 APSR.C = carry; 3926 // APSR.V unchanged 3927 #endif 3928 3929 return EmulateShiftImm(opcode, encoding, SRType_ASR); 3930 } 3931 3932 // Arithmetic Shift Right (register) shifts a register value right by a variable 3933 // number of bits, 3934 // shifting in copies of its sign bit, and writes the result to the destination 3935 // register. 3936 // The variable number of bits is read from the bottom byte of a register. It 3937 // can optionally update 3938 // the condition flags based on the result. 3939 bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode, 3940 const ARMEncoding encoding) { 3941 #if 0 3942 // ARM pseudo code... 3943 if ConditionPassed() then 3944 EncodingSpecificOperations(); 3945 shift_n = UInt(R[m]<7:0>); 3946 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3947 R[d] = result; 3948 if setflags then 3949 APSR.N = result<31>; 3950 APSR.Z = IsZeroBit(result); 3951 APSR.C = carry; 3952 // APSR.V unchanged 3953 #endif 3954 3955 return EmulateShiftReg(opcode, encoding, SRType_ASR); 3956 } 3957 3958 // Logical Shift Left (immediate) shifts a register value left by an immediate 3959 // number of bits, 3960 // shifting in zeros, and writes the result to the destination register. It can 3961 // optionally 3962 // update the condition flags based on the result. 3963 bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode, 3964 const ARMEncoding encoding) { 3965 #if 0 3966 // ARM pseudo code... 3967 if ConditionPassed() then 3968 EncodingSpecificOperations(); 3969 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3970 if d == 15 then // Can only occur for ARM encoding 3971 ALUWritePC(result); // setflags is always FALSE here 3972 else 3973 R[d] = result; 3974 if setflags then 3975 APSR.N = result<31>; 3976 APSR.Z = IsZeroBit(result); 3977 APSR.C = carry; 3978 // APSR.V unchanged 3979 #endif 3980 3981 return EmulateShiftImm(opcode, encoding, SRType_LSL); 3982 } 3983 3984 // Logical Shift Left (register) shifts a register value left by a variable 3985 // number of bits, 3986 // shifting in zeros, and writes the result to the destination register. The 3987 // variable number 3988 // of bits is read from the bottom byte of a register. It can optionally update 3989 // the condition 3990 // flags based on the result. 3991 bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode, 3992 const ARMEncoding encoding) { 3993 #if 0 3994 // ARM pseudo code... 3995 if ConditionPassed() then 3996 EncodingSpecificOperations(); 3997 shift_n = UInt(R[m]<7:0>); 3998 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3999 R[d] = result; 4000 if setflags then 4001 APSR.N = result<31>; 4002 APSR.Z = IsZeroBit(result); 4003 APSR.C = carry; 4004 // APSR.V unchanged 4005 #endif 4006 4007 return EmulateShiftReg(opcode, encoding, SRType_LSL); 4008 } 4009 4010 // Logical Shift Right (immediate) shifts a register value right by an immediate 4011 // number of bits, 4012 // shifting in zeros, and writes the result to the destination register. It can 4013 // optionally 4014 // update the condition flags based on the result. 4015 bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode, 4016 const ARMEncoding encoding) { 4017 #if 0 4018 // ARM pseudo code... 4019 if ConditionPassed() then 4020 EncodingSpecificOperations(); 4021 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 4022 if d == 15 then // Can only occur for ARM encoding 4023 ALUWritePC(result); // setflags is always FALSE here 4024 else 4025 R[d] = result; 4026 if setflags then 4027 APSR.N = result<31>; 4028 APSR.Z = IsZeroBit(result); 4029 APSR.C = carry; 4030 // APSR.V unchanged 4031 #endif 4032 4033 return EmulateShiftImm(opcode, encoding, SRType_LSR); 4034 } 4035 4036 // Logical Shift Right (register) shifts a register value right by a variable 4037 // number of bits, 4038 // shifting in zeros, and writes the result to the destination register. The 4039 // variable number 4040 // of bits is read from the bottom byte of a register. It can optionally update 4041 // the condition 4042 // flags based on the result. 4043 bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode, 4044 const ARMEncoding encoding) { 4045 #if 0 4046 // ARM pseudo code... 4047 if ConditionPassed() then 4048 EncodingSpecificOperations(); 4049 shift_n = UInt(R[m]<7:0>); 4050 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 4051 R[d] = result; 4052 if setflags then 4053 APSR.N = result<31>; 4054 APSR.Z = IsZeroBit(result); 4055 APSR.C = carry; 4056 // APSR.V unchanged 4057 #endif 4058 4059 return EmulateShiftReg(opcode, encoding, SRType_LSR); 4060 } 4061 4062 // Rotate Right (immediate) provides the value of the contents of a register 4063 // rotated by a constant value. 4064 // The bits that are rotated off the right end are inserted into the vacated bit 4065 // positions on the left. 4066 // It can optionally update the condition flags based on the result. 4067 bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode, 4068 const ARMEncoding encoding) { 4069 #if 0 4070 // ARM pseudo code... 4071 if ConditionPassed() then 4072 EncodingSpecificOperations(); 4073 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 4074 if d == 15 then // Can only occur for ARM encoding 4075 ALUWritePC(result); // setflags is always FALSE here 4076 else 4077 R[d] = result; 4078 if setflags then 4079 APSR.N = result<31>; 4080 APSR.Z = IsZeroBit(result); 4081 APSR.C = carry; 4082 // APSR.V unchanged 4083 #endif 4084 4085 return EmulateShiftImm(opcode, encoding, SRType_ROR); 4086 } 4087 4088 // Rotate Right (register) provides the value of the contents of a register 4089 // rotated by a variable number of bits. 4090 // The bits that are rotated off the right end are inserted into the vacated bit 4091 // positions on the left. 4092 // The variable number of bits is read from the bottom byte of a register. It 4093 // can optionally update the condition 4094 // flags based on the result. 4095 bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode, 4096 const ARMEncoding encoding) { 4097 #if 0 4098 // ARM pseudo code... 4099 if ConditionPassed() then 4100 EncodingSpecificOperations(); 4101 shift_n = UInt(R[m]<7:0>); 4102 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 4103 R[d] = result; 4104 if setflags then 4105 APSR.N = result<31>; 4106 APSR.Z = IsZeroBit(result); 4107 APSR.C = carry; 4108 // APSR.V unchanged 4109 #endif 4110 4111 return EmulateShiftReg(opcode, encoding, SRType_ROR); 4112 } 4113 4114 // Rotate Right with Extend provides the value of the contents of a register 4115 // shifted right by one place, 4116 // with the carry flag shifted into bit [31]. 4117 // 4118 // RRX can optionally update the condition flags based on the result. 4119 // In that case, bit [0] is shifted into the carry flag. 4120 bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode, 4121 const ARMEncoding encoding) { 4122 #if 0 4123 // ARM pseudo code... 4124 if ConditionPassed() then 4125 EncodingSpecificOperations(); 4126 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 4127 if d == 15 then // Can only occur for ARM encoding 4128 ALUWritePC(result); // setflags is always FALSE here 4129 else 4130 R[d] = result; 4131 if setflags then 4132 APSR.N = result<31>; 4133 APSR.Z = IsZeroBit(result); 4134 APSR.C = carry; 4135 // APSR.V unchanged 4136 #endif 4137 4138 return EmulateShiftImm(opcode, encoding, SRType_RRX); 4139 } 4140 4141 bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode, 4142 const ARMEncoding encoding, 4143 ARM_ShifterType shift_type) { 4144 // assert(shift_type == SRType_ASR 4145 // || shift_type == SRType_LSL 4146 // || shift_type == SRType_LSR 4147 // || shift_type == SRType_ROR 4148 // || shift_type == SRType_RRX); 4149 4150 bool success = false; 4151 4152 if (ConditionPassed(opcode)) { 4153 uint32_t Rd; // the destination register 4154 uint32_t Rm; // the first operand register 4155 uint32_t imm5; // encoding for the shift amount 4156 uint32_t carry; // the carry bit after the shift operation 4157 bool setflags; 4158 4159 // Special case handling! 4160 // A8.6.139 ROR (immediate) -- Encoding T1 4161 ARMEncoding use_encoding = encoding; 4162 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) { 4163 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding 4164 // to 4165 // have the same decoding of bit fields as the other Thumb2 shift 4166 // operations. 4167 use_encoding = eEncodingT2; 4168 } 4169 4170 switch (use_encoding) { 4171 case eEncodingT1: 4172 // Due to the above special case handling! 4173 if (shift_type == SRType_ROR) 4174 return false; 4175 4176 Rd = Bits32(opcode, 2, 0); 4177 Rm = Bits32(opcode, 5, 3); 4178 setflags = !InITBlock(); 4179 imm5 = Bits32(opcode, 10, 6); 4180 break; 4181 case eEncodingT2: 4182 // A8.6.141 RRX 4183 // There's no imm form of RRX instructions. 4184 if (shift_type == SRType_RRX) 4185 return false; 4186 4187 Rd = Bits32(opcode, 11, 8); 4188 Rm = Bits32(opcode, 3, 0); 4189 setflags = BitIsSet(opcode, 20); 4190 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 4191 if (BadReg(Rd) || BadReg(Rm)) 4192 return false; 4193 break; 4194 case eEncodingA1: 4195 Rd = Bits32(opcode, 15, 12); 4196 Rm = Bits32(opcode, 3, 0); 4197 setflags = BitIsSet(opcode, 20); 4198 imm5 = Bits32(opcode, 11, 7); 4199 break; 4200 default: 4201 return false; 4202 } 4203 4204 // A8.6.139 ROR (immediate) 4205 if (shift_type == SRType_ROR && imm5 == 0) 4206 shift_type = SRType_RRX; 4207 4208 // Get the first operand. 4209 uint32_t value = ReadCoreReg(Rm, &success); 4210 if (!success) 4211 return false; 4212 4213 // Decode the shift amount if not RRX. 4214 uint32_t amt = 4215 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 4216 4217 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 4218 if (!success) 4219 return false; 4220 4221 // The context specifies that an immediate is to be moved into Rd. 4222 EmulateInstruction::Context context; 4223 context.type = EmulateInstruction::eContextImmediate; 4224 context.SetNoArgs(); 4225 4226 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 4227 return false; 4228 } 4229 return true; 4230 } 4231 4232 bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode, 4233 const ARMEncoding encoding, 4234 ARM_ShifterType shift_type) { 4235 // assert(shift_type == SRType_ASR 4236 // || shift_type == SRType_LSL 4237 // || shift_type == SRType_LSR 4238 // || shift_type == SRType_ROR); 4239 4240 bool success = false; 4241 4242 if (ConditionPassed(opcode)) { 4243 uint32_t Rd; // the destination register 4244 uint32_t Rn; // the first operand register 4245 uint32_t 4246 Rm; // the register whose bottom byte contains the amount to shift by 4247 uint32_t carry; // the carry bit after the shift operation 4248 bool setflags; 4249 switch (encoding) { 4250 case eEncodingT1: 4251 Rd = Bits32(opcode, 2, 0); 4252 Rn = Rd; 4253 Rm = Bits32(opcode, 5, 3); 4254 setflags = !InITBlock(); 4255 break; 4256 case eEncodingT2: 4257 Rd = Bits32(opcode, 11, 8); 4258 Rn = Bits32(opcode, 19, 16); 4259 Rm = Bits32(opcode, 3, 0); 4260 setflags = BitIsSet(opcode, 20); 4261 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 4262 return false; 4263 break; 4264 case eEncodingA1: 4265 Rd = Bits32(opcode, 15, 12); 4266 Rn = Bits32(opcode, 3, 0); 4267 Rm = Bits32(opcode, 11, 8); 4268 setflags = BitIsSet(opcode, 20); 4269 if (Rd == 15 || Rn == 15 || Rm == 15) 4270 return false; 4271 break; 4272 default: 4273 return false; 4274 } 4275 4276 // Get the first operand. 4277 uint32_t value = ReadCoreReg(Rn, &success); 4278 if (!success) 4279 return false; 4280 // Get the Rm register content. 4281 uint32_t val = ReadCoreReg(Rm, &success); 4282 if (!success) 4283 return false; 4284 4285 // Get the shift amount. 4286 uint32_t amt = Bits32(val, 7, 0); 4287 4288 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 4289 if (!success) 4290 return false; 4291 4292 // The context specifies that an immediate is to be moved into Rd. 4293 EmulateInstruction::Context context; 4294 context.type = EmulateInstruction::eContextImmediate; 4295 context.SetNoArgs(); 4296 4297 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 4298 return false; 4299 } 4300 return true; 4301 } 4302 4303 // LDM loads multiple registers from consecutive memory locations, using an 4304 // address from a base register. Optionally the address just above the highest 4305 // of those locations 4306 // can be written back to the base register. 4307 bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode, 4308 const ARMEncoding encoding) { 4309 #if 0 4310 // ARM pseudo code... 4311 if ConditionPassed() 4312 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 4313 address = R[n]; 4314 4315 for i = 0 to 14 4316 if registers<i> == '1' then 4317 R[i] = MemA[address, 4]; address = address + 4; 4318 if registers<15> == '1' then 4319 LoadWritePC (MemA[address, 4]); 4320 4321 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 4322 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 4323 4324 #endif 4325 4326 bool success = false; 4327 if (ConditionPassed(opcode)) { 4328 uint32_t n; 4329 uint32_t registers = 0; 4330 bool wback; 4331 const uint32_t addr_byte_size = GetAddressByteSize(); 4332 switch (encoding) { 4333 case eEncodingT1: 4334 // n = UInt(Rn); registers = '00000000':register_list; wback = 4335 // (registers<n> == '0'); 4336 n = Bits32(opcode, 10, 8); 4337 registers = Bits32(opcode, 7, 0); 4338 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4339 wback = BitIsClear(registers, n); 4340 // if BitCount(registers) < 1 then UNPREDICTABLE; 4341 if (BitCount(registers) < 1) 4342 return false; 4343 break; 4344 case eEncodingT2: 4345 // if W == '1' && Rn == '1101' then SEE POP; 4346 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 4347 n = Bits32(opcode, 19, 16); 4348 registers = Bits32(opcode, 15, 0); 4349 registers = registers & 0xdfff; // Make sure bit 13 is zero. 4350 wback = BitIsSet(opcode, 21); 4351 4352 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 4353 // UNPREDICTABLE; 4354 if ((n == 15) || (BitCount(registers) < 2) || 4355 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 4356 return false; 4357 4358 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 4359 // UNPREDICTABLE; 4360 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 4361 return false; 4362 4363 // if wback && registers<n> == '1' then UNPREDICTABLE; 4364 if (wback && BitIsSet(registers, n)) 4365 return false; 4366 break; 4367 4368 case eEncodingA1: 4369 n = Bits32(opcode, 19, 16); 4370 registers = Bits32(opcode, 15, 0); 4371 wback = BitIsSet(opcode, 21); 4372 if ((n == 15) || (BitCount(registers) < 1)) 4373 return false; 4374 break; 4375 default: 4376 return false; 4377 } 4378 4379 int32_t offset = 0; 4380 const addr_t base_address = 4381 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4382 if (!success) 4383 return false; 4384 4385 EmulateInstruction::Context context; 4386 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4387 RegisterInfo dwarf_reg; 4388 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4389 context.SetRegisterPlusOffset(dwarf_reg, offset); 4390 4391 for (int i = 0; i < 14; ++i) { 4392 if (BitIsSet(registers, i)) { 4393 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4394 context.SetRegisterPlusOffset(dwarf_reg, offset); 4395 if (wback && (n == 13)) // Pop Instruction 4396 { 4397 context.type = EmulateInstruction::eContextPopRegisterOffStack; 4398 context.SetAddress(base_address + offset); 4399 } 4400 4401 // R[i] = MemA [address, 4]; address = address + 4; 4402 uint32_t data = MemARead(context, base_address + offset, addr_byte_size, 4403 0, &success); 4404 if (!success) 4405 return false; 4406 4407 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4408 data)) 4409 return false; 4410 4411 offset += addr_byte_size; 4412 } 4413 } 4414 4415 if (BitIsSet(registers, 15)) { 4416 // LoadWritePC (MemA [address, 4]); 4417 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4418 context.SetRegisterPlusOffset(dwarf_reg, offset); 4419 uint32_t data = 4420 MemARead(context, base_address + offset, addr_byte_size, 0, &success); 4421 if (!success) 4422 return false; 4423 // In ARMv5T and above, this is an interworking branch. 4424 if (!LoadWritePC(context, data)) 4425 return false; 4426 } 4427 4428 if (wback && BitIsClear(registers, n)) { 4429 // R[n] = R[n] + 4 * BitCount (registers) 4430 int32_t offset = addr_byte_size * BitCount(registers); 4431 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4432 context.SetRegisterPlusOffset(dwarf_reg, offset); 4433 4434 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4435 base_address + offset)) 4436 return false; 4437 } 4438 if (wback && BitIsSet(registers, n)) 4439 // R[n] bits(32) UNKNOWN; 4440 return WriteBits32Unknown(n); 4441 } 4442 return true; 4443 } 4444 4445 // LDMDA loads multiple registers from consecutive memory locations using an 4446 // address from a base register. 4447 // The consecutive memory locations end at this address and the address just 4448 // below the lowest of those locations 4449 // can optionally be written back to the base register. 4450 bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode, 4451 const ARMEncoding encoding) { 4452 #if 0 4453 // ARM pseudo code... 4454 if ConditionPassed() then 4455 EncodingSpecificOperations(); 4456 address = R[n] - 4*BitCount(registers) + 4; 4457 4458 for i = 0 to 14 4459 if registers<i> == '1' then 4460 R[i] = MemA[address,4]; address = address + 4; 4461 4462 if registers<15> == '1' then 4463 LoadWritePC(MemA[address,4]); 4464 4465 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4466 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4467 #endif 4468 4469 bool success = false; 4470 4471 if (ConditionPassed(opcode)) { 4472 uint32_t n; 4473 uint32_t registers = 0; 4474 bool wback; 4475 const uint32_t addr_byte_size = GetAddressByteSize(); 4476 4477 // EncodingSpecificOperations(); 4478 switch (encoding) { 4479 case eEncodingA1: 4480 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4481 n = Bits32(opcode, 19, 16); 4482 registers = Bits32(opcode, 15, 0); 4483 wback = BitIsSet(opcode, 21); 4484 4485 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4486 if ((n == 15) || (BitCount(registers) < 1)) 4487 return false; 4488 4489 break; 4490 4491 default: 4492 return false; 4493 } 4494 // address = R[n] - 4*BitCount(registers) + 4; 4495 4496 int32_t offset = 0; 4497 addr_t Rn = ReadCoreReg(n, &success); 4498 4499 if (!success) 4500 return false; 4501 4502 addr_t address = 4503 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size; 4504 4505 EmulateInstruction::Context context; 4506 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4507 RegisterInfo dwarf_reg; 4508 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4509 context.SetRegisterPlusOffset(dwarf_reg, offset); 4510 4511 // for i = 0 to 14 4512 for (int i = 0; i < 14; ++i) { 4513 // if registers<i> == '1' then 4514 if (BitIsSet(registers, i)) { 4515 // R[i] = MemA[address,4]; address = address + 4; 4516 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4517 uint32_t data = 4518 MemARead(context, address + offset, addr_byte_size, 0, &success); 4519 if (!success) 4520 return false; 4521 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4522 data)) 4523 return false; 4524 offset += addr_byte_size; 4525 } 4526 } 4527 4528 // if registers<15> == '1' then 4529 // LoadWritePC(MemA[address,4]); 4530 if (BitIsSet(registers, 15)) { 4531 context.SetRegisterPlusOffset(dwarf_reg, offset); 4532 uint32_t data = 4533 MemARead(context, address + offset, addr_byte_size, 0, &success); 4534 if (!success) 4535 return false; 4536 // In ARMv5T and above, this is an interworking branch. 4537 if (!LoadWritePC(context, data)) 4538 return false; 4539 } 4540 4541 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4542 if (wback && BitIsClear(registers, n)) { 4543 if (!success) 4544 return false; 4545 4546 offset = (addr_byte_size * BitCount(registers)) * -1; 4547 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4548 context.SetImmediateSigned(offset); 4549 addr_t addr = Rn + offset; 4550 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4551 addr)) 4552 return false; 4553 } 4554 4555 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4556 if (wback && BitIsSet(registers, n)) 4557 return WriteBits32Unknown(n); 4558 } 4559 return true; 4560 } 4561 4562 // LDMDB loads multiple registers from consecutive memory locations using an 4563 // address from a base register. The 4564 // consecutive memory locations end just below this address, and the address of 4565 // the lowest of those locations can 4566 // be optionally written back to the base register. 4567 bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode, 4568 const ARMEncoding encoding) { 4569 #if 0 4570 // ARM pseudo code... 4571 if ConditionPassed() then 4572 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4573 address = R[n] - 4*BitCount(registers); 4574 4575 for i = 0 to 14 4576 if registers<i> == '1' then 4577 R[i] = MemA[address,4]; address = address + 4; 4578 if registers<15> == '1' then 4579 LoadWritePC(MemA[address,4]); 4580 4581 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4582 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 4583 #endif 4584 4585 bool success = false; 4586 4587 if (ConditionPassed(opcode)) { 4588 uint32_t n; 4589 uint32_t registers = 0; 4590 bool wback; 4591 const uint32_t addr_byte_size = GetAddressByteSize(); 4592 switch (encoding) { 4593 case eEncodingT1: 4594 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 4595 n = Bits32(opcode, 19, 16); 4596 registers = Bits32(opcode, 15, 0); 4597 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 4598 wback = BitIsSet(opcode, 21); 4599 4600 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 4601 // UNPREDICTABLE; 4602 if ((n == 15) || (BitCount(registers) < 2) || 4603 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 4604 return false; 4605 4606 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 4607 // UNPREDICTABLE; 4608 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 4609 return false; 4610 4611 // if wback && registers<n> == '1' then UNPREDICTABLE; 4612 if (wback && BitIsSet(registers, n)) 4613 return false; 4614 4615 break; 4616 4617 case eEncodingA1: 4618 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4619 n = Bits32(opcode, 19, 16); 4620 registers = Bits32(opcode, 15, 0); 4621 wback = BitIsSet(opcode, 21); 4622 4623 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4624 if ((n == 15) || (BitCount(registers) < 1)) 4625 return false; 4626 4627 break; 4628 4629 default: 4630 return false; 4631 } 4632 4633 // address = R[n] - 4*BitCount(registers); 4634 4635 int32_t offset = 0; 4636 addr_t Rn = 4637 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4638 4639 if (!success) 4640 return false; 4641 4642 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4643 EmulateInstruction::Context context; 4644 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4645 RegisterInfo dwarf_reg; 4646 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4647 context.SetRegisterPlusOffset(dwarf_reg, Rn - address); 4648 4649 for (int i = 0; i < 14; ++i) { 4650 if (BitIsSet(registers, i)) { 4651 // R[i] = MemA[address,4]; address = address + 4; 4652 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4653 uint32_t data = 4654 MemARead(context, address + offset, addr_byte_size, 0, &success); 4655 if (!success) 4656 return false; 4657 4658 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4659 data)) 4660 return false; 4661 4662 offset += addr_byte_size; 4663 } 4664 } 4665 4666 // if registers<15> == '1' then 4667 // LoadWritePC(MemA[address,4]); 4668 if (BitIsSet(registers, 15)) { 4669 context.SetRegisterPlusOffset(dwarf_reg, offset); 4670 uint32_t data = 4671 MemARead(context, address + offset, addr_byte_size, 0, &success); 4672 if (!success) 4673 return false; 4674 // In ARMv5T and above, this is an interworking branch. 4675 if (!LoadWritePC(context, data)) 4676 return false; 4677 } 4678 4679 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4680 if (wback && BitIsClear(registers, n)) { 4681 if (!success) 4682 return false; 4683 4684 offset = (addr_byte_size * BitCount(registers)) * -1; 4685 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4686 context.SetImmediateSigned(offset); 4687 addr_t addr = Rn + offset; 4688 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4689 addr)) 4690 return false; 4691 } 4692 4693 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4694 // possible for encoding A1 4695 if (wback && BitIsSet(registers, n)) 4696 return WriteBits32Unknown(n); 4697 } 4698 return true; 4699 } 4700 4701 // LDMIB loads multiple registers from consecutive memory locations using an 4702 // address from a base register. The 4703 // consecutive memory locations start just above this address, and thea ddress 4704 // of the last of those locations can 4705 // optinoally be written back to the base register. 4706 bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode, 4707 const ARMEncoding encoding) { 4708 #if 0 4709 if ConditionPassed() then 4710 EncodingSpecificOperations(); 4711 address = R[n] + 4; 4712 4713 for i = 0 to 14 4714 if registers<i> == '1' then 4715 R[i] = MemA[address,4]; address = address + 4; 4716 if registers<15> == '1' then 4717 LoadWritePC(MemA[address,4]); 4718 4719 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4720 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4721 #endif 4722 4723 bool success = false; 4724 4725 if (ConditionPassed(opcode)) { 4726 uint32_t n; 4727 uint32_t registers = 0; 4728 bool wback; 4729 const uint32_t addr_byte_size = GetAddressByteSize(); 4730 switch (encoding) { 4731 case eEncodingA1: 4732 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4733 n = Bits32(opcode, 19, 16); 4734 registers = Bits32(opcode, 15, 0); 4735 wback = BitIsSet(opcode, 21); 4736 4737 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4738 if ((n == 15) || (BitCount(registers) < 1)) 4739 return false; 4740 4741 break; 4742 default: 4743 return false; 4744 } 4745 // address = R[n] + 4; 4746 4747 int32_t offset = 0; 4748 addr_t Rn = 4749 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4750 4751 if (!success) 4752 return false; 4753 4754 addr_t address = Rn + addr_byte_size; 4755 4756 EmulateInstruction::Context context; 4757 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4758 RegisterInfo dwarf_reg; 4759 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4760 context.SetRegisterPlusOffset(dwarf_reg, offset); 4761 4762 for (int i = 0; i < 14; ++i) { 4763 if (BitIsSet(registers, i)) { 4764 // R[i] = MemA[address,4]; address = address + 4; 4765 4766 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size); 4767 uint32_t data = 4768 MemARead(context, address + offset, addr_byte_size, 0, &success); 4769 if (!success) 4770 return false; 4771 4772 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4773 data)) 4774 return false; 4775 4776 offset += addr_byte_size; 4777 } 4778 } 4779 4780 // if registers<15> == '1' then 4781 // LoadWritePC(MemA[address,4]); 4782 if (BitIsSet(registers, 15)) { 4783 context.SetRegisterPlusOffset(dwarf_reg, offset); 4784 uint32_t data = 4785 MemARead(context, address + offset, addr_byte_size, 0, &success); 4786 if (!success) 4787 return false; 4788 // In ARMv5T and above, this is an interworking branch. 4789 if (!LoadWritePC(context, data)) 4790 return false; 4791 } 4792 4793 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4794 if (wback && BitIsClear(registers, n)) { 4795 if (!success) 4796 return false; 4797 4798 offset = addr_byte_size * BitCount(registers); 4799 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4800 context.SetImmediateSigned(offset); 4801 addr_t addr = Rn + offset; 4802 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4803 addr)) 4804 return false; 4805 } 4806 4807 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4808 // possible for encoding A1 4809 if (wback && BitIsSet(registers, n)) 4810 return WriteBits32Unknown(n); 4811 } 4812 return true; 4813 } 4814 4815 // Load Register (immediate) calculates an address from a base register value 4816 // and 4817 // an immediate offset, loads a word from memory, and writes to a register. 4818 // LDR (immediate, Thumb) 4819 bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode, 4820 const ARMEncoding encoding) { 4821 #if 0 4822 // ARM pseudo code... 4823 if (ConditionPassed()) 4824 { 4825 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 4826 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4827 address = if index then offset_addr else R[n]; 4828 data = MemU[address,4]; 4829 if wback then R[n] = offset_addr; 4830 if t == 15 then 4831 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 4832 elsif UnalignedSupport() || address<1:0> = '00' then 4833 R[t] = data; 4834 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 4835 } 4836 #endif 4837 4838 bool success = false; 4839 4840 if (ConditionPassed(opcode)) { 4841 uint32_t Rt; // the destination register 4842 uint32_t Rn; // the base register 4843 uint32_t imm32; // the immediate offset used to form the address 4844 addr_t offset_addr; // the offset address 4845 addr_t address; // the calculated address 4846 uint32_t data; // the literal data value from memory load 4847 bool add, index, wback; 4848 switch (encoding) { 4849 case eEncodingT1: 4850 Rt = Bits32(opcode, 2, 0); 4851 Rn = Bits32(opcode, 5, 3); 4852 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 4853 // index = TRUE; add = TRUE; wback = FALSE 4854 add = true; 4855 index = true; 4856 wback = false; 4857 4858 break; 4859 4860 case eEncodingT2: 4861 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4862 Rt = Bits32(opcode, 10, 8); 4863 Rn = 13; 4864 imm32 = Bits32(opcode, 7, 0) << 2; 4865 4866 // index = TRUE; add = TRUE; wback = FALSE; 4867 index = true; 4868 add = true; 4869 wback = false; 4870 4871 break; 4872 4873 case eEncodingT3: 4874 // if Rn == '1111' then SEE LDR (literal); 4875 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4876 Rt = Bits32(opcode, 15, 12); 4877 Rn = Bits32(opcode, 19, 16); 4878 imm32 = Bits32(opcode, 11, 0); 4879 4880 // index = TRUE; add = TRUE; wback = FALSE; 4881 index = true; 4882 add = true; 4883 wback = false; 4884 4885 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4886 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4887 return false; 4888 4889 break; 4890 4891 case eEncodingT4: 4892 // if Rn == '1111' then SEE LDR (literal); 4893 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4894 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == 4895 // '00000100' then SEE POP; 4896 // if P == '0' && W == '0' then UNDEFINED; 4897 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 4898 return false; 4899 4900 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4901 Rt = Bits32(opcode, 15, 12); 4902 Rn = Bits32(opcode, 19, 16); 4903 imm32 = Bits32(opcode, 7, 0); 4904 4905 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4906 index = BitIsSet(opcode, 10); 4907 add = BitIsSet(opcode, 9); 4908 wback = BitIsSet(opcode, 8); 4909 4910 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) 4911 // then UNPREDICTABLE; 4912 if ((wback && (Rn == Rt)) || 4913 ((Rt == 15) && InITBlock() && !LastInITBlock())) 4914 return false; 4915 4916 break; 4917 4918 default: 4919 return false; 4920 } 4921 uint32_t base = ReadCoreReg(Rn, &success); 4922 if (!success) 4923 return false; 4924 if (add) 4925 offset_addr = base + imm32; 4926 else 4927 offset_addr = base - imm32; 4928 4929 address = (index ? offset_addr : base); 4930 4931 RegisterInfo base_reg; 4932 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4933 if (wback) { 4934 EmulateInstruction::Context ctx; 4935 if (Rn == 13) { 4936 ctx.type = eContextAdjustStackPointer; 4937 ctx.SetImmediateSigned((int32_t)(offset_addr - base)); 4938 } else if (Rn == GetFramePointerRegisterNumber()) { 4939 ctx.type = eContextSetFramePointer; 4940 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4941 } else { 4942 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4943 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4944 } 4945 4946 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn, 4947 offset_addr)) 4948 return false; 4949 } 4950 4951 // Prepare to write to the Rt register. 4952 EmulateInstruction::Context context; 4953 context.type = EmulateInstruction::eContextRegisterLoad; 4954 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4955 4956 // Read memory from the address. 4957 data = MemURead(context, address, 4, 0, &success); 4958 if (!success) 4959 return false; 4960 4961 if (Rt == 15) { 4962 if (Bits32(address, 1, 0) == 0) { 4963 if (!LoadWritePC(context, data)) 4964 return false; 4965 } else 4966 return false; 4967 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 4968 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 4969 data)) 4970 return false; 4971 } else 4972 WriteBits32Unknown(Rt); 4973 } 4974 return true; 4975 } 4976 4977 // STM (Store Multiple Increment After) stores multiple registers to consecutive 4978 // memory locations using an address 4979 // from a base register. The consecutive memory locations start at this 4980 // address, and the address just above the last 4981 // of those locations can optionally be written back to the base register. 4982 bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode, 4983 const ARMEncoding encoding) { 4984 #if 0 4985 if ConditionPassed() then 4986 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4987 address = R[n]; 4988 4989 for i = 0 to 14 4990 if registers<i> == '1' then 4991 if i == n && wback && i != LowestSetBit(registers) then 4992 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4993 else 4994 MemA[address,4] = R[i]; 4995 address = address + 4; 4996 4997 if registers<15> == '1' then // Only possible for encoding A1 4998 MemA[address,4] = PCStoreValue(); 4999 if wback then R[n] = R[n] + 4*BitCount(registers); 5000 #endif 5001 5002 bool success = false; 5003 5004 if (ConditionPassed(opcode)) { 5005 uint32_t n; 5006 uint32_t registers = 0; 5007 bool wback; 5008 const uint32_t addr_byte_size = GetAddressByteSize(); 5009 5010 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5011 switch (encoding) { 5012 case eEncodingT1: 5013 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 5014 n = Bits32(opcode, 10, 8); 5015 registers = Bits32(opcode, 7, 0); 5016 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 5017 wback = true; 5018 5019 // if BitCount(registers) < 1 then UNPREDICTABLE; 5020 if (BitCount(registers) < 1) 5021 return false; 5022 5023 break; 5024 5025 case eEncodingT2: 5026 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 5027 n = Bits32(opcode, 19, 16); 5028 registers = Bits32(opcode, 15, 0); 5029 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 5030 wback = BitIsSet(opcode, 21); 5031 5032 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 5033 if ((n == 15) || (BitCount(registers) < 2)) 5034 return false; 5035 5036 // if wback && registers<n> == '1' then UNPREDICTABLE; 5037 if (wback && BitIsSet(registers, n)) 5038 return false; 5039 5040 break; 5041 5042 case eEncodingA1: 5043 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 5044 n = Bits32(opcode, 19, 16); 5045 registers = Bits32(opcode, 15, 0); 5046 wback = BitIsSet(opcode, 21); 5047 5048 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 5049 if ((n == 15) || (BitCount(registers) < 1)) 5050 return false; 5051 5052 break; 5053 5054 default: 5055 return false; 5056 } 5057 5058 // address = R[n]; 5059 int32_t offset = 0; 5060 const addr_t address = 5061 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5062 if (!success) 5063 return false; 5064 5065 EmulateInstruction::Context context; 5066 context.type = EmulateInstruction::eContextRegisterStore; 5067 RegisterInfo base_reg; 5068 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5069 5070 // for i = 0 to 14 5071 uint32_t lowest_set_bit = 14; 5072 for (uint32_t i = 0; i < 14; ++i) { 5073 // if registers<i> == '1' then 5074 if (BitIsSet(registers, i)) { 5075 if (i < lowest_set_bit) 5076 lowest_set_bit = i; 5077 // if i == n && wback && i != LowestSetBit(registers) then 5078 if ((i == n) && wback && (i != lowest_set_bit)) 5079 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings 5080 // T1 and A1 5081 WriteBits32UnknownToMemory(address + offset); 5082 else { 5083 // MemA[address,4] = R[i]; 5084 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5085 0, &success); 5086 if (!success) 5087 return false; 5088 5089 RegisterInfo data_reg; 5090 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5091 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 5092 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5093 return false; 5094 } 5095 5096 // address = address + 4; 5097 offset += addr_byte_size; 5098 } 5099 } 5100 5101 // if registers<15> == '1' then // Only possible for encoding A1 5102 // MemA[address,4] = PCStoreValue(); 5103 if (BitIsSet(registers, 15)) { 5104 RegisterInfo pc_reg; 5105 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5106 context.SetRegisterPlusOffset(pc_reg, 8); 5107 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5108 if (!success) 5109 return false; 5110 5111 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5112 return false; 5113 } 5114 5115 // if wback then R[n] = R[n] + 4*BitCount(registers); 5116 if (wback) { 5117 offset = addr_byte_size * BitCount(registers); 5118 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5119 context.SetImmediateSigned(offset); 5120 addr_t data = address + offset; 5121 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5122 data)) 5123 return false; 5124 } 5125 } 5126 return true; 5127 } 5128 5129 // STMDA (Store Multiple Decrement After) stores multiple registers to 5130 // consecutive memory locations using an address 5131 // from a base register. The consecutive memory locations end at this address, 5132 // and the address just below the lowest 5133 // of those locations can optionally be written back to the base register. 5134 bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode, 5135 const ARMEncoding encoding) { 5136 #if 0 5137 if ConditionPassed() then 5138 EncodingSpecificOperations(); 5139 address = R[n] - 4*BitCount(registers) + 4; 5140 5141 for i = 0 to 14 5142 if registers<i> == '1' then 5143 if i == n && wback && i != LowestSetBit(registers) then 5144 MemA[address,4] = bits(32) UNKNOWN; 5145 else 5146 MemA[address,4] = R[i]; 5147 address = address + 4; 5148 5149 if registers<15> == '1' then 5150 MemA[address,4] = PCStoreValue(); 5151 5152 if wback then R[n] = R[n] - 4*BitCount(registers); 5153 #endif 5154 5155 bool success = false; 5156 5157 if (ConditionPassed(opcode)) { 5158 uint32_t n; 5159 uint32_t registers = 0; 5160 bool wback; 5161 const uint32_t addr_byte_size = GetAddressByteSize(); 5162 5163 // EncodingSpecificOperations(); 5164 switch (encoding) { 5165 case eEncodingA1: 5166 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 5167 n = Bits32(opcode, 19, 16); 5168 registers = Bits32(opcode, 15, 0); 5169 wback = BitIsSet(opcode, 21); 5170 5171 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 5172 if ((n == 15) || (BitCount(registers) < 1)) 5173 return false; 5174 break; 5175 default: 5176 return false; 5177 } 5178 5179 // address = R[n] - 4*BitCount(registers) + 4; 5180 int32_t offset = 0; 5181 addr_t Rn = ReadCoreReg(n, &success); 5182 if (!success) 5183 return false; 5184 5185 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4; 5186 5187 EmulateInstruction::Context context; 5188 context.type = EmulateInstruction::eContextRegisterStore; 5189 RegisterInfo base_reg; 5190 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5191 5192 // for i = 0 to 14 5193 uint32_t lowest_bit_set = 14; 5194 for (uint32_t i = 0; i < 14; ++i) { 5195 // if registers<i> == '1' then 5196 if (BitIsSet(registers, i)) { 5197 if (i < lowest_bit_set) 5198 lowest_bit_set = i; 5199 // if i == n && wback && i != LowestSetBit(registers) then 5200 if ((i == n) && wback && (i != lowest_bit_set)) 5201 // MemA[address,4] = bits(32) UNKNOWN; 5202 WriteBits32UnknownToMemory(address + offset); 5203 else { 5204 // MemA[address,4] = R[i]; 5205 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5206 0, &success); 5207 if (!success) 5208 return false; 5209 5210 RegisterInfo data_reg; 5211 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5212 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5213 Rn - (address + offset)); 5214 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5215 return false; 5216 } 5217 5218 // address = address + 4; 5219 offset += addr_byte_size; 5220 } 5221 } 5222 5223 // if registers<15> == '1' then 5224 // MemA[address,4] = PCStoreValue(); 5225 if (BitIsSet(registers, 15)) { 5226 RegisterInfo pc_reg; 5227 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5228 context.SetRegisterPlusOffset(pc_reg, 8); 5229 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5230 if (!success) 5231 return false; 5232 5233 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5234 return false; 5235 } 5236 5237 // if wback then R[n] = R[n] - 4*BitCount(registers); 5238 if (wback) { 5239 offset = (addr_byte_size * BitCount(registers)) * -1; 5240 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5241 context.SetImmediateSigned(offset); 5242 addr_t data = Rn + offset; 5243 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5244 data)) 5245 return false; 5246 } 5247 } 5248 return true; 5249 } 5250 5251 // STMDB (Store Multiple Decrement Before) stores multiple registers to 5252 // consecutive memory locations using an address 5253 // from a base register. The consecutive memory locations end just below this 5254 // address, and the address of the first of 5255 // those locations can optionally be written back to the base register. 5256 bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode, 5257 const ARMEncoding encoding) { 5258 #if 0 5259 if ConditionPassed() then 5260 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5261 address = R[n] - 4*BitCount(registers); 5262 5263 for i = 0 to 14 5264 if registers<i> == '1' then 5265 if i == n && wback && i != LowestSetBit(registers) then 5266 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 5267 else 5268 MemA[address,4] = R[i]; 5269 address = address + 4; 5270 5271 if registers<15> == '1' then // Only possible for encoding A1 5272 MemA[address,4] = PCStoreValue(); 5273 5274 if wback then R[n] = R[n] - 4*BitCount(registers); 5275 #endif 5276 5277 bool success = false; 5278 5279 if (ConditionPassed(opcode)) { 5280 uint32_t n; 5281 uint32_t registers = 0; 5282 bool wback; 5283 const uint32_t addr_byte_size = GetAddressByteSize(); 5284 5285 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5286 switch (encoding) { 5287 case eEncodingT1: 5288 // if W == '1' && Rn == '1101' then SEE PUSH; 5289 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) { 5290 // See PUSH 5291 } 5292 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 5293 n = Bits32(opcode, 19, 16); 5294 registers = Bits32(opcode, 15, 0); 5295 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 5296 wback = BitIsSet(opcode, 21); 5297 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 5298 if ((n == 15) || BitCount(registers) < 2) 5299 return false; 5300 // if wback && registers<n> == '1' then UNPREDICTABLE; 5301 if (wback && BitIsSet(registers, n)) 5302 return false; 5303 break; 5304 5305 case eEncodingA1: 5306 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE 5307 // PUSH; 5308 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) && 5309 BitCount(Bits32(opcode, 15, 0)) >= 2) { 5310 // See Push 5311 } 5312 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 5313 n = Bits32(opcode, 19, 16); 5314 registers = Bits32(opcode, 15, 0); 5315 wback = BitIsSet(opcode, 21); 5316 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 5317 if ((n == 15) || BitCount(registers) < 1) 5318 return false; 5319 break; 5320 5321 default: 5322 return false; 5323 } 5324 5325 // address = R[n] - 4*BitCount(registers); 5326 5327 int32_t offset = 0; 5328 addr_t Rn = 5329 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5330 if (!success) 5331 return false; 5332 5333 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 5334 5335 EmulateInstruction::Context context; 5336 context.type = EmulateInstruction::eContextRegisterStore; 5337 RegisterInfo base_reg; 5338 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5339 5340 // for i = 0 to 14 5341 uint32_t lowest_set_bit = 14; 5342 for (uint32_t i = 0; i < 14; ++i) { 5343 // if registers<i> == '1' then 5344 if (BitIsSet(registers, i)) { 5345 if (i < lowest_set_bit) 5346 lowest_set_bit = i; 5347 // if i == n && wback && i != LowestSetBit(registers) then 5348 if ((i == n) && wback && (i != lowest_set_bit)) 5349 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding 5350 // A1 5351 WriteBits32UnknownToMemory(address + offset); 5352 else { 5353 // MemA[address,4] = R[i]; 5354 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5355 0, &success); 5356 if (!success) 5357 return false; 5358 5359 RegisterInfo data_reg; 5360 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5361 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5362 Rn - (address + offset)); 5363 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5364 return false; 5365 } 5366 5367 // address = address + 4; 5368 offset += addr_byte_size; 5369 } 5370 } 5371 5372 // if registers<15> == '1' then // Only possible for encoding A1 5373 // MemA[address,4] = PCStoreValue(); 5374 if (BitIsSet(registers, 15)) { 5375 RegisterInfo pc_reg; 5376 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5377 context.SetRegisterPlusOffset(pc_reg, 8); 5378 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5379 if (!success) 5380 return false; 5381 5382 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5383 return false; 5384 } 5385 5386 // if wback then R[n] = R[n] - 4*BitCount(registers); 5387 if (wback) { 5388 offset = (addr_byte_size * BitCount(registers)) * -1; 5389 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5390 context.SetImmediateSigned(offset); 5391 addr_t data = Rn + offset; 5392 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5393 data)) 5394 return false; 5395 } 5396 } 5397 return true; 5398 } 5399 5400 // STMIB (Store Multiple Increment Before) stores multiple registers to 5401 // consecutive memory locations using an address 5402 // from a base register. The consecutive memory locations start just above this 5403 // address, and the address of the last 5404 // of those locations can optionally be written back to the base register. 5405 bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode, 5406 const ARMEncoding encoding) { 5407 #if 0 5408 if ConditionPassed() then 5409 EncodingSpecificOperations(); 5410 address = R[n] + 4; 5411 5412 for i = 0 to 14 5413 if registers<i> == '1' then 5414 if i == n && wback && i != LowestSetBit(registers) then 5415 MemA[address,4] = bits(32) UNKNOWN; 5416 else 5417 MemA[address,4] = R[i]; 5418 address = address + 4; 5419 5420 if registers<15> == '1' then 5421 MemA[address,4] = PCStoreValue(); 5422 5423 if wback then R[n] = R[n] + 4*BitCount(registers); 5424 #endif 5425 5426 bool success = false; 5427 5428 if (ConditionPassed(opcode)) { 5429 uint32_t n; 5430 uint32_t registers = 0; 5431 bool wback; 5432 const uint32_t addr_byte_size = GetAddressByteSize(); 5433 5434 // EncodingSpecificOperations(); 5435 switch (encoding) { 5436 case eEncodingA1: 5437 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 5438 n = Bits32(opcode, 19, 16); 5439 registers = Bits32(opcode, 15, 0); 5440 wback = BitIsSet(opcode, 21); 5441 5442 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 5443 if ((n == 15) && (BitCount(registers) < 1)) 5444 return false; 5445 break; 5446 default: 5447 return false; 5448 } 5449 // address = R[n] + 4; 5450 5451 int32_t offset = 0; 5452 addr_t Rn = ReadCoreReg(n, &success); 5453 if (!success) 5454 return false; 5455 5456 addr_t address = Rn + addr_byte_size; 5457 5458 EmulateInstruction::Context context; 5459 context.type = EmulateInstruction::eContextRegisterStore; 5460 RegisterInfo base_reg; 5461 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5462 5463 uint32_t lowest_set_bit = 14; 5464 // for i = 0 to 14 5465 for (uint32_t i = 0; i < 14; ++i) { 5466 // if registers<i> == '1' then 5467 if (BitIsSet(registers, i)) { 5468 if (i < lowest_set_bit) 5469 lowest_set_bit = i; 5470 // if i == n && wback && i != LowestSetBit(registers) then 5471 if ((i == n) && wback && (i != lowest_set_bit)) 5472 // MemA[address,4] = bits(32) UNKNOWN; 5473 WriteBits32UnknownToMemory(address + offset); 5474 // else 5475 else { 5476 // MemA[address,4] = R[i]; 5477 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5478 0, &success); 5479 if (!success) 5480 return false; 5481 5482 RegisterInfo data_reg; 5483 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5484 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5485 offset + addr_byte_size); 5486 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5487 return false; 5488 } 5489 5490 // address = address + 4; 5491 offset += addr_byte_size; 5492 } 5493 } 5494 5495 // if registers<15> == '1' then 5496 // MemA[address,4] = PCStoreValue(); 5497 if (BitIsSet(registers, 15)) { 5498 RegisterInfo pc_reg; 5499 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5500 context.SetRegisterPlusOffset(pc_reg, 8); 5501 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5502 if (!success) 5503 return false; 5504 5505 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5506 return false; 5507 } 5508 5509 // if wback then R[n] = R[n] + 4*BitCount(registers); 5510 if (wback) { 5511 offset = addr_byte_size * BitCount(registers); 5512 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5513 context.SetImmediateSigned(offset); 5514 addr_t data = Rn + offset; 5515 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5516 data)) 5517 return false; 5518 } 5519 } 5520 return true; 5521 } 5522 5523 // STR (store immediate) calculates an address from a base register value and an 5524 // immediate offset, and stores a word 5525 // from a register to memory. It can use offset, post-indexed, or pre-indexed 5526 // addressing. 5527 bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode, 5528 const ARMEncoding encoding) { 5529 #if 0 5530 if ConditionPassed() then 5531 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5532 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5533 address = if index then offset_addr else R[n]; 5534 if UnalignedSupport() || address<1:0> == '00' then 5535 MemU[address,4] = R[t]; 5536 else // Can only occur before ARMv7 5537 MemU[address,4] = bits(32) UNKNOWN; 5538 if wback then R[n] = offset_addr; 5539 #endif 5540 5541 bool success = false; 5542 5543 if (ConditionPassed(opcode)) { 5544 const uint32_t addr_byte_size = GetAddressByteSize(); 5545 5546 uint32_t t; 5547 uint32_t n; 5548 uint32_t imm32; 5549 bool index; 5550 bool add; 5551 bool wback; 5552 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5553 switch (encoding) { 5554 case eEncodingT1: 5555 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 5556 t = Bits32(opcode, 2, 0); 5557 n = Bits32(opcode, 5, 3); 5558 imm32 = Bits32(opcode, 10, 6) << 2; 5559 5560 // index = TRUE; add = TRUE; wback = FALSE; 5561 index = true; 5562 add = false; 5563 wback = false; 5564 break; 5565 5566 case eEncodingT2: 5567 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 5568 t = Bits32(opcode, 10, 8); 5569 n = 13; 5570 imm32 = Bits32(opcode, 7, 0) << 2; 5571 5572 // index = TRUE; add = TRUE; wback = FALSE; 5573 index = true; 5574 add = true; 5575 wback = false; 5576 break; 5577 5578 case eEncodingT3: 5579 // if Rn == '1111' then UNDEFINED; 5580 if (Bits32(opcode, 19, 16) == 15) 5581 return false; 5582 5583 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5584 t = Bits32(opcode, 15, 12); 5585 n = Bits32(opcode, 19, 16); 5586 imm32 = Bits32(opcode, 11, 0); 5587 5588 // index = TRUE; add = TRUE; wback = FALSE; 5589 index = true; 5590 add = true; 5591 wback = false; 5592 5593 // if t == 15 then UNPREDICTABLE; 5594 if (t == 15) 5595 return false; 5596 break; 5597 5598 case eEncodingT4: 5599 // if P == '1' && U == '1' && W == '0' then SEE STRT; 5600 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == 5601 // '00000100' then SEE PUSH; 5602 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5603 if ((Bits32(opcode, 19, 16) == 15) || 5604 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))) 5605 return false; 5606 5607 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5608 t = Bits32(opcode, 15, 12); 5609 n = Bits32(opcode, 19, 16); 5610 imm32 = Bits32(opcode, 7, 0); 5611 5612 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5613 index = BitIsSet(opcode, 10); 5614 add = BitIsSet(opcode, 9); 5615 wback = BitIsSet(opcode, 8); 5616 5617 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 5618 if ((t == 15) || (wback && (n == t))) 5619 return false; 5620 break; 5621 5622 default: 5623 return false; 5624 } 5625 5626 addr_t offset_addr; 5627 addr_t address; 5628 5629 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5630 uint32_t base_address = ReadCoreReg(n, &success); 5631 if (!success) 5632 return false; 5633 5634 if (add) 5635 offset_addr = base_address + imm32; 5636 else 5637 offset_addr = base_address - imm32; 5638 5639 // address = if index then offset_addr else R[n]; 5640 if (index) 5641 address = offset_addr; 5642 else 5643 address = base_address; 5644 5645 EmulateInstruction::Context context; 5646 if (n == 13) 5647 context.type = eContextPushRegisterOnStack; 5648 else 5649 context.type = eContextRegisterStore; 5650 5651 RegisterInfo base_reg; 5652 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5653 5654 // if UnalignedSupport() || address<1:0> == '00' then 5655 if (UnalignedSupport() || 5656 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 5657 // MemU[address,4] = R[t]; 5658 uint32_t data = 5659 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5660 if (!success) 5661 return false; 5662 5663 RegisterInfo data_reg; 5664 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5665 int32_t offset = address - base_address; 5666 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 5667 if (!MemUWrite(context, address, data, addr_byte_size)) 5668 return false; 5669 } else { 5670 // MemU[address,4] = bits(32) UNKNOWN; 5671 WriteBits32UnknownToMemory(address); 5672 } 5673 5674 // if wback then R[n] = offset_addr; 5675 if (wback) { 5676 if (n == 13) 5677 context.type = eContextAdjustStackPointer; 5678 else 5679 context.type = eContextAdjustBaseRegister; 5680 context.SetAddress(offset_addr); 5681 5682 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5683 offset_addr)) 5684 return false; 5685 } 5686 } 5687 return true; 5688 } 5689 5690 // STR (Store Register) calculates an address from a base register value and an 5691 // offset register value, stores a 5692 // word from a register to memory. The offset register value can optionally be 5693 // shifted. 5694 bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode, 5695 const ARMEncoding encoding) { 5696 #if 0 5697 if ConditionPassed() then 5698 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5699 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5700 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5701 address = if index then offset_addr else R[n]; 5702 if t == 15 then // Only possible for encoding A1 5703 data = PCStoreValue(); 5704 else 5705 data = R[t]; 5706 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 5707 MemU[address,4] = data; 5708 else // Can only occur before ARMv7 5709 MemU[address,4] = bits(32) UNKNOWN; 5710 if wback then R[n] = offset_addr; 5711 #endif 5712 5713 bool success = false; 5714 5715 if (ConditionPassed(opcode)) { 5716 const uint32_t addr_byte_size = GetAddressByteSize(); 5717 5718 uint32_t t; 5719 uint32_t n; 5720 uint32_t m; 5721 ARM_ShifterType shift_t; 5722 uint32_t shift_n; 5723 bool index; 5724 bool add; 5725 bool wback; 5726 5727 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5728 switch (encoding) { 5729 case eEncodingT1: 5730 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5731 // in ThumbEE"; 5732 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5733 t = Bits32(opcode, 2, 0); 5734 n = Bits32(opcode, 5, 3); 5735 m = Bits32(opcode, 8, 6); 5736 5737 // index = TRUE; add = TRUE; wback = FALSE; 5738 index = true; 5739 add = true; 5740 wback = false; 5741 5742 // (shift_t, shift_n) = (SRType_LSL, 0); 5743 shift_t = SRType_LSL; 5744 shift_n = 0; 5745 break; 5746 5747 case eEncodingT2: 5748 // if Rn == '1111' then UNDEFINED; 5749 if (Bits32(opcode, 19, 16) == 15) 5750 return false; 5751 5752 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5753 t = Bits32(opcode, 15, 12); 5754 n = Bits32(opcode, 19, 16); 5755 m = Bits32(opcode, 3, 0); 5756 5757 // index = TRUE; add = TRUE; wback = FALSE; 5758 index = true; 5759 add = true; 5760 wback = false; 5761 5762 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5763 shift_t = SRType_LSL; 5764 shift_n = Bits32(opcode, 5, 4); 5765 5766 // if t == 15 || BadReg(m) then UNPREDICTABLE; 5767 if ((t == 15) || (BadReg(m))) 5768 return false; 5769 break; 5770 5771 case eEncodingA1: { 5772 // if P == '0' && W == '1' then SEE STRT; 5773 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5774 t = Bits32(opcode, 15, 12); 5775 n = Bits32(opcode, 19, 16); 5776 m = Bits32(opcode, 3, 0); 5777 5778 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5779 // (W == '1'); 5780 index = BitIsSet(opcode, 24); 5781 add = BitIsSet(opcode, 23); 5782 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5783 5784 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5785 uint32_t typ = Bits32(opcode, 6, 5); 5786 uint32_t imm5 = Bits32(opcode, 11, 7); 5787 shift_n = DecodeImmShift(typ, imm5, shift_t); 5788 5789 // if m == 15 then UNPREDICTABLE; 5790 if (m == 15) 5791 return false; 5792 5793 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5794 if (wback && ((n == 15) || (n == t))) 5795 return false; 5796 5797 break; 5798 } 5799 default: 5800 return false; 5801 } 5802 5803 addr_t offset_addr; 5804 addr_t address; 5805 int32_t offset = 0; 5806 5807 addr_t base_address = 5808 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5809 if (!success) 5810 return false; 5811 5812 uint32_t Rm_data = 5813 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5814 if (!success) 5815 return false; 5816 5817 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5818 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success); 5819 if (!success) 5820 return false; 5821 5822 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5823 if (add) 5824 offset_addr = base_address + offset; 5825 else 5826 offset_addr = base_address - offset; 5827 5828 // address = if index then offset_addr else R[n]; 5829 if (index) 5830 address = offset_addr; 5831 else 5832 address = base_address; 5833 5834 uint32_t data; 5835 // if t == 15 then // Only possible for encoding A1 5836 if (t == 15) 5837 // data = PCStoreValue(); 5838 data = ReadCoreReg(PC_REG, &success); 5839 else 5840 // data = R[t]; 5841 data = 5842 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5843 5844 if (!success) 5845 return false; 5846 5847 EmulateInstruction::Context context; 5848 context.type = eContextRegisterStore; 5849 5850 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == 5851 // InstrSet_ARM then 5852 if (UnalignedSupport() || 5853 (BitIsClear(address, 1) && BitIsClear(address, 0)) || 5854 CurrentInstrSet() == eModeARM) { 5855 // MemU[address,4] = data; 5856 5857 RegisterInfo base_reg; 5858 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5859 5860 RegisterInfo data_reg; 5861 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5862 5863 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5864 address - base_address); 5865 if (!MemUWrite(context, address, data, addr_byte_size)) 5866 return false; 5867 5868 } else 5869 // MemU[address,4] = bits(32) UNKNOWN; 5870 WriteBits32UnknownToMemory(address); 5871 5872 // if wback then R[n] = offset_addr; 5873 if (wback) { 5874 context.type = eContextRegisterLoad; 5875 context.SetAddress(offset_addr); 5876 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5877 offset_addr)) 5878 return false; 5879 } 5880 } 5881 return true; 5882 } 5883 5884 bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode, 5885 const ARMEncoding encoding) { 5886 #if 0 5887 if ConditionPassed() then 5888 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5889 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5890 address = if index then offset_addr else R[n]; 5891 MemU[address,1] = R[t]<7:0>; 5892 if wback then R[n] = offset_addr; 5893 #endif 5894 5895 bool success = false; 5896 5897 if (ConditionPassed(opcode)) { 5898 uint32_t t; 5899 uint32_t n; 5900 uint32_t imm32; 5901 bool index; 5902 bool add; 5903 bool wback; 5904 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5905 switch (encoding) { 5906 case eEncodingT1: 5907 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5908 t = Bits32(opcode, 2, 0); 5909 n = Bits32(opcode, 5, 3); 5910 imm32 = Bits32(opcode, 10, 6); 5911 5912 // index = TRUE; add = TRUE; wback = FALSE; 5913 index = true; 5914 add = true; 5915 wback = false; 5916 break; 5917 5918 case eEncodingT2: 5919 // if Rn == '1111' then UNDEFINED; 5920 if (Bits32(opcode, 19, 16) == 15) 5921 return false; 5922 5923 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5924 t = Bits32(opcode, 15, 12); 5925 n = Bits32(opcode, 19, 16); 5926 imm32 = Bits32(opcode, 11, 0); 5927 5928 // index = TRUE; add = TRUE; wback = FALSE; 5929 index = true; 5930 add = true; 5931 wback = false; 5932 5933 // if BadReg(t) then UNPREDICTABLE; 5934 if (BadReg(t)) 5935 return false; 5936 break; 5937 5938 case eEncodingT3: 5939 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5940 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5941 if (Bits32(opcode, 19, 16) == 15) 5942 return false; 5943 5944 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5945 t = Bits32(opcode, 15, 12); 5946 n = Bits32(opcode, 19, 16); 5947 imm32 = Bits32(opcode, 7, 0); 5948 5949 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5950 index = BitIsSet(opcode, 10); 5951 add = BitIsSet(opcode, 9); 5952 wback = BitIsSet(opcode, 8); 5953 5954 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5955 if ((BadReg(t)) || (wback && (n == t))) 5956 return false; 5957 break; 5958 5959 default: 5960 return false; 5961 } 5962 5963 addr_t offset_addr; 5964 addr_t address; 5965 addr_t base_address = 5966 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5967 if (!success) 5968 return false; 5969 5970 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5971 if (add) 5972 offset_addr = base_address + imm32; 5973 else 5974 offset_addr = base_address - imm32; 5975 5976 // address = if index then offset_addr else R[n]; 5977 if (index) 5978 address = offset_addr; 5979 else 5980 address = base_address; 5981 5982 // MemU[address,1] = R[t]<7:0> 5983 RegisterInfo base_reg; 5984 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5985 5986 RegisterInfo data_reg; 5987 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5988 5989 EmulateInstruction::Context context; 5990 context.type = eContextRegisterStore; 5991 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5992 address - base_address); 5993 5994 uint32_t data = 5995 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5996 if (!success) 5997 return false; 5998 5999 data = Bits32(data, 7, 0); 6000 6001 if (!MemUWrite(context, address, data, 1)) 6002 return false; 6003 6004 // if wback then R[n] = offset_addr; 6005 if (wback) { 6006 context.type = eContextRegisterLoad; 6007 context.SetAddress(offset_addr); 6008 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6009 offset_addr)) 6010 return false; 6011 } 6012 } 6013 6014 return true; 6015 } 6016 6017 // STRH (register) calculates an address from a base register value and an 6018 // offset register value, and stores a 6019 // halfword from a register to memory. The offset register value can be shifted 6020 // left by 0, 1, 2, or 3 bits. 6021 bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode, 6022 const ARMEncoding encoding) { 6023 #if 0 6024 if ConditionPassed() then 6025 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6026 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6027 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6028 address = if index then offset_addr else R[n]; 6029 if UnalignedSupport() || address<0> == '0' then 6030 MemU[address,2] = R[t]<15:0>; 6031 else // Can only occur before ARMv7 6032 MemU[address,2] = bits(16) UNKNOWN; 6033 if wback then R[n] = offset_addr; 6034 #endif 6035 6036 bool success = false; 6037 6038 if (ConditionPassed(opcode)) { 6039 uint32_t t; 6040 uint32_t n; 6041 uint32_t m; 6042 bool index; 6043 bool add; 6044 bool wback; 6045 ARM_ShifterType shift_t; 6046 uint32_t shift_n; 6047 6048 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6049 switch (encoding) { 6050 case eEncodingT1: 6051 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 6052 // in ThumbEE"; 6053 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6054 t = Bits32(opcode, 2, 0); 6055 n = Bits32(opcode, 5, 3); 6056 m = Bits32(opcode, 8, 6); 6057 6058 // index = TRUE; add = TRUE; wback = FALSE; 6059 index = true; 6060 add = true; 6061 wback = false; 6062 6063 // (shift_t, shift_n) = (SRType_LSL, 0); 6064 shift_t = SRType_LSL; 6065 shift_n = 0; 6066 6067 break; 6068 6069 case eEncodingT2: 6070 // if Rn == '1111' then UNDEFINED; 6071 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6072 t = Bits32(opcode, 15, 12); 6073 n = Bits32(opcode, 19, 16); 6074 m = Bits32(opcode, 3, 0); 6075 if (n == 15) 6076 return false; 6077 6078 // index = TRUE; add = TRUE; wback = FALSE; 6079 index = true; 6080 add = true; 6081 wback = false; 6082 6083 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6084 shift_t = SRType_LSL; 6085 shift_n = Bits32(opcode, 5, 4); 6086 6087 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 6088 if (BadReg(t) || BadReg(m)) 6089 return false; 6090 6091 break; 6092 6093 case eEncodingA1: 6094 // if P == '0' && W == '1' then SEE STRHT; 6095 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6096 t = Bits32(opcode, 15, 12); 6097 n = Bits32(opcode, 19, 16); 6098 m = Bits32(opcode, 3, 0); 6099 6100 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6101 // (W == '1'); 6102 index = BitIsSet(opcode, 24); 6103 add = BitIsSet(opcode, 23); 6104 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6105 6106 // (shift_t, shift_n) = (SRType_LSL, 0); 6107 shift_t = SRType_LSL; 6108 shift_n = 0; 6109 6110 // if t == 15 || m == 15 then UNPREDICTABLE; 6111 if ((t == 15) || (m == 15)) 6112 return false; 6113 6114 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6115 if (wback && ((n == 15) || (n == t))) 6116 return false; 6117 6118 break; 6119 6120 default: 6121 return false; 6122 } 6123 6124 uint32_t Rm = ReadCoreReg(m, &success); 6125 if (!success) 6126 return false; 6127 6128 uint32_t Rn = ReadCoreReg(n, &success); 6129 if (!success) 6130 return false; 6131 6132 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6133 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 6134 if (!success) 6135 return false; 6136 6137 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6138 addr_t offset_addr; 6139 if (add) 6140 offset_addr = Rn + offset; 6141 else 6142 offset_addr = Rn - offset; 6143 6144 // address = if index then offset_addr else R[n]; 6145 addr_t address; 6146 if (index) 6147 address = offset_addr; 6148 else 6149 address = Rn; 6150 6151 EmulateInstruction::Context context; 6152 context.type = eContextRegisterStore; 6153 RegisterInfo base_reg; 6154 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6155 RegisterInfo offset_reg; 6156 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 6157 6158 // if UnalignedSupport() || address<0> == '0' then 6159 if (UnalignedSupport() || BitIsClear(address, 0)) { 6160 // MemU[address,2] = R[t]<15:0>; 6161 uint32_t Rt = ReadCoreReg(t, &success); 6162 if (!success) 6163 return false; 6164 6165 EmulateInstruction::Context context; 6166 context.type = eContextRegisterStore; 6167 RegisterInfo base_reg; 6168 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6169 RegisterInfo offset_reg; 6170 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 6171 RegisterInfo data_reg; 6172 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6173 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 6174 data_reg); 6175 6176 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2)) 6177 return false; 6178 } else // Can only occur before ARMv7 6179 { 6180 // MemU[address,2] = bits(16) UNKNOWN; 6181 } 6182 6183 // if wback then R[n] = offset_addr; 6184 if (wback) { 6185 context.type = eContextAdjustBaseRegister; 6186 context.SetAddress(offset_addr); 6187 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6188 offset_addr)) 6189 return false; 6190 } 6191 } 6192 6193 return true; 6194 } 6195 6196 // Add with Carry (immediate) adds an immediate value and the carry flag value 6197 // to a register value, 6198 // and writes the result to the destination register. It can optionally update 6199 // the condition flags 6200 // based on the result. 6201 bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode, 6202 const ARMEncoding encoding) { 6203 #if 0 6204 // ARM pseudo code... 6205 if ConditionPassed() then 6206 EncodingSpecificOperations(); 6207 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 6208 if d == 15 then // Can only occur for ARM encoding 6209 ALUWritePC(result); // setflags is always FALSE here 6210 else 6211 R[d] = result; 6212 if setflags then 6213 APSR.N = result<31>; 6214 APSR.Z = IsZeroBit(result); 6215 APSR.C = carry; 6216 APSR.V = overflow; 6217 #endif 6218 6219 bool success = false; 6220 6221 if (ConditionPassed(opcode)) { 6222 uint32_t Rd, Rn; 6223 uint32_t 6224 imm32; // the immediate value to be added to the value obtained from Rn 6225 bool setflags; 6226 switch (encoding) { 6227 case eEncodingT1: 6228 Rd = Bits32(opcode, 11, 8); 6229 Rn = Bits32(opcode, 19, 16); 6230 setflags = BitIsSet(opcode, 20); 6231 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 6232 if (BadReg(Rd) || BadReg(Rn)) 6233 return false; 6234 break; 6235 case eEncodingA1: 6236 Rd = Bits32(opcode, 15, 12); 6237 Rn = Bits32(opcode, 19, 16); 6238 setflags = BitIsSet(opcode, 20); 6239 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 6240 6241 if (Rd == 15 && setflags) 6242 return EmulateSUBSPcLrEtc(opcode, encoding); 6243 break; 6244 default: 6245 return false; 6246 } 6247 6248 // Read the first operand. 6249 int32_t val1 = ReadCoreReg(Rn, &success); 6250 if (!success) 6251 return false; 6252 6253 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 6254 6255 EmulateInstruction::Context context; 6256 context.type = EmulateInstruction::eContextImmediate; 6257 context.SetNoArgs(); 6258 6259 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 6260 res.carry_out, res.overflow)) 6261 return false; 6262 } 6263 return true; 6264 } 6265 6266 // Add with Carry (register) adds a register value, the carry flag value, and an 6267 // optionally-shifted 6268 // register value, and writes the result to the destination register. It can 6269 // optionally update the 6270 // condition flags based on the result. 6271 bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode, 6272 const ARMEncoding encoding) { 6273 #if 0 6274 // ARM pseudo code... 6275 if ConditionPassed() then 6276 EncodingSpecificOperations(); 6277 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 6278 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 6279 if d == 15 then // Can only occur for ARM encoding 6280 ALUWritePC(result); // setflags is always FALSE here 6281 else 6282 R[d] = result; 6283 if setflags then 6284 APSR.N = result<31>; 6285 APSR.Z = IsZeroBit(result); 6286 APSR.C = carry; 6287 APSR.V = overflow; 6288 #endif 6289 6290 bool success = false; 6291 6292 if (ConditionPassed(opcode)) { 6293 uint32_t Rd, Rn, Rm; 6294 ARM_ShifterType shift_t; 6295 uint32_t shift_n; // the shift applied to the value read from Rm 6296 bool setflags; 6297 switch (encoding) { 6298 case eEncodingT1: 6299 Rd = Rn = Bits32(opcode, 2, 0); 6300 Rm = Bits32(opcode, 5, 3); 6301 setflags = !InITBlock(); 6302 shift_t = SRType_LSL; 6303 shift_n = 0; 6304 break; 6305 case eEncodingT2: 6306 Rd = Bits32(opcode, 11, 8); 6307 Rn = Bits32(opcode, 19, 16); 6308 Rm = Bits32(opcode, 3, 0); 6309 setflags = BitIsSet(opcode, 20); 6310 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6311 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 6312 return false; 6313 break; 6314 case eEncodingA1: 6315 Rd = Bits32(opcode, 15, 12); 6316 Rn = Bits32(opcode, 19, 16); 6317 Rm = Bits32(opcode, 3, 0); 6318 setflags = BitIsSet(opcode, 20); 6319 shift_n = DecodeImmShiftARM(opcode, shift_t); 6320 6321 if (Rd == 15 && setflags) 6322 return EmulateSUBSPcLrEtc(opcode, encoding); 6323 break; 6324 default: 6325 return false; 6326 } 6327 6328 // Read the first operand. 6329 int32_t val1 = ReadCoreReg(Rn, &success); 6330 if (!success) 6331 return false; 6332 6333 // Read the second operand. 6334 int32_t val2 = ReadCoreReg(Rm, &success); 6335 if (!success) 6336 return false; 6337 6338 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 6339 if (!success) 6340 return false; 6341 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 6342 6343 EmulateInstruction::Context context; 6344 context.type = EmulateInstruction::eContextImmediate; 6345 context.SetNoArgs(); 6346 6347 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 6348 res.carry_out, res.overflow)) 6349 return false; 6350 } 6351 return true; 6352 } 6353 6354 // This instruction adds an immediate value to the PC value to form a 6355 // PC-relative address, 6356 // and writes the result to the destination register. 6357 bool EmulateInstructionARM::EmulateADR(const uint32_t opcode, 6358 const ARMEncoding encoding) { 6359 #if 0 6360 // ARM pseudo code... 6361 if ConditionPassed() then 6362 EncodingSpecificOperations(); 6363 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 6364 if d == 15 then // Can only occur for ARM encodings 6365 ALUWritePC(result); 6366 else 6367 R[d] = result; 6368 #endif 6369 6370 bool success = false; 6371 6372 if (ConditionPassed(opcode)) { 6373 uint32_t Rd; 6374 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 6375 bool add; 6376 switch (encoding) { 6377 case eEncodingT1: 6378 Rd = Bits32(opcode, 10, 8); 6379 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 6380 add = true; 6381 break; 6382 case eEncodingT2: 6383 case eEncodingT3: 6384 Rd = Bits32(opcode, 11, 8); 6385 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 6386 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 6387 if (BadReg(Rd)) 6388 return false; 6389 break; 6390 case eEncodingA1: 6391 case eEncodingA2: 6392 Rd = Bits32(opcode, 15, 12); 6393 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 6394 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 6395 break; 6396 default: 6397 return false; 6398 } 6399 6400 // Read the PC value. 6401 uint32_t pc = ReadCoreReg(PC_REG, &success); 6402 if (!success) 6403 return false; 6404 6405 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 6406 6407 EmulateInstruction::Context context; 6408 context.type = EmulateInstruction::eContextImmediate; 6409 context.SetNoArgs(); 6410 6411 if (!WriteCoreReg(context, result, Rd)) 6412 return false; 6413 } 6414 return true; 6415 } 6416 6417 // This instruction performs a bitwise AND of a register value and an immediate 6418 // value, and writes the result 6419 // to the destination register. It can optionally update the condition flags 6420 // based on the result. 6421 bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode, 6422 const ARMEncoding encoding) { 6423 #if 0 6424 // ARM pseudo code... 6425 if ConditionPassed() then 6426 EncodingSpecificOperations(); 6427 result = R[n] AND imm32; 6428 if d == 15 then // Can only occur for ARM encoding 6429 ALUWritePC(result); // setflags is always FALSE here 6430 else 6431 R[d] = result; 6432 if setflags then 6433 APSR.N = result<31>; 6434 APSR.Z = IsZeroBit(result); 6435 APSR.C = carry; 6436 // APSR.V unchanged 6437 #endif 6438 6439 bool success = false; 6440 6441 if (ConditionPassed(opcode)) { 6442 uint32_t Rd, Rn; 6443 uint32_t 6444 imm32; // the immediate value to be ANDed to the value obtained from Rn 6445 bool setflags; 6446 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6447 switch (encoding) { 6448 case eEncodingT1: 6449 Rd = Bits32(opcode, 11, 8); 6450 Rn = Bits32(opcode, 19, 16); 6451 setflags = BitIsSet(opcode, 20); 6452 imm32 = ThumbExpandImm_C( 6453 opcode, APSR_C, 6454 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6455 // if Rd == '1111' && S == '1' then SEE TST (immediate); 6456 if (Rd == 15 && setflags) 6457 return EmulateTSTImm(opcode, eEncodingT1); 6458 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 6459 return false; 6460 break; 6461 case eEncodingA1: 6462 Rd = Bits32(opcode, 15, 12); 6463 Rn = Bits32(opcode, 19, 16); 6464 setflags = BitIsSet(opcode, 20); 6465 imm32 = 6466 ARMExpandImm_C(opcode, APSR_C, 6467 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6468 6469 if (Rd == 15 && setflags) 6470 return EmulateSUBSPcLrEtc(opcode, encoding); 6471 break; 6472 default: 6473 return false; 6474 } 6475 6476 // Read the first operand. 6477 uint32_t val1 = ReadCoreReg(Rn, &success); 6478 if (!success) 6479 return false; 6480 6481 uint32_t result = val1 & imm32; 6482 6483 EmulateInstruction::Context context; 6484 context.type = EmulateInstruction::eContextImmediate; 6485 context.SetNoArgs(); 6486 6487 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6488 return false; 6489 } 6490 return true; 6491 } 6492 6493 // This instruction performs a bitwise AND of a register value and an 6494 // optionally-shifted register value, 6495 // and writes the result to the destination register. It can optionally update 6496 // the condition flags 6497 // based on the result. 6498 bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode, 6499 const ARMEncoding encoding) { 6500 #if 0 6501 // ARM pseudo code... 6502 if ConditionPassed() then 6503 EncodingSpecificOperations(); 6504 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6505 result = R[n] AND shifted; 6506 if d == 15 then // Can only occur for ARM encoding 6507 ALUWritePC(result); // setflags is always FALSE here 6508 else 6509 R[d] = result; 6510 if setflags then 6511 APSR.N = result<31>; 6512 APSR.Z = IsZeroBit(result); 6513 APSR.C = carry; 6514 // APSR.V unchanged 6515 #endif 6516 6517 bool success = false; 6518 6519 if (ConditionPassed(opcode)) { 6520 uint32_t Rd, Rn, Rm; 6521 ARM_ShifterType shift_t; 6522 uint32_t shift_n; // the shift applied to the value read from Rm 6523 bool setflags; 6524 uint32_t carry; 6525 switch (encoding) { 6526 case eEncodingT1: 6527 Rd = Rn = Bits32(opcode, 2, 0); 6528 Rm = Bits32(opcode, 5, 3); 6529 setflags = !InITBlock(); 6530 shift_t = SRType_LSL; 6531 shift_n = 0; 6532 break; 6533 case eEncodingT2: 6534 Rd = Bits32(opcode, 11, 8); 6535 Rn = Bits32(opcode, 19, 16); 6536 Rm = Bits32(opcode, 3, 0); 6537 setflags = BitIsSet(opcode, 20); 6538 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6539 // if Rd == '1111' && S == '1' then SEE TST (register); 6540 if (Rd == 15 && setflags) 6541 return EmulateTSTReg(opcode, eEncodingT2); 6542 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 6543 return false; 6544 break; 6545 case eEncodingA1: 6546 Rd = Bits32(opcode, 15, 12); 6547 Rn = Bits32(opcode, 19, 16); 6548 Rm = Bits32(opcode, 3, 0); 6549 setflags = BitIsSet(opcode, 20); 6550 shift_n = DecodeImmShiftARM(opcode, shift_t); 6551 6552 if (Rd == 15 && setflags) 6553 return EmulateSUBSPcLrEtc(opcode, encoding); 6554 break; 6555 default: 6556 return false; 6557 } 6558 6559 // Read the first operand. 6560 uint32_t val1 = ReadCoreReg(Rn, &success); 6561 if (!success) 6562 return false; 6563 6564 // Read the second operand. 6565 uint32_t val2 = ReadCoreReg(Rm, &success); 6566 if (!success) 6567 return false; 6568 6569 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6570 if (!success) 6571 return false; 6572 uint32_t result = val1 & shifted; 6573 6574 EmulateInstruction::Context context; 6575 context.type = EmulateInstruction::eContextImmediate; 6576 context.SetNoArgs(); 6577 6578 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6579 return false; 6580 } 6581 return true; 6582 } 6583 6584 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and 6585 // the complement of an 6586 // immediate value, and writes the result to the destination register. It can 6587 // optionally update the 6588 // condition flags based on the result. 6589 bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode, 6590 const ARMEncoding encoding) { 6591 #if 0 6592 // ARM pseudo code... 6593 if ConditionPassed() then 6594 EncodingSpecificOperations(); 6595 result = R[n] AND NOT(imm32); 6596 if d == 15 then // Can only occur for ARM encoding 6597 ALUWritePC(result); // setflags is always FALSE here 6598 else 6599 R[d] = result; 6600 if setflags then 6601 APSR.N = result<31>; 6602 APSR.Z = IsZeroBit(result); 6603 APSR.C = carry; 6604 // APSR.V unchanged 6605 #endif 6606 6607 bool success = false; 6608 6609 if (ConditionPassed(opcode)) { 6610 uint32_t Rd, Rn; 6611 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to 6612 // the value obtained from Rn 6613 bool setflags; 6614 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6615 switch (encoding) { 6616 case eEncodingT1: 6617 Rd = Bits32(opcode, 11, 8); 6618 Rn = Bits32(opcode, 19, 16); 6619 setflags = BitIsSet(opcode, 20); 6620 imm32 = ThumbExpandImm_C( 6621 opcode, APSR_C, 6622 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6623 if (BadReg(Rd) || BadReg(Rn)) 6624 return false; 6625 break; 6626 case eEncodingA1: 6627 Rd = Bits32(opcode, 15, 12); 6628 Rn = Bits32(opcode, 19, 16); 6629 setflags = BitIsSet(opcode, 20); 6630 imm32 = 6631 ARMExpandImm_C(opcode, APSR_C, 6632 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6633 6634 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6635 // instructions; 6636 if (Rd == 15 && setflags) 6637 return EmulateSUBSPcLrEtc(opcode, encoding); 6638 break; 6639 default: 6640 return false; 6641 } 6642 6643 // Read the first operand. 6644 uint32_t val1 = ReadCoreReg(Rn, &success); 6645 if (!success) 6646 return false; 6647 6648 uint32_t result = val1 & ~imm32; 6649 6650 EmulateInstruction::Context context; 6651 context.type = EmulateInstruction::eContextImmediate; 6652 context.SetNoArgs(); 6653 6654 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6655 return false; 6656 } 6657 return true; 6658 } 6659 6660 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and 6661 // the complement of an 6662 // optionally-shifted register value, and writes the result to the destination 6663 // register. 6664 // It can optionally update the condition flags based on the result. 6665 bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode, 6666 const ARMEncoding encoding) { 6667 #if 0 6668 // ARM pseudo code... 6669 if ConditionPassed() then 6670 EncodingSpecificOperations(); 6671 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6672 result = R[n] AND NOT(shifted); 6673 if d == 15 then // Can only occur for ARM encoding 6674 ALUWritePC(result); // setflags is always FALSE here 6675 else 6676 R[d] = result; 6677 if setflags then 6678 APSR.N = result<31>; 6679 APSR.Z = IsZeroBit(result); 6680 APSR.C = carry; 6681 // APSR.V unchanged 6682 #endif 6683 6684 bool success = false; 6685 6686 if (ConditionPassed(opcode)) { 6687 uint32_t Rd, Rn, Rm; 6688 ARM_ShifterType shift_t; 6689 uint32_t shift_n; // the shift applied to the value read from Rm 6690 bool setflags; 6691 uint32_t carry; 6692 switch (encoding) { 6693 case eEncodingT1: 6694 Rd = Rn = Bits32(opcode, 2, 0); 6695 Rm = Bits32(opcode, 5, 3); 6696 setflags = !InITBlock(); 6697 shift_t = SRType_LSL; 6698 shift_n = 0; 6699 break; 6700 case eEncodingT2: 6701 Rd = Bits32(opcode, 11, 8); 6702 Rn = Bits32(opcode, 19, 16); 6703 Rm = Bits32(opcode, 3, 0); 6704 setflags = BitIsSet(opcode, 20); 6705 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6706 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 6707 return false; 6708 break; 6709 case eEncodingA1: 6710 Rd = Bits32(opcode, 15, 12); 6711 Rn = Bits32(opcode, 19, 16); 6712 Rm = Bits32(opcode, 3, 0); 6713 setflags = BitIsSet(opcode, 20); 6714 shift_n = DecodeImmShiftARM(opcode, shift_t); 6715 6716 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6717 // instructions; 6718 if (Rd == 15 && setflags) 6719 return EmulateSUBSPcLrEtc(opcode, encoding); 6720 break; 6721 default: 6722 return false; 6723 } 6724 6725 // Read the first operand. 6726 uint32_t val1 = ReadCoreReg(Rn, &success); 6727 if (!success) 6728 return false; 6729 6730 // Read the second operand. 6731 uint32_t val2 = ReadCoreReg(Rm, &success); 6732 if (!success) 6733 return false; 6734 6735 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6736 if (!success) 6737 return false; 6738 uint32_t result = val1 & ~shifted; 6739 6740 EmulateInstruction::Context context; 6741 context.type = EmulateInstruction::eContextImmediate; 6742 context.SetNoArgs(); 6743 6744 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6745 return false; 6746 } 6747 return true; 6748 } 6749 6750 // LDR (immediate, ARM) calculates an address from a base register value and an 6751 // immediate offset, loads a word 6752 // from memory, and writes it to a register. It can use offset, post-indexed, 6753 // or pre-indexed addressing. 6754 bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode, 6755 const ARMEncoding encoding) { 6756 #if 0 6757 if ConditionPassed() then 6758 EncodingSpecificOperations(); 6759 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6760 address = if index then offset_addr else R[n]; 6761 data = MemU[address,4]; 6762 if wback then R[n] = offset_addr; 6763 if t == 15 then 6764 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6765 elsif UnalignedSupport() || address<1:0> = '00' then 6766 R[t] = data; 6767 else // Can only apply before ARMv7 6768 R[t] = ROR(data, 8*UInt(address<1:0>)); 6769 #endif 6770 6771 bool success = false; 6772 6773 if (ConditionPassed(opcode)) { 6774 const uint32_t addr_byte_size = GetAddressByteSize(); 6775 6776 uint32_t t; 6777 uint32_t n; 6778 uint32_t imm32; 6779 bool index; 6780 bool add; 6781 bool wback; 6782 6783 switch (encoding) { 6784 case eEncodingA1: 6785 // if Rn == '1111' then SEE LDR (literal); 6786 // if P == '0' && W == '1' then SEE LDRT; 6787 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == 6788 // '000000000100' then SEE POP; 6789 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6790 t = Bits32(opcode, 15, 12); 6791 n = Bits32(opcode, 19, 16); 6792 imm32 = Bits32(opcode, 11, 0); 6793 6794 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6795 // (W == '1'); 6796 index = BitIsSet(opcode, 24); 6797 add = BitIsSet(opcode, 23); 6798 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6799 6800 // if wback && n == t then UNPREDICTABLE; 6801 if (wback && (n == t)) 6802 return false; 6803 6804 break; 6805 6806 default: 6807 return false; 6808 } 6809 6810 addr_t address; 6811 addr_t offset_addr; 6812 addr_t base_address = ReadCoreReg(n, &success); 6813 if (!success) 6814 return false; 6815 6816 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6817 if (add) 6818 offset_addr = base_address + imm32; 6819 else 6820 offset_addr = base_address - imm32; 6821 6822 // address = if index then offset_addr else R[n]; 6823 if (index) 6824 address = offset_addr; 6825 else 6826 address = base_address; 6827 6828 // data = MemU[address,4]; 6829 6830 RegisterInfo base_reg; 6831 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6832 6833 EmulateInstruction::Context context; 6834 context.type = eContextRegisterLoad; 6835 context.SetRegisterPlusOffset(base_reg, address - base_address); 6836 6837 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6838 if (!success) 6839 return false; 6840 6841 // if wback then R[n] = offset_addr; 6842 if (wback) { 6843 context.type = eContextAdjustBaseRegister; 6844 context.SetAddress(offset_addr); 6845 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6846 offset_addr)) 6847 return false; 6848 } 6849 6850 // if t == 15 then 6851 if (t == 15) { 6852 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6853 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6854 // LoadWritePC (data); 6855 context.type = eContextRegisterLoad; 6856 context.SetRegisterPlusOffset(base_reg, address - base_address); 6857 LoadWritePC(context, data); 6858 } else 6859 return false; 6860 } 6861 // elsif UnalignedSupport() || address<1:0> = '00' then 6862 else if (UnalignedSupport() || 6863 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6864 // R[t] = data; 6865 context.type = eContextRegisterLoad; 6866 context.SetRegisterPlusOffset(base_reg, address - base_address); 6867 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6868 data)) 6869 return false; 6870 } 6871 // else // Can only apply before ARMv7 6872 else { 6873 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6874 data = ROR(data, Bits32(address, 1, 0), &success); 6875 if (!success) 6876 return false; 6877 context.type = eContextRegisterLoad; 6878 context.SetImmediate(data); 6879 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6880 data)) 6881 return false; 6882 } 6883 } 6884 return true; 6885 } 6886 6887 // LDR (register) calculates an address from a base register value and an offset 6888 // register value, loads a word 6889 // from memory, and writes it to a register. The offset register value can 6890 // optionally be shifted. 6891 bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode, 6892 const ARMEncoding encoding) { 6893 #if 0 6894 if ConditionPassed() then 6895 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6896 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6897 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6898 address = if index then offset_addr else R[n]; 6899 data = MemU[address,4]; 6900 if wback then R[n] = offset_addr; 6901 if t == 15 then 6902 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6903 elsif UnalignedSupport() || address<1:0> = '00' then 6904 R[t] = data; 6905 else // Can only apply before ARMv7 6906 if CurrentInstrSet() == InstrSet_ARM then 6907 R[t] = ROR(data, 8*UInt(address<1:0>)); 6908 else 6909 R[t] = bits(32) UNKNOWN; 6910 #endif 6911 6912 bool success = false; 6913 6914 if (ConditionPassed(opcode)) { 6915 const uint32_t addr_byte_size = GetAddressByteSize(); 6916 6917 uint32_t t; 6918 uint32_t n; 6919 uint32_t m; 6920 bool index; 6921 bool add; 6922 bool wback; 6923 ARM_ShifterType shift_t; 6924 uint32_t shift_n; 6925 6926 switch (encoding) { 6927 case eEncodingT1: 6928 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 6929 // in ThumbEE"; 6930 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6931 t = Bits32(opcode, 2, 0); 6932 n = Bits32(opcode, 5, 3); 6933 m = Bits32(opcode, 8, 6); 6934 6935 // index = TRUE; add = TRUE; wback = FALSE; 6936 index = true; 6937 add = true; 6938 wback = false; 6939 6940 // (shift_t, shift_n) = (SRType_LSL, 0); 6941 shift_t = SRType_LSL; 6942 shift_n = 0; 6943 6944 break; 6945 6946 case eEncodingT2: 6947 // if Rn == '1111' then SEE LDR (literal); 6948 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6949 t = Bits32(opcode, 15, 12); 6950 n = Bits32(opcode, 19, 16); 6951 m = Bits32(opcode, 3, 0); 6952 6953 // index = TRUE; add = TRUE; wback = FALSE; 6954 index = true; 6955 add = true; 6956 wback = false; 6957 6958 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6959 shift_t = SRType_LSL; 6960 shift_n = Bits32(opcode, 5, 4); 6961 6962 // if BadReg(m) then UNPREDICTABLE; 6963 if (BadReg(m)) 6964 return false; 6965 6966 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6967 if ((t == 15) && InITBlock() && !LastInITBlock()) 6968 return false; 6969 6970 break; 6971 6972 case eEncodingA1: { 6973 // if P == '0' && W == '1' then SEE LDRT; 6974 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6975 t = Bits32(opcode, 15, 12); 6976 n = Bits32(opcode, 19, 16); 6977 m = Bits32(opcode, 3, 0); 6978 6979 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6980 // (W == '1'); 6981 index = BitIsSet(opcode, 24); 6982 add = BitIsSet(opcode, 23); 6983 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6984 6985 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6986 uint32_t type = Bits32(opcode, 6, 5); 6987 uint32_t imm5 = Bits32(opcode, 11, 7); 6988 shift_n = DecodeImmShift(type, imm5, shift_t); 6989 6990 // if m == 15 then UNPREDICTABLE; 6991 if (m == 15) 6992 return false; 6993 6994 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6995 if (wback && ((n == 15) || (n == t))) 6996 return false; 6997 } break; 6998 6999 default: 7000 return false; 7001 } 7002 7003 uint32_t Rm = 7004 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7005 if (!success) 7006 return false; 7007 7008 uint32_t Rn = 7009 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7010 if (!success) 7011 return false; 7012 7013 addr_t offset_addr; 7014 addr_t address; 7015 7016 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an 7017 // application level alias for the CPSR". 7018 addr_t offset = 7019 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success); 7020 if (!success) 7021 return false; 7022 7023 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7024 if (add) 7025 offset_addr = Rn + offset; 7026 else 7027 offset_addr = Rn - offset; 7028 7029 // address = if index then offset_addr else R[n]; 7030 if (index) 7031 address = offset_addr; 7032 else 7033 address = Rn; 7034 7035 // data = MemU[address,4]; 7036 RegisterInfo base_reg; 7037 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7038 7039 EmulateInstruction::Context context; 7040 context.type = eContextRegisterLoad; 7041 context.SetRegisterPlusOffset(base_reg, address - Rn); 7042 7043 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 7044 if (!success) 7045 return false; 7046 7047 // if wback then R[n] = offset_addr; 7048 if (wback) { 7049 context.type = eContextAdjustBaseRegister; 7050 context.SetAddress(offset_addr); 7051 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7052 offset_addr)) 7053 return false; 7054 } 7055 7056 // if t == 15 then 7057 if (t == 15) { 7058 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 7059 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 7060 context.type = eContextRegisterLoad; 7061 context.SetRegisterPlusOffset(base_reg, address - Rn); 7062 LoadWritePC(context, data); 7063 } else 7064 return false; 7065 } 7066 // elsif UnalignedSupport() || address<1:0> = '00' then 7067 else if (UnalignedSupport() || 7068 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 7069 // R[t] = data; 7070 context.type = eContextRegisterLoad; 7071 context.SetRegisterPlusOffset(base_reg, address - Rn); 7072 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7073 data)) 7074 return false; 7075 } else // Can only apply before ARMv7 7076 { 7077 // if CurrentInstrSet() == InstrSet_ARM then 7078 if (CurrentInstrSet() == eModeARM) { 7079 // R[t] = ROR(data, 8*UInt(address<1:0>)); 7080 data = ROR(data, Bits32(address, 1, 0), &success); 7081 if (!success) 7082 return false; 7083 context.type = eContextRegisterLoad; 7084 context.SetImmediate(data); 7085 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7086 data)) 7087 return false; 7088 } else { 7089 // R[t] = bits(32) UNKNOWN; 7090 WriteBits32Unknown(t); 7091 } 7092 } 7093 } 7094 return true; 7095 } 7096 7097 // LDRB (immediate, Thumb) 7098 bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode, 7099 const ARMEncoding encoding) { 7100 #if 0 7101 if ConditionPassed() then 7102 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7103 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7104 address = if index then offset_addr else R[n]; 7105 R[t] = ZeroExtend(MemU[address,1], 32); 7106 if wback then R[n] = offset_addr; 7107 #endif 7108 7109 bool success = false; 7110 7111 if (ConditionPassed(opcode)) { 7112 uint32_t t; 7113 uint32_t n; 7114 uint32_t imm32; 7115 bool index; 7116 bool add; 7117 bool wback; 7118 7119 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7120 switch (encoding) { 7121 case eEncodingT1: 7122 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 7123 t = Bits32(opcode, 2, 0); 7124 n = Bits32(opcode, 5, 3); 7125 imm32 = Bits32(opcode, 10, 6); 7126 7127 // index = TRUE; add = TRUE; wback = FALSE; 7128 index = true; 7129 add = true; 7130 wback = false; 7131 7132 break; 7133 7134 case eEncodingT2: 7135 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7136 t = Bits32(opcode, 15, 12); 7137 n = Bits32(opcode, 19, 16); 7138 imm32 = Bits32(opcode, 11, 0); 7139 7140 // index = TRUE; add = TRUE; wback = FALSE; 7141 index = true; 7142 add = true; 7143 wback = false; 7144 7145 // if Rt == '1111' then SEE PLD; 7146 if (t == 15) 7147 return false; // PLD is not implemented yet 7148 7149 // if Rn == '1111' then SEE LDRB (literal); 7150 if (n == 15) 7151 return EmulateLDRBLiteral(opcode, eEncodingT1); 7152 7153 // if t == 13 then UNPREDICTABLE; 7154 if (t == 13) 7155 return false; 7156 7157 break; 7158 7159 case eEncodingT3: 7160 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 7161 // if P == '0' && W == '0' then UNDEFINED; 7162 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7163 return false; 7164 7165 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7166 t = Bits32(opcode, 15, 12); 7167 n = Bits32(opcode, 19, 16); 7168 imm32 = Bits32(opcode, 7, 0); 7169 7170 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7171 index = BitIsSet(opcode, 10); 7172 add = BitIsSet(opcode, 9); 7173 wback = BitIsSet(opcode, 8); 7174 7175 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 7176 if (t == 15) 7177 return false; // PLD is not implemented yet 7178 7179 // if Rn == '1111' then SEE LDRB (literal); 7180 if (n == 15) 7181 return EmulateLDRBLiteral(opcode, eEncodingT1); 7182 7183 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7184 if (BadReg(t) || (wback && (n == t))) 7185 return false; 7186 7187 break; 7188 7189 default: 7190 return false; 7191 } 7192 7193 uint32_t Rn = 7194 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7195 if (!success) 7196 return false; 7197 7198 addr_t address; 7199 addr_t offset_addr; 7200 7201 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7202 if (add) 7203 offset_addr = Rn + imm32; 7204 else 7205 offset_addr = Rn - imm32; 7206 7207 // address = if index then offset_addr else R[n]; 7208 if (index) 7209 address = offset_addr; 7210 else 7211 address = Rn; 7212 7213 // R[t] = ZeroExtend(MemU[address,1], 32); 7214 RegisterInfo base_reg; 7215 RegisterInfo data_reg; 7216 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7217 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 7218 7219 EmulateInstruction::Context context; 7220 context.type = eContextRegisterLoad; 7221 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 7222 7223 uint64_t data = MemURead(context, address, 1, 0, &success); 7224 if (!success) 7225 return false; 7226 7227 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7228 return false; 7229 7230 // if wback then R[n] = offset_addr; 7231 if (wback) { 7232 context.type = eContextAdjustBaseRegister; 7233 context.SetAddress(offset_addr); 7234 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7235 offset_addr)) 7236 return false; 7237 } 7238 } 7239 return true; 7240 } 7241 7242 // LDRB (literal) calculates an address from the PC value and an immediate 7243 // offset, loads a byte from memory, 7244 // zero-extends it to form a 32-bit word and writes it to a register. 7245 bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode, 7246 const ARMEncoding encoding) { 7247 #if 0 7248 if ConditionPassed() then 7249 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7250 base = Align(PC,4); 7251 address = if add then (base + imm32) else (base - imm32); 7252 R[t] = ZeroExtend(MemU[address,1], 32); 7253 #endif 7254 7255 bool success = false; 7256 7257 if (ConditionPassed(opcode)) { 7258 uint32_t t; 7259 uint32_t imm32; 7260 bool add; 7261 switch (encoding) { 7262 case eEncodingT1: 7263 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7264 t = Bits32(opcode, 15, 12); 7265 imm32 = Bits32(opcode, 11, 0); 7266 add = BitIsSet(opcode, 23); 7267 7268 // if Rt == '1111' then SEE PLD; 7269 if (t == 15) 7270 return false; // PLD is not implemented yet 7271 7272 // if t == 13 then UNPREDICTABLE; 7273 if (t == 13) 7274 return false; 7275 7276 break; 7277 7278 case eEncodingA1: 7279 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7280 t = Bits32(opcode, 15, 12); 7281 imm32 = Bits32(opcode, 11, 0); 7282 add = BitIsSet(opcode, 23); 7283 7284 // if t == 15 then UNPREDICTABLE; 7285 if (t == 15) 7286 return false; 7287 break; 7288 7289 default: 7290 return false; 7291 } 7292 7293 // base = Align(PC,4); 7294 uint32_t pc_val = ReadCoreReg(PC_REG, &success); 7295 if (!success) 7296 return false; 7297 7298 uint32_t base = AlignPC(pc_val); 7299 7300 addr_t address; 7301 // address = if add then (base + imm32) else (base - imm32); 7302 if (add) 7303 address = base + imm32; 7304 else 7305 address = base - imm32; 7306 7307 // R[t] = ZeroExtend(MemU[address,1], 32); 7308 EmulateInstruction::Context context; 7309 context.type = eContextRelativeBranchImmediate; 7310 context.SetImmediate(address - base); 7311 7312 uint64_t data = MemURead(context, address, 1, 0, &success); 7313 if (!success) 7314 return false; 7315 7316 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7317 return false; 7318 } 7319 return true; 7320 } 7321 7322 // LDRB (register) calculates an address from a base register value and an 7323 // offset rigister value, loads a byte from 7324 // memory, zero-extends it to form a 32-bit word, and writes it to a register. 7325 // The offset register value can 7326 // optionally be shifted. 7327 bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode, 7328 const ARMEncoding encoding) { 7329 #if 0 7330 if ConditionPassed() then 7331 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7332 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7333 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7334 address = if index then offset_addr else R[n]; 7335 R[t] = ZeroExtend(MemU[address,1],32); 7336 if wback then R[n] = offset_addr; 7337 #endif 7338 7339 bool success = false; 7340 7341 if (ConditionPassed(opcode)) { 7342 uint32_t t; 7343 uint32_t n; 7344 uint32_t m; 7345 bool index; 7346 bool add; 7347 bool wback; 7348 ARM_ShifterType shift_t; 7349 uint32_t shift_n; 7350 7351 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7352 switch (encoding) { 7353 case eEncodingT1: 7354 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7355 t = Bits32(opcode, 2, 0); 7356 n = Bits32(opcode, 5, 3); 7357 m = Bits32(opcode, 8, 6); 7358 7359 // index = TRUE; add = TRUE; wback = FALSE; 7360 index = true; 7361 add = true; 7362 wback = false; 7363 7364 // (shift_t, shift_n) = (SRType_LSL, 0); 7365 shift_t = SRType_LSL; 7366 shift_n = 0; 7367 break; 7368 7369 case eEncodingT2: 7370 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7371 t = Bits32(opcode, 15, 12); 7372 n = Bits32(opcode, 19, 16); 7373 m = Bits32(opcode, 3, 0); 7374 7375 // index = TRUE; add = TRUE; wback = FALSE; 7376 index = true; 7377 add = true; 7378 wback = false; 7379 7380 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7381 shift_t = SRType_LSL; 7382 shift_n = Bits32(opcode, 5, 4); 7383 7384 // if Rt == '1111' then SEE PLD; 7385 if (t == 15) 7386 return false; // PLD is not implemented yet 7387 7388 // if Rn == '1111' then SEE LDRB (literal); 7389 if (n == 15) 7390 return EmulateLDRBLiteral(opcode, eEncodingT1); 7391 7392 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7393 if ((t == 13) || BadReg(m)) 7394 return false; 7395 break; 7396 7397 case eEncodingA1: { 7398 // if P == '0' && W == '1' then SEE LDRBT; 7399 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7400 t = Bits32(opcode, 15, 12); 7401 n = Bits32(opcode, 19, 16); 7402 m = Bits32(opcode, 3, 0); 7403 7404 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7405 // (W == '1'); 7406 index = BitIsSet(opcode, 24); 7407 add = BitIsSet(opcode, 23); 7408 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7409 7410 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 7411 uint32_t type = Bits32(opcode, 6, 5); 7412 uint32_t imm5 = Bits32(opcode, 11, 7); 7413 shift_n = DecodeImmShift(type, imm5, shift_t); 7414 7415 // if t == 15 || m == 15 then UNPREDICTABLE; 7416 if ((t == 15) || (m == 15)) 7417 return false; 7418 7419 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7420 if (wback && ((n == 15) || (n == t))) 7421 return false; 7422 } break; 7423 7424 default: 7425 return false; 7426 } 7427 7428 addr_t offset_addr; 7429 addr_t address; 7430 7431 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7432 uint32_t Rm = 7433 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7434 if (!success) 7435 return false; 7436 7437 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7438 if (!success) 7439 return false; 7440 7441 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7442 uint32_t Rn = 7443 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7444 if (!success) 7445 return false; 7446 7447 if (add) 7448 offset_addr = Rn + offset; 7449 else 7450 offset_addr = Rn - offset; 7451 7452 // address = if index then offset_addr else R[n]; 7453 if (index) 7454 address = offset_addr; 7455 else 7456 address = Rn; 7457 7458 // R[t] = ZeroExtend(MemU[address,1],32); 7459 RegisterInfo base_reg; 7460 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7461 7462 EmulateInstruction::Context context; 7463 context.type = eContextRegisterLoad; 7464 context.SetRegisterPlusOffset(base_reg, address - Rn); 7465 7466 uint64_t data = MemURead(context, address, 1, 0, &success); 7467 if (!success) 7468 return false; 7469 7470 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7471 return false; 7472 7473 // if wback then R[n] = offset_addr; 7474 if (wback) { 7475 context.type = eContextAdjustBaseRegister; 7476 context.SetAddress(offset_addr); 7477 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7478 offset_addr)) 7479 return false; 7480 } 7481 } 7482 return true; 7483 } 7484 7485 // LDRH (immediate, Thumb) calculates an address from a base register value and 7486 // an immediate offset, loads a 7487 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to 7488 // a register. It can use offset, 7489 // post-indexed, or pre-indexed addressing. 7490 bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode, 7491 const ARMEncoding encoding) { 7492 #if 0 7493 if ConditionPassed() then 7494 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7495 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7496 address = if index then offset_addr else R[n]; 7497 data = MemU[address,2]; 7498 if wback then R[n] = offset_addr; 7499 if UnalignedSupport() || address<0> = '0' then 7500 R[t] = ZeroExtend(data, 32); 7501 else // Can only apply before ARMv7 7502 R[t] = bits(32) UNKNOWN; 7503 #endif 7504 7505 bool success = false; 7506 7507 if (ConditionPassed(opcode)) { 7508 uint32_t t; 7509 uint32_t n; 7510 uint32_t imm32; 7511 bool index; 7512 bool add; 7513 bool wback; 7514 7515 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7516 switch (encoding) { 7517 case eEncodingT1: 7518 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 7519 t = Bits32(opcode, 2, 0); 7520 n = Bits32(opcode, 5, 3); 7521 imm32 = Bits32(opcode, 10, 6) << 1; 7522 7523 // index = TRUE; add = TRUE; wback = FALSE; 7524 index = true; 7525 add = true; 7526 wback = false; 7527 7528 break; 7529 7530 case eEncodingT2: 7531 // if Rt == '1111' then SEE "Unallocated memory hints"; 7532 // if Rn == '1111' then SEE LDRH (literal); 7533 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7534 t = Bits32(opcode, 15, 12); 7535 n = Bits32(opcode, 19, 16); 7536 imm32 = Bits32(opcode, 11, 0); 7537 7538 // index = TRUE; add = TRUE; wback = FALSE; 7539 index = true; 7540 add = true; 7541 wback = false; 7542 7543 // if t == 13 then UNPREDICTABLE; 7544 if (t == 13) 7545 return false; 7546 break; 7547 7548 case eEncodingT3: 7549 // if Rn == '1111' then SEE LDRH (literal); 7550 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7551 // "Unallocated memory hints"; 7552 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 7553 // if P == '0' && W == '0' then UNDEFINED; 7554 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7555 return false; 7556 7557 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7558 t = Bits32(opcode, 15, 12); 7559 n = Bits32(opcode, 19, 16); 7560 imm32 = Bits32(opcode, 7, 0); 7561 7562 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7563 index = BitIsSet(opcode, 10); 7564 add = BitIsSet(opcode, 9); 7565 wback = BitIsSet(opcode, 8); 7566 7567 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7568 if (BadReg(t) || (wback && (n == t))) 7569 return false; 7570 break; 7571 7572 default: 7573 return false; 7574 } 7575 7576 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7577 uint32_t Rn = 7578 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7579 if (!success) 7580 return false; 7581 7582 addr_t offset_addr; 7583 addr_t address; 7584 7585 if (add) 7586 offset_addr = Rn + imm32; 7587 else 7588 offset_addr = Rn - imm32; 7589 7590 // address = if index then offset_addr else R[n]; 7591 if (index) 7592 address = offset_addr; 7593 else 7594 address = Rn; 7595 7596 // data = MemU[address,2]; 7597 RegisterInfo base_reg; 7598 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7599 7600 EmulateInstruction::Context context; 7601 context.type = eContextRegisterLoad; 7602 context.SetRegisterPlusOffset(base_reg, address - Rn); 7603 7604 uint64_t data = MemURead(context, address, 2, 0, &success); 7605 if (!success) 7606 return false; 7607 7608 // if wback then R[n] = offset_addr; 7609 if (wback) { 7610 context.type = eContextAdjustBaseRegister; 7611 context.SetAddress(offset_addr); 7612 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7613 offset_addr)) 7614 return false; 7615 } 7616 7617 // if UnalignedSupport() || address<0> = '0' then 7618 if (UnalignedSupport() || BitIsClear(address, 0)) { 7619 // R[t] = ZeroExtend(data, 32); 7620 context.type = eContextRegisterLoad; 7621 context.SetRegisterPlusOffset(base_reg, address - Rn); 7622 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7623 data)) 7624 return false; 7625 } else // Can only apply before ARMv7 7626 { 7627 // R[t] = bits(32) UNKNOWN; 7628 WriteBits32Unknown(t); 7629 } 7630 } 7631 return true; 7632 } 7633 7634 // LDRH (literal) caculates an address from the PC value and an immediate 7635 // offset, loads a halfword from memory, 7636 // zero-extends it to form a 32-bit word, and writes it to a register. 7637 bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode, 7638 const ARMEncoding encoding) { 7639 #if 0 7640 if ConditionPassed() then 7641 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7642 base = Align(PC,4); 7643 address = if add then (base + imm32) else (base - imm32); 7644 data = MemU[address,2]; 7645 if UnalignedSupport() || address<0> = '0' then 7646 R[t] = ZeroExtend(data, 32); 7647 else // Can only apply before ARMv7 7648 R[t] = bits(32) UNKNOWN; 7649 #endif 7650 7651 bool success = false; 7652 7653 if (ConditionPassed(opcode)) { 7654 uint32_t t; 7655 uint32_t imm32; 7656 bool add; 7657 7658 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7659 switch (encoding) { 7660 case eEncodingT1: 7661 // if Rt == '1111' then SEE "Unallocated memory hints"; 7662 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7663 t = Bits32(opcode, 15, 12); 7664 imm32 = Bits32(opcode, 11, 0); 7665 add = BitIsSet(opcode, 23); 7666 7667 // if t == 13 then UNPREDICTABLE; 7668 if (t == 13) 7669 return false; 7670 7671 break; 7672 7673 case eEncodingA1: { 7674 uint32_t imm4H = Bits32(opcode, 11, 8); 7675 uint32_t imm4L = Bits32(opcode, 3, 0); 7676 7677 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7678 t = Bits32(opcode, 15, 12); 7679 imm32 = (imm4H << 4) | imm4L; 7680 add = BitIsSet(opcode, 23); 7681 7682 // if t == 15 then UNPREDICTABLE; 7683 if (t == 15) 7684 return false; 7685 break; 7686 } 7687 7688 default: 7689 return false; 7690 } 7691 7692 // base = Align(PC,4); 7693 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7694 if (!success) 7695 return false; 7696 7697 addr_t base = AlignPC(pc_value); 7698 addr_t address; 7699 7700 // address = if add then (base + imm32) else (base - imm32); 7701 if (add) 7702 address = base + imm32; 7703 else 7704 address = base - imm32; 7705 7706 // data = MemU[address,2]; 7707 RegisterInfo base_reg; 7708 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7709 7710 EmulateInstruction::Context context; 7711 context.type = eContextRegisterLoad; 7712 context.SetRegisterPlusOffset(base_reg, address - base); 7713 7714 uint64_t data = MemURead(context, address, 2, 0, &success); 7715 if (!success) 7716 return false; 7717 7718 // if UnalignedSupport() || address<0> = '0' then 7719 if (UnalignedSupport() || BitIsClear(address, 0)) { 7720 // R[t] = ZeroExtend(data, 32); 7721 context.type = eContextRegisterLoad; 7722 context.SetRegisterPlusOffset(base_reg, address - base); 7723 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7724 data)) 7725 return false; 7726 7727 } else // Can only apply before ARMv7 7728 { 7729 // R[t] = bits(32) UNKNOWN; 7730 WriteBits32Unknown(t); 7731 } 7732 } 7733 return true; 7734 } 7735 7736 // LDRH (literal) calculates an address from a base register value and an offset 7737 // register value, loads a halfword 7738 // from memory, zero-extends it to form a 32-bit word, and writes it to a 7739 // register. The offset register value can 7740 // be shifted left by 0, 1, 2, or 3 bits. 7741 bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode, 7742 const ARMEncoding encoding) { 7743 #if 0 7744 if ConditionPassed() then 7745 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7746 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7747 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7748 address = if index then offset_addr else R[n]; 7749 data = MemU[address,2]; 7750 if wback then R[n] = offset_addr; 7751 if UnalignedSupport() || address<0> = '0' then 7752 R[t] = ZeroExtend(data, 32); 7753 else // Can only apply before ARMv7 7754 R[t] = bits(32) UNKNOWN; 7755 #endif 7756 7757 bool success = false; 7758 7759 if (ConditionPassed(opcode)) { 7760 uint32_t t; 7761 uint32_t n; 7762 uint32_t m; 7763 bool index; 7764 bool add; 7765 bool wback; 7766 ARM_ShifterType shift_t; 7767 uint32_t shift_n; 7768 7769 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7770 switch (encoding) { 7771 case eEncodingT1: 7772 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 7773 // in ThumbEE"; 7774 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7775 t = Bits32(opcode, 2, 0); 7776 n = Bits32(opcode, 5, 3); 7777 m = Bits32(opcode, 8, 6); 7778 7779 // index = TRUE; add = TRUE; wback = FALSE; 7780 index = true; 7781 add = true; 7782 wback = false; 7783 7784 // (shift_t, shift_n) = (SRType_LSL, 0); 7785 shift_t = SRType_LSL; 7786 shift_n = 0; 7787 7788 break; 7789 7790 case eEncodingT2: 7791 // if Rn == '1111' then SEE LDRH (literal); 7792 // if Rt == '1111' then SEE "Unallocated memory hints"; 7793 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7794 t = Bits32(opcode, 15, 12); 7795 n = Bits32(opcode, 19, 16); 7796 m = Bits32(opcode, 3, 0); 7797 7798 // index = TRUE; add = TRUE; wback = FALSE; 7799 index = true; 7800 add = true; 7801 wback = false; 7802 7803 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7804 shift_t = SRType_LSL; 7805 shift_n = Bits32(opcode, 5, 4); 7806 7807 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7808 if ((t == 13) || BadReg(m)) 7809 return false; 7810 break; 7811 7812 case eEncodingA1: 7813 // if P == '0' && W == '1' then SEE LDRHT; 7814 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7815 t = Bits32(opcode, 15, 12); 7816 n = Bits32(opcode, 19, 16); 7817 m = Bits32(opcode, 3, 0); 7818 7819 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7820 // (W == '1'); 7821 index = BitIsSet(opcode, 24); 7822 add = BitIsSet(opcode, 23); 7823 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7824 7825 // (shift_t, shift_n) = (SRType_LSL, 0); 7826 shift_t = SRType_LSL; 7827 shift_n = 0; 7828 7829 // if t == 15 || m == 15 then UNPREDICTABLE; 7830 if ((t == 15) || (m == 15)) 7831 return false; 7832 7833 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7834 if (wback && ((n == 15) || (n == t))) 7835 return false; 7836 7837 break; 7838 7839 default: 7840 return false; 7841 } 7842 7843 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7844 7845 uint64_t Rm = 7846 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7847 if (!success) 7848 return false; 7849 7850 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7851 if (!success) 7852 return false; 7853 7854 addr_t offset_addr; 7855 addr_t address; 7856 7857 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7858 uint64_t Rn = 7859 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7860 if (!success) 7861 return false; 7862 7863 if (add) 7864 offset_addr = Rn + offset; 7865 else 7866 offset_addr = Rn - offset; 7867 7868 // address = if index then offset_addr else R[n]; 7869 if (index) 7870 address = offset_addr; 7871 else 7872 address = Rn; 7873 7874 // data = MemU[address,2]; 7875 RegisterInfo base_reg; 7876 RegisterInfo offset_reg; 7877 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7878 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7879 7880 EmulateInstruction::Context context; 7881 context.type = eContextRegisterLoad; 7882 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7883 uint64_t data = MemURead(context, address, 2, 0, &success); 7884 if (!success) 7885 return false; 7886 7887 // if wback then R[n] = offset_addr; 7888 if (wback) { 7889 context.type = eContextAdjustBaseRegister; 7890 context.SetAddress(offset_addr); 7891 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7892 offset_addr)) 7893 return false; 7894 } 7895 7896 // if UnalignedSupport() || address<0> = '0' then 7897 if (UnalignedSupport() || BitIsClear(address, 0)) { 7898 // R[t] = ZeroExtend(data, 32); 7899 context.type = eContextRegisterLoad; 7900 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7901 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7902 data)) 7903 return false; 7904 } else // Can only apply before ARMv7 7905 { 7906 // R[t] = bits(32) UNKNOWN; 7907 WriteBits32Unknown(t); 7908 } 7909 } 7910 return true; 7911 } 7912 7913 // LDRSB (immediate) calculates an address from a base register value and an 7914 // immediate offset, loads a byte from 7915 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7916 // It can use offset, post-indexed, 7917 // or pre-indexed addressing. 7918 bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode, 7919 const ARMEncoding encoding) { 7920 #if 0 7921 if ConditionPassed() then 7922 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7923 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7924 address = if index then offset_addr else R[n]; 7925 R[t] = SignExtend(MemU[address,1], 32); 7926 if wback then R[n] = offset_addr; 7927 #endif 7928 7929 bool success = false; 7930 7931 if (ConditionPassed(opcode)) { 7932 uint32_t t; 7933 uint32_t n; 7934 uint32_t imm32; 7935 bool index; 7936 bool add; 7937 bool wback; 7938 7939 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7940 switch (encoding) { 7941 case eEncodingT1: 7942 // if Rt == '1111' then SEE PLI; 7943 // if Rn == '1111' then SEE LDRSB (literal); 7944 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7945 t = Bits32(opcode, 15, 12); 7946 n = Bits32(opcode, 19, 16); 7947 imm32 = Bits32(opcode, 11, 0); 7948 7949 // index = TRUE; add = TRUE; wback = FALSE; 7950 index = true; 7951 add = true; 7952 wback = false; 7953 7954 // if t == 13 then UNPREDICTABLE; 7955 if (t == 13) 7956 return false; 7957 7958 break; 7959 7960 case eEncodingT2: 7961 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7962 // if Rn == '1111' then SEE LDRSB (literal); 7963 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7964 // if P == '0' && W == '0' then UNDEFINED; 7965 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7966 return false; 7967 7968 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7969 t = Bits32(opcode, 15, 12); 7970 n = Bits32(opcode, 19, 16); 7971 imm32 = Bits32(opcode, 7, 0); 7972 7973 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7974 index = BitIsSet(opcode, 10); 7975 add = BitIsSet(opcode, 9); 7976 wback = BitIsSet(opcode, 8); 7977 7978 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7979 if (((t == 13) || 7980 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) || 7981 BitIsSet(opcode, 8)))) || 7982 (wback && (n == t))) 7983 return false; 7984 7985 break; 7986 7987 case eEncodingA1: { 7988 // if Rn == '1111' then SEE LDRSB (literal); 7989 // if P == '0' && W == '1' then SEE LDRSBT; 7990 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7991 t = Bits32(opcode, 15, 12); 7992 n = Bits32(opcode, 19, 16); 7993 7994 uint32_t imm4H = Bits32(opcode, 11, 8); 7995 uint32_t imm4L = Bits32(opcode, 3, 0); 7996 imm32 = (imm4H << 4) | imm4L; 7997 7998 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7999 // (W == '1'); 8000 index = BitIsSet(opcode, 24); 8001 add = BitIsSet(opcode, 23); 8002 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 8003 8004 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 8005 if ((t == 15) || (wback && (n == t))) 8006 return false; 8007 8008 break; 8009 } 8010 8011 default: 8012 return false; 8013 } 8014 8015 uint64_t Rn = ReadCoreReg(n, &success); 8016 if (!success) 8017 return false; 8018 8019 addr_t offset_addr; 8020 addr_t address; 8021 8022 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 8023 if (add) 8024 offset_addr = Rn + imm32; 8025 else 8026 offset_addr = Rn - imm32; 8027 8028 // address = if index then offset_addr else R[n]; 8029 if (index) 8030 address = offset_addr; 8031 else 8032 address = Rn; 8033 8034 // R[t] = SignExtend(MemU[address,1], 32); 8035 RegisterInfo base_reg; 8036 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8037 8038 EmulateInstruction::Context context; 8039 context.type = eContextRegisterLoad; 8040 context.SetRegisterPlusOffset(base_reg, address - Rn); 8041 8042 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 8043 if (!success) 8044 return false; 8045 8046 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 8047 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8048 (uint64_t)signed_data)) 8049 return false; 8050 8051 // if wback then R[n] = offset_addr; 8052 if (wback) { 8053 context.type = eContextAdjustBaseRegister; 8054 context.SetAddress(offset_addr); 8055 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8056 offset_addr)) 8057 return false; 8058 } 8059 } 8060 8061 return true; 8062 } 8063 8064 // LDRSB (literal) calculates an address from the PC value and an immediate 8065 // offset, loads a byte from memory, 8066 // sign-extends it to form a 32-bit word, and writes tit to a register. 8067 bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode, 8068 const ARMEncoding encoding) { 8069 #if 0 8070 if ConditionPassed() then 8071 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8072 base = Align(PC,4); 8073 address = if add then (base + imm32) else (base - imm32); 8074 R[t] = SignExtend(MemU[address,1], 32); 8075 #endif 8076 8077 bool success = false; 8078 8079 if (ConditionPassed(opcode)) { 8080 uint32_t t; 8081 uint32_t imm32; 8082 bool add; 8083 8084 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8085 switch (encoding) { 8086 case eEncodingT1: 8087 // if Rt == '1111' then SEE PLI; 8088 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 8089 t = Bits32(opcode, 15, 12); 8090 imm32 = Bits32(opcode, 11, 0); 8091 add = BitIsSet(opcode, 23); 8092 8093 // if t == 13 then UNPREDICTABLE; 8094 if (t == 13) 8095 return false; 8096 8097 break; 8098 8099 case eEncodingA1: { 8100 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 8101 t = Bits32(opcode, 15, 12); 8102 uint32_t imm4H = Bits32(opcode, 11, 8); 8103 uint32_t imm4L = Bits32(opcode, 3, 0); 8104 imm32 = (imm4H << 4) | imm4L; 8105 add = BitIsSet(opcode, 23); 8106 8107 // if t == 15 then UNPREDICTABLE; 8108 if (t == 15) 8109 return false; 8110 8111 break; 8112 } 8113 8114 default: 8115 return false; 8116 } 8117 8118 // base = Align(PC,4); 8119 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 8120 if (!success) 8121 return false; 8122 uint64_t base = AlignPC(pc_value); 8123 8124 // address = if add then (base + imm32) else (base - imm32); 8125 addr_t address; 8126 if (add) 8127 address = base + imm32; 8128 else 8129 address = base - imm32; 8130 8131 // R[t] = SignExtend(MemU[address,1], 32); 8132 RegisterInfo base_reg; 8133 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 8134 8135 EmulateInstruction::Context context; 8136 context.type = eContextRegisterLoad; 8137 context.SetRegisterPlusOffset(base_reg, address - base); 8138 8139 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 8140 if (!success) 8141 return false; 8142 8143 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 8144 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8145 (uint64_t)signed_data)) 8146 return false; 8147 } 8148 return true; 8149 } 8150 8151 // LDRSB (register) calculates an address from a base register value and an 8152 // offset register value, loadsa byte from 8153 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 8154 // The offset register value can be 8155 // shifted left by 0, 1, 2, or 3 bits. 8156 bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode, 8157 const ARMEncoding encoding) { 8158 #if 0 8159 if ConditionPassed() then 8160 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8161 offset = Shift(R[m], shift_t, shift_n, APSR.C); 8162 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8163 address = if index then offset_addr else R[n]; 8164 R[t] = SignExtend(MemU[address,1], 32); 8165 if wback then R[n] = offset_addr; 8166 #endif 8167 8168 bool success = false; 8169 8170 if (ConditionPassed(opcode)) { 8171 uint32_t t; 8172 uint32_t n; 8173 uint32_t m; 8174 bool index; 8175 bool add; 8176 bool wback; 8177 ARM_ShifterType shift_t; 8178 uint32_t shift_n; 8179 8180 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8181 switch (encoding) { 8182 case eEncodingT1: 8183 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8184 t = Bits32(opcode, 2, 0); 8185 n = Bits32(opcode, 5, 3); 8186 m = Bits32(opcode, 8, 6); 8187 8188 // index = TRUE; add = TRUE; wback = FALSE; 8189 index = true; 8190 add = true; 8191 wback = false; 8192 8193 // (shift_t, shift_n) = (SRType_LSL, 0); 8194 shift_t = SRType_LSL; 8195 shift_n = 0; 8196 8197 break; 8198 8199 case eEncodingT2: 8200 // if Rt == '1111' then SEE PLI; 8201 // if Rn == '1111' then SEE LDRSB (literal); 8202 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8203 t = Bits32(opcode, 15, 12); 8204 n = Bits32(opcode, 19, 16); 8205 m = Bits32(opcode, 3, 0); 8206 8207 // index = TRUE; add = TRUE; wback = FALSE; 8208 index = true; 8209 add = true; 8210 wback = false; 8211 8212 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 8213 shift_t = SRType_LSL; 8214 shift_n = Bits32(opcode, 5, 4); 8215 8216 // if t == 13 || BadReg(m) then UNPREDICTABLE; 8217 if ((t == 13) || BadReg(m)) 8218 return false; 8219 break; 8220 8221 case eEncodingA1: 8222 // if P == '0' && W == '1' then SEE LDRSBT; 8223 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8224 t = Bits32(opcode, 15, 12); 8225 n = Bits32(opcode, 19, 16); 8226 m = Bits32(opcode, 3, 0); 8227 8228 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8229 // (W == '1'); 8230 index = BitIsSet(opcode, 24); 8231 add = BitIsSet(opcode, 23); 8232 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8233 8234 // (shift_t, shift_n) = (SRType_LSL, 0); 8235 shift_t = SRType_LSL; 8236 shift_n = 0; 8237 8238 // if t == 15 || m == 15 then UNPREDICTABLE; 8239 if ((t == 15) || (m == 15)) 8240 return false; 8241 8242 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 8243 if (wback && ((n == 15) || (n == t))) 8244 return false; 8245 break; 8246 8247 default: 8248 return false; 8249 } 8250 8251 uint64_t Rm = 8252 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8253 if (!success) 8254 return false; 8255 8256 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 8257 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 8258 if (!success) 8259 return false; 8260 8261 addr_t offset_addr; 8262 addr_t address; 8263 8264 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8265 uint64_t Rn = 8266 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8267 if (!success) 8268 return false; 8269 8270 if (add) 8271 offset_addr = Rn + offset; 8272 else 8273 offset_addr = Rn - offset; 8274 8275 // address = if index then offset_addr else R[n]; 8276 if (index) 8277 address = offset_addr; 8278 else 8279 address = Rn; 8280 8281 // R[t] = SignExtend(MemU[address,1], 32); 8282 RegisterInfo base_reg; 8283 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8284 RegisterInfo offset_reg; 8285 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 8286 8287 EmulateInstruction::Context context; 8288 context.type = eContextRegisterLoad; 8289 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8290 8291 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 8292 if (!success) 8293 return false; 8294 8295 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 8296 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8297 (uint64_t)signed_data)) 8298 return false; 8299 8300 // if wback then R[n] = offset_addr; 8301 if (wback) { 8302 context.type = eContextAdjustBaseRegister; 8303 context.SetAddress(offset_addr); 8304 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8305 offset_addr)) 8306 return false; 8307 } 8308 } 8309 return true; 8310 } 8311 8312 // LDRSH (immediate) calculates an address from a base register value and an 8313 // immediate offset, loads a halfword from 8314 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 8315 // It can use offset, post-indexed, or 8316 // pre-indexed addressing. 8317 bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode, 8318 const ARMEncoding encoding) { 8319 #if 0 8320 if ConditionPassed() then 8321 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8322 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 8323 address = if index then offset_addr else R[n]; 8324 data = MemU[address,2]; 8325 if wback then R[n] = offset_addr; 8326 if UnalignedSupport() || address<0> = '0' then 8327 R[t] = SignExtend(data, 32); 8328 else // Can only apply before ARMv7 8329 R[t] = bits(32) UNKNOWN; 8330 #endif 8331 8332 bool success = false; 8333 8334 if (ConditionPassed(opcode)) { 8335 uint32_t t; 8336 uint32_t n; 8337 uint32_t imm32; 8338 bool index; 8339 bool add; 8340 bool wback; 8341 8342 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8343 switch (encoding) { 8344 case eEncodingT1: 8345 // if Rn == '1111' then SEE LDRSH (literal); 8346 // if Rt == '1111' then SEE "Unallocated memory hints"; 8347 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 8348 t = Bits32(opcode, 15, 12); 8349 n = Bits32(opcode, 19, 16); 8350 imm32 = Bits32(opcode, 11, 0); 8351 8352 // index = TRUE; add = TRUE; wback = FALSE; 8353 index = true; 8354 add = true; 8355 wback = false; 8356 8357 // if t == 13 then UNPREDICTABLE; 8358 if (t == 13) 8359 return false; 8360 8361 break; 8362 8363 case eEncodingT2: 8364 // if Rn == '1111' then SEE LDRSH (literal); 8365 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 8366 // "Unallocated memory hints"; 8367 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 8368 // if P == '0' && W == '0' then UNDEFINED; 8369 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 8370 return false; 8371 8372 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 8373 t = Bits32(opcode, 15, 12); 8374 n = Bits32(opcode, 19, 16); 8375 imm32 = Bits32(opcode, 7, 0); 8376 8377 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 8378 index = BitIsSet(opcode, 10); 8379 add = BitIsSet(opcode, 9); 8380 wback = BitIsSet(opcode, 8); 8381 8382 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 8383 if (BadReg(t) || (wback && (n == t))) 8384 return false; 8385 8386 break; 8387 8388 case eEncodingA1: { 8389 // if Rn == '1111' then SEE LDRSH (literal); 8390 // if P == '0' && W == '1' then SEE LDRSHT; 8391 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 8392 t = Bits32(opcode, 15, 12); 8393 n = Bits32(opcode, 19, 16); 8394 uint32_t imm4H = Bits32(opcode, 11, 8); 8395 uint32_t imm4L = Bits32(opcode, 3, 0); 8396 imm32 = (imm4H << 4) | imm4L; 8397 8398 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8399 // (W == '1'); 8400 index = BitIsSet(opcode, 24); 8401 add = BitIsSet(opcode, 23); 8402 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8403 8404 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 8405 if ((t == 15) || (wback && (n == t))) 8406 return false; 8407 8408 break; 8409 } 8410 8411 default: 8412 return false; 8413 } 8414 8415 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 8416 uint64_t Rn = 8417 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8418 if (!success) 8419 return false; 8420 8421 addr_t offset_addr; 8422 if (add) 8423 offset_addr = Rn + imm32; 8424 else 8425 offset_addr = Rn - imm32; 8426 8427 // address = if index then offset_addr else R[n]; 8428 addr_t address; 8429 if (index) 8430 address = offset_addr; 8431 else 8432 address = Rn; 8433 8434 // data = MemU[address,2]; 8435 RegisterInfo base_reg; 8436 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8437 8438 EmulateInstruction::Context context; 8439 context.type = eContextRegisterLoad; 8440 context.SetRegisterPlusOffset(base_reg, address - Rn); 8441 8442 uint64_t data = MemURead(context, address, 2, 0, &success); 8443 if (!success) 8444 return false; 8445 8446 // if wback then R[n] = offset_addr; 8447 if (wback) { 8448 context.type = eContextAdjustBaseRegister; 8449 context.SetAddress(offset_addr); 8450 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8451 offset_addr)) 8452 return false; 8453 } 8454 8455 // if UnalignedSupport() || address<0> = '0' then 8456 if (UnalignedSupport() || BitIsClear(address, 0)) { 8457 // R[t] = SignExtend(data, 32); 8458 int64_t signed_data = llvm::SignExtend64<16>(data); 8459 context.type = eContextRegisterLoad; 8460 context.SetRegisterPlusOffset(base_reg, address - Rn); 8461 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8462 (uint64_t)signed_data)) 8463 return false; 8464 } else // Can only apply before ARMv7 8465 { 8466 // R[t] = bits(32) UNKNOWN; 8467 WriteBits32Unknown(t); 8468 } 8469 } 8470 return true; 8471 } 8472 8473 // LDRSH (literal) calculates an address from the PC value and an immediate 8474 // offset, loads a halfword from memory, 8475 // sign-extends it to from a 32-bit word, and writes it to a register. 8476 bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode, 8477 const ARMEncoding encoding) { 8478 #if 0 8479 if ConditionPassed() then 8480 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8481 base = Align(PC,4); 8482 address = if add then (base + imm32) else (base - imm32); 8483 data = MemU[address,2]; 8484 if UnalignedSupport() || address<0> = '0' then 8485 R[t] = SignExtend(data, 32); 8486 else // Can only apply before ARMv7 8487 R[t] = bits(32) UNKNOWN; 8488 #endif 8489 8490 bool success = false; 8491 8492 if (ConditionPassed(opcode)) { 8493 uint32_t t; 8494 uint32_t imm32; 8495 bool add; 8496 8497 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8498 switch (encoding) { 8499 case eEncodingT1: 8500 // if Rt == '1111' then SEE "Unallocated memory hints"; 8501 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 8502 t = Bits32(opcode, 15, 12); 8503 imm32 = Bits32(opcode, 11, 0); 8504 add = BitIsSet(opcode, 23); 8505 8506 // if t == 13 then UNPREDICTABLE; 8507 if (t == 13) 8508 return false; 8509 8510 break; 8511 8512 case eEncodingA1: { 8513 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 8514 t = Bits32(opcode, 15, 12); 8515 uint32_t imm4H = Bits32(opcode, 11, 8); 8516 uint32_t imm4L = Bits32(opcode, 3, 0); 8517 imm32 = (imm4H << 4) | imm4L; 8518 add = BitIsSet(opcode, 23); 8519 8520 // if t == 15 then UNPREDICTABLE; 8521 if (t == 15) 8522 return false; 8523 8524 break; 8525 } 8526 default: 8527 return false; 8528 } 8529 8530 // base = Align(PC,4); 8531 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 8532 if (!success) 8533 return false; 8534 8535 uint64_t base = AlignPC(pc_value); 8536 8537 addr_t address; 8538 // address = if add then (base + imm32) else (base - imm32); 8539 if (add) 8540 address = base + imm32; 8541 else 8542 address = base - imm32; 8543 8544 // data = MemU[address,2]; 8545 RegisterInfo base_reg; 8546 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 8547 8548 EmulateInstruction::Context context; 8549 context.type = eContextRegisterLoad; 8550 context.SetRegisterPlusOffset(base_reg, imm32); 8551 8552 uint64_t data = MemURead(context, address, 2, 0, &success); 8553 if (!success) 8554 return false; 8555 8556 // if UnalignedSupport() || address<0> = '0' then 8557 if (UnalignedSupport() || BitIsClear(address, 0)) { 8558 // R[t] = SignExtend(data, 32); 8559 int64_t signed_data = llvm::SignExtend64<16>(data); 8560 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8561 (uint64_t)signed_data)) 8562 return false; 8563 } else // Can only apply before ARMv7 8564 { 8565 // R[t] = bits(32) UNKNOWN; 8566 WriteBits32Unknown(t); 8567 } 8568 } 8569 return true; 8570 } 8571 8572 // LDRSH (register) calculates an address from a base register value and an 8573 // offset register value, loads a halfword 8574 // from memory, sign-extends it to form a 32-bit word, and writes it to a 8575 // register. The offset register value can be 8576 // shifted left by 0, 1, 2, or 3 bits. 8577 bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode, 8578 const ARMEncoding encoding) { 8579 #if 0 8580 if ConditionPassed() then 8581 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8582 offset = Shift(R[m], shift_t, shift_n, APSR.C); 8583 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8584 address = if index then offset_addr else R[n]; 8585 data = MemU[address,2]; 8586 if wback then R[n] = offset_addr; 8587 if UnalignedSupport() || address<0> = '0' then 8588 R[t] = SignExtend(data, 32); 8589 else // Can only apply before ARMv7 8590 R[t] = bits(32) UNKNOWN; 8591 #endif 8592 8593 bool success = false; 8594 8595 if (ConditionPassed(opcode)) { 8596 uint32_t t; 8597 uint32_t n; 8598 uint32_t m; 8599 bool index; 8600 bool add; 8601 bool wback; 8602 ARM_ShifterType shift_t; 8603 uint32_t shift_n; 8604 8605 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8606 switch (encoding) { 8607 case eEncodingT1: 8608 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 8609 // in ThumbEE"; 8610 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8611 t = Bits32(opcode, 2, 0); 8612 n = Bits32(opcode, 5, 3); 8613 m = Bits32(opcode, 8, 6); 8614 8615 // index = TRUE; add = TRUE; wback = FALSE; 8616 index = true; 8617 add = true; 8618 wback = false; 8619 8620 // (shift_t, shift_n) = (SRType_LSL, 0); 8621 shift_t = SRType_LSL; 8622 shift_n = 0; 8623 8624 break; 8625 8626 case eEncodingT2: 8627 // if Rn == '1111' then SEE LDRSH (literal); 8628 // if Rt == '1111' then SEE "Unallocated memory hints"; 8629 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8630 t = Bits32(opcode, 15, 12); 8631 n = Bits32(opcode, 19, 16); 8632 m = Bits32(opcode, 3, 0); 8633 8634 // index = TRUE; add = TRUE; wback = FALSE; 8635 index = true; 8636 add = true; 8637 wback = false; 8638 8639 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 8640 shift_t = SRType_LSL; 8641 shift_n = Bits32(opcode, 5, 4); 8642 8643 // if t == 13 || BadReg(m) then UNPREDICTABLE; 8644 if ((t == 13) || BadReg(m)) 8645 return false; 8646 8647 break; 8648 8649 case eEncodingA1: 8650 // if P == '0' && W == '1' then SEE LDRSHT; 8651 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8652 t = Bits32(opcode, 15, 12); 8653 n = Bits32(opcode, 19, 16); 8654 m = Bits32(opcode, 3, 0); 8655 8656 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8657 // (W == '1'); 8658 index = BitIsSet(opcode, 24); 8659 add = BitIsSet(opcode, 23); 8660 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8661 8662 // (shift_t, shift_n) = (SRType_LSL, 0); 8663 shift_t = SRType_LSL; 8664 shift_n = 0; 8665 8666 // if t == 15 || m == 15 then UNPREDICTABLE; 8667 if ((t == 15) || (m == 15)) 8668 return false; 8669 8670 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 8671 if (wback && ((n == 15) || (n == t))) 8672 return false; 8673 8674 break; 8675 8676 default: 8677 return false; 8678 } 8679 8680 uint64_t Rm = 8681 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8682 if (!success) 8683 return false; 8684 8685 uint64_t Rn = 8686 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8687 if (!success) 8688 return false; 8689 8690 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 8691 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 8692 if (!success) 8693 return false; 8694 8695 addr_t offset_addr; 8696 addr_t address; 8697 8698 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8699 if (add) 8700 offset_addr = Rn + offset; 8701 else 8702 offset_addr = Rn - offset; 8703 8704 // address = if index then offset_addr else R[n]; 8705 if (index) 8706 address = offset_addr; 8707 else 8708 address = Rn; 8709 8710 // data = MemU[address,2]; 8711 RegisterInfo base_reg; 8712 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8713 8714 RegisterInfo offset_reg; 8715 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 8716 8717 EmulateInstruction::Context context; 8718 context.type = eContextRegisterLoad; 8719 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8720 8721 uint64_t data = MemURead(context, address, 2, 0, &success); 8722 if (!success) 8723 return false; 8724 8725 // if wback then R[n] = offset_addr; 8726 if (wback) { 8727 context.type = eContextAdjustBaseRegister; 8728 context.SetAddress(offset_addr); 8729 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8730 offset_addr)) 8731 return false; 8732 } 8733 8734 // if UnalignedSupport() || address<0> = '0' then 8735 if (UnalignedSupport() || BitIsClear(address, 0)) { 8736 // R[t] = SignExtend(data, 32); 8737 context.type = eContextRegisterLoad; 8738 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8739 8740 int64_t signed_data = llvm::SignExtend64<16>(data); 8741 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8742 (uint64_t)signed_data)) 8743 return false; 8744 } else // Can only apply before ARMv7 8745 { 8746 // R[t] = bits(32) UNKNOWN; 8747 WriteBits32Unknown(t); 8748 } 8749 } 8750 return true; 8751 } 8752 8753 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and 8754 // writes the result to the destination 8755 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before 8756 // extracting the 8-bit value. 8757 bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode, 8758 const ARMEncoding encoding) { 8759 #if 0 8760 if ConditionPassed() then 8761 EncodingSpecificOperations(); 8762 rotated = ROR(R[m], rotation); 8763 R[d] = SignExtend(rotated<7:0>, 32); 8764 #endif 8765 8766 bool success = false; 8767 8768 if (ConditionPassed(opcode)) { 8769 uint32_t d; 8770 uint32_t m; 8771 uint32_t rotation; 8772 8773 // EncodingSpecificOperations(); 8774 switch (encoding) { 8775 case eEncodingT1: 8776 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8777 d = Bits32(opcode, 2, 0); 8778 m = Bits32(opcode, 5, 3); 8779 rotation = 0; 8780 8781 break; 8782 8783 case eEncodingT2: 8784 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8785 d = Bits32(opcode, 11, 8); 8786 m = Bits32(opcode, 3, 0); 8787 rotation = Bits32(opcode, 5, 4) << 3; 8788 8789 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8790 if (BadReg(d) || BadReg(m)) 8791 return false; 8792 8793 break; 8794 8795 case eEncodingA1: 8796 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8797 d = Bits32(opcode, 15, 12); 8798 m = Bits32(opcode, 3, 0); 8799 rotation = Bits32(opcode, 11, 10) << 3; 8800 8801 // if d == 15 || m == 15 then UNPREDICTABLE; 8802 if ((d == 15) || (m == 15)) 8803 return false; 8804 8805 break; 8806 8807 default: 8808 return false; 8809 } 8810 8811 uint64_t Rm = 8812 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8813 if (!success) 8814 return false; 8815 8816 // rotated = ROR(R[m], rotation); 8817 uint64_t rotated = ROR(Rm, rotation, &success); 8818 if (!success) 8819 return false; 8820 8821 // R[d] = SignExtend(rotated<7:0>, 32); 8822 int64_t data = llvm::SignExtend64<8>(rotated); 8823 8824 RegisterInfo source_reg; 8825 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8826 8827 EmulateInstruction::Context context; 8828 context.type = eContextRegisterLoad; 8829 context.SetRegister(source_reg); 8830 8831 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8832 (uint64_t)data)) 8833 return false; 8834 } 8835 return true; 8836 } 8837 8838 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and 8839 // writes the result to the destination 8840 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8841 // extracting the 16-bit value. 8842 bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode, 8843 const ARMEncoding encoding) { 8844 #if 0 8845 if ConditionPassed() then 8846 EncodingSpecificOperations(); 8847 rotated = ROR(R[m], rotation); 8848 R[d] = SignExtend(rotated<15:0>, 32); 8849 #endif 8850 8851 bool success = false; 8852 8853 if (ConditionPassed(opcode)) { 8854 uint32_t d; 8855 uint32_t m; 8856 uint32_t rotation; 8857 8858 // EncodingSpecificOperations(); 8859 switch (encoding) { 8860 case eEncodingT1: 8861 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8862 d = Bits32(opcode, 2, 0); 8863 m = Bits32(opcode, 5, 3); 8864 rotation = 0; 8865 8866 break; 8867 8868 case eEncodingT2: 8869 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8870 d = Bits32(opcode, 11, 8); 8871 m = Bits32(opcode, 3, 0); 8872 rotation = Bits32(opcode, 5, 4) << 3; 8873 8874 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8875 if (BadReg(d) || BadReg(m)) 8876 return false; 8877 8878 break; 8879 8880 case eEncodingA1: 8881 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8882 d = Bits32(opcode, 15, 12); 8883 m = Bits32(opcode, 3, 0); 8884 rotation = Bits32(opcode, 11, 10) << 3; 8885 8886 // if d == 15 || m == 15 then UNPREDICTABLE; 8887 if ((d == 15) || (m == 15)) 8888 return false; 8889 8890 break; 8891 8892 default: 8893 return false; 8894 } 8895 8896 uint64_t Rm = 8897 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8898 if (!success) 8899 return false; 8900 8901 // rotated = ROR(R[m], rotation); 8902 uint64_t rotated = ROR(Rm, rotation, &success); 8903 if (!success) 8904 return false; 8905 8906 // R[d] = SignExtend(rotated<15:0>, 32); 8907 RegisterInfo source_reg; 8908 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8909 8910 EmulateInstruction::Context context; 8911 context.type = eContextRegisterLoad; 8912 context.SetRegister(source_reg); 8913 8914 int64_t data = llvm::SignExtend64<16>(rotated); 8915 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8916 (uint64_t)data)) 8917 return false; 8918 } 8919 8920 return true; 8921 } 8922 8923 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and 8924 // writes the result to the destination 8925 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8926 // extracting the 8-bit value. 8927 bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode, 8928 const ARMEncoding encoding) { 8929 #if 0 8930 if ConditionPassed() then 8931 EncodingSpecificOperations(); 8932 rotated = ROR(R[m], rotation); 8933 R[d] = ZeroExtend(rotated<7:0>, 32); 8934 #endif 8935 8936 bool success = false; 8937 8938 if (ConditionPassed(opcode)) { 8939 uint32_t d; 8940 uint32_t m; 8941 uint32_t rotation; 8942 8943 // EncodingSpecificOperations(); 8944 switch (encoding) { 8945 case eEncodingT1: 8946 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8947 d = Bits32(opcode, 2, 0); 8948 m = Bits32(opcode, 5, 3); 8949 rotation = 0; 8950 8951 break; 8952 8953 case eEncodingT2: 8954 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8955 d = Bits32(opcode, 11, 8); 8956 m = Bits32(opcode, 3, 0); 8957 rotation = Bits32(opcode, 5, 4) << 3; 8958 8959 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8960 if (BadReg(d) || BadReg(m)) 8961 return false; 8962 8963 break; 8964 8965 case eEncodingA1: 8966 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8967 d = Bits32(opcode, 15, 12); 8968 m = Bits32(opcode, 3, 0); 8969 rotation = Bits32(opcode, 11, 10) << 3; 8970 8971 // if d == 15 || m == 15 then UNPREDICTABLE; 8972 if ((d == 15) || (m == 15)) 8973 return false; 8974 8975 break; 8976 8977 default: 8978 return false; 8979 } 8980 8981 uint64_t Rm = 8982 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8983 if (!success) 8984 return false; 8985 8986 // rotated = ROR(R[m], rotation); 8987 uint64_t rotated = ROR(Rm, rotation, &success); 8988 if (!success) 8989 return false; 8990 8991 // R[d] = ZeroExtend(rotated<7:0>, 32); 8992 RegisterInfo source_reg; 8993 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8994 8995 EmulateInstruction::Context context; 8996 context.type = eContextRegisterLoad; 8997 context.SetRegister(source_reg); 8998 8999 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 9000 Bits32(rotated, 7, 0))) 9001 return false; 9002 } 9003 return true; 9004 } 9005 9006 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and 9007 // writes the result to the destination 9008 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 9009 // extracting the 16-bit value. 9010 bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode, 9011 const ARMEncoding encoding) { 9012 #if 0 9013 if ConditionPassed() then 9014 EncodingSpecificOperations(); 9015 rotated = ROR(R[m], rotation); 9016 R[d] = ZeroExtend(rotated<15:0>, 32); 9017 #endif 9018 9019 bool success = false; 9020 9021 if (ConditionPassed(opcode)) { 9022 uint32_t d; 9023 uint32_t m; 9024 uint32_t rotation; 9025 9026 switch (encoding) { 9027 case eEncodingT1: 9028 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 9029 d = Bits32(opcode, 2, 0); 9030 m = Bits32(opcode, 5, 3); 9031 rotation = 0; 9032 9033 break; 9034 9035 case eEncodingT2: 9036 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 9037 d = Bits32(opcode, 11, 8); 9038 m = Bits32(opcode, 3, 0); 9039 rotation = Bits32(opcode, 5, 4) << 3; 9040 9041 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 9042 if (BadReg(d) || BadReg(m)) 9043 return false; 9044 9045 break; 9046 9047 case eEncodingA1: 9048 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 9049 d = Bits32(opcode, 15, 12); 9050 m = Bits32(opcode, 3, 0); 9051 rotation = Bits32(opcode, 11, 10) << 3; 9052 9053 // if d == 15 || m == 15 then UNPREDICTABLE; 9054 if ((d == 15) || (m == 15)) 9055 return false; 9056 9057 break; 9058 9059 default: 9060 return false; 9061 } 9062 9063 uint64_t Rm = 9064 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 9065 if (!success) 9066 return false; 9067 9068 // rotated = ROR(R[m], rotation); 9069 uint64_t rotated = ROR(Rm, rotation, &success); 9070 if (!success) 9071 return false; 9072 9073 // R[d] = ZeroExtend(rotated<15:0>, 32); 9074 RegisterInfo source_reg; 9075 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 9076 9077 EmulateInstruction::Context context; 9078 context.type = eContextRegisterLoad; 9079 context.SetRegister(source_reg); 9080 9081 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 9082 Bits32(rotated, 15, 0))) 9083 return false; 9084 } 9085 return true; 9086 } 9087 9088 // RFE (Return From Exception) loads the PC and the CPSR from the word at the 9089 // specified address and the following 9090 // word respectively. 9091 bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode, 9092 const ARMEncoding encoding) { 9093 #if 0 9094 if ConditionPassed() then 9095 EncodingSpecificOperations(); 9096 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 9097 UNPREDICTABLE; 9098 else 9099 address = if increment then R[n] else R[n]-8; 9100 if wordhigher then address = address+4; 9101 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 9102 BranchWritePC(MemA[address,4]); 9103 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 9104 #endif 9105 9106 bool success = false; 9107 9108 if (ConditionPassed(opcode)) { 9109 uint32_t n; 9110 bool wback; 9111 bool increment; 9112 bool wordhigher; 9113 9114 // EncodingSpecificOperations(); 9115 switch (encoding) { 9116 case eEncodingT1: 9117 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = 9118 // FALSE; 9119 n = Bits32(opcode, 19, 16); 9120 wback = BitIsSet(opcode, 21); 9121 increment = false; 9122 wordhigher = false; 9123 9124 // if n == 15 then UNPREDICTABLE; 9125 if (n == 15) 9126 return false; 9127 9128 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 9129 if (InITBlock() && !LastInITBlock()) 9130 return false; 9131 9132 break; 9133 9134 case eEncodingT2: 9135 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 9136 n = Bits32(opcode, 19, 16); 9137 wback = BitIsSet(opcode, 21); 9138 increment = true; 9139 wordhigher = false; 9140 9141 // if n == 15 then UNPREDICTABLE; 9142 if (n == 15) 9143 return false; 9144 9145 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 9146 if (InITBlock() && !LastInITBlock()) 9147 return false; 9148 9149 break; 9150 9151 case eEncodingA1: 9152 // n = UInt(Rn); 9153 n = Bits32(opcode, 19, 16); 9154 9155 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 9156 wback = BitIsSet(opcode, 21); 9157 increment = BitIsSet(opcode, 23); 9158 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23)); 9159 9160 // if n == 15 then UNPREDICTABLE; 9161 if (n == 15) 9162 return false; 9163 9164 break; 9165 9166 default: 9167 return false; 9168 } 9169 9170 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE 9171 // then 9172 if (!CurrentModeIsPrivileged()) 9173 // UNPREDICTABLE; 9174 return false; 9175 else { 9176 uint64_t Rn = 9177 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 9178 if (!success) 9179 return false; 9180 9181 addr_t address; 9182 // address = if increment then R[n] else R[n]-8; 9183 if (increment) 9184 address = Rn; 9185 else 9186 address = Rn - 8; 9187 9188 // if wordhigher then address = address+4; 9189 if (wordhigher) 9190 address = address + 4; 9191 9192 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 9193 RegisterInfo base_reg; 9194 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9195 9196 EmulateInstruction::Context context; 9197 context.type = eContextReturnFromException; 9198 context.SetRegisterPlusOffset(base_reg, address - Rn); 9199 9200 uint64_t data = MemARead(context, address + 4, 4, 0, &success); 9201 if (!success) 9202 return false; 9203 9204 CPSRWriteByInstr(data, 15, true); 9205 9206 // BranchWritePC(MemA[address,4]); 9207 uint64_t data2 = MemARead(context, address, 4, 0, &success); 9208 if (!success) 9209 return false; 9210 9211 BranchWritePC(context, data2); 9212 9213 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 9214 if (wback) { 9215 context.type = eContextAdjustBaseRegister; 9216 if (increment) { 9217 context.SetOffset(8); 9218 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 9219 Rn + 8)) 9220 return false; 9221 } else { 9222 context.SetOffset(-8); 9223 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 9224 Rn - 8)) 9225 return false; 9226 } 9227 } // if wback 9228 } 9229 } // if ConditionPassed() 9230 return true; 9231 } 9232 9233 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a 9234 // register value and an immediate value, 9235 // and writes the result to the destination register. It can optionally update 9236 // the condition flags based on 9237 // the result. 9238 bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode, 9239 const ARMEncoding encoding) { 9240 #if 0 9241 // ARM pseudo code... 9242 if ConditionPassed() then 9243 EncodingSpecificOperations(); 9244 result = R[n] EOR imm32; 9245 if d == 15 then // Can only occur for ARM encoding 9246 ALUWritePC(result); // setflags is always FALSE here 9247 else 9248 R[d] = result; 9249 if setflags then 9250 APSR.N = result<31>; 9251 APSR.Z = IsZeroBit(result); 9252 APSR.C = carry; 9253 // APSR.V unchanged 9254 #endif 9255 9256 bool success = false; 9257 9258 if (ConditionPassed(opcode)) { 9259 uint32_t Rd, Rn; 9260 uint32_t 9261 imm32; // the immediate value to be ORed to the value obtained from Rn 9262 bool setflags; 9263 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9264 switch (encoding) { 9265 case eEncodingT1: 9266 Rd = Bits32(opcode, 11, 8); 9267 Rn = Bits32(opcode, 19, 16); 9268 setflags = BitIsSet(opcode, 20); 9269 imm32 = ThumbExpandImm_C( 9270 opcode, APSR_C, 9271 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9272 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 9273 if (Rd == 15 && setflags) 9274 return EmulateTEQImm(opcode, eEncodingT1); 9275 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 9276 return false; 9277 break; 9278 case eEncodingA1: 9279 Rd = Bits32(opcode, 15, 12); 9280 Rn = Bits32(opcode, 19, 16); 9281 setflags = BitIsSet(opcode, 20); 9282 imm32 = 9283 ARMExpandImm_C(opcode, APSR_C, 9284 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9285 9286 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9287 // instructions; 9288 if (Rd == 15 && setflags) 9289 return EmulateSUBSPcLrEtc(opcode, encoding); 9290 break; 9291 default: 9292 return false; 9293 } 9294 9295 // Read the first operand. 9296 uint32_t val1 = ReadCoreReg(Rn, &success); 9297 if (!success) 9298 return false; 9299 9300 uint32_t result = val1 ^ imm32; 9301 9302 EmulateInstruction::Context context; 9303 context.type = EmulateInstruction::eContextImmediate; 9304 context.SetNoArgs(); 9305 9306 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9307 return false; 9308 } 9309 return true; 9310 } 9311 9312 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register 9313 // value and an 9314 // optionally-shifted register value, and writes the result to the destination 9315 // register. 9316 // It can optionally update the condition flags based on the result. 9317 bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode, 9318 const ARMEncoding encoding) { 9319 #if 0 9320 // ARM pseudo code... 9321 if ConditionPassed() then 9322 EncodingSpecificOperations(); 9323 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9324 result = R[n] EOR shifted; 9325 if d == 15 then // Can only occur for ARM encoding 9326 ALUWritePC(result); // setflags is always FALSE here 9327 else 9328 R[d] = result; 9329 if setflags then 9330 APSR.N = result<31>; 9331 APSR.Z = IsZeroBit(result); 9332 APSR.C = carry; 9333 // APSR.V unchanged 9334 #endif 9335 9336 bool success = false; 9337 9338 if (ConditionPassed(opcode)) { 9339 uint32_t Rd, Rn, Rm; 9340 ARM_ShifterType shift_t; 9341 uint32_t shift_n; // the shift applied to the value read from Rm 9342 bool setflags; 9343 uint32_t carry; 9344 switch (encoding) { 9345 case eEncodingT1: 9346 Rd = Rn = Bits32(opcode, 2, 0); 9347 Rm = Bits32(opcode, 5, 3); 9348 setflags = !InITBlock(); 9349 shift_t = SRType_LSL; 9350 shift_n = 0; 9351 break; 9352 case eEncodingT2: 9353 Rd = Bits32(opcode, 11, 8); 9354 Rn = Bits32(opcode, 19, 16); 9355 Rm = Bits32(opcode, 3, 0); 9356 setflags = BitIsSet(opcode, 20); 9357 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9358 // if Rd == '1111' && S == '1' then SEE TEQ (register); 9359 if (Rd == 15 && setflags) 9360 return EmulateTEQReg(opcode, eEncodingT1); 9361 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 9362 return false; 9363 break; 9364 case eEncodingA1: 9365 Rd = Bits32(opcode, 15, 12); 9366 Rn = Bits32(opcode, 19, 16); 9367 Rm = Bits32(opcode, 3, 0); 9368 setflags = BitIsSet(opcode, 20); 9369 shift_n = DecodeImmShiftARM(opcode, shift_t); 9370 9371 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9372 // instructions; 9373 if (Rd == 15 && setflags) 9374 return EmulateSUBSPcLrEtc(opcode, encoding); 9375 break; 9376 default: 9377 return false; 9378 } 9379 9380 // Read the first operand. 9381 uint32_t val1 = ReadCoreReg(Rn, &success); 9382 if (!success) 9383 return false; 9384 9385 // Read the second operand. 9386 uint32_t val2 = ReadCoreReg(Rm, &success); 9387 if (!success) 9388 return false; 9389 9390 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9391 if (!success) 9392 return false; 9393 uint32_t result = val1 ^ shifted; 9394 9395 EmulateInstruction::Context context; 9396 context.type = EmulateInstruction::eContextImmediate; 9397 context.SetNoArgs(); 9398 9399 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9400 return false; 9401 } 9402 return true; 9403 } 9404 9405 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value 9406 // and an immediate value, and 9407 // writes the result to the destination register. It can optionally update the 9408 // condition flags based 9409 // on the result. 9410 bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode, 9411 const ARMEncoding encoding) { 9412 #if 0 9413 // ARM pseudo code... 9414 if ConditionPassed() then 9415 EncodingSpecificOperations(); 9416 result = R[n] OR imm32; 9417 if d == 15 then // Can only occur for ARM encoding 9418 ALUWritePC(result); // setflags is always FALSE here 9419 else 9420 R[d] = result; 9421 if setflags then 9422 APSR.N = result<31>; 9423 APSR.Z = IsZeroBit(result); 9424 APSR.C = carry; 9425 // APSR.V unchanged 9426 #endif 9427 9428 bool success = false; 9429 9430 if (ConditionPassed(opcode)) { 9431 uint32_t Rd, Rn; 9432 uint32_t 9433 imm32; // the immediate value to be ORed to the value obtained from Rn 9434 bool setflags; 9435 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9436 switch (encoding) { 9437 case eEncodingT1: 9438 Rd = Bits32(opcode, 11, 8); 9439 Rn = Bits32(opcode, 19, 16); 9440 setflags = BitIsSet(opcode, 20); 9441 imm32 = ThumbExpandImm_C( 9442 opcode, APSR_C, 9443 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9444 // if Rn == '1111' then SEE MOV (immediate); 9445 if (Rn == 15) 9446 return EmulateMOVRdImm(opcode, eEncodingT2); 9447 if (BadReg(Rd) || Rn == 13) 9448 return false; 9449 break; 9450 case eEncodingA1: 9451 Rd = Bits32(opcode, 15, 12); 9452 Rn = Bits32(opcode, 19, 16); 9453 setflags = BitIsSet(opcode, 20); 9454 imm32 = 9455 ARMExpandImm_C(opcode, APSR_C, 9456 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9457 9458 if (Rd == 15 && setflags) 9459 return EmulateSUBSPcLrEtc(opcode, encoding); 9460 break; 9461 default: 9462 return false; 9463 } 9464 9465 // Read the first operand. 9466 uint32_t val1 = ReadCoreReg(Rn, &success); 9467 if (!success) 9468 return false; 9469 9470 uint32_t result = val1 | imm32; 9471 9472 EmulateInstruction::Context context; 9473 context.type = EmulateInstruction::eContextImmediate; 9474 context.SetNoArgs(); 9475 9476 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9477 return false; 9478 } 9479 return true; 9480 } 9481 9482 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value 9483 // and an optionally-shifted register 9484 // value, and writes the result to the destination register. It can optionally 9485 // update the condition flags based 9486 // on the result. 9487 bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode, 9488 const ARMEncoding encoding) { 9489 #if 0 9490 // ARM pseudo code... 9491 if ConditionPassed() then 9492 EncodingSpecificOperations(); 9493 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9494 result = R[n] OR shifted; 9495 if d == 15 then // Can only occur for ARM encoding 9496 ALUWritePC(result); // setflags is always FALSE here 9497 else 9498 R[d] = result; 9499 if setflags then 9500 APSR.N = result<31>; 9501 APSR.Z = IsZeroBit(result); 9502 APSR.C = carry; 9503 // APSR.V unchanged 9504 #endif 9505 9506 bool success = false; 9507 9508 if (ConditionPassed(opcode)) { 9509 uint32_t Rd, Rn, Rm; 9510 ARM_ShifterType shift_t; 9511 uint32_t shift_n; // the shift applied to the value read from Rm 9512 bool setflags; 9513 uint32_t carry; 9514 switch (encoding) { 9515 case eEncodingT1: 9516 Rd = Rn = Bits32(opcode, 2, 0); 9517 Rm = Bits32(opcode, 5, 3); 9518 setflags = !InITBlock(); 9519 shift_t = SRType_LSL; 9520 shift_n = 0; 9521 break; 9522 case eEncodingT2: 9523 Rd = Bits32(opcode, 11, 8); 9524 Rn = Bits32(opcode, 19, 16); 9525 Rm = Bits32(opcode, 3, 0); 9526 setflags = BitIsSet(opcode, 20); 9527 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9528 // if Rn == '1111' then SEE MOV (register); 9529 if (Rn == 15) 9530 return EmulateMOVRdRm(opcode, eEncodingT3); 9531 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 9532 return false; 9533 break; 9534 case eEncodingA1: 9535 Rd = Bits32(opcode, 15, 12); 9536 Rn = Bits32(opcode, 19, 16); 9537 Rm = Bits32(opcode, 3, 0); 9538 setflags = BitIsSet(opcode, 20); 9539 shift_n = DecodeImmShiftARM(opcode, shift_t); 9540 9541 if (Rd == 15 && setflags) 9542 return EmulateSUBSPcLrEtc(opcode, encoding); 9543 break; 9544 default: 9545 return false; 9546 } 9547 9548 // Read the first operand. 9549 uint32_t val1 = ReadCoreReg(Rn, &success); 9550 if (!success) 9551 return false; 9552 9553 // Read the second operand. 9554 uint32_t val2 = ReadCoreReg(Rm, &success); 9555 if (!success) 9556 return false; 9557 9558 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9559 if (!success) 9560 return false; 9561 uint32_t result = val1 | shifted; 9562 9563 EmulateInstruction::Context context; 9564 context.type = EmulateInstruction::eContextImmediate; 9565 context.SetNoArgs(); 9566 9567 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9568 return false; 9569 } 9570 return true; 9571 } 9572 9573 // Reverse Subtract (immediate) subtracts a register value from an immediate 9574 // value, and writes the result to 9575 // the destination register. It can optionally update the condition flags based 9576 // on the result. 9577 bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode, 9578 const ARMEncoding encoding) { 9579 #if 0 9580 // ARM pseudo code... 9581 if ConditionPassed() then 9582 EncodingSpecificOperations(); 9583 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 9584 if d == 15 then // Can only occur for ARM encoding 9585 ALUWritePC(result); // setflags is always FALSE here 9586 else 9587 R[d] = result; 9588 if setflags then 9589 APSR.N = result<31>; 9590 APSR.Z = IsZeroBit(result); 9591 APSR.C = carry; 9592 APSR.V = overflow; 9593 #endif 9594 9595 bool success = false; 9596 9597 uint32_t Rd; // the destination register 9598 uint32_t Rn; // the first operand 9599 bool setflags; 9600 uint32_t 9601 imm32; // the immediate value to be added to the value obtained from Rn 9602 switch (encoding) { 9603 case eEncodingT1: 9604 Rd = Bits32(opcode, 2, 0); 9605 Rn = Bits32(opcode, 5, 3); 9606 setflags = !InITBlock(); 9607 imm32 = 0; 9608 break; 9609 case eEncodingT2: 9610 Rd = Bits32(opcode, 11, 8); 9611 Rn = Bits32(opcode, 19, 16); 9612 setflags = BitIsSet(opcode, 20); 9613 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9614 if (BadReg(Rd) || BadReg(Rn)) 9615 return false; 9616 break; 9617 case eEncodingA1: 9618 Rd = Bits32(opcode, 15, 12); 9619 Rn = Bits32(opcode, 19, 16); 9620 setflags = BitIsSet(opcode, 20); 9621 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9622 9623 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9624 // instructions; 9625 if (Rd == 15 && setflags) 9626 return EmulateSUBSPcLrEtc(opcode, encoding); 9627 break; 9628 default: 9629 return false; 9630 } 9631 // Read the register value from the operand register Rn. 9632 uint32_t reg_val = ReadCoreReg(Rn, &success); 9633 if (!success) 9634 return false; 9635 9636 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 9637 9638 EmulateInstruction::Context context; 9639 context.type = EmulateInstruction::eContextImmediate; 9640 context.SetNoArgs(); 9641 9642 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9643 res.carry_out, res.overflow)) 9644 return false; 9645 9646 return true; 9647 } 9648 9649 // Reverse Subtract (register) subtracts a register value from an 9650 // optionally-shifted register value, and writes the 9651 // result to the destination register. It can optionally update the condition 9652 // flags based on the result. 9653 bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode, 9654 const ARMEncoding encoding) { 9655 #if 0 9656 // ARM pseudo code... 9657 if ConditionPassed() then 9658 EncodingSpecificOperations(); 9659 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9660 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 9661 if d == 15 then // Can only occur for ARM encoding 9662 ALUWritePC(result); // setflags is always FALSE here 9663 else 9664 R[d] = result; 9665 if setflags then 9666 APSR.N = result<31>; 9667 APSR.Z = IsZeroBit(result); 9668 APSR.C = carry; 9669 APSR.V = overflow; 9670 #endif 9671 9672 bool success = false; 9673 9674 uint32_t Rd; // the destination register 9675 uint32_t Rn; // the first operand 9676 uint32_t Rm; // the second operand 9677 bool setflags; 9678 ARM_ShifterType shift_t; 9679 uint32_t shift_n; // the shift applied to the value read from Rm 9680 switch (encoding) { 9681 case eEncodingT1: 9682 Rd = Bits32(opcode, 11, 8); 9683 Rn = Bits32(opcode, 19, 16); 9684 Rm = Bits32(opcode, 3, 0); 9685 setflags = BitIsSet(opcode, 20); 9686 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9687 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 9688 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9689 return false; 9690 break; 9691 case eEncodingA1: 9692 Rd = Bits32(opcode, 15, 12); 9693 Rn = Bits32(opcode, 19, 16); 9694 Rm = Bits32(opcode, 3, 0); 9695 setflags = BitIsSet(opcode, 20); 9696 shift_n = DecodeImmShiftARM(opcode, shift_t); 9697 9698 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9699 // instructions; 9700 if (Rd == 15 && setflags) 9701 return EmulateSUBSPcLrEtc(opcode, encoding); 9702 break; 9703 default: 9704 return false; 9705 } 9706 // Read the register value from register Rn. 9707 uint32_t val1 = ReadCoreReg(Rn, &success); 9708 if (!success) 9709 return false; 9710 9711 // Read the register value from register Rm. 9712 uint32_t val2 = ReadCoreReg(Rm, &success); 9713 if (!success) 9714 return false; 9715 9716 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9717 if (!success) 9718 return false; 9719 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 9720 9721 EmulateInstruction::Context context; 9722 context.type = EmulateInstruction::eContextImmediate; 9723 context.SetNoArgs(); 9724 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9725 res.carry_out, res.overflow)) 9726 return false; 9727 9728 return true; 9729 } 9730 9731 // Reverse Subtract with Carry (immediate) subtracts a register value and the 9732 // value of NOT (Carry flag) from 9733 // an immediate value, and writes the result to the destination register. It can 9734 // optionally update the condition 9735 // flags based on the result. 9736 bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode, 9737 const ARMEncoding encoding) { 9738 #if 0 9739 // ARM pseudo code... 9740 if ConditionPassed() then 9741 EncodingSpecificOperations(); 9742 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 9743 if d == 15 then 9744 ALUWritePC(result); // setflags is always FALSE here 9745 else 9746 R[d] = result; 9747 if setflags then 9748 APSR.N = result<31>; 9749 APSR.Z = IsZeroBit(result); 9750 APSR.C = carry; 9751 APSR.V = overflow; 9752 #endif 9753 9754 bool success = false; 9755 9756 uint32_t Rd; // the destination register 9757 uint32_t Rn; // the first operand 9758 bool setflags; 9759 uint32_t 9760 imm32; // the immediate value to be added to the value obtained from Rn 9761 switch (encoding) { 9762 case eEncodingA1: 9763 Rd = Bits32(opcode, 15, 12); 9764 Rn = Bits32(opcode, 19, 16); 9765 setflags = BitIsSet(opcode, 20); 9766 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9767 9768 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9769 // instructions; 9770 if (Rd == 15 && setflags) 9771 return EmulateSUBSPcLrEtc(opcode, encoding); 9772 break; 9773 default: 9774 return false; 9775 } 9776 // Read the register value from the operand register Rn. 9777 uint32_t reg_val = ReadCoreReg(Rn, &success); 9778 if (!success) 9779 return false; 9780 9781 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 9782 9783 EmulateInstruction::Context context; 9784 context.type = EmulateInstruction::eContextImmediate; 9785 context.SetNoArgs(); 9786 9787 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9788 res.carry_out, res.overflow)) 9789 return false; 9790 9791 return true; 9792 } 9793 9794 // Reverse Subtract with Carry (register) subtracts a register value and the 9795 // value of NOT (Carry flag) from an 9796 // optionally-shifted register value, and writes the result to the destination 9797 // register. It can optionally update the 9798 // condition flags based on the result. 9799 bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode, 9800 const ARMEncoding encoding) { 9801 #if 0 9802 // ARM pseudo code... 9803 if ConditionPassed() then 9804 EncodingSpecificOperations(); 9805 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9806 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 9807 if d == 15 then 9808 ALUWritePC(result); // setflags is always FALSE here 9809 else 9810 R[d] = result; 9811 if setflags then 9812 APSR.N = result<31>; 9813 APSR.Z = IsZeroBit(result); 9814 APSR.C = carry; 9815 APSR.V = overflow; 9816 #endif 9817 9818 bool success = false; 9819 9820 uint32_t Rd; // the destination register 9821 uint32_t Rn; // the first operand 9822 uint32_t Rm; // the second operand 9823 bool setflags; 9824 ARM_ShifterType shift_t; 9825 uint32_t shift_n; // the shift applied to the value read from Rm 9826 switch (encoding) { 9827 case eEncodingA1: 9828 Rd = Bits32(opcode, 15, 12); 9829 Rn = Bits32(opcode, 19, 16); 9830 Rm = Bits32(opcode, 3, 0); 9831 setflags = BitIsSet(opcode, 20); 9832 shift_n = DecodeImmShiftARM(opcode, shift_t); 9833 9834 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9835 // instructions; 9836 if (Rd == 15 && setflags) 9837 return EmulateSUBSPcLrEtc(opcode, encoding); 9838 break; 9839 default: 9840 return false; 9841 } 9842 // Read the register value from register Rn. 9843 uint32_t val1 = ReadCoreReg(Rn, &success); 9844 if (!success) 9845 return false; 9846 9847 // Read the register value from register Rm. 9848 uint32_t val2 = ReadCoreReg(Rm, &success); 9849 if (!success) 9850 return false; 9851 9852 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9853 if (!success) 9854 return false; 9855 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 9856 9857 EmulateInstruction::Context context; 9858 context.type = EmulateInstruction::eContextImmediate; 9859 context.SetNoArgs(); 9860 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9861 res.carry_out, res.overflow)) 9862 return false; 9863 9864 return true; 9865 } 9866 9867 // Subtract with Carry (immediate) subtracts an immediate value and the value of 9868 // NOT (Carry flag) from a register value, and writes the result to the 9869 // destination register. 9870 // It can optionally update the condition flags based on the result. 9871 bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode, 9872 const ARMEncoding encoding) { 9873 #if 0 9874 // ARM pseudo code... 9875 if ConditionPassed() then 9876 EncodingSpecificOperations(); 9877 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 9878 if d == 15 then // Can only occur for ARM encoding 9879 ALUWritePC(result); // setflags is always FALSE here 9880 else 9881 R[d] = result; 9882 if setflags then 9883 APSR.N = result<31>; 9884 APSR.Z = IsZeroBit(result); 9885 APSR.C = carry; 9886 APSR.V = overflow; 9887 #endif 9888 9889 bool success = false; 9890 9891 uint32_t Rd; // the destination register 9892 uint32_t Rn; // the first operand 9893 bool setflags; 9894 uint32_t 9895 imm32; // the immediate value to be added to the value obtained from Rn 9896 switch (encoding) { 9897 case eEncodingT1: 9898 Rd = Bits32(opcode, 11, 8); 9899 Rn = Bits32(opcode, 19, 16); 9900 setflags = BitIsSet(opcode, 20); 9901 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9902 if (BadReg(Rd) || BadReg(Rn)) 9903 return false; 9904 break; 9905 case eEncodingA1: 9906 Rd = Bits32(opcode, 15, 12); 9907 Rn = Bits32(opcode, 19, 16); 9908 setflags = BitIsSet(opcode, 20); 9909 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9910 9911 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9912 // instructions; 9913 if (Rd == 15 && setflags) 9914 return EmulateSUBSPcLrEtc(opcode, encoding); 9915 break; 9916 default: 9917 return false; 9918 } 9919 // Read the register value from the operand register Rn. 9920 uint32_t reg_val = ReadCoreReg(Rn, &success); 9921 if (!success) 9922 return false; 9923 9924 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9925 9926 EmulateInstruction::Context context; 9927 context.type = EmulateInstruction::eContextImmediate; 9928 context.SetNoArgs(); 9929 9930 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9931 res.carry_out, res.overflow)) 9932 return false; 9933 9934 return true; 9935 } 9936 9937 // Subtract with Carry (register) subtracts an optionally-shifted register value 9938 // and the value of 9939 // NOT (Carry flag) from a register value, and writes the result to the 9940 // destination register. 9941 // It can optionally update the condition flags based on the result. 9942 bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode, 9943 const ARMEncoding encoding) { 9944 #if 0 9945 // ARM pseudo code... 9946 if ConditionPassed() then 9947 EncodingSpecificOperations(); 9948 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9949 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9950 if d == 15 then // Can only occur for ARM encoding 9951 ALUWritePC(result); // setflags is always FALSE here 9952 else 9953 R[d] = result; 9954 if setflags then 9955 APSR.N = result<31>; 9956 APSR.Z = IsZeroBit(result); 9957 APSR.C = carry; 9958 APSR.V = overflow; 9959 #endif 9960 9961 bool success = false; 9962 9963 uint32_t Rd; // the destination register 9964 uint32_t Rn; // the first operand 9965 uint32_t Rm; // the second operand 9966 bool setflags; 9967 ARM_ShifterType shift_t; 9968 uint32_t shift_n; // the shift applied to the value read from Rm 9969 switch (encoding) { 9970 case eEncodingT1: 9971 Rd = Rn = Bits32(opcode, 2, 0); 9972 Rm = Bits32(opcode, 5, 3); 9973 setflags = !InITBlock(); 9974 shift_t = SRType_LSL; 9975 shift_n = 0; 9976 break; 9977 case eEncodingT2: 9978 Rd = Bits32(opcode, 11, 8); 9979 Rn = Bits32(opcode, 19, 16); 9980 Rm = Bits32(opcode, 3, 0); 9981 setflags = BitIsSet(opcode, 20); 9982 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9983 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9984 return false; 9985 break; 9986 case eEncodingA1: 9987 Rd = Bits32(opcode, 15, 12); 9988 Rn = Bits32(opcode, 19, 16); 9989 Rm = Bits32(opcode, 3, 0); 9990 setflags = BitIsSet(opcode, 20); 9991 shift_n = DecodeImmShiftARM(opcode, shift_t); 9992 9993 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9994 // instructions; 9995 if (Rd == 15 && setflags) 9996 return EmulateSUBSPcLrEtc(opcode, encoding); 9997 break; 9998 default: 9999 return false; 10000 } 10001 // Read the register value from register Rn. 10002 uint32_t val1 = ReadCoreReg(Rn, &success); 10003 if (!success) 10004 return false; 10005 10006 // Read the register value from register Rm. 10007 uint32_t val2 = ReadCoreReg(Rm, &success); 10008 if (!success) 10009 return false; 10010 10011 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 10012 if (!success) 10013 return false; 10014 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 10015 10016 EmulateInstruction::Context context; 10017 context.type = EmulateInstruction::eContextImmediate; 10018 context.SetNoArgs(); 10019 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 10020 res.carry_out, res.overflow)) 10021 return false; 10022 10023 return true; 10024 } 10025 10026 // This instruction subtracts an immediate value from a register value, and 10027 // writes the result 10028 // to the destination register. It can optionally update the condition flags 10029 // based on the result. 10030 bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode, 10031 const ARMEncoding encoding) { 10032 #if 0 10033 // ARM pseudo code... 10034 if ConditionPassed() then 10035 EncodingSpecificOperations(); 10036 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 10037 R[d] = result; 10038 if setflags then 10039 APSR.N = result<31>; 10040 APSR.Z = IsZeroBit(result); 10041 APSR.C = carry; 10042 APSR.V = overflow; 10043 #endif 10044 10045 bool success = false; 10046 10047 uint32_t Rd; // the destination register 10048 uint32_t Rn; // the first operand 10049 bool setflags; 10050 uint32_t imm32; // the immediate value to be subtracted from the value 10051 // obtained from Rn 10052 switch (encoding) { 10053 case eEncodingT1: 10054 Rd = Bits32(opcode, 2, 0); 10055 Rn = Bits32(opcode, 5, 3); 10056 setflags = !InITBlock(); 10057 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 10058 break; 10059 case eEncodingT2: 10060 Rd = Rn = Bits32(opcode, 10, 8); 10061 setflags = !InITBlock(); 10062 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 10063 break; 10064 case eEncodingT3: 10065 Rd = Bits32(opcode, 11, 8); 10066 Rn = Bits32(opcode, 19, 16); 10067 setflags = BitIsSet(opcode, 20); 10068 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 10069 10070 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 10071 if (Rd == 15 && setflags) 10072 return EmulateCMPImm(opcode, eEncodingT2); 10073 10074 // if Rn == '1101' then SEE SUB (SP minus immediate); 10075 if (Rn == 13) 10076 return EmulateSUBSPImm(opcode, eEncodingT2); 10077 10078 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 10079 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 10080 return false; 10081 break; 10082 case eEncodingT4: 10083 Rd = Bits32(opcode, 11, 8); 10084 Rn = Bits32(opcode, 19, 16); 10085 setflags = BitIsSet(opcode, 20); 10086 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 10087 10088 // if Rn == '1111' then SEE ADR; 10089 if (Rn == 15) 10090 return EmulateADR(opcode, eEncodingT2); 10091 10092 // if Rn == '1101' then SEE SUB (SP minus immediate); 10093 if (Rn == 13) 10094 return EmulateSUBSPImm(opcode, eEncodingT3); 10095 10096 if (BadReg(Rd)) 10097 return false; 10098 break; 10099 default: 10100 return false; 10101 } 10102 // Read the register value from the operand register Rn. 10103 uint32_t reg_val = ReadCoreReg(Rn, &success); 10104 if (!success) 10105 return false; 10106 10107 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 10108 10109 EmulateInstruction::Context context; 10110 context.type = EmulateInstruction::eContextImmediate; 10111 context.SetNoArgs(); 10112 10113 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 10114 res.carry_out, res.overflow)) 10115 return false; 10116 10117 return true; 10118 } 10119 10120 // This instruction subtracts an immediate value from a register value, and 10121 // writes the result 10122 // to the destination register. It can optionally update the condition flags 10123 // based on the result. 10124 bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode, 10125 const ARMEncoding encoding) { 10126 #if 0 10127 // ARM pseudo code... 10128 if ConditionPassed() then 10129 EncodingSpecificOperations(); 10130 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 10131 if d == 15 then 10132 ALUWritePC(result); // setflags is always FALSE here 10133 else 10134 R[d] = result; 10135 if setflags then 10136 APSR.N = result<31>; 10137 APSR.Z = IsZeroBit(result); 10138 APSR.C = carry; 10139 APSR.V = overflow; 10140 #endif 10141 10142 bool success = false; 10143 10144 if (ConditionPassed(opcode)) { 10145 uint32_t Rd; // the destination register 10146 uint32_t Rn; // the first operand 10147 bool setflags; 10148 uint32_t imm32; // the immediate value to be subtracted from the value 10149 // obtained from Rn 10150 switch (encoding) { 10151 case eEncodingA1: 10152 Rd = Bits32(opcode, 15, 12); 10153 Rn = Bits32(opcode, 19, 16); 10154 setflags = BitIsSet(opcode, 20); 10155 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 10156 10157 // if Rn == '1111' && S == '0' then SEE ADR; 10158 if (Rn == 15 && !setflags) 10159 return EmulateADR(opcode, eEncodingA2); 10160 10161 // if Rn == '1101' then SEE SUB (SP minus immediate); 10162 if (Rn == 13) 10163 return EmulateSUBSPImm(opcode, eEncodingA1); 10164 10165 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10166 // instructions; 10167 if (Rd == 15 && setflags) 10168 return EmulateSUBSPcLrEtc(opcode, encoding); 10169 break; 10170 default: 10171 return false; 10172 } 10173 // Read the register value from the operand register Rn. 10174 uint32_t reg_val = ReadCoreReg(Rn, &success); 10175 if (!success) 10176 return false; 10177 10178 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 10179 10180 EmulateInstruction::Context context; 10181 if (Rd == 13) 10182 context.type = EmulateInstruction::eContextAdjustStackPointer; 10183 else 10184 context.type = EmulateInstruction::eContextRegisterPlusOffset; 10185 10186 RegisterInfo dwarf_reg; 10187 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 10188 int64_t imm32_signed = imm32; 10189 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed); 10190 10191 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 10192 res.carry_out, res.overflow)) 10193 return false; 10194 } 10195 return true; 10196 } 10197 10198 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a 10199 // register value and an 10200 // immediate value. It updates the condition flags based on the result, and 10201 // discards the result. 10202 bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode, 10203 const ARMEncoding encoding) { 10204 #if 0 10205 // ARM pseudo code... 10206 if ConditionPassed() then 10207 EncodingSpecificOperations(); 10208 result = R[n] EOR imm32; 10209 APSR.N = result<31>; 10210 APSR.Z = IsZeroBit(result); 10211 APSR.C = carry; 10212 // APSR.V unchanged 10213 #endif 10214 10215 bool success = false; 10216 10217 if (ConditionPassed(opcode)) { 10218 uint32_t Rn; 10219 uint32_t 10220 imm32; // the immediate value to be ANDed to the value obtained from Rn 10221 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 10222 switch (encoding) { 10223 case eEncodingT1: 10224 Rn = Bits32(opcode, 19, 16); 10225 imm32 = ThumbExpandImm_C( 10226 opcode, APSR_C, 10227 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 10228 if (BadReg(Rn)) 10229 return false; 10230 break; 10231 case eEncodingA1: 10232 Rn = Bits32(opcode, 19, 16); 10233 imm32 = 10234 ARMExpandImm_C(opcode, APSR_C, 10235 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 10236 break; 10237 default: 10238 return false; 10239 } 10240 10241 // Read the first operand. 10242 uint32_t val1 = ReadCoreReg(Rn, &success); 10243 if (!success) 10244 return false; 10245 10246 uint32_t result = val1 ^ imm32; 10247 10248 EmulateInstruction::Context context; 10249 context.type = EmulateInstruction::eContextImmediate; 10250 context.SetNoArgs(); 10251 10252 if (!WriteFlags(context, result, carry)) 10253 return false; 10254 } 10255 return true; 10256 } 10257 10258 // Test Equivalence (register) performs a bitwise exclusive OR operation on a 10259 // register value and an 10260 // optionally-shifted register value. It updates the condition flags based on 10261 // the result, and discards 10262 // the result. 10263 bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode, 10264 const ARMEncoding encoding) { 10265 #if 0 10266 // ARM pseudo code... 10267 if ConditionPassed() then 10268 EncodingSpecificOperations(); 10269 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 10270 result = R[n] EOR shifted; 10271 APSR.N = result<31>; 10272 APSR.Z = IsZeroBit(result); 10273 APSR.C = carry; 10274 // APSR.V unchanged 10275 #endif 10276 10277 bool success = false; 10278 10279 if (ConditionPassed(opcode)) { 10280 uint32_t Rn, Rm; 10281 ARM_ShifterType shift_t; 10282 uint32_t shift_n; // the shift applied to the value read from Rm 10283 uint32_t carry; 10284 switch (encoding) { 10285 case eEncodingT1: 10286 Rn = Bits32(opcode, 19, 16); 10287 Rm = Bits32(opcode, 3, 0); 10288 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10289 if (BadReg(Rn) || BadReg(Rm)) 10290 return false; 10291 break; 10292 case eEncodingA1: 10293 Rn = Bits32(opcode, 19, 16); 10294 Rm = Bits32(opcode, 3, 0); 10295 shift_n = DecodeImmShiftARM(opcode, shift_t); 10296 break; 10297 default: 10298 return false; 10299 } 10300 10301 // Read the first operand. 10302 uint32_t val1 = ReadCoreReg(Rn, &success); 10303 if (!success) 10304 return false; 10305 10306 // Read the second operand. 10307 uint32_t val2 = ReadCoreReg(Rm, &success); 10308 if (!success) 10309 return false; 10310 10311 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 10312 if (!success) 10313 return false; 10314 uint32_t result = val1 ^ shifted; 10315 10316 EmulateInstruction::Context context; 10317 context.type = EmulateInstruction::eContextImmediate; 10318 context.SetNoArgs(); 10319 10320 if (!WriteFlags(context, result, carry)) 10321 return false; 10322 } 10323 return true; 10324 } 10325 10326 // Test (immediate) performs a bitwise AND operation on a register value and an 10327 // immediate value. 10328 // It updates the condition flags based on the result, and discards the result. 10329 bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode, 10330 const ARMEncoding encoding) { 10331 #if 0 10332 // ARM pseudo code... 10333 if ConditionPassed() then 10334 EncodingSpecificOperations(); 10335 result = R[n] AND imm32; 10336 APSR.N = result<31>; 10337 APSR.Z = IsZeroBit(result); 10338 APSR.C = carry; 10339 // APSR.V unchanged 10340 #endif 10341 10342 bool success = false; 10343 10344 if (ConditionPassed(opcode)) { 10345 uint32_t Rn; 10346 uint32_t 10347 imm32; // the immediate value to be ANDed to the value obtained from Rn 10348 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 10349 switch (encoding) { 10350 case eEncodingT1: 10351 Rn = Bits32(opcode, 19, 16); 10352 imm32 = ThumbExpandImm_C( 10353 opcode, APSR_C, 10354 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 10355 if (BadReg(Rn)) 10356 return false; 10357 break; 10358 case eEncodingA1: 10359 Rn = Bits32(opcode, 19, 16); 10360 imm32 = 10361 ARMExpandImm_C(opcode, APSR_C, 10362 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 10363 break; 10364 default: 10365 return false; 10366 } 10367 10368 // Read the first operand. 10369 uint32_t val1 = ReadCoreReg(Rn, &success); 10370 if (!success) 10371 return false; 10372 10373 uint32_t result = val1 & imm32; 10374 10375 EmulateInstruction::Context context; 10376 context.type = EmulateInstruction::eContextImmediate; 10377 context.SetNoArgs(); 10378 10379 if (!WriteFlags(context, result, carry)) 10380 return false; 10381 } 10382 return true; 10383 } 10384 10385 // Test (register) performs a bitwise AND operation on a register value and an 10386 // optionally-shifted register value. 10387 // It updates the condition flags based on the result, and discards the result. 10388 bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode, 10389 const ARMEncoding encoding) { 10390 #if 0 10391 // ARM pseudo code... 10392 if ConditionPassed() then 10393 EncodingSpecificOperations(); 10394 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 10395 result = R[n] AND shifted; 10396 APSR.N = result<31>; 10397 APSR.Z = IsZeroBit(result); 10398 APSR.C = carry; 10399 // APSR.V unchanged 10400 #endif 10401 10402 bool success = false; 10403 10404 if (ConditionPassed(opcode)) { 10405 uint32_t Rn, Rm; 10406 ARM_ShifterType shift_t; 10407 uint32_t shift_n; // the shift applied to the value read from Rm 10408 uint32_t carry; 10409 switch (encoding) { 10410 case eEncodingT1: 10411 Rn = Bits32(opcode, 2, 0); 10412 Rm = Bits32(opcode, 5, 3); 10413 shift_t = SRType_LSL; 10414 shift_n = 0; 10415 break; 10416 case eEncodingT2: 10417 Rn = Bits32(opcode, 19, 16); 10418 Rm = Bits32(opcode, 3, 0); 10419 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10420 if (BadReg(Rn) || BadReg(Rm)) 10421 return false; 10422 break; 10423 case eEncodingA1: 10424 Rn = Bits32(opcode, 19, 16); 10425 Rm = Bits32(opcode, 3, 0); 10426 shift_n = DecodeImmShiftARM(opcode, shift_t); 10427 break; 10428 default: 10429 return false; 10430 } 10431 10432 // Read the first operand. 10433 uint32_t val1 = ReadCoreReg(Rn, &success); 10434 if (!success) 10435 return false; 10436 10437 // Read the second operand. 10438 uint32_t val2 = ReadCoreReg(Rm, &success); 10439 if (!success) 10440 return false; 10441 10442 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 10443 if (!success) 10444 return false; 10445 uint32_t result = val1 & shifted; 10446 10447 EmulateInstruction::Context context; 10448 context.type = EmulateInstruction::eContextImmediate; 10449 context.SetNoArgs(); 10450 10451 if (!WriteFlags(context, result, carry)) 10452 return false; 10453 } 10454 return true; 10455 } 10456 10457 // A8.6.216 SUB (SP minus register) 10458 bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode, 10459 const ARMEncoding encoding) { 10460 #if 0 10461 if ConditionPassed() then 10462 EncodingSpecificOperations(); 10463 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10464 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10465 if d == 15 then // Can only occur for ARM encoding 10466 ALUWritePC(result); // setflags is always FALSE here 10467 else 10468 R[d] = result; 10469 if setflags then 10470 APSR.N = result<31>; 10471 APSR.Z = IsZeroBit(result); 10472 APSR.C = carry; 10473 APSR.V = overflow; 10474 #endif 10475 10476 bool success = false; 10477 10478 if (ConditionPassed(opcode)) { 10479 uint32_t d; 10480 uint32_t m; 10481 bool setflags; 10482 ARM_ShifterType shift_t; 10483 uint32_t shift_n; 10484 10485 switch (encoding) { 10486 case eEncodingT1: 10487 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10488 d = Bits32(opcode, 11, 8); 10489 m = Bits32(opcode, 3, 0); 10490 setflags = BitIsSet(opcode, 20); 10491 10492 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10493 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10494 10495 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then 10496 // UNPREDICTABLE; 10497 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 10498 return false; 10499 10500 // if d == 15 || BadReg(m) then UNPREDICTABLE; 10501 if ((d == 15) || BadReg(m)) 10502 return false; 10503 break; 10504 10505 case eEncodingA1: 10506 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10507 d = Bits32(opcode, 15, 12); 10508 m = Bits32(opcode, 3, 0); 10509 setflags = BitIsSet(opcode, 20); 10510 10511 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10512 // instructions; 10513 if (d == 15 && setflags) 10514 EmulateSUBSPcLrEtc(opcode, encoding); 10515 10516 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10517 shift_n = DecodeImmShiftARM(opcode, shift_t); 10518 break; 10519 10520 default: 10521 return false; 10522 } 10523 10524 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10525 uint32_t Rm = ReadCoreReg(m, &success); 10526 if (!success) 10527 return false; 10528 10529 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10530 if (!success) 10531 return false; 10532 10533 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10534 uint32_t sp_val = ReadCoreReg(SP_REG, &success); 10535 if (!success) 10536 return false; 10537 10538 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1); 10539 10540 EmulateInstruction::Context context; 10541 context.type = eContextArithmetic; 10542 RegisterInfo sp_reg; 10543 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 10544 RegisterInfo dwarf_reg; 10545 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 10546 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg); 10547 10548 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10549 res.carry_out, res.overflow)) 10550 return false; 10551 } 10552 return true; 10553 } 10554 10555 // A8.6.7 ADD (register-shifted register) 10556 bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode, 10557 const ARMEncoding encoding) { 10558 #if 0 10559 if ConditionPassed() then 10560 EncodingSpecificOperations(); 10561 shift_n = UInt(R[s]<7:0>); 10562 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10563 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10564 R[d] = result; 10565 if setflags then 10566 APSR.N = result<31>; 10567 APSR.Z = IsZeroBit(result); 10568 APSR.C = carry; 10569 APSR.V = overflow; 10570 #endif 10571 10572 bool success = false; 10573 10574 if (ConditionPassed(opcode)) { 10575 uint32_t d; 10576 uint32_t n; 10577 uint32_t m; 10578 uint32_t s; 10579 bool setflags; 10580 ARM_ShifterType shift_t; 10581 10582 switch (encoding) { 10583 case eEncodingA1: 10584 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 10585 d = Bits32(opcode, 15, 12); 10586 n = Bits32(opcode, 19, 16); 10587 m = Bits32(opcode, 3, 0); 10588 s = Bits32(opcode, 11, 8); 10589 10590 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 10591 setflags = BitIsSet(opcode, 20); 10592 shift_t = DecodeRegShift(Bits32(opcode, 6, 5)); 10593 10594 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 10595 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 10596 return false; 10597 break; 10598 10599 default: 10600 return false; 10601 } 10602 10603 // shift_n = UInt(R[s]<7:0>); 10604 uint32_t Rs = ReadCoreReg(s, &success); 10605 if (!success) 10606 return false; 10607 10608 uint32_t shift_n = Bits32(Rs, 7, 0); 10609 10610 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10611 uint32_t Rm = ReadCoreReg(m, &success); 10612 if (!success) 10613 return false; 10614 10615 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10616 if (!success) 10617 return false; 10618 10619 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10620 uint32_t Rn = ReadCoreReg(n, &success); 10621 if (!success) 10622 return false; 10623 10624 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0); 10625 10626 // R[d] = result; 10627 EmulateInstruction::Context context; 10628 context.type = eContextArithmetic; 10629 RegisterInfo reg_n; 10630 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10631 RegisterInfo reg_m; 10632 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10633 10634 context.SetRegisterRegisterOperands(reg_n, reg_m); 10635 10636 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 10637 res.result)) 10638 return false; 10639 10640 // if setflags then 10641 // APSR.N = result<31>; 10642 // APSR.Z = IsZeroBit(result); 10643 // APSR.C = carry; 10644 // APSR.V = overflow; 10645 if (setflags) 10646 return WriteFlags(context, res.result, res.carry_out, res.overflow); 10647 } 10648 return true; 10649 } 10650 10651 // A8.6.213 SUB (register) 10652 bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode, 10653 const ARMEncoding encoding) { 10654 #if 0 10655 if ConditionPassed() then 10656 EncodingSpecificOperations(); 10657 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10658 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10659 if d == 15 then // Can only occur for ARM encoding 10660 ALUWritePC(result); // setflags is always FALSE here 10661 else 10662 R[d] = result; 10663 if setflags then 10664 APSR.N = result<31>; 10665 APSR.Z = IsZeroBit(result); 10666 APSR.C = carry; 10667 APSR.V = overflow; 10668 #endif 10669 10670 bool success = false; 10671 10672 if (ConditionPassed(opcode)) { 10673 uint32_t d; 10674 uint32_t n; 10675 uint32_t m; 10676 bool setflags; 10677 ARM_ShifterType shift_t; 10678 uint32_t shift_n; 10679 10680 switch (encoding) { 10681 case eEncodingT1: 10682 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 10683 d = Bits32(opcode, 2, 0); 10684 n = Bits32(opcode, 5, 3); 10685 m = Bits32(opcode, 8, 6); 10686 setflags = !InITBlock(); 10687 10688 // (shift_t, shift_n) = (SRType_LSL, 0); 10689 shift_t = SRType_LSL; 10690 shift_n = 0; 10691 10692 break; 10693 10694 case eEncodingT2: 10695 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 10696 d = Bits32(opcode, 11, 8); 10697 n = Bits32(opcode, 19, 16); 10698 m = Bits32(opcode, 3, 0); 10699 setflags = BitIsSet(opcode, 20); 10700 10701 // if Rd == "1111" && S == "1" then SEE CMP (register); 10702 if (d == 15 && setflags == 1) 10703 return EmulateCMPImm(opcode, eEncodingT3); 10704 10705 // if Rn == "1101" then SEE SUB (SP minus register); 10706 if (n == 13) 10707 return EmulateSUBSPReg(opcode, eEncodingT1); 10708 10709 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10710 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10711 10712 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then 10713 // UNPREDICTABLE; 10714 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) || 10715 BadReg(m)) 10716 return false; 10717 10718 break; 10719 10720 case eEncodingA1: 10721 // if Rn == '1101' then SEE SUB (SP minus register); 10722 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 10723 d = Bits32(opcode, 15, 12); 10724 n = Bits32(opcode, 19, 16); 10725 m = Bits32(opcode, 3, 0); 10726 setflags = BitIsSet(opcode, 20); 10727 10728 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10729 // instructions; 10730 if ((d == 15) && setflags) 10731 EmulateSUBSPcLrEtc(opcode, encoding); 10732 10733 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10734 shift_n = DecodeImmShiftARM(opcode, shift_t); 10735 10736 break; 10737 10738 default: 10739 return false; 10740 } 10741 10742 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10743 uint32_t Rm = ReadCoreReg(m, &success); 10744 if (!success) 10745 return false; 10746 10747 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10748 if (!success) 10749 return false; 10750 10751 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10752 uint32_t Rn = ReadCoreReg(n, &success); 10753 if (!success) 10754 return false; 10755 10756 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1); 10757 10758 // if d == 15 then // Can only occur for ARM encoding 10759 // ALUWritePC(result); // setflags is always FALSE here 10760 // else 10761 // R[d] = result; 10762 // if setflags then 10763 // APSR.N = result<31>; 10764 // APSR.Z = IsZeroBit(result); 10765 // APSR.C = carry; 10766 // APSR.V = overflow; 10767 10768 EmulateInstruction::Context context; 10769 context.type = eContextArithmetic; 10770 RegisterInfo reg_n; 10771 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10772 RegisterInfo reg_m; 10773 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10774 context.SetRegisterRegisterOperands(reg_n, reg_m); 10775 10776 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10777 res.carry_out, res.overflow)) 10778 return false; 10779 } 10780 return true; 10781 } 10782 10783 // A8.6.202 STREX 10784 // Store Register Exclusive calculates an address from a base register value and 10785 // an immediate offset, and stores a 10786 // word from a register to memory if the executing processor has exclusive 10787 // access to the memory addressed. 10788 bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode, 10789 const ARMEncoding encoding) { 10790 #if 0 10791 if ConditionPassed() then 10792 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10793 address = R[n] + imm32; 10794 if ExclusiveMonitorsPass(address,4) then 10795 MemA[address,4] = R[t]; 10796 R[d] = 0; 10797 else 10798 R[d] = 1; 10799 #endif 10800 10801 bool success = false; 10802 10803 if (ConditionPassed(opcode)) { 10804 uint32_t d; 10805 uint32_t t; 10806 uint32_t n; 10807 uint32_t imm32; 10808 const uint32_t addr_byte_size = GetAddressByteSize(); 10809 10810 switch (encoding) { 10811 case eEncodingT1: 10812 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 10813 // 32); 10814 d = Bits32(opcode, 11, 8); 10815 t = Bits32(opcode, 15, 12); 10816 n = Bits32(opcode, 19, 16); 10817 imm32 = Bits32(opcode, 7, 0) << 2; 10818 10819 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 10820 if (BadReg(d) || BadReg(t) || (n == 15)) 10821 return false; 10822 10823 // if d == n || d == t then UNPREDICTABLE; 10824 if ((d == n) || (d == t)) 10825 return false; 10826 10827 break; 10828 10829 case eEncodingA1: 10830 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero 10831 // offset 10832 d = Bits32(opcode, 15, 12); 10833 t = Bits32(opcode, 3, 0); 10834 n = Bits32(opcode, 19, 16); 10835 imm32 = 0; 10836 10837 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 10838 if ((d == 15) || (t == 15) || (n == 15)) 10839 return false; 10840 10841 // if d == n || d == t then UNPREDICTABLE; 10842 if ((d == n) || (d == t)) 10843 return false; 10844 10845 break; 10846 10847 default: 10848 return false; 10849 } 10850 10851 // address = R[n] + imm32; 10852 uint32_t Rn = ReadCoreReg(n, &success); 10853 if (!success) 10854 return false; 10855 10856 addr_t address = Rn + imm32; 10857 10858 RegisterInfo base_reg; 10859 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10860 RegisterInfo data_reg; 10861 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10862 EmulateInstruction::Context context; 10863 context.type = eContextRegisterStore; 10864 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32); 10865 10866 // if ExclusiveMonitorsPass(address,4) then 10867 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the 10868 // sake of emulation, we will say this 10869 // always return 10870 // true. 10871 if (true) { 10872 // MemA[address,4] = R[t]; 10873 uint32_t Rt = 10874 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 10875 if (!success) 10876 return false; 10877 10878 if (!MemAWrite(context, address, Rt, addr_byte_size)) 10879 return false; 10880 10881 // R[d] = 0; 10882 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 10883 return false; 10884 } 10885 #if 0 // unreachable because if true 10886 else 10887 { 10888 // R[d] = 1; 10889 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 10890 return false; 10891 } 10892 #endif // unreachable because if true 10893 } 10894 return true; 10895 } 10896 10897 // A8.6.197 STRB (immediate, ARM) 10898 bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode, 10899 const ARMEncoding encoding) { 10900 #if 0 10901 if ConditionPassed() then 10902 EncodingSpecificOperations(); 10903 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10904 address = if index then offset_addr else R[n]; 10905 MemU[address,1] = R[t]<7:0>; 10906 if wback then R[n] = offset_addr; 10907 #endif 10908 10909 bool success = false; 10910 10911 if (ConditionPassed(opcode)) { 10912 uint32_t t; 10913 uint32_t n; 10914 uint32_t imm32; 10915 bool index; 10916 bool add; 10917 bool wback; 10918 10919 switch (encoding) { 10920 case eEncodingA1: 10921 // if P == '0' && W == '1' then SEE STRBT; 10922 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10923 t = Bits32(opcode, 15, 12); 10924 n = Bits32(opcode, 19, 16); 10925 imm32 = Bits32(opcode, 11, 0); 10926 10927 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10928 index = BitIsSet(opcode, 24); 10929 add = BitIsSet(opcode, 23); 10930 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10931 10932 // if t == 15 then UNPREDICTABLE; 10933 if (t == 15) 10934 return false; 10935 10936 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10937 if (wback && ((n == 15) || (n == t))) 10938 return false; 10939 10940 break; 10941 10942 default: 10943 return false; 10944 } 10945 10946 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10947 uint32_t Rn = ReadCoreReg(n, &success); 10948 if (!success) 10949 return false; 10950 10951 addr_t offset_addr; 10952 if (add) 10953 offset_addr = Rn + imm32; 10954 else 10955 offset_addr = Rn - imm32; 10956 10957 // address = if index then offset_addr else R[n]; 10958 addr_t address; 10959 if (index) 10960 address = offset_addr; 10961 else 10962 address = Rn; 10963 10964 // MemU[address,1] = R[t]<7:0>; 10965 uint32_t Rt = ReadCoreReg(t, &success); 10966 if (!success) 10967 return false; 10968 10969 RegisterInfo base_reg; 10970 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10971 RegisterInfo data_reg; 10972 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10973 EmulateInstruction::Context context; 10974 context.type = eContextRegisterStore; 10975 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10976 10977 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1)) 10978 return false; 10979 10980 // if wback then R[n] = offset_addr; 10981 if (wback) { 10982 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10983 offset_addr)) 10984 return false; 10985 } 10986 } 10987 return true; 10988 } 10989 10990 // A8.6.194 STR (immediate, ARM) 10991 bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode, 10992 const ARMEncoding encoding) { 10993 #if 0 10994 if ConditionPassed() then 10995 EncodingSpecificOperations(); 10996 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10997 address = if index then offset_addr else R[n]; 10998 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10999 if wback then R[n] = offset_addr; 11000 #endif 11001 11002 bool success = false; 11003 11004 if (ConditionPassed(opcode)) { 11005 uint32_t t; 11006 uint32_t n; 11007 uint32_t imm32; 11008 bool index; 11009 bool add; 11010 bool wback; 11011 11012 const uint32_t addr_byte_size = GetAddressByteSize(); 11013 11014 switch (encoding) { 11015 case eEncodingA1: 11016 // if P == '0' && W == '1' then SEE STRT; 11017 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == 11018 // '000000000100' then SEE PUSH; 11019 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 11020 t = Bits32(opcode, 15, 12); 11021 n = Bits32(opcode, 19, 16); 11022 imm32 = Bits32(opcode, 11, 0); 11023 11024 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11025 index = BitIsSet(opcode, 24); 11026 add = BitIsSet(opcode, 23); 11027 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11028 11029 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 11030 if (wback && ((n == 15) || (n == t))) 11031 return false; 11032 11033 break; 11034 11035 default: 11036 return false; 11037 } 11038 11039 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11040 uint32_t Rn = ReadCoreReg(n, &success); 11041 if (!success) 11042 return false; 11043 11044 addr_t offset_addr; 11045 if (add) 11046 offset_addr = Rn + imm32; 11047 else 11048 offset_addr = Rn - imm32; 11049 11050 // address = if index then offset_addr else R[n]; 11051 addr_t address; 11052 if (index) 11053 address = offset_addr; 11054 else 11055 address = Rn; 11056 11057 RegisterInfo base_reg; 11058 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11059 RegisterInfo data_reg; 11060 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11061 EmulateInstruction::Context context; 11062 context.type = eContextRegisterStore; 11063 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11064 11065 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 11066 uint32_t Rt = ReadCoreReg(t, &success); 11067 if (!success) 11068 return false; 11069 11070 if (t == 15) { 11071 uint32_t pc_value = ReadCoreReg(PC_REG, &success); 11072 if (!success) 11073 return false; 11074 11075 if (!MemUWrite(context, address, pc_value, addr_byte_size)) 11076 return false; 11077 } else { 11078 if (!MemUWrite(context, address, Rt, addr_byte_size)) 11079 return false; 11080 } 11081 11082 // if wback then R[n] = offset_addr; 11083 if (wback) { 11084 context.type = eContextAdjustBaseRegister; 11085 context.SetImmediate(offset_addr); 11086 11087 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11088 offset_addr)) 11089 return false; 11090 } 11091 } 11092 return true; 11093 } 11094 11095 // A8.6.66 LDRD (immediate) 11096 // Load Register Dual (immediate) calculates an address from a base register 11097 // value and an immediate offset, loads two 11098 // words from memory, and writes them to two registers. It can use offset, 11099 // post-indexed, or pre-indexed addressing. 11100 bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode, 11101 const ARMEncoding encoding) { 11102 #if 0 11103 if ConditionPassed() then 11104 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 11105 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11106 address = if index then offset_addr else R[n]; 11107 R[t] = MemA[address,4]; 11108 R[t2] = MemA[address+4,4]; 11109 if wback then R[n] = offset_addr; 11110 #endif 11111 11112 bool success = false; 11113 11114 if (ConditionPassed(opcode)) { 11115 uint32_t t; 11116 uint32_t t2; 11117 uint32_t n; 11118 uint32_t imm32; 11119 bool index; 11120 bool add; 11121 bool wback; 11122 11123 switch (encoding) { 11124 case eEncodingT1: 11125 // if P == '0' && W == '0' then SEE 'Related encodings'; 11126 // if Rn == '1111' then SEE LDRD (literal); 11127 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 11128 // ZeroExtend(imm8:'00', 32); 11129 t = Bits32(opcode, 15, 12); 11130 t2 = Bits32(opcode, 11, 8); 11131 n = Bits32(opcode, 19, 16); 11132 imm32 = Bits32(opcode, 7, 0) << 2; 11133 11134 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 11135 index = BitIsSet(opcode, 24); 11136 add = BitIsSet(opcode, 23); 11137 wback = BitIsSet(opcode, 21); 11138 11139 // if wback && (n == t || n == t2) then UNPREDICTABLE; 11140 if (wback && ((n == t) || (n == t2))) 11141 return false; 11142 11143 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 11144 if (BadReg(t) || BadReg(t2) || (t == t2)) 11145 return false; 11146 11147 break; 11148 11149 case eEncodingA1: 11150 // if Rn == '1111' then SEE LDRD (literal); 11151 // if Rt<0> == '1' then UNPREDICTABLE; 11152 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 11153 // 32); 11154 t = Bits32(opcode, 15, 12); 11155 if (BitIsSet(t, 0)) 11156 return false; 11157 t2 = t + 1; 11158 n = Bits32(opcode, 19, 16); 11159 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 11160 11161 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11162 index = BitIsSet(opcode, 24); 11163 add = BitIsSet(opcode, 23); 11164 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11165 11166 // if P == '0' && W == '1' then UNPREDICTABLE; 11167 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11168 return false; 11169 11170 // if wback && (n == t || n == t2) then UNPREDICTABLE; 11171 if (wback && ((n == t) || (n == t2))) 11172 return false; 11173 11174 // if t2 == 15 then UNPREDICTABLE; 11175 if (t2 == 15) 11176 return false; 11177 11178 break; 11179 11180 default: 11181 return false; 11182 } 11183 11184 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11185 uint32_t Rn = ReadCoreReg(n, &success); 11186 if (!success) 11187 return false; 11188 11189 addr_t offset_addr; 11190 if (add) 11191 offset_addr = Rn + imm32; 11192 else 11193 offset_addr = Rn - imm32; 11194 11195 // address = if index then offset_addr else R[n]; 11196 addr_t address; 11197 if (index) 11198 address = offset_addr; 11199 else 11200 address = Rn; 11201 11202 // R[t] = MemA[address,4]; 11203 RegisterInfo base_reg; 11204 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11205 11206 EmulateInstruction::Context context; 11207 if (n == 13) 11208 context.type = eContextPopRegisterOffStack; 11209 else 11210 context.type = eContextRegisterLoad; 11211 context.SetAddress(address); 11212 11213 const uint32_t addr_byte_size = GetAddressByteSize(); 11214 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11215 if (!success) 11216 return false; 11217 11218 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 11219 return false; 11220 11221 // R[t2] = MemA[address+4,4]; 11222 context.SetAddress(address + 4); 11223 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 11224 if (!success) 11225 return false; 11226 11227 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 11228 data)) 11229 return false; 11230 11231 // if wback then R[n] = offset_addr; 11232 if (wback) { 11233 context.type = eContextAdjustBaseRegister; 11234 context.SetAddress(offset_addr); 11235 11236 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11237 offset_addr)) 11238 return false; 11239 } 11240 } 11241 return true; 11242 } 11243 11244 // A8.6.68 LDRD (register) 11245 // Load Register Dual (register) calculates an address from a base register 11246 // value and a register offset, loads two 11247 // words from memory, and writes them to two registers. It can use offset, 11248 // post-indexed or pre-indexed addressing. 11249 bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode, 11250 const ARMEncoding encoding) { 11251 #if 0 11252 if ConditionPassed() then 11253 EncodingSpecificOperations(); 11254 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11255 address = if index then offset_addr else R[n]; 11256 R[t] = MemA[address,4]; 11257 R[t2] = MemA[address+4,4]; 11258 if wback then R[n] = offset_addr; 11259 #endif 11260 11261 bool success = false; 11262 11263 if (ConditionPassed(opcode)) { 11264 uint32_t t; 11265 uint32_t t2; 11266 uint32_t n; 11267 uint32_t m; 11268 bool index; 11269 bool add; 11270 bool wback; 11271 11272 switch (encoding) { 11273 case eEncodingA1: 11274 // if Rt<0> == '1' then UNPREDICTABLE; 11275 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 11276 t = Bits32(opcode, 15, 12); 11277 if (BitIsSet(t, 0)) 11278 return false; 11279 t2 = t + 1; 11280 n = Bits32(opcode, 19, 16); 11281 m = Bits32(opcode, 3, 0); 11282 11283 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11284 index = BitIsSet(opcode, 24); 11285 add = BitIsSet(opcode, 23); 11286 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11287 11288 // if P == '0' && W == '1' then UNPREDICTABLE; 11289 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11290 return false; 11291 11292 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 11293 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 11294 return false; 11295 11296 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11297 if (wback && ((n == 15) || (n == t) || (n == t2))) 11298 return false; 11299 11300 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 11301 if ((ArchVersion() < 6) && wback && (m == n)) 11302 return false; 11303 break; 11304 11305 default: 11306 return false; 11307 } 11308 11309 uint32_t Rn = ReadCoreReg(n, &success); 11310 if (!success) 11311 return false; 11312 RegisterInfo base_reg; 11313 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11314 11315 uint32_t Rm = ReadCoreReg(m, &success); 11316 if (!success) 11317 return false; 11318 RegisterInfo offset_reg; 11319 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 11320 11321 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11322 addr_t offset_addr; 11323 if (add) 11324 offset_addr = Rn + Rm; 11325 else 11326 offset_addr = Rn - Rm; 11327 11328 // address = if index then offset_addr else R[n]; 11329 addr_t address; 11330 if (index) 11331 address = offset_addr; 11332 else 11333 address = Rn; 11334 11335 EmulateInstruction::Context context; 11336 if (n == 13) 11337 context.type = eContextPopRegisterOffStack; 11338 else 11339 context.type = eContextRegisterLoad; 11340 context.SetAddress(address); 11341 11342 // R[t] = MemA[address,4]; 11343 const uint32_t addr_byte_size = GetAddressByteSize(); 11344 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11345 if (!success) 11346 return false; 11347 11348 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 11349 return false; 11350 11351 // R[t2] = MemA[address+4,4]; 11352 11353 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 11354 if (!success) 11355 return false; 11356 11357 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 11358 data)) 11359 return false; 11360 11361 // if wback then R[n] = offset_addr; 11362 if (wback) { 11363 context.type = eContextAdjustBaseRegister; 11364 context.SetAddress(offset_addr); 11365 11366 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11367 offset_addr)) 11368 return false; 11369 } 11370 } 11371 return true; 11372 } 11373 11374 // A8.6.200 STRD (immediate) 11375 // Store Register Dual (immediate) calculates an address from a base register 11376 // value and an immediate offset, and 11377 // stores two words from two registers to memory. It can use offset, 11378 // post-indexed, or pre-indexed addressing. 11379 bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode, 11380 const ARMEncoding encoding) { 11381 #if 0 11382 if ConditionPassed() then 11383 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 11384 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11385 address = if index then offset_addr else R[n]; 11386 MemA[address,4] = R[t]; 11387 MemA[address+4,4] = R[t2]; 11388 if wback then R[n] = offset_addr; 11389 #endif 11390 11391 bool success = false; 11392 11393 if (ConditionPassed(opcode)) { 11394 uint32_t t; 11395 uint32_t t2; 11396 uint32_t n; 11397 uint32_t imm32; 11398 bool index; 11399 bool add; 11400 bool wback; 11401 11402 switch (encoding) { 11403 case eEncodingT1: 11404 // if P == '0' && W == '0' then SEE 'Related encodings'; 11405 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 11406 // ZeroExtend(imm8:'00', 32); 11407 t = Bits32(opcode, 15, 12); 11408 t2 = Bits32(opcode, 11, 8); 11409 n = Bits32(opcode, 19, 16); 11410 imm32 = Bits32(opcode, 7, 0) << 2; 11411 11412 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 11413 index = BitIsSet(opcode, 24); 11414 add = BitIsSet(opcode, 23); 11415 wback = BitIsSet(opcode, 21); 11416 11417 // if wback && (n == t || n == t2) then UNPREDICTABLE; 11418 if (wback && ((n == t) || (n == t2))) 11419 return false; 11420 11421 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 11422 if ((n == 15) || BadReg(t) || BadReg(t2)) 11423 return false; 11424 11425 break; 11426 11427 case eEncodingA1: 11428 // if Rt<0> == '1' then UNPREDICTABLE; 11429 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 11430 // 32); 11431 t = Bits32(opcode, 15, 12); 11432 if (BitIsSet(t, 0)) 11433 return false; 11434 11435 t2 = t + 1; 11436 n = Bits32(opcode, 19, 16); 11437 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 11438 11439 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11440 index = BitIsSet(opcode, 24); 11441 add = BitIsSet(opcode, 23); 11442 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11443 11444 // if P == '0' && W == '1' then UNPREDICTABLE; 11445 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11446 return false; 11447 11448 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11449 if (wback && ((n == 15) || (n == t) || (n == t2))) 11450 return false; 11451 11452 // if t2 == 15 then UNPREDICTABLE; 11453 if (t2 == 15) 11454 return false; 11455 11456 break; 11457 11458 default: 11459 return false; 11460 } 11461 11462 RegisterInfo base_reg; 11463 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11464 11465 uint32_t Rn = ReadCoreReg(n, &success); 11466 if (!success) 11467 return false; 11468 11469 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11470 addr_t offset_addr; 11471 if (add) 11472 offset_addr = Rn + imm32; 11473 else 11474 offset_addr = Rn - imm32; 11475 11476 // address = if index then offset_addr else R[n]; 11477 addr_t address; 11478 if (index) 11479 address = offset_addr; 11480 else 11481 address = Rn; 11482 11483 // MemA[address,4] = R[t]; 11484 RegisterInfo data_reg; 11485 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11486 11487 uint32_t data = ReadCoreReg(t, &success); 11488 if (!success) 11489 return false; 11490 11491 EmulateInstruction::Context context; 11492 if (n == 13) 11493 context.type = eContextPushRegisterOnStack; 11494 else 11495 context.type = eContextRegisterStore; 11496 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11497 11498 const uint32_t addr_byte_size = GetAddressByteSize(); 11499 11500 if (!MemAWrite(context, address, data, addr_byte_size)) 11501 return false; 11502 11503 // MemA[address+4,4] = R[t2]; 11504 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11505 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11506 (address + 4) - Rn); 11507 11508 data = ReadCoreReg(t2, &success); 11509 if (!success) 11510 return false; 11511 11512 if (!MemAWrite(context, address + 4, data, addr_byte_size)) 11513 return false; 11514 11515 // if wback then R[n] = offset_addr; 11516 if (wback) { 11517 if (n == 13) 11518 context.type = eContextAdjustStackPointer; 11519 else 11520 context.type = eContextAdjustBaseRegister; 11521 context.SetAddress(offset_addr); 11522 11523 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11524 offset_addr)) 11525 return false; 11526 } 11527 } 11528 return true; 11529 } 11530 11531 // A8.6.201 STRD (register) 11532 bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode, 11533 const ARMEncoding encoding) { 11534 #if 0 11535 if ConditionPassed() then 11536 EncodingSpecificOperations(); 11537 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11538 address = if index then offset_addr else R[n]; 11539 MemA[address,4] = R[t]; 11540 MemA[address+4,4] = R[t2]; 11541 if wback then R[n] = offset_addr; 11542 #endif 11543 11544 bool success = false; 11545 11546 if (ConditionPassed(opcode)) { 11547 uint32_t t; 11548 uint32_t t2; 11549 uint32_t n; 11550 uint32_t m; 11551 bool index; 11552 bool add; 11553 bool wback; 11554 11555 switch (encoding) { 11556 case eEncodingA1: 11557 // if Rt<0> == '1' then UNPREDICTABLE; 11558 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 11559 t = Bits32(opcode, 15, 12); 11560 if (BitIsSet(t, 0)) 11561 return false; 11562 11563 t2 = t + 1; 11564 n = Bits32(opcode, 19, 16); 11565 m = Bits32(opcode, 3, 0); 11566 11567 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11568 index = BitIsSet(opcode, 24); 11569 add = BitIsSet(opcode, 23); 11570 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11571 11572 // if P == '0' && W == '1' then UNPREDICTABLE; 11573 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11574 return false; 11575 11576 // if t2 == 15 || m == 15 then UNPREDICTABLE; 11577 if ((t2 == 15) || (m == 15)) 11578 return false; 11579 11580 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11581 if (wback && ((n == 15) || (n == t) || (n == t2))) 11582 return false; 11583 11584 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 11585 if ((ArchVersion() < 6) && wback && (m == n)) 11586 return false; 11587 11588 break; 11589 11590 default: 11591 return false; 11592 } 11593 11594 RegisterInfo base_reg; 11595 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11596 RegisterInfo offset_reg; 11597 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 11598 RegisterInfo data_reg; 11599 11600 uint32_t Rn = ReadCoreReg(n, &success); 11601 if (!success) 11602 return false; 11603 11604 uint32_t Rm = ReadCoreReg(m, &success); 11605 if (!success) 11606 return false; 11607 11608 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11609 addr_t offset_addr; 11610 if (add) 11611 offset_addr = Rn + Rm; 11612 else 11613 offset_addr = Rn - Rm; 11614 11615 // address = if index then offset_addr else R[n]; 11616 addr_t address; 11617 if (index) 11618 address = offset_addr; 11619 else 11620 address = Rn; 11621 // MemA[address,4] = R[t]; 11622 uint32_t Rt = ReadCoreReg(t, &success); 11623 if (!success) 11624 return false; 11625 11626 EmulateInstruction::Context context; 11627 if (t == 13) 11628 context.type = eContextPushRegisterOnStack; 11629 else 11630 context.type = eContextRegisterStore; 11631 11632 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11633 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11634 data_reg); 11635 11636 const uint32_t addr_byte_size = GetAddressByteSize(); 11637 11638 if (!MemAWrite(context, address, Rt, addr_byte_size)) 11639 return false; 11640 11641 // MemA[address+4,4] = R[t2]; 11642 uint32_t Rt2 = ReadCoreReg(t2, &success); 11643 if (!success) 11644 return false; 11645 11646 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11647 11648 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11649 data_reg); 11650 11651 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size)) 11652 return false; 11653 11654 // if wback then R[n] = offset_addr; 11655 if (wback) { 11656 context.type = eContextAdjustBaseRegister; 11657 context.SetAddress(offset_addr); 11658 11659 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11660 offset_addr)) 11661 return false; 11662 } 11663 } 11664 return true; 11665 } 11666 11667 // A8.6.319 VLDM 11668 // Vector Load Multiple loads multiple extension registers from consecutive 11669 // memory locations using an address from 11670 // an ARM core register. 11671 bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode, 11672 const ARMEncoding encoding) { 11673 #if 0 11674 if ConditionPassed() then 11675 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11676 address = if add then R[n] else R[n]-imm32; 11677 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11678 for r = 0 to regs-1 11679 if single_regs then 11680 S[d+r] = MemA[address,4]; address = address+4; 11681 else 11682 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 11683 // Combine the word-aligned words in the correct order for current endianness. 11684 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11685 #endif 11686 11687 bool success = false; 11688 11689 if (ConditionPassed(opcode)) { 11690 bool single_regs; 11691 bool add; 11692 bool wback; 11693 uint32_t d; 11694 uint32_t n; 11695 uint32_t imm32; 11696 uint32_t regs; 11697 11698 switch (encoding) { 11699 case eEncodingT1: 11700 case eEncodingA1: 11701 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11702 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11703 // if P == '1' && W == '0' then SEE VLDR; 11704 // if P == U && W == '1' then UNDEFINED; 11705 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11706 return false; 11707 11708 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11709 // !), 101 (DB with !) 11710 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11711 single_regs = false; 11712 add = BitIsSet(opcode, 23); 11713 wback = BitIsSet(opcode, 21); 11714 11715 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11716 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11717 n = Bits32(opcode, 19, 16); 11718 imm32 = Bits32(opcode, 7, 0) << 2; 11719 11720 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 11721 regs = Bits32(opcode, 7, 0) / 2; 11722 11723 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11724 // UNPREDICTABLE; 11725 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 11726 return false; 11727 11728 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11729 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11730 return false; 11731 11732 break; 11733 11734 case eEncodingT2: 11735 case eEncodingA2: 11736 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11737 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11738 // if P == '1' && W == '0' then SEE VLDR; 11739 // if P == U && W == '1' then UNDEFINED; 11740 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11741 return false; 11742 11743 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11744 // !), 101 (DB with !) 11745 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = 11746 // UInt(Vd:D); n = UInt(Rn); 11747 single_regs = true; 11748 add = BitIsSet(opcode, 23); 11749 wback = BitIsSet(opcode, 21); 11750 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11751 n = Bits32(opcode, 19, 16); 11752 11753 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11754 imm32 = Bits32(opcode, 7, 0) << 2; 11755 regs = Bits32(opcode, 7, 0); 11756 11757 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11758 // UNPREDICTABLE; 11759 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11760 return false; 11761 11762 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11763 if ((regs == 0) || ((d + regs) > 32)) 11764 return false; 11765 break; 11766 11767 default: 11768 return false; 11769 } 11770 11771 RegisterInfo base_reg; 11772 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11773 11774 uint32_t Rn = ReadCoreReg(n, &success); 11775 if (!success) 11776 return false; 11777 11778 // address = if add then R[n] else R[n]-imm32; 11779 addr_t address; 11780 if (add) 11781 address = Rn; 11782 else 11783 address = Rn - imm32; 11784 11785 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11786 EmulateInstruction::Context context; 11787 11788 if (wback) { 11789 uint32_t value; 11790 if (add) 11791 value = Rn + imm32; 11792 else 11793 value = Rn - imm32; 11794 11795 context.type = eContextAdjustBaseRegister; 11796 context.SetImmediateSigned(value - Rn); 11797 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11798 value)) 11799 return false; 11800 } 11801 11802 const uint32_t addr_byte_size = GetAddressByteSize(); 11803 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11804 11805 context.type = eContextRegisterLoad; 11806 11807 // for r = 0 to regs-1 11808 for (uint32_t r = 0; r < regs; ++r) { 11809 if (single_regs) { 11810 // S[d+r] = MemA[address,4]; address = address+4; 11811 context.SetRegisterPlusOffset(base_reg, address - Rn); 11812 11813 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11814 if (!success) 11815 return false; 11816 11817 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11818 start_reg + d + r, data)) 11819 return false; 11820 11821 address = address + 4; 11822 } else { 11823 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = 11824 // address+8; 11825 context.SetRegisterPlusOffset(base_reg, address - Rn); 11826 uint32_t word1 = 11827 MemARead(context, address, addr_byte_size, 0, &success); 11828 if (!success) 11829 return false; 11830 11831 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn); 11832 uint32_t word2 = 11833 MemARead(context, address + 4, addr_byte_size, 0, &success); 11834 if (!success) 11835 return false; 11836 11837 address = address + 8; 11838 // // Combine the word-aligned words in the correct order for current 11839 // endianness. 11840 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11841 uint64_t data; 11842 if (GetByteOrder() == eByteOrderBig) { 11843 data = word1; 11844 data = (data << 32) | word2; 11845 } else { 11846 data = word2; 11847 data = (data << 32) | word1; 11848 } 11849 11850 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11851 start_reg + d + r, data)) 11852 return false; 11853 } 11854 } 11855 } 11856 return true; 11857 } 11858 11859 // A8.6.399 VSTM 11860 // Vector Store Multiple stores multiple extension registers to consecutive 11861 // memory locations using an address from an 11862 // ARM core register. 11863 bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode, 11864 const ARMEncoding encoding) { 11865 #if 0 11866 if ConditionPassed() then 11867 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11868 address = if add then R[n] else R[n]-imm32; 11869 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11870 for r = 0 to regs-1 11871 if single_regs then 11872 MemA[address,4] = S[d+r]; address = address+4; 11873 else 11874 // Store as two word-aligned words in the correct order for current endianness. 11875 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11876 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11877 address = address+8; 11878 #endif 11879 11880 bool success = false; 11881 11882 if (ConditionPassed(opcode)) { 11883 bool single_regs; 11884 bool add; 11885 bool wback; 11886 uint32_t d; 11887 uint32_t n; 11888 uint32_t imm32; 11889 uint32_t regs; 11890 11891 switch (encoding) { 11892 case eEncodingT1: 11893 case eEncodingA1: 11894 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11895 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11896 // if P == '1' && W == '0' then SEE VSTR; 11897 // if P == U && W == '1' then UNDEFINED; 11898 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11899 return false; 11900 11901 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11902 // !), 101 (DB with !) 11903 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11904 single_regs = false; 11905 add = BitIsSet(opcode, 23); 11906 wback = BitIsSet(opcode, 21); 11907 11908 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11909 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11910 n = Bits32(opcode, 19, 16); 11911 imm32 = Bits32(opcode, 7, 0) << 2; 11912 11913 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11914 regs = Bits32(opcode, 7, 0) / 2; 11915 11916 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11917 // UNPREDICTABLE; 11918 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11919 return false; 11920 11921 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11922 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11923 return false; 11924 11925 break; 11926 11927 case eEncodingT2: 11928 case eEncodingA2: 11929 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11930 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11931 // if P == '1' && W == '0' then SEE VSTR; 11932 // if P == U && W == '1' then UNDEFINED; 11933 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11934 return false; 11935 11936 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11937 // !), 101 (DB with !) 11938 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = 11939 // UInt(Vd:D); n = UInt(Rn); 11940 single_regs = true; 11941 add = BitIsSet(opcode, 23); 11942 wback = BitIsSet(opcode, 21); 11943 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11944 n = Bits32(opcode, 19, 16); 11945 11946 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11947 imm32 = Bits32(opcode, 7, 0) << 2; 11948 regs = Bits32(opcode, 7, 0); 11949 11950 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11951 // UNPREDICTABLE; 11952 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11953 return false; 11954 11955 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11956 if ((regs == 0) || ((d + regs) > 32)) 11957 return false; 11958 11959 break; 11960 11961 default: 11962 return false; 11963 } 11964 11965 RegisterInfo base_reg; 11966 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11967 11968 uint32_t Rn = ReadCoreReg(n, &success); 11969 if (!success) 11970 return false; 11971 11972 // address = if add then R[n] else R[n]-imm32; 11973 addr_t address; 11974 if (add) 11975 address = Rn; 11976 else 11977 address = Rn - imm32; 11978 11979 EmulateInstruction::Context context; 11980 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11981 if (wback) { 11982 uint32_t value; 11983 if (add) 11984 value = Rn + imm32; 11985 else 11986 value = Rn - imm32; 11987 11988 context.type = eContextAdjustBaseRegister; 11989 context.SetRegisterPlusOffset(base_reg, value - Rn); 11990 11991 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11992 value)) 11993 return false; 11994 } 11995 11996 const uint32_t addr_byte_size = GetAddressByteSize(); 11997 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11998 11999 context.type = eContextRegisterStore; 12000 // for r = 0 to regs-1 12001 for (uint32_t r = 0; r < regs; ++r) { 12002 12003 if (single_regs) { 12004 // MemA[address,4] = S[d+r]; address = address+4; 12005 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 12006 start_reg + d + r, 0, &success); 12007 if (!success) 12008 return false; 12009 12010 RegisterInfo data_reg; 12011 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 12012 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12013 address - Rn); 12014 if (!MemAWrite(context, address, data, addr_byte_size)) 12015 return false; 12016 12017 address = address + 4; 12018 } else { 12019 // // Store as two word-aligned words in the correct order for current 12020 // endianness. 12021 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else 12022 // D[d+r]<31:0>; 12023 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else 12024 // D[d+r]<63:32>; 12025 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 12026 start_reg + d + r, 0, &success); 12027 if (!success) 12028 return false; 12029 12030 RegisterInfo data_reg; 12031 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 12032 12033 if (GetByteOrder() == eByteOrderBig) { 12034 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12035 address - Rn); 12036 if (!MemAWrite(context, address, Bits64(data, 63, 32), 12037 addr_byte_size)) 12038 return false; 12039 12040 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12041 (address + 4) - Rn); 12042 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 12043 addr_byte_size)) 12044 return false; 12045 } else { 12046 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12047 address - Rn); 12048 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 12049 return false; 12050 12051 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12052 (address + 4) - Rn); 12053 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 12054 addr_byte_size)) 12055 return false; 12056 } 12057 // address = address+8; 12058 address = address + 8; 12059 } 12060 } 12061 } 12062 return true; 12063 } 12064 12065 // A8.6.320 12066 // This instruction loads a single extension register from memory, using an 12067 // address from an ARM core register, with 12068 // an optional offset. 12069 bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode, 12070 ARMEncoding encoding) { 12071 #if 0 12072 if ConditionPassed() then 12073 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 12074 base = if n == 15 then Align(PC,4) else R[n]; 12075 address = if add then (base + imm32) else (base - imm32); 12076 if single_reg then 12077 S[d] = MemA[address,4]; 12078 else 12079 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 12080 // Combine the word-aligned words in the correct order for current endianness. 12081 D[d] = if BigEndian() then word1:word2 else word2:word1; 12082 #endif 12083 12084 bool success = false; 12085 12086 if (ConditionPassed(opcode)) { 12087 bool single_reg; 12088 bool add; 12089 uint32_t imm32; 12090 uint32_t d; 12091 uint32_t n; 12092 12093 switch (encoding) { 12094 case eEncodingT1: 12095 case eEncodingA1: 12096 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 12097 // 32); 12098 single_reg = false; 12099 add = BitIsSet(opcode, 23); 12100 imm32 = Bits32(opcode, 7, 0) << 2; 12101 12102 // d = UInt(D:Vd); n = UInt(Rn); 12103 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12104 n = Bits32(opcode, 19, 16); 12105 12106 break; 12107 12108 case eEncodingT2: 12109 case eEncodingA2: 12110 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 12111 single_reg = true; 12112 add = BitIsSet(opcode, 23); 12113 imm32 = Bits32(opcode, 7, 0) << 2; 12114 12115 // d = UInt(Vd:D); n = UInt(Rn); 12116 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 12117 n = Bits32(opcode, 19, 16); 12118 12119 break; 12120 12121 default: 12122 return false; 12123 } 12124 RegisterInfo base_reg; 12125 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12126 12127 uint32_t Rn = ReadCoreReg(n, &success); 12128 if (!success) 12129 return false; 12130 12131 // base = if n == 15 then Align(PC,4) else R[n]; 12132 uint32_t base; 12133 if (n == 15) 12134 base = AlignPC(Rn); 12135 else 12136 base = Rn; 12137 12138 // address = if add then (base + imm32) else (base - imm32); 12139 addr_t address; 12140 if (add) 12141 address = base + imm32; 12142 else 12143 address = base - imm32; 12144 12145 const uint32_t addr_byte_size = GetAddressByteSize(); 12146 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 12147 12148 EmulateInstruction::Context context; 12149 context.type = eContextRegisterLoad; 12150 context.SetRegisterPlusOffset(base_reg, address - base); 12151 12152 if (single_reg) { 12153 // S[d] = MemA[address,4]; 12154 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 12155 if (!success) 12156 return false; 12157 12158 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 12159 data)) 12160 return false; 12161 } else { 12162 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 12163 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success); 12164 if (!success) 12165 return false; 12166 12167 context.SetRegisterPlusOffset(base_reg, (address + 4) - base); 12168 uint32_t word2 = 12169 MemARead(context, address + 4, addr_byte_size, 0, &success); 12170 if (!success) 12171 return false; 12172 // // Combine the word-aligned words in the correct order for current 12173 // endianness. 12174 // D[d] = if BigEndian() then word1:word2 else word2:word1; 12175 uint64_t data64; 12176 if (GetByteOrder() == eByteOrderBig) { 12177 data64 = word1; 12178 data64 = (data64 << 32) | word2; 12179 } else { 12180 data64 = word2; 12181 data64 = (data64 << 32) | word1; 12182 } 12183 12184 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 12185 data64)) 12186 return false; 12187 } 12188 } 12189 return true; 12190 } 12191 12192 // A8.6.400 VSTR 12193 // This instruction stores a signle extension register to memory, using an 12194 // address from an ARM core register, with an 12195 // optional offset. 12196 bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode, 12197 ARMEncoding encoding) { 12198 #if 0 12199 if ConditionPassed() then 12200 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 12201 address = if add then (R[n] + imm32) else (R[n] - imm32); 12202 if single_reg then 12203 MemA[address,4] = S[d]; 12204 else 12205 // Store as two word-aligned words in the correct order for current endianness. 12206 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 12207 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 12208 #endif 12209 12210 bool success = false; 12211 12212 if (ConditionPassed(opcode)) { 12213 bool single_reg; 12214 bool add; 12215 uint32_t imm32; 12216 uint32_t d; 12217 uint32_t n; 12218 12219 switch (encoding) { 12220 case eEncodingT1: 12221 case eEncodingA1: 12222 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 12223 // 32); 12224 single_reg = false; 12225 add = BitIsSet(opcode, 23); 12226 imm32 = Bits32(opcode, 7, 0) << 2; 12227 12228 // d = UInt(D:Vd); n = UInt(Rn); 12229 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12230 n = Bits32(opcode, 19, 16); 12231 12232 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 12233 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 12234 return false; 12235 12236 break; 12237 12238 case eEncodingT2: 12239 case eEncodingA2: 12240 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 12241 single_reg = true; 12242 add = BitIsSet(opcode, 23); 12243 imm32 = Bits32(opcode, 7, 0) << 2; 12244 12245 // d = UInt(Vd:D); n = UInt(Rn); 12246 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 12247 n = Bits32(opcode, 19, 16); 12248 12249 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 12250 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 12251 return false; 12252 12253 break; 12254 12255 default: 12256 return false; 12257 } 12258 12259 RegisterInfo base_reg; 12260 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12261 12262 uint32_t Rn = ReadCoreReg(n, &success); 12263 if (!success) 12264 return false; 12265 12266 // address = if add then (R[n] + imm32) else (R[n] - imm32); 12267 addr_t address; 12268 if (add) 12269 address = Rn + imm32; 12270 else 12271 address = Rn - imm32; 12272 12273 const uint32_t addr_byte_size = GetAddressByteSize(); 12274 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 12275 12276 RegisterInfo data_reg; 12277 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg); 12278 EmulateInstruction::Context context; 12279 context.type = eContextRegisterStore; 12280 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 12281 12282 if (single_reg) { 12283 // MemA[address,4] = S[d]; 12284 uint32_t data = 12285 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 12286 if (!success) 12287 return false; 12288 12289 if (!MemAWrite(context, address, data, addr_byte_size)) 12290 return false; 12291 } else { 12292 // // Store as two word-aligned words in the correct order for current 12293 // endianness. 12294 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 12295 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 12296 uint64_t data = 12297 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 12298 if (!success) 12299 return false; 12300 12301 if (GetByteOrder() == eByteOrderBig) { 12302 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size)) 12303 return false; 12304 12305 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12306 (address + 4) - Rn); 12307 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 12308 addr_byte_size)) 12309 return false; 12310 } else { 12311 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 12312 return false; 12313 12314 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12315 (address + 4) - Rn); 12316 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 12317 addr_byte_size)) 12318 return false; 12319 } 12320 } 12321 } 12322 return true; 12323 } 12324 12325 // A8.6.307 VLDI1 (multiple single elements) 12326 // This instruction loads elements from memory into one, two, three or four 12327 // registers, without de-interleaving. Every 12328 // element of each register is loaded. 12329 bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode, 12330 ARMEncoding encoding) { 12331 #if 0 12332 if ConditionPassed() then 12333 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12334 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12335 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12336 for r = 0 to regs-1 12337 for e = 0 to elements-1 12338 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 12339 address = address + ebytes; 12340 #endif 12341 12342 bool success = false; 12343 12344 if (ConditionPassed(opcode)) { 12345 uint32_t regs; 12346 uint32_t alignment; 12347 uint32_t ebytes; 12348 uint32_t esize; 12349 uint32_t elements; 12350 uint32_t d; 12351 uint32_t n; 12352 uint32_t m; 12353 bool wback; 12354 bool register_index; 12355 12356 switch (encoding) { 12357 case eEncodingT1: 12358 case eEncodingA1: { 12359 // case type of 12360 // when '0111' 12361 // regs = 1; if align<1> == '1' then UNDEFINED; 12362 // when '1010' 12363 // regs = 2; if align == '11' then UNDEFINED; 12364 // when '0110' 12365 // regs = 3; if align<1> == '1' then UNDEFINED; 12366 // when '0010' 12367 // regs = 4; 12368 // otherwise 12369 // SEE 'Related encodings'; 12370 uint32_t type = Bits32(opcode, 11, 8); 12371 uint32_t align = Bits32(opcode, 5, 4); 12372 if (type == 7) // '0111' 12373 { 12374 regs = 1; 12375 if (BitIsSet(align, 1)) 12376 return false; 12377 } else if (type == 10) // '1010' 12378 { 12379 regs = 2; 12380 if (align == 3) 12381 return false; 12382 12383 } else if (type == 6) // '0110' 12384 { 12385 regs = 3; 12386 if (BitIsSet(align, 1)) 12387 return false; 12388 } else if (type == 2) // '0010' 12389 { 12390 regs = 4; 12391 } else 12392 return false; 12393 12394 // alignment = if align == '00' then 1 else 4 << UInt(align); 12395 if (align == 0) 12396 alignment = 1; 12397 else 12398 alignment = 4 << align; 12399 12400 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 12401 ebytes = 1 << Bits32(opcode, 7, 6); 12402 esize = 8 * ebytes; 12403 elements = 8 / ebytes; 12404 12405 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12406 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12407 n = Bits32(opcode, 19, 15); 12408 m = Bits32(opcode, 3, 0); 12409 12410 // wback = (m != 15); register_index = (m != 15 && m != 13); 12411 wback = (m != 15); 12412 register_index = ((m != 15) && (m != 13)); 12413 12414 // if d+regs > 32 then UNPREDICTABLE; 12415 if ((d + regs) > 32) 12416 return false; 12417 } break; 12418 12419 default: 12420 return false; 12421 } 12422 12423 RegisterInfo base_reg; 12424 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12425 12426 uint32_t Rn = ReadCoreReg(n, &success); 12427 if (!success) 12428 return false; 12429 12430 // address = R[n]; if (address MOD alignment) != 0 then 12431 // GenerateAlignmentException(); 12432 addr_t address = Rn; 12433 if ((address % alignment) != 0) 12434 return false; 12435 12436 EmulateInstruction::Context context; 12437 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12438 if (wback) { 12439 uint32_t Rm = ReadCoreReg(m, &success); 12440 if (!success) 12441 return false; 12442 12443 uint32_t offset; 12444 if (register_index) 12445 offset = Rm; 12446 else 12447 offset = 8 * regs; 12448 12449 uint32_t value = Rn + offset; 12450 context.type = eContextAdjustBaseRegister; 12451 context.SetRegisterPlusOffset(base_reg, offset); 12452 12453 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12454 value)) 12455 return false; 12456 } 12457 12458 // for r = 0 to regs-1 12459 for (uint32_t r = 0; r < regs; ++r) { 12460 // for e = 0 to elements-1 12461 uint64_t assembled_data = 0; 12462 for (uint32_t e = 0; e < elements; ++e) { 12463 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 12464 context.type = eContextRegisterLoad; 12465 context.SetRegisterPlusOffset(base_reg, address - Rn); 12466 uint64_t data = MemURead(context, address, ebytes, 0, &success); 12467 if (!success) 12468 return false; 12469 12470 assembled_data = 12471 (data << (e * esize)) | 12472 assembled_data; // New data goes to the left of existing data 12473 12474 // address = address + ebytes; 12475 address = address + ebytes; 12476 } 12477 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12478 assembled_data)) 12479 return false; 12480 } 12481 } 12482 return true; 12483 } 12484 12485 // A8.6.308 VLD1 (single element to one lane) 12486 // 12487 bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode, 12488 const ARMEncoding encoding) { 12489 #if 0 12490 if ConditionPassed() then 12491 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12492 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12493 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12494 Elem[D[d],index,esize] = MemU[address,ebytes]; 12495 #endif 12496 12497 bool success = false; 12498 12499 if (ConditionPassed(opcode)) { 12500 uint32_t ebytes; 12501 uint32_t esize; 12502 uint32_t index; 12503 uint32_t alignment; 12504 uint32_t d; 12505 uint32_t n; 12506 uint32_t m; 12507 bool wback; 12508 bool register_index; 12509 12510 switch (encoding) { 12511 case eEncodingT1: 12512 case eEncodingA1: { 12513 uint32_t size = Bits32(opcode, 11, 10); 12514 uint32_t index_align = Bits32(opcode, 7, 4); 12515 // if size == '11' then SEE VLD1 (single element to all lanes); 12516 if (size == 3) 12517 return EmulateVLD1SingleAll(opcode, encoding); 12518 // case size of 12519 if (size == 0) // when '00' 12520 { 12521 // if index_align<0> != '0' then UNDEFINED; 12522 if (BitIsClear(index_align, 0)) 12523 return false; 12524 12525 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12526 ebytes = 1; 12527 esize = 8; 12528 index = Bits32(index_align, 3, 1); 12529 alignment = 1; 12530 } else if (size == 1) // when '01' 12531 { 12532 // if index_align<1> != '0' then UNDEFINED; 12533 if (BitIsClear(index_align, 1)) 12534 return false; 12535 12536 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12537 ebytes = 2; 12538 esize = 16; 12539 index = Bits32(index_align, 3, 2); 12540 12541 // alignment = if index_align<0> == '0' then 1 else 2; 12542 if (BitIsClear(index_align, 0)) 12543 alignment = 1; 12544 else 12545 alignment = 2; 12546 } else if (size == 2) // when '10' 12547 { 12548 // if index_align<2> != '0' then UNDEFINED; 12549 if (BitIsClear(index_align, 2)) 12550 return false; 12551 12552 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12553 // UNDEFINED; 12554 if ((Bits32(index_align, 1, 0) != 0) && 12555 (Bits32(index_align, 1, 0) != 3)) 12556 return false; 12557 12558 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12559 ebytes = 4; 12560 esize = 32; 12561 index = Bit32(index_align, 3); 12562 12563 // alignment = if index_align<1:0> == '00' then 1 else 4; 12564 if (Bits32(index_align, 1, 0) == 0) 12565 alignment = 1; 12566 else 12567 alignment = 4; 12568 } else { 12569 return false; 12570 } 12571 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12572 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12573 n = Bits32(opcode, 19, 16); 12574 m = Bits32(opcode, 3, 0); 12575 12576 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12577 // then UNPREDICTABLE; 12578 wback = (m != 15); 12579 register_index = ((m != 15) && (m != 13)); 12580 12581 if (n == 15) 12582 return false; 12583 12584 } break; 12585 12586 default: 12587 return false; 12588 } 12589 12590 RegisterInfo base_reg; 12591 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12592 12593 uint32_t Rn = ReadCoreReg(n, &success); 12594 if (!success) 12595 return false; 12596 12597 // address = R[n]; if (address MOD alignment) != 0 then 12598 // GenerateAlignmentException(); 12599 addr_t address = Rn; 12600 if ((address % alignment) != 0) 12601 return false; 12602 12603 EmulateInstruction::Context context; 12604 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12605 if (wback) { 12606 uint32_t Rm = ReadCoreReg(m, &success); 12607 if (!success) 12608 return false; 12609 12610 uint32_t offset; 12611 if (register_index) 12612 offset = Rm; 12613 else 12614 offset = ebytes; 12615 12616 uint32_t value = Rn + offset; 12617 12618 context.type = eContextAdjustBaseRegister; 12619 context.SetRegisterPlusOffset(base_reg, offset); 12620 12621 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12622 value)) 12623 return false; 12624 } 12625 12626 // Elem[D[d],index,esize] = MemU[address,ebytes]; 12627 uint32_t element = MemURead(context, address, esize, 0, &success); 12628 if (!success) 12629 return false; 12630 12631 element = element << (index * esize); 12632 12633 uint64_t reg_data = 12634 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12635 if (!success) 12636 return false; 12637 12638 uint64_t all_ones = -1; 12639 uint64_t mask = all_ones 12640 << ((index + 1) * esize); // mask is all 1's to left of 12641 // where 'element' goes, & all 0's 12642 // at element & to the right of element. 12643 if (index > 0) 12644 mask = mask | Bits64(all_ones, (index * esize) - 1, 12645 0); // add 1's to the right of where 'element' goes. 12646 // now mask should be 0's where element goes & 1's 12647 // everywhere else. 12648 12649 uint64_t masked_reg = 12650 reg_data & mask; // Take original reg value & zero out 'element' bits 12651 reg_data = 12652 masked_reg & element; // Put 'element' into those bits in reg_data. 12653 12654 context.type = eContextRegisterLoad; 12655 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 12656 reg_data)) 12657 return false; 12658 } 12659 return true; 12660 } 12661 12662 // A8.6.391 VST1 (multiple single elements) 12663 // Vector Store (multiple single elements) stores elements to memory from one, 12664 // two, three, or four registers, without 12665 // interleaving. Every element of each register is stored. 12666 bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode, 12667 ARMEncoding encoding) { 12668 #if 0 12669 if ConditionPassed() then 12670 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12671 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12672 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12673 for r = 0 to regs-1 12674 for e = 0 to elements-1 12675 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12676 address = address + ebytes; 12677 #endif 12678 12679 bool success = false; 12680 12681 if (ConditionPassed(opcode)) { 12682 uint32_t regs; 12683 uint32_t alignment; 12684 uint32_t ebytes; 12685 uint32_t esize; 12686 uint32_t elements; 12687 uint32_t d; 12688 uint32_t n; 12689 uint32_t m; 12690 bool wback; 12691 bool register_index; 12692 12693 switch (encoding) { 12694 case eEncodingT1: 12695 case eEncodingA1: { 12696 uint32_t type = Bits32(opcode, 11, 8); 12697 uint32_t align = Bits32(opcode, 5, 4); 12698 12699 // case type of 12700 if (type == 7) // when '0111' 12701 { 12702 // regs = 1; if align<1> == '1' then UNDEFINED; 12703 regs = 1; 12704 if (BitIsSet(align, 1)) 12705 return false; 12706 } else if (type == 10) // when '1010' 12707 { 12708 // regs = 2; if align == '11' then UNDEFINED; 12709 regs = 2; 12710 if (align == 3) 12711 return false; 12712 } else if (type == 6) // when '0110' 12713 { 12714 // regs = 3; if align<1> == '1' then UNDEFINED; 12715 regs = 3; 12716 if (BitIsSet(align, 1)) 12717 return false; 12718 } else if (type == 2) // when '0010' 12719 // regs = 4; 12720 regs = 4; 12721 else // otherwise 12722 // SEE 'Related encodings'; 12723 return false; 12724 12725 // alignment = if align == '00' then 1 else 4 << UInt(align); 12726 if (align == 0) 12727 alignment = 1; 12728 else 12729 alignment = 4 << align; 12730 12731 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 12732 ebytes = 1 << Bits32(opcode, 7, 6); 12733 esize = 8 * ebytes; 12734 elements = 8 / ebytes; 12735 12736 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12737 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12738 n = Bits32(opcode, 19, 16); 12739 m = Bits32(opcode, 3, 0); 12740 12741 // wback = (m != 15); register_index = (m != 15 && m != 13); 12742 wback = (m != 15); 12743 register_index = ((m != 15) && (m != 13)); 12744 12745 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12746 if ((d + regs) > 32) 12747 return false; 12748 12749 if (n == 15) 12750 return false; 12751 12752 } break; 12753 12754 default: 12755 return false; 12756 } 12757 12758 RegisterInfo base_reg; 12759 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12760 12761 uint32_t Rn = ReadCoreReg(n, &success); 12762 if (!success) 12763 return false; 12764 12765 // address = R[n]; if (address MOD alignment) != 0 then 12766 // GenerateAlignmentException(); 12767 addr_t address = Rn; 12768 if ((address % alignment) != 0) 12769 return false; 12770 12771 EmulateInstruction::Context context; 12772 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12773 if (wback) { 12774 uint32_t Rm = ReadCoreReg(m, &success); 12775 if (!success) 12776 return false; 12777 12778 uint32_t offset; 12779 if (register_index) 12780 offset = Rm; 12781 else 12782 offset = 8 * regs; 12783 12784 context.type = eContextAdjustBaseRegister; 12785 context.SetRegisterPlusOffset(base_reg, offset); 12786 12787 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12788 Rn + offset)) 12789 return false; 12790 } 12791 12792 RegisterInfo data_reg; 12793 context.type = eContextRegisterStore; 12794 // for r = 0 to regs-1 12795 for (uint32_t r = 0; r < regs; ++r) { 12796 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 12797 uint64_t register_data = ReadRegisterUnsigned( 12798 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 12799 if (!success) 12800 return false; 12801 12802 // for e = 0 to elements-1 12803 for (uint32_t e = 0; e < elements; ++e) { 12804 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12805 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize); 12806 12807 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12808 address - Rn); 12809 if (!MemUWrite(context, address, word, ebytes)) 12810 return false; 12811 12812 // address = address + ebytes; 12813 address = address + ebytes; 12814 } 12815 } 12816 } 12817 return true; 12818 } 12819 12820 // A8.6.392 VST1 (single element from one lane) 12821 // This instruction stores one element to memory from one element of a register. 12822 bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode, 12823 ARMEncoding encoding) { 12824 #if 0 12825 if ConditionPassed() then 12826 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12827 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12828 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12829 MemU[address,ebytes] = Elem[D[d],index,esize]; 12830 #endif 12831 12832 bool success = false; 12833 12834 if (ConditionPassed(opcode)) { 12835 uint32_t ebytes; 12836 uint32_t esize; 12837 uint32_t index; 12838 uint32_t alignment; 12839 uint32_t d; 12840 uint32_t n; 12841 uint32_t m; 12842 bool wback; 12843 bool register_index; 12844 12845 switch (encoding) { 12846 case eEncodingT1: 12847 case eEncodingA1: { 12848 uint32_t size = Bits32(opcode, 11, 10); 12849 uint32_t index_align = Bits32(opcode, 7, 4); 12850 12851 // if size == '11' then UNDEFINED; 12852 if (size == 3) 12853 return false; 12854 12855 // case size of 12856 if (size == 0) // when '00' 12857 { 12858 // if index_align<0> != '0' then UNDEFINED; 12859 if (BitIsClear(index_align, 0)) 12860 return false; 12861 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12862 ebytes = 1; 12863 esize = 8; 12864 index = Bits32(index_align, 3, 1); 12865 alignment = 1; 12866 } else if (size == 1) // when '01' 12867 { 12868 // if index_align<1> != '0' then UNDEFINED; 12869 if (BitIsClear(index_align, 1)) 12870 return false; 12871 12872 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12873 ebytes = 2; 12874 esize = 16; 12875 index = Bits32(index_align, 3, 2); 12876 12877 // alignment = if index_align<0> == '0' then 1 else 2; 12878 if (BitIsClear(index_align, 0)) 12879 alignment = 1; 12880 else 12881 alignment = 2; 12882 } else if (size == 2) // when '10' 12883 { 12884 // if index_align<2> != '0' then UNDEFINED; 12885 if (BitIsClear(index_align, 2)) 12886 return false; 12887 12888 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12889 // UNDEFINED; 12890 if ((Bits32(index_align, 1, 0) != 0) && 12891 (Bits32(index_align, 1, 0) != 3)) 12892 return false; 12893 12894 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12895 ebytes = 4; 12896 esize = 32; 12897 index = Bit32(index_align, 3); 12898 12899 // alignment = if index_align<1:0> == '00' then 1 else 4; 12900 if (Bits32(index_align, 1, 0) == 0) 12901 alignment = 1; 12902 else 12903 alignment = 4; 12904 } else { 12905 return false; 12906 } 12907 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12908 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12909 n = Bits32(opcode, 19, 16); 12910 m = Bits32(opcode, 3, 0); 12911 12912 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12913 // then UNPREDICTABLE; 12914 wback = (m != 15); 12915 register_index = ((m != 15) && (m != 13)); 12916 12917 if (n == 15) 12918 return false; 12919 } break; 12920 12921 default: 12922 return false; 12923 } 12924 12925 RegisterInfo base_reg; 12926 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12927 12928 uint32_t Rn = ReadCoreReg(n, &success); 12929 if (!success) 12930 return false; 12931 12932 // address = R[n]; if (address MOD alignment) != 0 then 12933 // GenerateAlignmentException(); 12934 addr_t address = Rn; 12935 if ((address % alignment) != 0) 12936 return false; 12937 12938 EmulateInstruction::Context context; 12939 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12940 if (wback) { 12941 uint32_t Rm = ReadCoreReg(m, &success); 12942 if (!success) 12943 return false; 12944 12945 uint32_t offset; 12946 if (register_index) 12947 offset = Rm; 12948 else 12949 offset = ebytes; 12950 12951 context.type = eContextAdjustBaseRegister; 12952 context.SetRegisterPlusOffset(base_reg, offset); 12953 12954 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12955 Rn + offset)) 12956 return false; 12957 } 12958 12959 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12960 uint64_t register_data = 12961 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12962 if (!success) 12963 return false; 12964 12965 uint64_t word = 12966 Bits64(register_data, ((index + 1) * esize) - 1, index * esize); 12967 12968 RegisterInfo data_reg; 12969 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12970 context.type = eContextRegisterStore; 12971 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 12972 12973 if (!MemUWrite(context, address, word, ebytes)) 12974 return false; 12975 } 12976 return true; 12977 } 12978 12979 // A8.6.309 VLD1 (single element to all lanes) 12980 // This instruction loads one element from memory into every element of one or 12981 // two vectors. 12982 bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode, 12983 const ARMEncoding encoding) { 12984 #if 0 12985 if ConditionPassed() then 12986 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12987 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12988 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12989 replicated_element = Replicate(MemU[address,ebytes], elements); 12990 for r = 0 to regs-1 12991 D[d+r] = replicated_element; 12992 #endif 12993 12994 bool success = false; 12995 12996 if (ConditionPassed(opcode)) { 12997 uint32_t ebytes; 12998 uint32_t elements; 12999 uint32_t regs; 13000 uint32_t alignment; 13001 uint32_t d; 13002 uint32_t n; 13003 uint32_t m; 13004 bool wback; 13005 bool register_index; 13006 13007 switch (encoding) { 13008 case eEncodingT1: 13009 case eEncodingA1: { 13010 // if size == '11' || (size == '00' && a == '1') then UNDEFINED; 13011 uint32_t size = Bits32(opcode, 7, 6); 13012 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4))) 13013 return false; 13014 13015 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' 13016 // then 1 else 2; 13017 ebytes = 1 << size; 13018 elements = 8 / ebytes; 13019 if (BitIsClear(opcode, 5)) 13020 regs = 1; 13021 else 13022 regs = 2; 13023 13024 // alignment = if a == '0' then 1 else ebytes; 13025 if (BitIsClear(opcode, 4)) 13026 alignment = 1; 13027 else 13028 alignment = ebytes; 13029 13030 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 13031 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 13032 n = Bits32(opcode, 19, 16); 13033 m = Bits32(opcode, 3, 0); 13034 13035 // wback = (m != 15); register_index = (m != 15 && m != 13); 13036 wback = (m != 15); 13037 register_index = ((m != 15) && (m != 13)); 13038 13039 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 13040 if ((d + regs) > 32) 13041 return false; 13042 13043 if (n == 15) 13044 return false; 13045 } break; 13046 13047 default: 13048 return false; 13049 } 13050 13051 RegisterInfo base_reg; 13052 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 13053 13054 uint32_t Rn = ReadCoreReg(n, &success); 13055 if (!success) 13056 return false; 13057 13058 // address = R[n]; if (address MOD alignment) != 0 then 13059 // GenerateAlignmentException(); 13060 addr_t address = Rn; 13061 if ((address % alignment) != 0) 13062 return false; 13063 13064 EmulateInstruction::Context context; 13065 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 13066 if (wback) { 13067 uint32_t Rm = ReadCoreReg(m, &success); 13068 if (!success) 13069 return false; 13070 13071 uint32_t offset; 13072 if (register_index) 13073 offset = Rm; 13074 else 13075 offset = ebytes; 13076 13077 context.type = eContextAdjustBaseRegister; 13078 context.SetRegisterPlusOffset(base_reg, offset); 13079 13080 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 13081 Rn + offset)) 13082 return false; 13083 } 13084 13085 // replicated_element = Replicate(MemU[address,ebytes], elements); 13086 13087 context.type = eContextRegisterLoad; 13088 uint64_t word = MemURead(context, address, ebytes, 0, &success); 13089 if (!success) 13090 return false; 13091 13092 uint64_t replicated_element = 0; 13093 uint32_t esize = ebytes * 8; 13094 for (uint32_t e = 0; e < elements; ++e) 13095 replicated_element = 13096 (replicated_element << esize) | Bits64(word, esize - 1, 0); 13097 13098 // for r = 0 to regs-1 13099 for (uint32_t r = 0; r < regs; ++r) { 13100 // D[d+r] = replicated_element; 13101 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 13102 replicated_element)) 13103 return false; 13104 } 13105 } 13106 return true; 13107 } 13108 13109 // B6.2.13 SUBS PC, LR and related instructions 13110 // The SUBS PC, LR, #<const? instruction provides an exception return without 13111 // the use of the stack. It subtracts the 13112 // immediate constant from the LR, branches to the resulting address, and also 13113 // copies the SPSR to the CPSR. 13114 bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode, 13115 const ARMEncoding encoding) { 13116 #if 0 13117 if ConditionPassed() then 13118 EncodingSpecificOperations(); 13119 if CurrentInstrSet() == InstrSet_ThumbEE then 13120 UNPREDICTABLE; 13121 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 13122 case opcode of 13123 when '0000' result = R[n] AND operand2; // AND 13124 when '0001' result = R[n] EOR operand2; // EOR 13125 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 13126 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 13127 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 13128 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 13129 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 13130 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 13131 when '1100' result = R[n] OR operand2; // ORR 13132 when '1101' result = operand2; // MOV 13133 when '1110' result = R[n] AND NOT(operand2); // BIC 13134 when '1111' result = NOT(operand2); // MVN 13135 CPSRWriteByInstr(SPSR[], '1111', TRUE); 13136 BranchWritePC(result); 13137 #endif 13138 13139 bool success = false; 13140 13141 if (ConditionPassed(opcode)) { 13142 uint32_t n; 13143 uint32_t m; 13144 uint32_t imm32; 13145 bool register_form; 13146 ARM_ShifterType shift_t; 13147 uint32_t shift_n; 13148 uint32_t code; 13149 13150 switch (encoding) { 13151 case eEncodingT1: 13152 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 13153 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = 13154 // '0010'; // = SUB 13155 n = 14; 13156 imm32 = Bits32(opcode, 7, 0); 13157 register_form = false; 13158 code = 2; 13159 13160 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 13161 if (InITBlock() && !LastInITBlock()) 13162 return false; 13163 13164 break; 13165 13166 case eEncodingA1: 13167 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 13168 n = Bits32(opcode, 19, 16); 13169 imm32 = ARMExpandImm(opcode); 13170 register_form = false; 13171 code = Bits32(opcode, 24, 21); 13172 13173 break; 13174 13175 case eEncodingA2: 13176 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 13177 n = Bits32(opcode, 19, 16); 13178 m = Bits32(opcode, 3, 0); 13179 register_form = true; 13180 13181 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 13182 shift_n = DecodeImmShiftARM(opcode, shift_t); 13183 13184 break; 13185 13186 default: 13187 return false; 13188 } 13189 13190 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) 13191 // else imm32; 13192 uint32_t operand2; 13193 if (register_form) { 13194 uint32_t Rm = ReadCoreReg(m, &success); 13195 if (!success) 13196 return false; 13197 13198 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success); 13199 if (!success) 13200 return false; 13201 } else { 13202 operand2 = imm32; 13203 } 13204 13205 uint32_t Rn = ReadCoreReg(n, &success); 13206 if (!success) 13207 return false; 13208 13209 AddWithCarryResult result; 13210 13211 // case opcode of 13212 switch (code) { 13213 case 0: // when '0000' 13214 // result = R[n] AND operand2; // AND 13215 result.result = Rn & operand2; 13216 break; 13217 13218 case 1: // when '0001' 13219 // result = R[n] EOR operand2; // EOR 13220 result.result = Rn ^ operand2; 13221 break; 13222 13223 case 2: // when '0010' 13224 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 13225 result = AddWithCarry(Rn, ~(operand2), 1); 13226 break; 13227 13228 case 3: // when '0011' 13229 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 13230 result = AddWithCarry(~(Rn), operand2, 1); 13231 break; 13232 13233 case 4: // when '0100' 13234 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 13235 result = AddWithCarry(Rn, operand2, 0); 13236 break; 13237 13238 case 5: // when '0101' 13239 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 13240 result = AddWithCarry(Rn, operand2, APSR_C); 13241 break; 13242 13243 case 6: // when '0110' 13244 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 13245 result = AddWithCarry(Rn, ~(operand2), APSR_C); 13246 break; 13247 13248 case 7: // when '0111' 13249 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 13250 result = AddWithCarry(~(Rn), operand2, APSR_C); 13251 break; 13252 13253 case 10: // when '1100' 13254 // result = R[n] OR operand2; // ORR 13255 result.result = Rn | operand2; 13256 break; 13257 13258 case 11: // when '1101' 13259 // result = operand2; // MOV 13260 result.result = operand2; 13261 break; 13262 13263 case 12: // when '1110' 13264 // result = R[n] AND NOT(operand2); // BIC 13265 result.result = Rn & ~(operand2); 13266 break; 13267 13268 case 15: // when '1111' 13269 // result = NOT(operand2); // MVN 13270 result.result = ~(operand2); 13271 break; 13272 13273 default: 13274 return false; 13275 } 13276 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 13277 13278 // For now, in emulation mode, we don't have access to the SPSR, so we will 13279 // use the CPSR instead, and hope for 13280 // the best. 13281 uint32_t spsr = 13282 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 13283 if (!success) 13284 return false; 13285 13286 CPSRWriteByInstr(spsr, 15, true); 13287 13288 // BranchWritePC(result); 13289 EmulateInstruction::Context context; 13290 context.type = eContextAdjustPC; 13291 context.SetImmediate(result.result); 13292 13293 BranchWritePC(context, result.result); 13294 } 13295 return true; 13296 } 13297 13298 EmulateInstructionARM::ARMOpcode * 13299 EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode, 13300 uint32_t arm_isa) { 13301 static ARMOpcode g_arm_opcodes[] = { 13302 //---------------------------------------------------------------------- 13303 // Prologue instructions 13304 //---------------------------------------------------------------------- 13305 13306 // push register(s) 13307 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13308 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 13309 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 13310 &EmulateInstructionARM::EmulatePUSH, "push <register>"}, 13311 13312 // set r7 to point to a stack offset 13313 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13314 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"}, 13315 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13316 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 13317 // copy the stack pointer to ip 13318 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, 13319 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"}, 13320 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13321 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"}, 13322 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13323 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 13324 13325 // adjust the stack pointer 13326 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13327 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 13328 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13329 &EmulateInstructionARM::EmulateSUBSPReg, 13330 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 13331 13332 // push one register 13333 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 13334 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13335 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"}, 13336 13337 // vector push consecutive extension register(s) 13338 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 13339 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 13340 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 13341 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 13342 13343 //---------------------------------------------------------------------- 13344 // Epilogue instructions 13345 //---------------------------------------------------------------------- 13346 13347 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13348 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 13349 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 13350 &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 13351 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 13352 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 13353 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 13354 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 13355 13356 //---------------------------------------------------------------------- 13357 // Supervisor Call (previously Software Interrupt) 13358 //---------------------------------------------------------------------- 13359 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13360 &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 13361 13362 //---------------------------------------------------------------------- 13363 // Branch instructions 13364 //---------------------------------------------------------------------- 13365 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and 13366 // "bl <label>". 13367 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, 13368 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 13369 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13370 &EmulateInstructionARM::EmulateB, "b #imm24"}, 13371 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13372 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 13373 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, 13374 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 13375 // for example, "bx lr" 13376 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, 13377 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 13378 // bxj 13379 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, 13380 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 13381 13382 //---------------------------------------------------------------------- 13383 // Data-processing instructions 13384 //---------------------------------------------------------------------- 13385 // adc (immediate) 13386 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13387 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 13388 // adc (register) 13389 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13390 &EmulateInstructionARM::EmulateADCReg, 13391 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13392 // add (immediate) 13393 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13394 &EmulateInstructionARM::EmulateADDImmARM, 13395 "add{s}<c> <Rd>, <Rn>, #const"}, 13396 // add (register) 13397 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13398 &EmulateInstructionARM::EmulateADDReg, 13399 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13400 // add (register-shifted register) 13401 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, 13402 &EmulateInstructionARM::EmulateADDRegShift, 13403 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 13404 // adr 13405 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13406 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13407 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, 13408 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 13409 // and (immediate) 13410 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13411 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 13412 // and (register) 13413 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13414 &EmulateInstructionARM::EmulateANDReg, 13415 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13416 // bic (immediate) 13417 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13418 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 13419 // bic (register) 13420 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13421 &EmulateInstructionARM::EmulateBICReg, 13422 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13423 // eor (immediate) 13424 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13425 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 13426 // eor (register) 13427 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13428 &EmulateInstructionARM::EmulateEORReg, 13429 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13430 // orr (immediate) 13431 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13432 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 13433 // orr (register) 13434 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13435 &EmulateInstructionARM::EmulateORRReg, 13436 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13437 // rsb (immediate) 13438 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13439 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 13440 // rsb (register) 13441 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13442 &EmulateInstructionARM::EmulateRSBReg, 13443 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13444 // rsc (immediate) 13445 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13446 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 13447 // rsc (register) 13448 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13449 &EmulateInstructionARM::EmulateRSCReg, 13450 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13451 // sbc (immediate) 13452 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13453 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13454 // sbc (register) 13455 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13456 &EmulateInstructionARM::EmulateSBCReg, 13457 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13458 // sub (immediate, ARM) 13459 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13460 &EmulateInstructionARM::EmulateSUBImmARM, 13461 "sub{s}<c> <Rd>, <Rn>, #<const>"}, 13462 // sub (sp minus immediate) 13463 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13464 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 13465 // sub (register) 13466 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13467 &EmulateInstructionARM::EmulateSUBReg, 13468 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 13469 // teq (immediate) 13470 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13471 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 13472 // teq (register) 13473 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13474 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13475 // tst (immediate) 13476 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13477 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 13478 // tst (register) 13479 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13480 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 13481 13482 // mov (immediate) 13483 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13484 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 13485 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 13486 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"}, 13487 // mov (register) 13488 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13489 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 13490 // mvn (immediate) 13491 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13492 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 13493 // mvn (register) 13494 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13495 &EmulateInstructionARM::EmulateMVNReg, 13496 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 13497 // cmn (immediate) 13498 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13499 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13500 // cmn (register) 13501 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13502 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13503 // cmp (immediate) 13504 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13505 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 13506 // cmp (register) 13507 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13508 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 13509 // asr (immediate) 13510 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, 13511 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 13512 // asr (register) 13513 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13514 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 13515 // lsl (immediate) 13516 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13517 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 13518 // lsl (register) 13519 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, 13520 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 13521 // lsr (immediate) 13522 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, 13523 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 13524 // lsr (register) 13525 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13526 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 13527 // rrx is a special case encoding of ror (immediate) 13528 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13529 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 13530 // ror (immediate) 13531 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13532 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 13533 // ror (register) 13534 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, 13535 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 13536 // mul 13537 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, 13538 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"}, 13539 13540 // subs pc, lr and related instructions 13541 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13542 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13543 "<opc>S<c> PC,#<const> | <Rn>,#<const>"}, 13544 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, 13545 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13546 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"}, 13547 13548 //---------------------------------------------------------------------- 13549 // Load instructions 13550 //---------------------------------------------------------------------- 13551 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13552 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13553 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13554 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"}, 13555 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13556 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13557 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13558 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"}, 13559 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13560 &EmulateInstructionARM::EmulateLDRImmediateARM, 13561 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"}, 13562 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13563 &EmulateInstructionARM::EmulateLDRRegister, 13564 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"}, 13565 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13566 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 13567 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13568 &EmulateInstructionARM::EmulateLDRBRegister, 13569 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"}, 13570 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13571 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13572 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13573 &EmulateInstructionARM::EmulateLDRHRegister, 13574 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13575 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13576 &EmulateInstructionARM::EmulateLDRSBImmediate, 13577 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"}, 13578 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13579 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"}, 13580 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13581 &EmulateInstructionARM::EmulateLDRSBRegister, 13582 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13583 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13584 &EmulateInstructionARM::EmulateLDRSHImmediate, 13585 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 13586 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13587 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13588 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13589 &EmulateInstructionARM::EmulateLDRSHRegister, 13590 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13591 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13592 &EmulateInstructionARM::EmulateLDRDImmediate, 13593 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 13594 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13595 &EmulateInstructionARM::EmulateLDRDRegister, 13596 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13597 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13598 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13599 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13600 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13601 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13602 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13603 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13604 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13605 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13606 &EmulateInstructionARM::EmulateVLD1Multiple, 13607 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13608 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13609 &EmulateInstructionARM::EmulateVLD1Single, 13610 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13611 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13612 &EmulateInstructionARM::EmulateVLD1SingleAll, 13613 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13614 13615 //---------------------------------------------------------------------- 13616 // Store instructions 13617 //---------------------------------------------------------------------- 13618 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13619 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13620 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13621 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"}, 13622 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13623 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13624 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13625 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"}, 13626 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13627 &EmulateInstructionARM::EmulateSTRRegister, 13628 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"}, 13629 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13630 &EmulateInstructionARM::EmulateSTRHRegister, 13631 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"}, 13632 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13633 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 13634 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13635 &EmulateInstructionARM::EmulateSTRBImmARM, 13636 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13637 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13638 &EmulateInstructionARM::EmulateSTRImmARM, 13639 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13640 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13641 &EmulateInstructionARM::EmulateSTRDImm, 13642 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 13643 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13644 &EmulateInstructionARM::EmulateSTRDReg, 13645 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13646 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13647 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13648 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13649 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13650 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13651 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 13652 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13653 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 13654 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13655 &EmulateInstructionARM::EmulateVST1Multiple, 13656 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13657 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13658 &EmulateInstructionARM::EmulateVST1Single, 13659 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13660 13661 //---------------------------------------------------------------------- 13662 // Other instructions 13663 //---------------------------------------------------------------------- 13664 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13665 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13666 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13667 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"}, 13668 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13669 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13670 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13671 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"}, 13672 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13673 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"} 13674 13675 }; 13676 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 13677 13678 for (size_t i = 0; i < k_num_arm_opcodes; ++i) { 13679 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 13680 (g_arm_opcodes[i].variants & arm_isa) != 0) 13681 return &g_arm_opcodes[i]; 13682 } 13683 return NULL; 13684 } 13685 13686 EmulateInstructionARM::ARMOpcode * 13687 EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode, 13688 uint32_t arm_isa) { 13689 13690 static ARMOpcode g_thumb_opcodes[] = { 13691 //---------------------------------------------------------------------- 13692 // Prologue instructions 13693 //---------------------------------------------------------------------- 13694 13695 // push register(s) 13696 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, 13697 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 13698 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13699 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"}, 13700 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13701 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"}, 13702 13703 // set r7 to point to a stack offset 13704 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13705 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"}, 13706 // copy the stack pointer to r7 13707 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, 13708 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"}, 13709 // move from high register to low register (comes after "mov r7, sp" to 13710 // resolve ambiguity) 13711 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, 13712 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"}, 13713 13714 // PC-relative load into register (see also EmulateADDSPRm) 13715 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13716 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 13717 13718 // adjust the stack pointer 13719 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, 13720 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 13721 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13722 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 13723 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13724 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 13725 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13726 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 13727 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13728 &EmulateInstructionARM::EmulateSUBSPReg, 13729 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 13730 13731 // vector push consecutive extension register(s) 13732 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13733 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 13734 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13735 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 13736 13737 //---------------------------------------------------------------------- 13738 // Epilogue instructions 13739 //---------------------------------------------------------------------- 13740 13741 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13742 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 13743 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13744 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 13745 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13746 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 13747 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13748 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"}, 13749 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13750 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"}, 13751 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13752 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 13753 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13754 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 13755 13756 //---------------------------------------------------------------------- 13757 // Supervisor Call (previously Software Interrupt) 13758 //---------------------------------------------------------------------- 13759 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13760 &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 13761 13762 //---------------------------------------------------------------------- 13763 // If Then makes up to four following instructions conditional. 13764 //---------------------------------------------------------------------- 13765 // The next 5 opcode _must_ come before the if then instruction 13766 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13767 &EmulateInstructionARM::EmulateNop, "nop"}, 13768 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13769 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 13770 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13771 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 13772 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13773 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 13774 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13775 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 13776 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13777 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 13778 13779 //---------------------------------------------------------------------- 13780 // Branch instructions 13781 //---------------------------------------------------------------------- 13782 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 13783 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13784 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 13785 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13786 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 13787 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13788 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 13789 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13790 &EmulateInstructionARM::EmulateB, 13791 "b<c>.w #imm8 (outside or last in IT)"}, 13792 // J1 == J2 == 1 13793 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, 13794 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 13795 // J1 == J2 == 1 13796 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, 13797 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 13798 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, 13799 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 13800 // for example, "bx lr" 13801 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, 13802 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 13803 // bxj 13804 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, 13805 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 13806 // compare and branch 13807 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13808 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 13809 // table branch byte 13810 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13811 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 13812 // table branch halfword 13813 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13814 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 13815 13816 //---------------------------------------------------------------------- 13817 // Data-processing instructions 13818 //---------------------------------------------------------------------- 13819 // adc (immediate) 13820 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13821 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 13822 // adc (register) 13823 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, 13824 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 13825 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13826 &EmulateInstructionARM::EmulateADCReg, 13827 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13828 // add (register) 13829 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13830 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 13831 // Make sure "add sp, <Rm>" comes before this instruction, so there's no 13832 // ambiguity decoding the two. 13833 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, 13834 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 13835 // adr 13836 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13837 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13838 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13839 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 13840 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13841 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13842 // and (immediate) 13843 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13844 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 13845 // and (register) 13846 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13847 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 13848 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13849 &EmulateInstructionARM::EmulateANDReg, 13850 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13851 // bic (immediate) 13852 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13853 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 13854 // bic (register) 13855 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, 13856 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 13857 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13858 &EmulateInstructionARM::EmulateBICReg, 13859 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13860 // eor (immediate) 13861 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13862 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 13863 // eor (register) 13864 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, 13865 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 13866 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13867 &EmulateInstructionARM::EmulateEORReg, 13868 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13869 // orr (immediate) 13870 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13871 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 13872 // orr (register) 13873 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, 13874 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 13875 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13876 &EmulateInstructionARM::EmulateORRReg, 13877 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13878 // rsb (immediate) 13879 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, 13880 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 13881 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13882 &EmulateInstructionARM::EmulateRSBImm, 13883 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 13884 // rsb (register) 13885 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13886 &EmulateInstructionARM::EmulateRSBReg, 13887 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13888 // sbc (immediate) 13889 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13890 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13891 // sbc (register) 13892 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, 13893 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 13894 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13895 &EmulateInstructionARM::EmulateSBCReg, 13896 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13897 // add (immediate, Thumb) 13898 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13899 &EmulateInstructionARM::EmulateADDImmThumb, 13900 "adds|add<c> <Rd>,<Rn>,#<imm3>"}, 13901 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13902 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"}, 13903 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13904 &EmulateInstructionARM::EmulateADDImmThumb, 13905 "add{s}<c>.w <Rd>,<Rn>,#<const>"}, 13906 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13907 &EmulateInstructionARM::EmulateADDImmThumb, 13908 "addw<c> <Rd>,<Rn>,#<imm12>"}, 13909 // sub (immediate, Thumb) 13910 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13911 &EmulateInstructionARM::EmulateSUBImmThumb, 13912 "subs|sub<c> <Rd>, <Rn> #imm3"}, 13913 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, 13914 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 13915 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13916 &EmulateInstructionARM::EmulateSUBImmThumb, 13917 "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 13918 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13919 &EmulateInstructionARM::EmulateSUBImmThumb, 13920 "subw<c> <Rd>, <Rn>, #imm12"}, 13921 // sub (sp minus immediate) 13922 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13923 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 13924 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13925 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 13926 // sub (register) 13927 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13928 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 13929 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13930 &EmulateInstructionARM::EmulateSUBReg, 13931 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 13932 // teq (immediate) 13933 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13934 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 13935 // teq (register) 13936 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13937 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13938 // tst (immediate) 13939 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13940 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 13941 // tst (register) 13942 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, 13943 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 13944 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13945 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 13946 13947 // move from high register to high register 13948 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, 13949 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 13950 // move from low register to low register 13951 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13952 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 13953 // mov{s}<c>.w <Rd>, <Rm> 13954 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13955 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 13956 // move immediate 13957 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13958 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 13959 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13960 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 13961 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13962 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 13963 // mvn (immediate) 13964 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13965 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 13966 // mvn (register) 13967 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13968 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 13969 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13970 &EmulateInstructionARM::EmulateMVNReg, 13971 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 13972 // cmn (immediate) 13973 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13974 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13975 // cmn (register) 13976 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13977 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 13978 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13979 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13980 // cmp (immediate) 13981 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13982 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 13983 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13984 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 13985 // cmp (register) (Rn and Rm both from r0-r7) 13986 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, 13987 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13988 // cmp (register) (Rn and Rm not both from r0-r7) 13989 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, 13990 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13991 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, 13992 &EmulateInstructionARM::EmulateCMPReg, 13993 "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 13994 // asr (immediate) 13995 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13996 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 13997 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13998 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 13999 // asr (register) 14000 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, 14001 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 14002 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14003 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 14004 // lsl (immediate) 14005 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, 14006 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 14007 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14008 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 14009 // lsl (register) 14010 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, 14011 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 14012 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14013 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 14014 // lsr (immediate) 14015 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, 14016 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 14017 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14018 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 14019 // lsr (register) 14020 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 14021 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 14022 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14023 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 14024 // rrx is a special case encoding of ror (immediate) 14025 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14026 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 14027 // ror (immediate) 14028 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14029 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 14030 // ror (register) 14031 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 14032 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 14033 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14034 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 14035 // mul 14036 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14037 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"}, 14038 // mul 14039 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14040 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"}, 14041 14042 // subs pc, lr and related instructions 14043 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14044 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"}, 14045 14046 //---------------------------------------------------------------------- 14047 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE 14048 // LDM.. Instructions in this table; 14049 // otherwise the wrong instructions will be selected. 14050 //---------------------------------------------------------------------- 14051 14052 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14053 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"}, 14054 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14055 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"}, 14056 14057 //---------------------------------------------------------------------- 14058 // Load instructions 14059 //---------------------------------------------------------------------- 14060 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14061 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 14062 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14063 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"}, 14064 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14065 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 14066 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14067 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 14068 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 14069 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 14070 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 14071 &EmulateInstructionARM::EmulateLDRRtRnImm, 14072 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 14073 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 14074 &EmulateInstructionARM::EmulateLDRRtRnImm, 14075 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 14076 // Thumb2 PC-relative load into register 14077 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14078 &EmulateInstructionARM::EmulateLDRRtPCRelative, 14079 "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 14080 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14081 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"}, 14082 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14083 &EmulateInstructionARM::EmulateLDRRegister, 14084 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"}, 14085 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14086 &EmulateInstructionARM::EmulateLDRBImmediate, 14087 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"}, 14088 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14089 &EmulateInstructionARM::EmulateLDRBImmediate, 14090 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 14091 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 14092 &EmulateInstructionARM::EmulateLDRBImmediate, 14093 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"}, 14094 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14095 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"}, 14096 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 14097 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"}, 14098 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14099 &EmulateInstructionARM::EmulateLDRBRegister, 14100 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 14101 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14102 &EmulateInstructionARM::EmulateLDRHImmediate, 14103 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"}, 14104 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14105 &EmulateInstructionARM::EmulateLDRHImmediate, 14106 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 14107 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 14108 &EmulateInstructionARM::EmulateLDRHImmediate, 14109 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"}, 14110 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14111 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 14112 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14113 &EmulateInstructionARM::EmulateLDRHRegister, 14114 "ldrh<c> <Rt>, [<Rn>,<Rm>]"}, 14115 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14116 &EmulateInstructionARM::EmulateLDRHRegister, 14117 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 14118 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14119 &EmulateInstructionARM::EmulateLDRSBImmediate, 14120 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"}, 14121 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14122 &EmulateInstructionARM::EmulateLDRSBImmediate, 14123 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 14124 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14125 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"}, 14126 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14127 &EmulateInstructionARM::EmulateLDRSBRegister, 14128 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"}, 14129 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14130 &EmulateInstructionARM::EmulateLDRSBRegister, 14131 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 14132 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14133 &EmulateInstructionARM::EmulateLDRSHImmediate, 14134 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"}, 14135 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14136 &EmulateInstructionARM::EmulateLDRSHImmediate, 14137 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 14138 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14139 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 14140 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14141 &EmulateInstructionARM::EmulateLDRSHRegister, 14142 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"}, 14143 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14144 &EmulateInstructionARM::EmulateLDRSHRegister, 14145 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 14146 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14147 &EmulateInstructionARM::EmulateLDRDImmediate, 14148 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 14149 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 14150 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 14151 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 14152 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 14153 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 14154 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 14155 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 14156 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 14157 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 14158 &EmulateInstructionARM::EmulateVLD1Multiple, 14159 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 14160 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 14161 &EmulateInstructionARM::EmulateVLD1Single, 14162 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 14163 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 14164 &EmulateInstructionARM::EmulateVLD1SingleAll, 14165 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 14166 14167 //---------------------------------------------------------------------- 14168 // Store instructions 14169 //---------------------------------------------------------------------- 14170 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14171 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 14172 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14173 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"}, 14174 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14175 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 14176 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14177 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"}, 14178 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 14179 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"}, 14180 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 14181 &EmulateInstructionARM::EmulateSTRThumb, 14182 "str<c>.w <Rt>, [<Rn>,#<imm12>]"}, 14183 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 14184 &EmulateInstructionARM::EmulateSTRThumb, 14185 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"}, 14186 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14187 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"}, 14188 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14189 &EmulateInstructionARM::EmulateSTRRegister, 14190 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"}, 14191 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14192 &EmulateInstructionARM::EmulateSTRBThumb, 14193 "strb<c> <Rt>, [<Rn>, #<imm5>]"}, 14194 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14195 &EmulateInstructionARM::EmulateSTRBThumb, 14196 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"}, 14197 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 14198 &EmulateInstructionARM::EmulateSTRBThumb, 14199 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"}, 14200 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 14201 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"}, 14202 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14203 &EmulateInstructionARM::EmulateSTRHRegister, 14204 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 14205 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14206 &EmulateInstructionARM::EmulateSTREX, 14207 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"}, 14208 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 14209 &EmulateInstructionARM::EmulateSTRDImm, 14210 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 14211 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 14212 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 14213 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 14214 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 14215 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 14216 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 14217 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 14218 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 14219 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 14220 &EmulateInstructionARM::EmulateVST1Multiple, 14221 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 14222 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 14223 &EmulateInstructionARM::EmulateVST1Single, 14224 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 14225 14226 //---------------------------------------------------------------------- 14227 // Other instructions 14228 //---------------------------------------------------------------------- 14229 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 14230 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"}, 14231 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, 14232 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 14233 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 14234 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"}, 14235 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14236 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 14237 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 14238 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"}, 14239 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14240 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 14241 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 14242 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"}, 14243 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 14244 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 14245 }; 14246 14247 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 14248 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) { 14249 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 14250 (g_thumb_opcodes[i].variants & arm_isa) != 0) 14251 return &g_thumb_opcodes[i]; 14252 } 14253 return NULL; 14254 } 14255 14256 bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) { 14257 m_arch = arch; 14258 m_arm_isa = 0; 14259 const char *arch_cstr = arch.GetArchitectureName(); 14260 if (arch_cstr) { 14261 if (0 == ::strcasecmp(arch_cstr, "armv4t")) 14262 m_arm_isa = ARMv4T; 14263 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) 14264 m_arm_isa = ARMv5TEJ; 14265 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) 14266 m_arm_isa = ARMv5TE; 14267 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) 14268 m_arm_isa = ARMv5T; 14269 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) 14270 m_arm_isa = ARMv6K; 14271 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) 14272 m_arm_isa = ARMv6T2; 14273 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) 14274 m_arm_isa = ARMv7S; 14275 else if (0 == ::strcasecmp(arch_cstr, "arm")) 14276 m_arm_isa = ARMvAll; 14277 else if (0 == ::strcasecmp(arch_cstr, "thumb")) 14278 m_arm_isa = ARMvAll; 14279 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5)) 14280 m_arm_isa = ARMv4; 14281 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5)) 14282 m_arm_isa = ARMv6; 14283 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5)) 14284 m_arm_isa = ARMv7; 14285 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5)) 14286 m_arm_isa = ARMv8; 14287 } 14288 return m_arm_isa != 0; 14289 } 14290 14291 bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode, 14292 const Address &inst_addr, 14293 Target *target) { 14294 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { 14295 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || 14296 m_arch.IsAlwaysThumbInstructions()) 14297 m_opcode_mode = eModeThumb; 14298 else { 14299 AddressClass addr_class = inst_addr.GetAddressClass(); 14300 14301 if ((addr_class == eAddressClassCode) || 14302 (addr_class == eAddressClassUnknown)) 14303 m_opcode_mode = eModeARM; 14304 else if (addr_class == eAddressClassCodeAlternateISA) 14305 m_opcode_mode = eModeThumb; 14306 else 14307 return false; 14308 } 14309 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions()) 14310 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 14311 else 14312 m_opcode_cpsr = CPSR_MODE_USR; 14313 return true; 14314 } 14315 return false; 14316 } 14317 14318 bool EmulateInstructionARM::ReadInstruction() { 14319 bool success = false; 14320 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric, 14321 LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 14322 if (success) { 14323 addr_t pc = 14324 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 14325 LLDB_INVALID_ADDRESS, &success); 14326 if (success) { 14327 Context read_inst_context; 14328 read_inst_context.type = eContextReadOpcode; 14329 read_inst_context.SetNoArgs(); 14330 14331 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) { 14332 m_opcode_mode = eModeThumb; 14333 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 14334 14335 if (success) { 14336 if ((thumb_opcode & 0xe000) != 0xe000 || 14337 ((thumb_opcode & 0x1800u) == 0)) { 14338 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder()); 14339 } else { 14340 m_opcode.SetOpcode32( 14341 (thumb_opcode << 16) | 14342 MemARead(read_inst_context, pc + 2, 2, 0, &success), 14343 GetByteOrder()); 14344 } 14345 } 14346 } else { 14347 m_opcode_mode = eModeARM; 14348 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success), 14349 GetByteOrder()); 14350 } 14351 14352 if (!m_ignore_conditions) { 14353 // If we are not ignoreing the conditions then init the it session from 14354 // the current 14355 // value of cpsr. 14356 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | 14357 Bits32(m_opcode_cpsr, 26, 25); 14358 if (it != 0) 14359 m_it_session.InitIT(it); 14360 } 14361 } 14362 } 14363 if (!success) { 14364 m_opcode_mode = eModeInvalid; 14365 m_addr = LLDB_INVALID_ADDRESS; 14366 } 14367 return success; 14368 } 14369 14370 uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; } 14371 14372 bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) { 14373 // If we are ignoring conditions, then always return true. 14374 // this allows us to iterate over disassembly code and still 14375 // emulate an instruction even if we don't have all the right 14376 // bits set in the CPSR register... 14377 if (m_ignore_conditions) 14378 return true; 14379 14380 const uint32_t cond = CurrentCond(opcode); 14381 if (cond == UINT32_MAX) 14382 return false; 14383 14384 bool result = false; 14385 switch (UnsignedBits(cond, 3, 1)) { 14386 case 0: 14387 if (m_opcode_cpsr == 0) 14388 result = true; 14389 else 14390 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 14391 break; 14392 case 1: 14393 if (m_opcode_cpsr == 0) 14394 result = true; 14395 else 14396 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 14397 break; 14398 case 2: 14399 if (m_opcode_cpsr == 0) 14400 result = true; 14401 else 14402 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 14403 break; 14404 case 3: 14405 if (m_opcode_cpsr == 0) 14406 result = true; 14407 else 14408 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 14409 break; 14410 case 4: 14411 if (m_opcode_cpsr == 0) 14412 result = true; 14413 else 14414 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && 14415 ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 14416 break; 14417 case 5: 14418 if (m_opcode_cpsr == 0) 14419 result = true; 14420 else { 14421 bool n = (m_opcode_cpsr & MASK_CPSR_N); 14422 bool v = (m_opcode_cpsr & MASK_CPSR_V); 14423 result = n == v; 14424 } 14425 break; 14426 case 6: 14427 if (m_opcode_cpsr == 0) 14428 result = true; 14429 else { 14430 bool n = (m_opcode_cpsr & MASK_CPSR_N); 14431 bool v = (m_opcode_cpsr & MASK_CPSR_V); 14432 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 14433 } 14434 break; 14435 case 7: 14436 // Always execute (cond == 0b1110, or the special 0b1111 which gives 14437 // opcodes different meanings, but always means execution happens. 14438 return true; 14439 } 14440 14441 if (cond & 1) 14442 result = !result; 14443 return result; 14444 } 14445 14446 uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) { 14447 switch (m_opcode_mode) { 14448 case eModeInvalid: 14449 break; 14450 14451 case eModeARM: 14452 return UnsignedBits(opcode, 31, 28); 14453 14454 case eModeThumb: 14455 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 14456 // 'cond' field of the encoding. 14457 { 14458 const uint32_t byte_size = m_opcode.GetByteSize(); 14459 if (byte_size == 2) { 14460 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 14461 return Bits32(opcode, 11, 8); 14462 } else if (byte_size == 4) { 14463 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 && 14464 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) { 14465 return Bits32(opcode, 25, 22); 14466 } 14467 } else 14468 // We have an invalid thumb instruction, let's bail out. 14469 break; 14470 14471 return m_it_session.GetCond(); 14472 } 14473 } 14474 return UINT32_MAX; // Return invalid value 14475 } 14476 14477 bool EmulateInstructionARM::InITBlock() { 14478 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 14479 } 14480 14481 bool EmulateInstructionARM::LastInITBlock() { 14482 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 14483 } 14484 14485 bool EmulateInstructionARM::BadMode(uint32_t mode) { 14486 14487 switch (mode) { 14488 case 16: 14489 return false; // '10000' 14490 case 17: 14491 return false; // '10001' 14492 case 18: 14493 return false; // '10010' 14494 case 19: 14495 return false; // '10011' 14496 case 22: 14497 return false; // '10110' 14498 case 23: 14499 return false; // '10111' 14500 case 27: 14501 return false; // '11011' 14502 case 31: 14503 return false; // '11111' 14504 default: 14505 return true; 14506 } 14507 return true; 14508 } 14509 14510 bool EmulateInstructionARM::CurrentModeIsPrivileged() { 14511 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0); 14512 14513 if (BadMode(mode)) 14514 return false; 14515 14516 if (mode == 16) 14517 return false; 14518 14519 return true; 14520 } 14521 14522 void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask, 14523 bool affect_execstate) { 14524 bool privileged = CurrentModeIsPrivileged(); 14525 14526 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20; 14527 14528 if (BitIsSet(bytemask, 3)) { 14529 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27); 14530 if (affect_execstate) 14531 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24); 14532 } 14533 14534 if (BitIsSet(bytemask, 2)) { 14535 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16); 14536 } 14537 14538 if (BitIsSet(bytemask, 1)) { 14539 if (affect_execstate) 14540 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10); 14541 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9); 14542 if (privileged) 14543 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8); 14544 } 14545 14546 if (BitIsSet(bytemask, 0)) { 14547 if (privileged) 14548 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6); 14549 if (affect_execstate) 14550 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5); 14551 if (privileged) 14552 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0); 14553 } 14554 14555 m_opcode_cpsr = tmp_cpsr; 14556 } 14557 14558 bool EmulateInstructionARM::BranchWritePC(const Context &context, 14559 uint32_t addr) { 14560 addr_t target; 14561 14562 // Check the current instruction set. 14563 if (CurrentInstrSet() == eModeARM) 14564 target = addr & 0xfffffffc; 14565 else 14566 target = addr & 0xfffffffe; 14567 14568 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14569 LLDB_REGNUM_GENERIC_PC, target)) 14570 return false; 14571 14572 return true; 14573 } 14574 14575 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by 14576 // inspecting addr. 14577 bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) { 14578 addr_t target; 14579 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 14580 // we want to record it and issue a WriteRegister callback so the clients 14581 // can track the mode changes accordingly. 14582 bool cpsr_changed = false; 14583 14584 if (BitIsSet(addr, 0)) { 14585 if (CurrentInstrSet() != eModeThumb) { 14586 SelectInstrSet(eModeThumb); 14587 cpsr_changed = true; 14588 } 14589 target = addr & 0xfffffffe; 14590 context.SetISA(eModeThumb); 14591 } else if (BitIsClear(addr, 1)) { 14592 if (CurrentInstrSet() != eModeARM) { 14593 SelectInstrSet(eModeARM); 14594 cpsr_changed = true; 14595 } 14596 target = addr & 0xfffffffc; 14597 context.SetISA(eModeARM); 14598 } else 14599 return false; // address<1:0> == '10' => UNPREDICTABLE 14600 14601 if (cpsr_changed) { 14602 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14603 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14604 return false; 14605 } 14606 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14607 LLDB_REGNUM_GENERIC_PC, target)) 14608 return false; 14609 14610 return true; 14611 } 14612 14613 // Dispatches to either BXWritePC or BranchWritePC based on architecture 14614 // versions. 14615 bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) { 14616 if (ArchVersion() >= ARMv5T) 14617 return BXWritePC(context, addr); 14618 else 14619 return BranchWritePC((const Context)context, addr); 14620 } 14621 14622 // Dispatches to either BXWritePC or BranchWritePC based on architecture 14623 // versions and current instruction set. 14624 bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) { 14625 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 14626 return BXWritePC(context, addr); 14627 else 14628 return BranchWritePC((const Context)context, addr); 14629 } 14630 14631 EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() { 14632 return m_opcode_mode; 14633 } 14634 14635 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 14636 // ReadInstruction() is performed. This function has a side effect of updating 14637 // the m_new_inst_cpsr member variable if necessary. 14638 bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) { 14639 m_new_inst_cpsr = m_opcode_cpsr; 14640 switch (arm_or_thumb) { 14641 default: 14642 return false; 14643 case eModeARM: 14644 // Clear the T bit. 14645 m_new_inst_cpsr &= ~MASK_CPSR_T; 14646 break; 14647 case eModeThumb: 14648 // Set the T bit. 14649 m_new_inst_cpsr |= MASK_CPSR_T; 14650 break; 14651 } 14652 return true; 14653 } 14654 14655 // This function returns TRUE if the processor currently provides support for 14656 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 14657 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 14658 bool EmulateInstructionARM::UnalignedSupport() { 14659 return (ArchVersion() >= ARMv7); 14660 } 14661 14662 // The main addition and subtraction instructions can produce status information 14663 // about both unsigned carry and signed overflow conditions. This status 14664 // information can be used to synthesize multi-word additions and subtractions. 14665 EmulateInstructionARM::AddWithCarryResult 14666 EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) { 14667 uint32_t result; 14668 uint8_t carry_out; 14669 uint8_t overflow; 14670 14671 uint64_t unsigned_sum = x + y + carry_in; 14672 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 14673 14674 result = UnsignedBits(unsigned_sum, 31, 0); 14675 // carry_out = (result == unsigned_sum ? 0 : 1); 14676 overflow = ((int32_t)result == signed_sum ? 0 : 1); 14677 14678 if (carry_in) 14679 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0; 14680 else 14681 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0; 14682 14683 AddWithCarryResult res = {result, carry_out, overflow}; 14684 return res; 14685 } 14686 14687 uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) { 14688 lldb::RegisterKind reg_kind; 14689 uint32_t reg_num; 14690 switch (num) { 14691 case SP_REG: 14692 reg_kind = eRegisterKindGeneric; 14693 reg_num = LLDB_REGNUM_GENERIC_SP; 14694 break; 14695 case LR_REG: 14696 reg_kind = eRegisterKindGeneric; 14697 reg_num = LLDB_REGNUM_GENERIC_RA; 14698 break; 14699 case PC_REG: 14700 reg_kind = eRegisterKindGeneric; 14701 reg_num = LLDB_REGNUM_GENERIC_PC; 14702 break; 14703 default: 14704 if (num < SP_REG) { 14705 reg_kind = eRegisterKindDWARF; 14706 reg_num = dwarf_r0 + num; 14707 } else { 14708 // assert(0 && "Invalid register number"); 14709 *success = false; 14710 return UINT32_MAX; 14711 } 14712 break; 14713 } 14714 14715 // Read our register. 14716 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success); 14717 14718 // When executing an ARM instruction , PC reads as the address of the current 14719 // instruction plus 8. 14720 // When executing a Thumb instruction , PC reads as the address of the current 14721 // instruction plus 4. 14722 if (num == 15) { 14723 if (CurrentInstrSet() == eModeARM) 14724 val += 8; 14725 else 14726 val += 4; 14727 } 14728 14729 return val; 14730 } 14731 14732 // Write the result to the ARM core register Rd, and optionally update the 14733 // condition flags based on the result. 14734 // 14735 // This helper method tries to encapsulate the following pseudocode from the 14736 // ARM Architecture Reference Manual: 14737 // 14738 // if d == 15 then // Can only occur for encoding A1 14739 // ALUWritePC(result); // setflags is always FALSE here 14740 // else 14741 // R[d] = result; 14742 // if setflags then 14743 // APSR.N = result<31>; 14744 // APSR.Z = IsZeroBit(result); 14745 // APSR.C = carry; 14746 // // APSR.V unchanged 14747 // 14748 // In the above case, the API client does not pass in the overflow arg, which 14749 // defaults to ~0u. 14750 bool EmulateInstructionARM::WriteCoreRegOptionalFlags( 14751 Context &context, const uint32_t result, const uint32_t Rd, bool setflags, 14752 const uint32_t carry, const uint32_t overflow) { 14753 if (Rd == 15) { 14754 if (!ALUWritePC(context, result)) 14755 return false; 14756 } else { 14757 lldb::RegisterKind reg_kind; 14758 uint32_t reg_num; 14759 switch (Rd) { 14760 case SP_REG: 14761 reg_kind = eRegisterKindGeneric; 14762 reg_num = LLDB_REGNUM_GENERIC_SP; 14763 break; 14764 case LR_REG: 14765 reg_kind = eRegisterKindGeneric; 14766 reg_num = LLDB_REGNUM_GENERIC_RA; 14767 break; 14768 default: 14769 reg_kind = eRegisterKindDWARF; 14770 reg_num = dwarf_r0 + Rd; 14771 } 14772 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result)) 14773 return false; 14774 if (setflags) 14775 return WriteFlags(context, result, carry, overflow); 14776 } 14777 return true; 14778 } 14779 14780 // This helper method tries to encapsulate the following pseudocode from the 14781 // ARM Architecture Reference Manual: 14782 // 14783 // APSR.N = result<31>; 14784 // APSR.Z = IsZeroBit(result); 14785 // APSR.C = carry; 14786 // APSR.V = overflow 14787 // 14788 // Default arguments can be specified for carry and overflow parameters, which 14789 // means 14790 // not to update the respective flags. 14791 bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result, 14792 const uint32_t carry, 14793 const uint32_t overflow) { 14794 m_new_inst_cpsr = m_opcode_cpsr; 14795 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 14796 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 14797 if (carry != ~0u) 14798 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 14799 if (overflow != ~0u) 14800 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 14801 if (m_new_inst_cpsr != m_opcode_cpsr) { 14802 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14803 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14804 return false; 14805 } 14806 return true; 14807 } 14808 14809 bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) { 14810 ARMOpcode *opcode_data = NULL; 14811 14812 if (m_opcode_mode == eModeThumb) 14813 opcode_data = 14814 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14815 else if (m_opcode_mode == eModeARM) 14816 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14817 14818 const bool auto_advance_pc = 14819 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 14820 m_ignore_conditions = 14821 evaluate_options & eEmulateInstructionOptionIgnoreConditions; 14822 14823 bool success = false; 14824 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) { 14825 m_opcode_cpsr = 14826 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 14827 } 14828 14829 // Only return false if we are unable to read the CPSR if we care about 14830 // conditions 14831 if (success == false && m_ignore_conditions == false) 14832 return false; 14833 14834 uint32_t orig_pc_value = 0; 14835 if (auto_advance_pc) { 14836 orig_pc_value = 14837 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14838 if (!success) 14839 return false; 14840 } 14841 14842 // Call the Emulate... function if we managed to decode the opcode. 14843 if (opcode_data) { 14844 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(), 14845 opcode_data->encoding); 14846 if (!success) 14847 return false; 14848 } 14849 14850 // Advance the ITSTATE bits to their values for the next instruction if we 14851 // haven't just executed 14852 // an IT instruction what initialized it. 14853 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() && 14854 (opcode_data == nullptr || 14855 opcode_data->callback != &EmulateInstructionARM::EmulateIT)) 14856 m_it_session.ITAdvance(); 14857 14858 if (auto_advance_pc) { 14859 uint32_t after_pc_value = 14860 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14861 if (!success) 14862 return false; 14863 14864 if (auto_advance_pc && (after_pc_value == orig_pc_value)) { 14865 after_pc_value += m_opcode.GetByteSize(); 14866 14867 EmulateInstruction::Context context; 14868 context.type = eContextAdvancePC; 14869 context.SetNoArgs(); 14870 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc, 14871 after_pc_value)) 14872 return false; 14873 } 14874 } 14875 return true; 14876 } 14877 14878 EmulateInstruction::InstructionCondition 14879 EmulateInstructionARM::GetInstructionCondition() { 14880 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32()); 14881 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX) 14882 return EmulateInstruction::UnconditionalCondition; 14883 return cond; 14884 } 14885 14886 bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, 14887 OptionValueDictionary *test_data) { 14888 if (!test_data) { 14889 out_stream->Printf("TestEmulation: Missing test data.\n"); 14890 return false; 14891 } 14892 14893 static ConstString opcode_key("opcode"); 14894 static ConstString before_key("before_state"); 14895 static ConstString after_key("after_state"); 14896 14897 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key); 14898 14899 uint32_t test_opcode; 14900 if ((value_sp.get() == NULL) || 14901 (value_sp->GetType() != OptionValue::eTypeUInt64)) { 14902 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n"); 14903 return false; 14904 } 14905 test_opcode = value_sp->GetUInt64Value(); 14906 14907 if (arch.GetTriple().getArch() == llvm::Triple::thumb || 14908 arch.IsAlwaysThumbInstructions()) { 14909 m_opcode_mode = eModeThumb; 14910 if (test_opcode < 0x10000) 14911 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder()); 14912 else 14913 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14914 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) { 14915 m_opcode_mode = eModeARM; 14916 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14917 } else { 14918 out_stream->Printf("TestEmulation: Invalid arch.\n"); 14919 return false; 14920 } 14921 14922 EmulationStateARM before_state; 14923 EmulationStateARM after_state; 14924 14925 value_sp = test_data->GetValueForKey(before_key); 14926 if ((value_sp.get() == NULL) || 14927 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14928 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n"); 14929 return false; 14930 } 14931 14932 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary(); 14933 if (!before_state.LoadStateFromDictionary(state_dictionary)) { 14934 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n"); 14935 return false; 14936 } 14937 14938 value_sp = test_data->GetValueForKey(after_key); 14939 if ((value_sp.get() == NULL) || 14940 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14941 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n"); 14942 return false; 14943 } 14944 14945 state_dictionary = value_sp->GetAsDictionary(); 14946 if (!after_state.LoadStateFromDictionary(state_dictionary)) { 14947 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n"); 14948 return false; 14949 } 14950 14951 SetBaton((void *)&before_state); 14952 SetCallbacks(&EmulationStateARM::ReadPseudoMemory, 14953 &EmulationStateARM::WritePseudoMemory, 14954 &EmulationStateARM::ReadPseudoRegister, 14955 &EmulationStateARM::WritePseudoRegister); 14956 14957 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 14958 if (!success) { 14959 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n"); 14960 return false; 14961 } 14962 14963 success = before_state.CompareState(after_state); 14964 if (!success) 14965 out_stream->Printf( 14966 "TestEmulation: 'before' and 'after' states do not match.\n"); 14967 14968 return success; 14969 } 14970 // 14971 // 14972 // const char * 14973 // EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 14974 //{ 14975 // if (reg_kind == eRegisterKindGeneric) 14976 // { 14977 // switch (reg_num) 14978 // { 14979 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 14980 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 14981 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 14982 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 14983 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 14984 // default: return NULL; 14985 // } 14986 // } 14987 // else if (reg_kind == eRegisterKindDWARF) 14988 // { 14989 // return GetARMDWARFRegisterName (reg_num); 14990 // } 14991 // return NULL; 14992 //} 14993 // 14994 bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { 14995 unwind_plan.Clear(); 14996 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 14997 14998 UnwindPlan::RowSP row(new UnwindPlan::Row); 14999 15000 // Our previous Call Frame Address is the stack pointer 15001 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0); 15002 15003 unwind_plan.AppendRow(row); 15004 unwind_plan.SetSourceName("EmulateInstructionARM"); 15005 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 15006 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 15007 unwind_plan.SetReturnAddressRegister(dwarf_lr); 15008 return true; 15009 } 15010