1 //===-- EmulateInstructionARM.cpp -----------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include <cstdlib> 10 11 #include "EmulateInstructionARM.h" 12 #include "EmulationStateARM.h" 13 #include "lldb/Core/Address.h" 14 #include "lldb/Core/PluginManager.h" 15 #include "lldb/Host/PosixApi.h" 16 #include "lldb/Interpreter/OptionValueArray.h" 17 #include "lldb/Interpreter/OptionValueDictionary.h" 18 #include "lldb/Symbol/UnwindPlan.h" 19 #include "lldb/Utility/ArchSpec.h" 20 #include "lldb/Utility/ConstString.h" 21 #include "lldb/Utility/Stream.h" 22 23 #include "Plugins/Process/Utility/ARMDefines.h" 24 #include "Plugins/Process/Utility/ARMUtils.h" 25 #include "Utility/ARM_DWARF_Registers.h" 26 27 #include "llvm/ADT/STLExtras.h" 28 #include "llvm/Support/MathExtras.h" 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionARM, InstructionARM) 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 // ITSession implementation 43 // 44 45 static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo ®_info) { 46 ::memset(®_info, 0, sizeof(RegisterInfo)); 47 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); 48 49 if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) { 50 reg_info.byte_size = 16; 51 reg_info.format = eFormatVectorOfUInt8; 52 reg_info.encoding = eEncodingVector; 53 } 54 55 if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) { 56 reg_info.byte_size = 8; 57 reg_info.format = eFormatFloat; 58 reg_info.encoding = eEncodingIEEE754; 59 } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) { 60 reg_info.byte_size = 4; 61 reg_info.format = eFormatFloat; 62 reg_info.encoding = eEncodingIEEE754; 63 } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) { 64 reg_info.byte_size = 12; 65 reg_info.format = eFormatFloat; 66 reg_info.encoding = eEncodingIEEE754; 67 } else { 68 reg_info.byte_size = 4; 69 reg_info.format = eFormatHex; 70 reg_info.encoding = eEncodingUint; 71 } 72 73 reg_info.kinds[eRegisterKindDWARF] = reg_num; 74 75 switch (reg_num) { 76 case dwarf_r0: 77 reg_info.name = "r0"; 78 break; 79 case dwarf_r1: 80 reg_info.name = "r1"; 81 break; 82 case dwarf_r2: 83 reg_info.name = "r2"; 84 break; 85 case dwarf_r3: 86 reg_info.name = "r3"; 87 break; 88 case dwarf_r4: 89 reg_info.name = "r4"; 90 break; 91 case dwarf_r5: 92 reg_info.name = "r5"; 93 break; 94 case dwarf_r6: 95 reg_info.name = "r6"; 96 break; 97 case dwarf_r7: 98 reg_info.name = "r7"; 99 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; 100 break; 101 case dwarf_r8: 102 reg_info.name = "r8"; 103 break; 104 case dwarf_r9: 105 reg_info.name = "r9"; 106 break; 107 case dwarf_r10: 108 reg_info.name = "r10"; 109 break; 110 case dwarf_r11: 111 reg_info.name = "r11"; 112 break; 113 case dwarf_r12: 114 reg_info.name = "r12"; 115 break; 116 case dwarf_sp: 117 reg_info.name = "sp"; 118 reg_info.alt_name = "r13"; 119 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; 120 break; 121 case dwarf_lr: 122 reg_info.name = "lr"; 123 reg_info.alt_name = "r14"; 124 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; 125 break; 126 case dwarf_pc: 127 reg_info.name = "pc"; 128 reg_info.alt_name = "r15"; 129 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; 130 break; 131 case dwarf_cpsr: 132 reg_info.name = "cpsr"; 133 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; 134 break; 135 136 case dwarf_s0: 137 reg_info.name = "s0"; 138 break; 139 case dwarf_s1: 140 reg_info.name = "s1"; 141 break; 142 case dwarf_s2: 143 reg_info.name = "s2"; 144 break; 145 case dwarf_s3: 146 reg_info.name = "s3"; 147 break; 148 case dwarf_s4: 149 reg_info.name = "s4"; 150 break; 151 case dwarf_s5: 152 reg_info.name = "s5"; 153 break; 154 case dwarf_s6: 155 reg_info.name = "s6"; 156 break; 157 case dwarf_s7: 158 reg_info.name = "s7"; 159 break; 160 case dwarf_s8: 161 reg_info.name = "s8"; 162 break; 163 case dwarf_s9: 164 reg_info.name = "s9"; 165 break; 166 case dwarf_s10: 167 reg_info.name = "s10"; 168 break; 169 case dwarf_s11: 170 reg_info.name = "s11"; 171 break; 172 case dwarf_s12: 173 reg_info.name = "s12"; 174 break; 175 case dwarf_s13: 176 reg_info.name = "s13"; 177 break; 178 case dwarf_s14: 179 reg_info.name = "s14"; 180 break; 181 case dwarf_s15: 182 reg_info.name = "s15"; 183 break; 184 case dwarf_s16: 185 reg_info.name = "s16"; 186 break; 187 case dwarf_s17: 188 reg_info.name = "s17"; 189 break; 190 case dwarf_s18: 191 reg_info.name = "s18"; 192 break; 193 case dwarf_s19: 194 reg_info.name = "s19"; 195 break; 196 case dwarf_s20: 197 reg_info.name = "s20"; 198 break; 199 case dwarf_s21: 200 reg_info.name = "s21"; 201 break; 202 case dwarf_s22: 203 reg_info.name = "s22"; 204 break; 205 case dwarf_s23: 206 reg_info.name = "s23"; 207 break; 208 case dwarf_s24: 209 reg_info.name = "s24"; 210 break; 211 case dwarf_s25: 212 reg_info.name = "s25"; 213 break; 214 case dwarf_s26: 215 reg_info.name = "s26"; 216 break; 217 case dwarf_s27: 218 reg_info.name = "s27"; 219 break; 220 case dwarf_s28: 221 reg_info.name = "s28"; 222 break; 223 case dwarf_s29: 224 reg_info.name = "s29"; 225 break; 226 case dwarf_s30: 227 reg_info.name = "s30"; 228 break; 229 case dwarf_s31: 230 reg_info.name = "s31"; 231 break; 232 233 // FPA Registers 0-7 234 case dwarf_f0: 235 reg_info.name = "f0"; 236 break; 237 case dwarf_f1: 238 reg_info.name = "f1"; 239 break; 240 case dwarf_f2: 241 reg_info.name = "f2"; 242 break; 243 case dwarf_f3: 244 reg_info.name = "f3"; 245 break; 246 case dwarf_f4: 247 reg_info.name = "f4"; 248 break; 249 case dwarf_f5: 250 reg_info.name = "f5"; 251 break; 252 case dwarf_f6: 253 reg_info.name = "f6"; 254 break; 255 case dwarf_f7: 256 reg_info.name = "f7"; 257 break; 258 259 // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator 260 // register 0 - 7 (they do overlap with wCGR0 - wCGR7) 261 case dwarf_wCGR0: 262 reg_info.name = "wCGR0/ACC0"; 263 break; 264 case dwarf_wCGR1: 265 reg_info.name = "wCGR1/ACC1"; 266 break; 267 case dwarf_wCGR2: 268 reg_info.name = "wCGR2/ACC2"; 269 break; 270 case dwarf_wCGR3: 271 reg_info.name = "wCGR3/ACC3"; 272 break; 273 case dwarf_wCGR4: 274 reg_info.name = "wCGR4/ACC4"; 275 break; 276 case dwarf_wCGR5: 277 reg_info.name = "wCGR5/ACC5"; 278 break; 279 case dwarf_wCGR6: 280 reg_info.name = "wCGR6/ACC6"; 281 break; 282 case dwarf_wCGR7: 283 reg_info.name = "wCGR7/ACC7"; 284 break; 285 286 // Intel wireless MMX data registers 0 - 15 287 case dwarf_wR0: 288 reg_info.name = "wR0"; 289 break; 290 case dwarf_wR1: 291 reg_info.name = "wR1"; 292 break; 293 case dwarf_wR2: 294 reg_info.name = "wR2"; 295 break; 296 case dwarf_wR3: 297 reg_info.name = "wR3"; 298 break; 299 case dwarf_wR4: 300 reg_info.name = "wR4"; 301 break; 302 case dwarf_wR5: 303 reg_info.name = "wR5"; 304 break; 305 case dwarf_wR6: 306 reg_info.name = "wR6"; 307 break; 308 case dwarf_wR7: 309 reg_info.name = "wR7"; 310 break; 311 case dwarf_wR8: 312 reg_info.name = "wR8"; 313 break; 314 case dwarf_wR9: 315 reg_info.name = "wR9"; 316 break; 317 case dwarf_wR10: 318 reg_info.name = "wR10"; 319 break; 320 case dwarf_wR11: 321 reg_info.name = "wR11"; 322 break; 323 case dwarf_wR12: 324 reg_info.name = "wR12"; 325 break; 326 case dwarf_wR13: 327 reg_info.name = "wR13"; 328 break; 329 case dwarf_wR14: 330 reg_info.name = "wR14"; 331 break; 332 case dwarf_wR15: 333 reg_info.name = "wR15"; 334 break; 335 336 case dwarf_spsr: 337 reg_info.name = "spsr"; 338 break; 339 case dwarf_spsr_fiq: 340 reg_info.name = "spsr_fiq"; 341 break; 342 case dwarf_spsr_irq: 343 reg_info.name = "spsr_irq"; 344 break; 345 case dwarf_spsr_abt: 346 reg_info.name = "spsr_abt"; 347 break; 348 case dwarf_spsr_und: 349 reg_info.name = "spsr_und"; 350 break; 351 case dwarf_spsr_svc: 352 reg_info.name = "spsr_svc"; 353 break; 354 355 case dwarf_r8_usr: 356 reg_info.name = "r8_usr"; 357 break; 358 case dwarf_r9_usr: 359 reg_info.name = "r9_usr"; 360 break; 361 case dwarf_r10_usr: 362 reg_info.name = "r10_usr"; 363 break; 364 case dwarf_r11_usr: 365 reg_info.name = "r11_usr"; 366 break; 367 case dwarf_r12_usr: 368 reg_info.name = "r12_usr"; 369 break; 370 case dwarf_r13_usr: 371 reg_info.name = "r13_usr"; 372 break; 373 case dwarf_r14_usr: 374 reg_info.name = "r14_usr"; 375 break; 376 case dwarf_r8_fiq: 377 reg_info.name = "r8_fiq"; 378 break; 379 case dwarf_r9_fiq: 380 reg_info.name = "r9_fiq"; 381 break; 382 case dwarf_r10_fiq: 383 reg_info.name = "r10_fiq"; 384 break; 385 case dwarf_r11_fiq: 386 reg_info.name = "r11_fiq"; 387 break; 388 case dwarf_r12_fiq: 389 reg_info.name = "r12_fiq"; 390 break; 391 case dwarf_r13_fiq: 392 reg_info.name = "r13_fiq"; 393 break; 394 case dwarf_r14_fiq: 395 reg_info.name = "r14_fiq"; 396 break; 397 case dwarf_r13_irq: 398 reg_info.name = "r13_irq"; 399 break; 400 case dwarf_r14_irq: 401 reg_info.name = "r14_irq"; 402 break; 403 case dwarf_r13_abt: 404 reg_info.name = "r13_abt"; 405 break; 406 case dwarf_r14_abt: 407 reg_info.name = "r14_abt"; 408 break; 409 case dwarf_r13_und: 410 reg_info.name = "r13_und"; 411 break; 412 case dwarf_r14_und: 413 reg_info.name = "r14_und"; 414 break; 415 case dwarf_r13_svc: 416 reg_info.name = "r13_svc"; 417 break; 418 case dwarf_r14_svc: 419 reg_info.name = "r14_svc"; 420 break; 421 422 // Intel wireless MMX control register in co-processor 0 - 7 423 case dwarf_wC0: 424 reg_info.name = "wC0"; 425 break; 426 case dwarf_wC1: 427 reg_info.name = "wC1"; 428 break; 429 case dwarf_wC2: 430 reg_info.name = "wC2"; 431 break; 432 case dwarf_wC3: 433 reg_info.name = "wC3"; 434 break; 435 case dwarf_wC4: 436 reg_info.name = "wC4"; 437 break; 438 case dwarf_wC5: 439 reg_info.name = "wC5"; 440 break; 441 case dwarf_wC6: 442 reg_info.name = "wC6"; 443 break; 444 case dwarf_wC7: 445 reg_info.name = "wC7"; 446 break; 447 448 // VFP-v3/Neon 449 case dwarf_d0: 450 reg_info.name = "d0"; 451 break; 452 case dwarf_d1: 453 reg_info.name = "d1"; 454 break; 455 case dwarf_d2: 456 reg_info.name = "d2"; 457 break; 458 case dwarf_d3: 459 reg_info.name = "d3"; 460 break; 461 case dwarf_d4: 462 reg_info.name = "d4"; 463 break; 464 case dwarf_d5: 465 reg_info.name = "d5"; 466 break; 467 case dwarf_d6: 468 reg_info.name = "d6"; 469 break; 470 case dwarf_d7: 471 reg_info.name = "d7"; 472 break; 473 case dwarf_d8: 474 reg_info.name = "d8"; 475 break; 476 case dwarf_d9: 477 reg_info.name = "d9"; 478 break; 479 case dwarf_d10: 480 reg_info.name = "d10"; 481 break; 482 case dwarf_d11: 483 reg_info.name = "d11"; 484 break; 485 case dwarf_d12: 486 reg_info.name = "d12"; 487 break; 488 case dwarf_d13: 489 reg_info.name = "d13"; 490 break; 491 case dwarf_d14: 492 reg_info.name = "d14"; 493 break; 494 case dwarf_d15: 495 reg_info.name = "d15"; 496 break; 497 case dwarf_d16: 498 reg_info.name = "d16"; 499 break; 500 case dwarf_d17: 501 reg_info.name = "d17"; 502 break; 503 case dwarf_d18: 504 reg_info.name = "d18"; 505 break; 506 case dwarf_d19: 507 reg_info.name = "d19"; 508 break; 509 case dwarf_d20: 510 reg_info.name = "d20"; 511 break; 512 case dwarf_d21: 513 reg_info.name = "d21"; 514 break; 515 case dwarf_d22: 516 reg_info.name = "d22"; 517 break; 518 case dwarf_d23: 519 reg_info.name = "d23"; 520 break; 521 case dwarf_d24: 522 reg_info.name = "d24"; 523 break; 524 case dwarf_d25: 525 reg_info.name = "d25"; 526 break; 527 case dwarf_d26: 528 reg_info.name = "d26"; 529 break; 530 case dwarf_d27: 531 reg_info.name = "d27"; 532 break; 533 case dwarf_d28: 534 reg_info.name = "d28"; 535 break; 536 case dwarf_d29: 537 reg_info.name = "d29"; 538 break; 539 case dwarf_d30: 540 reg_info.name = "d30"; 541 break; 542 case dwarf_d31: 543 reg_info.name = "d31"; 544 break; 545 546 // NEON 128-bit vector registers (overlays the d registers) 547 case dwarf_q0: 548 reg_info.name = "q0"; 549 break; 550 case dwarf_q1: 551 reg_info.name = "q1"; 552 break; 553 case dwarf_q2: 554 reg_info.name = "q2"; 555 break; 556 case dwarf_q3: 557 reg_info.name = "q3"; 558 break; 559 case dwarf_q4: 560 reg_info.name = "q4"; 561 break; 562 case dwarf_q5: 563 reg_info.name = "q5"; 564 break; 565 case dwarf_q6: 566 reg_info.name = "q6"; 567 break; 568 case dwarf_q7: 569 reg_info.name = "q7"; 570 break; 571 case dwarf_q8: 572 reg_info.name = "q8"; 573 break; 574 case dwarf_q9: 575 reg_info.name = "q9"; 576 break; 577 case dwarf_q10: 578 reg_info.name = "q10"; 579 break; 580 case dwarf_q11: 581 reg_info.name = "q11"; 582 break; 583 case dwarf_q12: 584 reg_info.name = "q12"; 585 break; 586 case dwarf_q13: 587 reg_info.name = "q13"; 588 break; 589 case dwarf_q14: 590 reg_info.name = "q14"; 591 break; 592 case dwarf_q15: 593 reg_info.name = "q15"; 594 break; 595 596 default: 597 return false; 598 } 599 return true; 600 } 601 602 // A8.6.50 603 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 604 static uint32_t CountITSize(uint32_t ITMask) { 605 // First count the trailing zeros of the IT mask. 606 uint32_t TZ = llvm::countTrailingZeros(ITMask); 607 if (TZ > 3) { 608 return 0; 609 } 610 return (4 - TZ); 611 } 612 613 // Init ITState. Note that at least one bit is always 1 in mask. 614 bool ITSession::InitIT(uint32_t bits7_0) { 615 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 616 if (ITCounter == 0) 617 return false; 618 619 // A8.6.50 IT 620 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 621 if (FirstCond == 0xF) { 622 return false; 623 } 624 if (FirstCond == 0xE && ITCounter != 1) { 625 return false; 626 } 627 628 ITState = bits7_0; 629 return true; 630 } 631 632 // Update ITState if necessary. 633 void ITSession::ITAdvance() { 634 // assert(ITCounter); 635 --ITCounter; 636 if (ITCounter == 0) 637 ITState = 0; 638 else { 639 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 640 SetBits32(ITState, 4, 0, NewITState4_0); 641 } 642 } 643 644 // Return true if we're inside an IT Block. 645 bool ITSession::InITBlock() { return ITCounter != 0; } 646 647 // Return true if we're the last instruction inside an IT Block. 648 bool ITSession::LastInITBlock() { return ITCounter == 1; } 649 650 // Get condition bits for the current thumb instruction. 651 uint32_t ITSession::GetCond() { 652 if (InITBlock()) 653 return Bits32(ITState, 7, 4); 654 else 655 return COND_AL; 656 } 657 658 // ARM constants used during decoding 659 #define REG_RD 0 660 #define LDM_REGLIST 1 661 #define SP_REG 13 662 #define LR_REG 14 663 #define PC_REG 15 664 #define PC_REGLIST_BIT 0x8000 665 666 #define ARMv4 (1u << 0) 667 #define ARMv4T (1u << 1) 668 #define ARMv5T (1u << 2) 669 #define ARMv5TE (1u << 3) 670 #define ARMv5TEJ (1u << 4) 671 #define ARMv6 (1u << 5) 672 #define ARMv6K (1u << 6) 673 #define ARMv6T2 (1u << 7) 674 #define ARMv7 (1u << 8) 675 #define ARMv7S (1u << 9) 676 #define ARMv8 (1u << 10) 677 #define ARMvAll (0xffffffffu) 678 679 #define ARMV4T_ABOVE \ 680 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \ 681 ARMv7S | ARMv8) 682 #define ARMV5_ABOVE \ 683 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \ 684 ARMv8) 685 #define ARMV5TE_ABOVE \ 686 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 687 #define ARMV5J_ABOVE \ 688 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 689 #define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 690 #define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 691 #define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8) 692 693 #define No_VFP 0 694 #define VFPv1 (1u << 1) 695 #define VFPv2 (1u << 2) 696 #define VFPv3 (1u << 3) 697 #define AdvancedSIMD (1u << 4) 698 699 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 700 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 701 #define VFPv2v3 (VFPv2 | VFPv3) 702 703 // 704 // EmulateInstructionARM implementation 705 // 706 707 void EmulateInstructionARM::Initialize() { 708 PluginManager::RegisterPlugin(GetPluginNameStatic(), 709 GetPluginDescriptionStatic(), CreateInstance); 710 } 711 712 void EmulateInstructionARM::Terminate() { 713 PluginManager::UnregisterPlugin(CreateInstance); 714 } 715 716 llvm::StringRef EmulateInstructionARM::GetPluginDescriptionStatic() { 717 return "Emulate instructions for the ARM architecture."; 718 } 719 720 EmulateInstruction * 721 EmulateInstructionARM::CreateInstance(const ArchSpec &arch, 722 InstructionType inst_type) { 723 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic( 724 inst_type)) { 725 if (arch.GetTriple().getArch() == llvm::Triple::arm) { 726 std::unique_ptr<EmulateInstructionARM> emulate_insn_up( 727 new EmulateInstructionARM(arch)); 728 729 if (emulate_insn_up) 730 return emulate_insn_up.release(); 731 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) { 732 std::unique_ptr<EmulateInstructionARM> emulate_insn_up( 733 new EmulateInstructionARM(arch)); 734 735 if (emulate_insn_up) 736 return emulate_insn_up.release(); 737 } 738 } 739 740 return nullptr; 741 } 742 743 bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) { 744 if (arch.GetTriple().getArch() == llvm::Triple::arm) 745 return true; 746 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 747 return true; 748 749 return false; 750 } 751 752 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for 753 // many ARM instructions. 754 bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) { 755 EmulateInstruction::Context context; 756 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 757 context.SetNoArgs(); 758 759 uint32_t random_data = rand(); 760 const uint32_t addr_byte_size = GetAddressByteSize(); 761 762 return MemAWrite(context, address, random_data, addr_byte_size); 763 } 764 765 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM 766 // instructions. 767 bool EmulateInstructionARM::WriteBits32Unknown(int n) { 768 EmulateInstruction::Context context; 769 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 770 context.SetNoArgs(); 771 772 bool success; 773 uint32_t data = 774 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 775 776 if (!success) 777 return false; 778 779 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data)) 780 return false; 781 782 return true; 783 } 784 785 bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind, 786 uint32_t reg_num, 787 RegisterInfo ®_info) { 788 if (reg_kind == eRegisterKindGeneric) { 789 switch (reg_num) { 790 case LLDB_REGNUM_GENERIC_PC: 791 reg_kind = eRegisterKindDWARF; 792 reg_num = dwarf_pc; 793 break; 794 case LLDB_REGNUM_GENERIC_SP: 795 reg_kind = eRegisterKindDWARF; 796 reg_num = dwarf_sp; 797 break; 798 case LLDB_REGNUM_GENERIC_FP: 799 reg_kind = eRegisterKindDWARF; 800 reg_num = dwarf_r7; 801 break; 802 case LLDB_REGNUM_GENERIC_RA: 803 reg_kind = eRegisterKindDWARF; 804 reg_num = dwarf_lr; 805 break; 806 case LLDB_REGNUM_GENERIC_FLAGS: 807 reg_kind = eRegisterKindDWARF; 808 reg_num = dwarf_cpsr; 809 break; 810 default: 811 return false; 812 } 813 } 814 815 if (reg_kind == eRegisterKindDWARF) 816 return GetARMDWARFRegisterInfo(reg_num, reg_info); 817 return false; 818 } 819 820 uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const { 821 if (m_arch.GetTriple().isAndroid()) 822 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android 823 bool is_apple = false; 824 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 825 is_apple = true; 826 switch (m_arch.GetTriple().getOS()) { 827 case llvm::Triple::Darwin: 828 case llvm::Triple::MacOSX: 829 case llvm::Triple::IOS: 830 case llvm::Triple::TvOS: 831 case llvm::Triple::WatchOS: 832 // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS: 833 is_apple = true; 834 break; 835 default: 836 break; 837 } 838 839 /* On Apple iOS et al, the frame pointer register is always r7. 840 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 841 * Windows on ARM, which is in thumb mode, uses r11 though. 842 */ 843 844 uint32_t fp_regnum = 11; 845 846 if (is_apple) 847 fp_regnum = 7; 848 849 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows()) 850 fp_regnum = 7; 851 852 return fp_regnum; 853 } 854 855 uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const { 856 bool is_apple = false; 857 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 858 is_apple = true; 859 switch (m_arch.GetTriple().getOS()) { 860 case llvm::Triple::Darwin: 861 case llvm::Triple::MacOSX: 862 case llvm::Triple::IOS: 863 is_apple = true; 864 break; 865 default: 866 break; 867 } 868 869 /* On Apple iOS et al, the frame pointer register is always r7. 870 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 871 * Windows on ARM, which is in thumb mode, uses r11 though. 872 */ 873 874 uint32_t fp_regnum = dwarf_r11; 875 876 if (is_apple) 877 fp_regnum = dwarf_r7; 878 879 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows()) 880 fp_regnum = dwarf_r7; 881 882 return fp_regnum; 883 } 884 885 // Push Multiple Registers stores multiple registers to the stack, storing to 886 // consecutive memory locations ending just below the address in SP, and 887 // updates 888 // SP to point to the start of the stored data. 889 bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode, 890 const ARMEncoding encoding) { 891 #if 0 892 // ARM pseudo code... 893 if (ConditionPassed()) 894 { 895 EncodingSpecificOperations(); 896 NullCheckIfThumbEE(13); 897 address = SP - 4*BitCount(registers); 898 899 for (i = 0 to 14) 900 { 901 if (registers<i> == '1') 902 { 903 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 904 MemA[address,4] = bits(32) UNKNOWN; 905 else 906 MemA[address,4] = R[i]; 907 address = address + 4; 908 } 909 } 910 911 if (registers<15> == '1') // Only possible for encoding A1 or A2 912 MemA[address,4] = PCStoreValue(); 913 914 SP = SP - 4*BitCount(registers); 915 } 916 #endif 917 918 bool success = false; 919 if (ConditionPassed(opcode)) { 920 const uint32_t addr_byte_size = GetAddressByteSize(); 921 const addr_t sp = ReadCoreReg(SP_REG, &success); 922 if (!success) 923 return false; 924 uint32_t registers = 0; 925 uint32_t Rt; // the source register 926 switch (encoding) { 927 case eEncodingT1: 928 registers = Bits32(opcode, 7, 0); 929 // The M bit represents LR. 930 if (Bit32(opcode, 8)) 931 registers |= (1u << 14); 932 // if BitCount(registers) < 1 then UNPREDICTABLE; 933 if (BitCount(registers) < 1) 934 return false; 935 break; 936 case eEncodingT2: 937 // Ignore bits 15 & 13. 938 registers = Bits32(opcode, 15, 0) & ~0xa000; 939 // if BitCount(registers) < 2 then UNPREDICTABLE; 940 if (BitCount(registers) < 2) 941 return false; 942 break; 943 case eEncodingT3: 944 Rt = Bits32(opcode, 15, 12); 945 // if BadReg(t) then UNPREDICTABLE; 946 if (BadReg(Rt)) 947 return false; 948 registers = (1u << Rt); 949 break; 950 case eEncodingA1: 951 registers = Bits32(opcode, 15, 0); 952 // Instead of return false, let's handle the following case as well, 953 // which amounts to pushing one reg onto the full descending stacks. 954 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 955 break; 956 case eEncodingA2: 957 Rt = Bits32(opcode, 15, 12); 958 // if t == 13 then UNPREDICTABLE; 959 if (Rt == dwarf_sp) 960 return false; 961 registers = (1u << Rt); 962 break; 963 default: 964 return false; 965 } 966 addr_t sp_offset = addr_byte_size * BitCount(registers); 967 addr_t addr = sp - sp_offset; 968 uint32_t i; 969 970 EmulateInstruction::Context context; 971 context.type = EmulateInstruction::eContextPushRegisterOnStack; 972 RegisterInfo reg_info; 973 RegisterInfo sp_reg; 974 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 975 for (i = 0; i < 15; ++i) { 976 if (BitIsSet(registers, i)) { 977 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info); 978 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 979 uint32_t reg_value = ReadCoreReg(i, &success); 980 if (!success) 981 return false; 982 if (!MemAWrite(context, addr, reg_value, addr_byte_size)) 983 return false; 984 addr += addr_byte_size; 985 } 986 } 987 988 if (BitIsSet(registers, 15)) { 989 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info); 990 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 991 const uint32_t pc = ReadCoreReg(PC_REG, &success); 992 if (!success) 993 return false; 994 if (!MemAWrite(context, addr, pc, addr_byte_size)) 995 return false; 996 } 997 998 context.type = EmulateInstruction::eContextAdjustStackPointer; 999 context.SetImmediateSigned(-sp_offset); 1000 1001 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1002 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1003 return false; 1004 } 1005 return true; 1006 } 1007 1008 // Pop Multiple Registers loads multiple registers from the stack, loading from 1009 // consecutive memory locations staring at the address in SP, and updates 1010 // SP to point just above the loaded data. 1011 bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode, 1012 const ARMEncoding encoding) { 1013 #if 0 1014 // ARM pseudo code... 1015 if (ConditionPassed()) 1016 { 1017 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 1018 address = SP; 1019 for i = 0 to 14 1020 if registers<i> == '1' then 1021 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 1022 if registers<15> == '1' then 1023 if UnalignedAllowed then 1024 LoadWritePC(MemU[address,4]); 1025 else 1026 LoadWritePC(MemA[address,4]); 1027 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 1028 if registers<13> == '1' then SP = bits(32) UNKNOWN; 1029 } 1030 #endif 1031 1032 bool success = false; 1033 1034 if (ConditionPassed(opcode)) { 1035 const uint32_t addr_byte_size = GetAddressByteSize(); 1036 const addr_t sp = ReadCoreReg(SP_REG, &success); 1037 if (!success) 1038 return false; 1039 uint32_t registers = 0; 1040 uint32_t Rt; // the destination register 1041 switch (encoding) { 1042 case eEncodingT1: 1043 registers = Bits32(opcode, 7, 0); 1044 // The P bit represents PC. 1045 if (Bit32(opcode, 8)) 1046 registers |= (1u << 15); 1047 // if BitCount(registers) < 1 then UNPREDICTABLE; 1048 if (BitCount(registers) < 1) 1049 return false; 1050 break; 1051 case eEncodingT2: 1052 // Ignore bit 13. 1053 registers = Bits32(opcode, 15, 0) & ~0x2000; 1054 // if BitCount(registers) < 2 || (P == '1' && M == '1') then 1055 // UNPREDICTABLE; 1056 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 1057 return false; 1058 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 1059 // UNPREDICTABLE; 1060 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 1061 return false; 1062 break; 1063 case eEncodingT3: 1064 Rt = Bits32(opcode, 15, 12); 1065 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then 1066 // UNPREDICTABLE; 1067 if (Rt == 13) 1068 return false; 1069 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1070 return false; 1071 registers = (1u << Rt); 1072 break; 1073 case eEncodingA1: 1074 registers = Bits32(opcode, 15, 0); 1075 // Instead of return false, let's handle the following case as well, 1076 // which amounts to popping one reg from the full descending stacks. 1077 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 1078 1079 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 1080 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 1081 return false; 1082 break; 1083 case eEncodingA2: 1084 Rt = Bits32(opcode, 15, 12); 1085 // if t == 13 then UNPREDICTABLE; 1086 if (Rt == dwarf_sp) 1087 return false; 1088 registers = (1u << Rt); 1089 break; 1090 default: 1091 return false; 1092 } 1093 addr_t sp_offset = addr_byte_size * BitCount(registers); 1094 addr_t addr = sp; 1095 uint32_t i, data; 1096 1097 EmulateInstruction::Context context; 1098 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1099 1100 RegisterInfo sp_reg; 1101 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1102 1103 for (i = 0; i < 15; ++i) { 1104 if (BitIsSet(registers, i)) { 1105 context.SetAddress(addr); 1106 data = MemARead(context, addr, 4, 0, &success); 1107 if (!success) 1108 return false; 1109 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 1110 data)) 1111 return false; 1112 addr += addr_byte_size; 1113 } 1114 } 1115 1116 if (BitIsSet(registers, 15)) { 1117 context.SetRegisterPlusOffset(sp_reg, addr - sp); 1118 data = MemARead(context, addr, 4, 0, &success); 1119 if (!success) 1120 return false; 1121 // In ARMv5T and above, this is an interworking branch. 1122 if (!LoadWritePC(context, data)) 1123 return false; 1124 // addr += addr_byte_size; 1125 } 1126 1127 context.type = EmulateInstruction::eContextAdjustStackPointer; 1128 context.SetImmediateSigned(sp_offset); 1129 1130 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1131 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1132 return false; 1133 } 1134 return true; 1135 } 1136 1137 // Set r7 or ip to point to saved value residing within the stack. 1138 // ADD (SP plus immediate) 1139 bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode, 1140 const ARMEncoding encoding) { 1141 #if 0 1142 // ARM pseudo code... 1143 if (ConditionPassed()) 1144 { 1145 EncodingSpecificOperations(); 1146 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1147 if d == 15 then 1148 ALUWritePC(result); // setflags is always FALSE here 1149 else 1150 R[d] = result; 1151 if setflags then 1152 APSR.N = result<31>; 1153 APSR.Z = IsZeroBit(result); 1154 APSR.C = carry; 1155 APSR.V = overflow; 1156 } 1157 #endif 1158 1159 bool success = false; 1160 1161 if (ConditionPassed(opcode)) { 1162 const addr_t sp = ReadCoreReg(SP_REG, &success); 1163 if (!success) 1164 return false; 1165 uint32_t Rd; // the destination register 1166 uint32_t imm32; 1167 switch (encoding) { 1168 case eEncodingT1: 1169 Rd = 7; 1170 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 1171 break; 1172 case eEncodingA1: 1173 Rd = Bits32(opcode, 15, 12); 1174 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1175 break; 1176 default: 1177 return false; 1178 } 1179 addr_t sp_offset = imm32; 1180 addr_t addr = sp + sp_offset; // a pointer to the stack area 1181 1182 EmulateInstruction::Context context; 1183 if (Rd == GetFramePointerRegisterNumber()) 1184 context.type = eContextSetFramePointer; 1185 else 1186 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1187 RegisterInfo sp_reg; 1188 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1189 context.SetRegisterPlusOffset(sp_reg, sp_offset); 1190 1191 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, 1192 addr)) 1193 return false; 1194 } 1195 return true; 1196 } 1197 1198 // Set r7 or ip to the current stack pointer. 1199 // MOV (register) 1200 bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode, 1201 const ARMEncoding encoding) { 1202 #if 0 1203 // ARM pseudo code... 1204 if (ConditionPassed()) 1205 { 1206 EncodingSpecificOperations(); 1207 result = R[m]; 1208 if d == 15 then 1209 ALUWritePC(result); // setflags is always FALSE here 1210 else 1211 R[d] = result; 1212 if setflags then 1213 APSR.N = result<31>; 1214 APSR.Z = IsZeroBit(result); 1215 // APSR.C unchanged 1216 // APSR.V unchanged 1217 } 1218 #endif 1219 1220 bool success = false; 1221 1222 if (ConditionPassed(opcode)) { 1223 const addr_t sp = ReadCoreReg(SP_REG, &success); 1224 if (!success) 1225 return false; 1226 uint32_t Rd; // the destination register 1227 switch (encoding) { 1228 case eEncodingT1: 1229 Rd = 7; 1230 break; 1231 case eEncodingA1: 1232 Rd = 12; 1233 break; 1234 default: 1235 return false; 1236 } 1237 1238 EmulateInstruction::Context context; 1239 if (Rd == GetFramePointerRegisterNumber()) 1240 context.type = EmulateInstruction::eContextSetFramePointer; 1241 else 1242 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1243 RegisterInfo sp_reg; 1244 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1245 context.SetRegisterPlusOffset(sp_reg, 0); 1246 1247 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 1248 return false; 1249 } 1250 return true; 1251 } 1252 1253 // Move from high register (r8-r15) to low register (r0-r7). 1254 // MOV (register) 1255 bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode, 1256 const ARMEncoding encoding) { 1257 return EmulateMOVRdRm(opcode, encoding); 1258 } 1259 1260 // Move from register to register. 1261 // MOV (register) 1262 bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode, 1263 const ARMEncoding encoding) { 1264 #if 0 1265 // ARM pseudo code... 1266 if (ConditionPassed()) 1267 { 1268 EncodingSpecificOperations(); 1269 result = R[m]; 1270 if d == 15 then 1271 ALUWritePC(result); // setflags is always FALSE here 1272 else 1273 R[d] = result; 1274 if setflags then 1275 APSR.N = result<31>; 1276 APSR.Z = IsZeroBit(result); 1277 // APSR.C unchanged 1278 // APSR.V unchanged 1279 } 1280 #endif 1281 1282 bool success = false; 1283 1284 if (ConditionPassed(opcode)) { 1285 uint32_t Rm; // the source register 1286 uint32_t Rd; // the destination register 1287 bool setflags; 1288 switch (encoding) { 1289 case eEncodingT1: 1290 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1291 Rm = Bits32(opcode, 6, 3); 1292 setflags = false; 1293 if (Rd == 15 && InITBlock() && !LastInITBlock()) 1294 return false; 1295 break; 1296 case eEncodingT2: 1297 Rd = Bits32(opcode, 2, 0); 1298 Rm = Bits32(opcode, 5, 3); 1299 setflags = true; 1300 if (InITBlock()) 1301 return false; 1302 break; 1303 case eEncodingT3: 1304 Rd = Bits32(opcode, 11, 8); 1305 Rm = Bits32(opcode, 3, 0); 1306 setflags = BitIsSet(opcode, 20); 1307 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1308 if (setflags && (BadReg(Rd) || BadReg(Rm))) 1309 return false; 1310 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then 1311 // UNPREDICTABLE; 1312 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 1313 return false; 1314 break; 1315 case eEncodingA1: 1316 Rd = Bits32(opcode, 15, 12); 1317 Rm = Bits32(opcode, 3, 0); 1318 setflags = BitIsSet(opcode, 20); 1319 1320 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1321 // instructions; 1322 if (Rd == 15 && setflags) 1323 return EmulateSUBSPcLrEtc(opcode, encoding); 1324 break; 1325 default: 1326 return false; 1327 } 1328 uint32_t result = ReadCoreReg(Rm, &success); 1329 if (!success) 1330 return false; 1331 1332 // The context specifies that Rm is to be moved into Rd. 1333 EmulateInstruction::Context context; 1334 if (Rd == 13) 1335 context.type = EmulateInstruction::eContextAdjustStackPointer; 1336 else if (Rd == GetFramePointerRegisterNumber() && Rm == 13) 1337 context.type = EmulateInstruction::eContextSetFramePointer; 1338 else 1339 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1340 RegisterInfo dwarf_reg; 1341 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1342 context.SetRegisterPlusOffset(dwarf_reg, 0); 1343 1344 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 1345 return false; 1346 } 1347 return true; 1348 } 1349 1350 // Move (immediate) writes an immediate value to the destination register. It 1351 // can optionally update the condition flags based on the value. 1352 // MOV (immediate) 1353 bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode, 1354 const ARMEncoding encoding) { 1355 #if 0 1356 // ARM pseudo code... 1357 if (ConditionPassed()) 1358 { 1359 EncodingSpecificOperations(); 1360 result = imm32; 1361 if d == 15 then // Can only occur for ARM encoding 1362 ALUWritePC(result); // setflags is always FALSE here 1363 else 1364 R[d] = result; 1365 if setflags then 1366 APSR.N = result<31>; 1367 APSR.Z = IsZeroBit(result); 1368 APSR.C = carry; 1369 // APSR.V unchanged 1370 } 1371 #endif 1372 1373 if (ConditionPassed(opcode)) { 1374 uint32_t Rd; // the destination register 1375 uint32_t imm32; // the immediate value to be written to Rd 1376 uint32_t carry = 1377 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 1378 // for setflags == false, this value is a don't care initialized to 1379 // 0 to silence the static analyzer 1380 bool setflags; 1381 switch (encoding) { 1382 case eEncodingT1: 1383 Rd = Bits32(opcode, 10, 8); 1384 setflags = !InITBlock(); 1385 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 1386 carry = APSR_C; 1387 1388 break; 1389 1390 case eEncodingT2: 1391 Rd = Bits32(opcode, 11, 8); 1392 setflags = BitIsSet(opcode, 20); 1393 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1394 if (BadReg(Rd)) 1395 return false; 1396 1397 break; 1398 1399 case eEncodingT3: { 1400 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 1401 // 32); 1402 Rd = Bits32(opcode, 11, 8); 1403 setflags = false; 1404 uint32_t imm4 = Bits32(opcode, 19, 16); 1405 uint32_t imm3 = Bits32(opcode, 14, 12); 1406 uint32_t i = Bit32(opcode, 26); 1407 uint32_t imm8 = Bits32(opcode, 7, 0); 1408 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 1409 1410 // if BadReg(d) then UNPREDICTABLE; 1411 if (BadReg(Rd)) 1412 return false; 1413 } break; 1414 1415 case eEncodingA1: 1416 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = 1417 // ARMExpandImm_C(imm12, APSR.C); 1418 Rd = Bits32(opcode, 15, 12); 1419 setflags = BitIsSet(opcode, 20); 1420 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1421 1422 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1423 // instructions; 1424 if ((Rd == 15) && setflags) 1425 return EmulateSUBSPcLrEtc(opcode, encoding); 1426 1427 break; 1428 1429 case eEncodingA2: { 1430 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 1431 Rd = Bits32(opcode, 15, 12); 1432 setflags = false; 1433 uint32_t imm4 = Bits32(opcode, 19, 16); 1434 uint32_t imm12 = Bits32(opcode, 11, 0); 1435 imm32 = (imm4 << 12) | imm12; 1436 1437 // if d == 15 then UNPREDICTABLE; 1438 if (Rd == 15) 1439 return false; 1440 } break; 1441 1442 default: 1443 return false; 1444 } 1445 uint32_t result = imm32; 1446 1447 // The context specifies that an immediate is to be moved into Rd. 1448 EmulateInstruction::Context context; 1449 context.type = EmulateInstruction::eContextImmediate; 1450 context.SetNoArgs(); 1451 1452 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1453 return false; 1454 } 1455 return true; 1456 } 1457 1458 // MUL multiplies two register values. The least significant 32 bits of the 1459 // result are written to the destination 1460 // register. These 32 bits do not depend on whether the source register values 1461 // are considered to be signed values or unsigned values. 1462 // 1463 // Optionally, it can update the condition flags based on the result. In the 1464 // Thumb instruction set, this option is limited to only a few forms of the 1465 // instruction. 1466 bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode, 1467 const ARMEncoding encoding) { 1468 #if 0 1469 if ConditionPassed() then 1470 EncodingSpecificOperations(); 1471 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1472 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1473 result = operand1 * operand2; 1474 R[d] = result<31:0>; 1475 if setflags then 1476 APSR.N = result<31>; 1477 APSR.Z = IsZeroBit(result); 1478 if ArchVersion() == 4 then 1479 APSR.C = bit UNKNOWN; 1480 // else APSR.C unchanged 1481 // APSR.V always unchanged 1482 #endif 1483 1484 if (ConditionPassed(opcode)) { 1485 uint32_t d; 1486 uint32_t n; 1487 uint32_t m; 1488 bool setflags; 1489 1490 // EncodingSpecificOperations(); 1491 switch (encoding) { 1492 case eEncodingT1: 1493 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 1494 d = Bits32(opcode, 2, 0); 1495 n = Bits32(opcode, 5, 3); 1496 m = Bits32(opcode, 2, 0); 1497 setflags = !InITBlock(); 1498 1499 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1500 if ((ArchVersion() < ARMv6) && (d == n)) 1501 return false; 1502 1503 break; 1504 1505 case eEncodingT2: 1506 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 1507 d = Bits32(opcode, 11, 8); 1508 n = Bits32(opcode, 19, 16); 1509 m = Bits32(opcode, 3, 0); 1510 setflags = false; 1511 1512 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 1513 if (BadReg(d) || BadReg(n) || BadReg(m)) 1514 return false; 1515 1516 break; 1517 1518 case eEncodingA1: 1519 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 1520 d = Bits32(opcode, 19, 16); 1521 n = Bits32(opcode, 3, 0); 1522 m = Bits32(opcode, 11, 8); 1523 setflags = BitIsSet(opcode, 20); 1524 1525 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1526 if ((d == 15) || (n == 15) || (m == 15)) 1527 return false; 1528 1529 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1530 if ((ArchVersion() < ARMv6) && (d == n)) 1531 return false; 1532 1533 break; 1534 1535 default: 1536 return false; 1537 } 1538 1539 bool success = false; 1540 1541 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final 1542 // results 1543 uint64_t operand1 = 1544 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1545 if (!success) 1546 return false; 1547 1548 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final 1549 // results 1550 uint64_t operand2 = 1551 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1552 if (!success) 1553 return false; 1554 1555 // result = operand1 * operand2; 1556 uint64_t result = operand1 * operand2; 1557 1558 // R[d] = result<31:0>; 1559 RegisterInfo op1_reg; 1560 RegisterInfo op2_reg; 1561 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1562 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1563 1564 EmulateInstruction::Context context; 1565 context.type = eContextArithmetic; 1566 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 1567 1568 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 1569 (0x0000ffff & result))) 1570 return false; 1571 1572 // if setflags then 1573 if (setflags) { 1574 // APSR.N = result<31>; 1575 // APSR.Z = IsZeroBit(result); 1576 m_new_inst_cpsr = m_opcode_cpsr; 1577 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31)); 1578 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1579 if (m_new_inst_cpsr != m_opcode_cpsr) { 1580 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1581 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1582 return false; 1583 } 1584 1585 // if ArchVersion() == 4 then 1586 // APSR.C = bit UNKNOWN; 1587 } 1588 } 1589 return true; 1590 } 1591 1592 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to 1593 // the destination register. It can optionally update the condition flags based 1594 // on the value. 1595 bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode, 1596 const ARMEncoding encoding) { 1597 #if 0 1598 // ARM pseudo code... 1599 if (ConditionPassed()) 1600 { 1601 EncodingSpecificOperations(); 1602 result = NOT(imm32); 1603 if d == 15 then // Can only occur for ARM encoding 1604 ALUWritePC(result); // setflags is always FALSE here 1605 else 1606 R[d] = result; 1607 if setflags then 1608 APSR.N = result<31>; 1609 APSR.Z = IsZeroBit(result); 1610 APSR.C = carry; 1611 // APSR.V unchanged 1612 } 1613 #endif 1614 1615 if (ConditionPassed(opcode)) { 1616 uint32_t Rd; // the destination register 1617 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1618 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1619 bool setflags; 1620 switch (encoding) { 1621 case eEncodingT1: 1622 Rd = Bits32(opcode, 11, 8); 1623 setflags = BitIsSet(opcode, 20); 1624 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1625 break; 1626 case eEncodingA1: 1627 Rd = Bits32(opcode, 15, 12); 1628 setflags = BitIsSet(opcode, 20); 1629 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1630 1631 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1632 // instructions; 1633 if (Rd == 15 && setflags) 1634 return EmulateSUBSPcLrEtc(opcode, encoding); 1635 break; 1636 default: 1637 return false; 1638 } 1639 uint32_t result = ~imm32; 1640 1641 // The context specifies that an immediate is to be moved into Rd. 1642 EmulateInstruction::Context context; 1643 context.type = EmulateInstruction::eContextImmediate; 1644 context.SetNoArgs(); 1645 1646 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1647 return false; 1648 } 1649 return true; 1650 } 1651 1652 // Bitwise NOT (register) writes the bitwise inverse of a register value to the 1653 // destination register. It can optionally update the condition flags based on 1654 // the result. 1655 bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode, 1656 const ARMEncoding encoding) { 1657 #if 0 1658 // ARM pseudo code... 1659 if (ConditionPassed()) 1660 { 1661 EncodingSpecificOperations(); 1662 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1663 result = NOT(shifted); 1664 if d == 15 then // Can only occur for ARM encoding 1665 ALUWritePC(result); // setflags is always FALSE here 1666 else 1667 R[d] = result; 1668 if setflags then 1669 APSR.N = result<31>; 1670 APSR.Z = IsZeroBit(result); 1671 APSR.C = carry; 1672 // APSR.V unchanged 1673 } 1674 #endif 1675 1676 if (ConditionPassed(opcode)) { 1677 uint32_t Rm; // the source register 1678 uint32_t Rd; // the destination register 1679 ARM_ShifterType shift_t; 1680 uint32_t shift_n; // the shift applied to the value read from Rm 1681 bool setflags; 1682 uint32_t carry; // the carry bit after the shift operation 1683 switch (encoding) { 1684 case eEncodingT1: 1685 Rd = Bits32(opcode, 2, 0); 1686 Rm = Bits32(opcode, 5, 3); 1687 setflags = !InITBlock(); 1688 shift_t = SRType_LSL; 1689 shift_n = 0; 1690 if (InITBlock()) 1691 return false; 1692 break; 1693 case eEncodingT2: 1694 Rd = Bits32(opcode, 11, 8); 1695 Rm = Bits32(opcode, 3, 0); 1696 setflags = BitIsSet(opcode, 20); 1697 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1698 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1699 if (BadReg(Rd) || BadReg(Rm)) 1700 return false; 1701 break; 1702 case eEncodingA1: 1703 Rd = Bits32(opcode, 15, 12); 1704 Rm = Bits32(opcode, 3, 0); 1705 setflags = BitIsSet(opcode, 20); 1706 shift_n = DecodeImmShiftARM(opcode, shift_t); 1707 break; 1708 default: 1709 return false; 1710 } 1711 bool success = false; 1712 uint32_t value = ReadCoreReg(Rm, &success); 1713 if (!success) 1714 return false; 1715 1716 uint32_t shifted = 1717 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1718 if (!success) 1719 return false; 1720 uint32_t result = ~shifted; 1721 1722 // The context specifies that an immediate is to be moved into Rd. 1723 EmulateInstruction::Context context; 1724 context.type = EmulateInstruction::eContextImmediate; 1725 context.SetNoArgs(); 1726 1727 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1728 return false; 1729 } 1730 return true; 1731 } 1732 1733 // PC relative immediate load into register, possibly followed by ADD (SP plus 1734 // register). 1735 // LDR (literal) 1736 bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode, 1737 const ARMEncoding encoding) { 1738 #if 0 1739 // ARM pseudo code... 1740 if (ConditionPassed()) 1741 { 1742 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1743 base = Align(PC,4); 1744 address = if add then (base + imm32) else (base - imm32); 1745 data = MemU[address,4]; 1746 if t == 15 then 1747 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1748 elsif UnalignedSupport() || address<1:0> = '00' then 1749 R[t] = data; 1750 else // Can only apply before ARMv7 1751 if CurrentInstrSet() == InstrSet_ARM then 1752 R[t] = ROR(data, 8*UInt(address<1:0>)); 1753 else 1754 R[t] = bits(32) UNKNOWN; 1755 } 1756 #endif 1757 1758 if (ConditionPassed(opcode)) { 1759 bool success = false; 1760 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1761 if (!success) 1762 return false; 1763 1764 // PC relative immediate load context 1765 EmulateInstruction::Context context; 1766 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1767 RegisterInfo pc_reg; 1768 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 1769 context.SetRegisterPlusOffset(pc_reg, 0); 1770 1771 uint32_t Rt; // the destination register 1772 uint32_t imm32; // immediate offset from the PC 1773 bool add; // +imm32 or -imm32? 1774 addr_t base; // the base address 1775 addr_t address; // the PC relative address 1776 uint32_t data; // the literal data value from the PC relative load 1777 switch (encoding) { 1778 case eEncodingT1: 1779 Rt = Bits32(opcode, 10, 8); 1780 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1781 add = true; 1782 break; 1783 case eEncodingT2: 1784 Rt = Bits32(opcode, 15, 12); 1785 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1786 add = BitIsSet(opcode, 23); 1787 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1788 return false; 1789 break; 1790 default: 1791 return false; 1792 } 1793 1794 base = Align(pc, 4); 1795 if (add) 1796 address = base + imm32; 1797 else 1798 address = base - imm32; 1799 1800 context.SetRegisterPlusOffset(pc_reg, address - base); 1801 data = MemURead(context, address, 4, 0, &success); 1802 if (!success) 1803 return false; 1804 1805 if (Rt == 15) { 1806 if (Bits32(address, 1, 0) == 0) { 1807 // In ARMv5T and above, this is an interworking branch. 1808 if (!LoadWritePC(context, data)) 1809 return false; 1810 } else 1811 return false; 1812 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 1813 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 1814 data)) 1815 return false; 1816 } else // We don't handle ARM for now. 1817 return false; 1818 } 1819 return true; 1820 } 1821 1822 // An add operation to adjust the SP. 1823 // ADD (SP plus immediate) 1824 bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode, 1825 const ARMEncoding encoding) { 1826 #if 0 1827 // ARM pseudo code... 1828 if (ConditionPassed()) 1829 { 1830 EncodingSpecificOperations(); 1831 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1832 if d == 15 then // Can only occur for ARM encoding 1833 ALUWritePC(result); // setflags is always FALSE here 1834 else 1835 R[d] = result; 1836 if setflags then 1837 APSR.N = result<31>; 1838 APSR.Z = IsZeroBit(result); 1839 APSR.C = carry; 1840 APSR.V = overflow; 1841 } 1842 #endif 1843 1844 bool success = false; 1845 1846 if (ConditionPassed(opcode)) { 1847 const addr_t sp = ReadCoreReg(SP_REG, &success); 1848 if (!success) 1849 return false; 1850 uint32_t imm32; // the immediate operand 1851 uint32_t d; 1852 bool setflags; 1853 switch (encoding) { 1854 case eEncodingT1: 1855 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1856 d = Bits32(opcode, 10, 8); 1857 imm32 = (Bits32(opcode, 7, 0) << 2); 1858 setflags = false; 1859 break; 1860 1861 case eEncodingT2: 1862 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1863 d = 13; 1864 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1865 setflags = false; 1866 break; 1867 1868 case eEncodingT3: 1869 // d = UInt(Rd); setflags = (S == "1"); imm32 = 1870 // ThumbExpandImm(i:imm3:imm8); 1871 d = Bits32(opcode, 11, 8); 1872 imm32 = ThumbExpandImm(opcode); 1873 setflags = Bit32(opcode, 20); 1874 1875 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 1876 if (d == 15 && setflags == 1) 1877 return false; // CMN (immediate) not yet supported 1878 1879 // if d == 15 && S == "0" then UNPREDICTABLE; 1880 if (d == 15 && setflags == 0) 1881 return false; 1882 break; 1883 1884 case eEncodingT4: { 1885 // if Rn == '1111' then SEE ADR; 1886 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 1887 d = Bits32(opcode, 11, 8); 1888 setflags = false; 1889 uint32_t i = Bit32(opcode, 26); 1890 uint32_t imm3 = Bits32(opcode, 14, 12); 1891 uint32_t imm8 = Bits32(opcode, 7, 0); 1892 imm32 = (i << 11) | (imm3 << 8) | imm8; 1893 1894 // if d == 15 then UNPREDICTABLE; 1895 if (d == 15) 1896 return false; 1897 } break; 1898 1899 default: 1900 return false; 1901 } 1902 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 1903 AddWithCarryResult res = AddWithCarry(sp, imm32, 0); 1904 1905 EmulateInstruction::Context context; 1906 if (d == 13) 1907 context.type = EmulateInstruction::eContextAdjustStackPointer; 1908 else 1909 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1910 1911 RegisterInfo sp_reg; 1912 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1913 context.SetRegisterPlusOffset(sp_reg, res.result - sp); 1914 1915 if (d == 15) { 1916 if (!ALUWritePC(context, res.result)) 1917 return false; 1918 } else { 1919 // R[d] = result; 1920 // if setflags then 1921 // APSR.N = result<31>; 1922 // APSR.Z = IsZeroBit(result); 1923 // APSR.C = carry; 1924 // APSR.V = overflow; 1925 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 1926 res.carry_out, res.overflow)) 1927 return false; 1928 } 1929 } 1930 return true; 1931 } 1932 1933 // An add operation to adjust the SP. 1934 // ADD (SP plus register) 1935 bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode, 1936 const ARMEncoding encoding) { 1937 #if 0 1938 // ARM pseudo code... 1939 if (ConditionPassed()) 1940 { 1941 EncodingSpecificOperations(); 1942 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1943 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1944 if d == 15 then 1945 ALUWritePC(result); // setflags is always FALSE here 1946 else 1947 R[d] = result; 1948 if setflags then 1949 APSR.N = result<31>; 1950 APSR.Z = IsZeroBit(result); 1951 APSR.C = carry; 1952 APSR.V = overflow; 1953 } 1954 #endif 1955 1956 bool success = false; 1957 1958 if (ConditionPassed(opcode)) { 1959 const addr_t sp = ReadCoreReg(SP_REG, &success); 1960 if (!success) 1961 return false; 1962 uint32_t Rm; // the second operand 1963 switch (encoding) { 1964 case eEncodingT2: 1965 Rm = Bits32(opcode, 6, 3); 1966 break; 1967 default: 1968 return false; 1969 } 1970 int32_t reg_value = ReadCoreReg(Rm, &success); 1971 if (!success) 1972 return false; 1973 1974 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1975 1976 EmulateInstruction::Context context; 1977 context.type = eContextArithmetic; 1978 RegisterInfo sp_reg; 1979 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1980 1981 RegisterInfo other_reg; 1982 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1983 context.SetRegisterRegisterOperands(sp_reg, other_reg); 1984 1985 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1986 LLDB_REGNUM_GENERIC_SP, addr)) 1987 return false; 1988 } 1989 return true; 1990 } 1991 1992 // Branch with Link and Exchange Instruction Sets (immediate) calls a 1993 // subroutine at a PC-relative address, and changes instruction set from ARM to 1994 // Thumb, or from Thumb to ARM. 1995 // BLX (immediate) 1996 bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode, 1997 const ARMEncoding encoding) { 1998 #if 0 1999 // ARM pseudo code... 2000 if (ConditionPassed()) 2001 { 2002 EncodingSpecificOperations(); 2003 if CurrentInstrSet() == InstrSet_ARM then 2004 LR = PC - 4; 2005 else 2006 LR = PC<31:1> : '1'; 2007 if targetInstrSet == InstrSet_ARM then 2008 targetAddress = Align(PC,4) + imm32; 2009 else 2010 targetAddress = PC + imm32; 2011 SelectInstrSet(targetInstrSet); 2012 BranchWritePC(targetAddress); 2013 } 2014 #endif 2015 2016 bool success = true; 2017 2018 if (ConditionPassed(opcode)) { 2019 EmulateInstruction::Context context; 2020 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2021 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2022 if (!success) 2023 return false; 2024 addr_t lr; // next instruction address 2025 addr_t target; // target address 2026 int32_t imm32; // PC-relative offset 2027 switch (encoding) { 2028 case eEncodingT1: { 2029 lr = pc | 1u; // return address 2030 uint32_t S = Bit32(opcode, 26); 2031 uint32_t imm10 = Bits32(opcode, 25, 16); 2032 uint32_t J1 = Bit32(opcode, 13); 2033 uint32_t J2 = Bit32(opcode, 11); 2034 uint32_t imm11 = Bits32(opcode, 10, 0); 2035 uint32_t I1 = !(J1 ^ S); 2036 uint32_t I2 = !(J2 ^ S); 2037 uint32_t imm25 = 2038 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2039 imm32 = llvm::SignExtend32<25>(imm25); 2040 target = pc + imm32; 2041 SelectInstrSet(eModeThumb); 2042 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2043 if (InITBlock() && !LastInITBlock()) 2044 return false; 2045 break; 2046 } 2047 case eEncodingT2: { 2048 lr = pc | 1u; // return address 2049 uint32_t S = Bit32(opcode, 26); 2050 uint32_t imm10H = Bits32(opcode, 25, 16); 2051 uint32_t J1 = Bit32(opcode, 13); 2052 uint32_t J2 = Bit32(opcode, 11); 2053 uint32_t imm10L = Bits32(opcode, 10, 1); 2054 uint32_t I1 = !(J1 ^ S); 2055 uint32_t I2 = !(J2 ^ S); 2056 uint32_t imm25 = 2057 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 2058 imm32 = llvm::SignExtend32<25>(imm25); 2059 target = Align(pc, 4) + imm32; 2060 SelectInstrSet(eModeARM); 2061 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32); 2062 if (InITBlock() && !LastInITBlock()) 2063 return false; 2064 break; 2065 } 2066 case eEncodingA1: 2067 lr = pc - 4; // return address 2068 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2069 target = Align(pc, 4) + imm32; 2070 SelectInstrSet(eModeARM); 2071 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2072 break; 2073 case eEncodingA2: 2074 lr = pc - 4; // return address 2075 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | 2076 Bits32(opcode, 24, 24) << 1); 2077 target = pc + imm32; 2078 SelectInstrSet(eModeThumb); 2079 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32); 2080 break; 2081 default: 2082 return false; 2083 } 2084 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2085 LLDB_REGNUM_GENERIC_RA, lr)) 2086 return false; 2087 if (!BranchWritePC(context, target)) 2088 return false; 2089 if (m_opcode_cpsr != m_new_inst_cpsr) 2090 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2091 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2092 return false; 2093 } 2094 return true; 2095 } 2096 2097 // Branch with Link and Exchange (register) calls a subroutine at an address 2098 // and instruction set specified by a register. 2099 // BLX (register) 2100 bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode, 2101 const ARMEncoding encoding) { 2102 #if 0 2103 // ARM pseudo code... 2104 if (ConditionPassed()) 2105 { 2106 EncodingSpecificOperations(); 2107 target = R[m]; 2108 if CurrentInstrSet() == InstrSet_ARM then 2109 next_instr_addr = PC - 4; 2110 LR = next_instr_addr; 2111 else 2112 next_instr_addr = PC - 2; 2113 LR = next_instr_addr<31:1> : '1'; 2114 BXWritePC(target); 2115 } 2116 #endif 2117 2118 bool success = false; 2119 2120 if (ConditionPassed(opcode)) { 2121 EmulateInstruction::Context context; 2122 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2123 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2124 addr_t lr; // next instruction address 2125 if (!success) 2126 return false; 2127 uint32_t Rm; // the register with the target address 2128 switch (encoding) { 2129 case eEncodingT1: 2130 lr = (pc - 2) | 1u; // return address 2131 Rm = Bits32(opcode, 6, 3); 2132 // if m == 15 then UNPREDICTABLE; 2133 if (Rm == 15) 2134 return false; 2135 if (InITBlock() && !LastInITBlock()) 2136 return false; 2137 break; 2138 case eEncodingA1: 2139 lr = pc - 4; // return address 2140 Rm = Bits32(opcode, 3, 0); 2141 // if m == 15 then UNPREDICTABLE; 2142 if (Rm == 15) 2143 return false; 2144 break; 2145 default: 2146 return false; 2147 } 2148 addr_t target = ReadCoreReg(Rm, &success); 2149 if (!success) 2150 return false; 2151 RegisterInfo dwarf_reg; 2152 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2153 context.SetRegister(dwarf_reg); 2154 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2155 LLDB_REGNUM_GENERIC_RA, lr)) 2156 return false; 2157 if (!BXWritePC(context, target)) 2158 return false; 2159 } 2160 return true; 2161 } 2162 2163 // Branch and Exchange causes a branch to an address and instruction set 2164 // specified by a register. 2165 bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode, 2166 const ARMEncoding encoding) { 2167 #if 0 2168 // ARM pseudo code... 2169 if (ConditionPassed()) 2170 { 2171 EncodingSpecificOperations(); 2172 BXWritePC(R[m]); 2173 } 2174 #endif 2175 2176 if (ConditionPassed(opcode)) { 2177 EmulateInstruction::Context context; 2178 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2179 uint32_t Rm; // the register with the target address 2180 switch (encoding) { 2181 case eEncodingT1: 2182 Rm = Bits32(opcode, 6, 3); 2183 if (InITBlock() && !LastInITBlock()) 2184 return false; 2185 break; 2186 case eEncodingA1: 2187 Rm = Bits32(opcode, 3, 0); 2188 break; 2189 default: 2190 return false; 2191 } 2192 bool success = false; 2193 addr_t target = ReadCoreReg(Rm, &success); 2194 if (!success) 2195 return false; 2196 2197 RegisterInfo dwarf_reg; 2198 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2199 context.SetRegister(dwarf_reg); 2200 if (!BXWritePC(context, target)) 2201 return false; 2202 } 2203 return true; 2204 } 2205 2206 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the 2207 // attempt fails, it branches to an address and instruction set specified by a 2208 // register as though it were a BX instruction. 2209 // 2210 // TODO: Emulate Jazelle architecture? 2211 // We currently assume that switching to Jazelle state fails, thus 2212 // treating BXJ as a BX operation. 2213 bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode, 2214 const ARMEncoding encoding) { 2215 #if 0 2216 // ARM pseudo code... 2217 if (ConditionPassed()) 2218 { 2219 EncodingSpecificOperations(); 2220 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 2221 BXWritePC(R[m]); 2222 else 2223 if JazelleAcceptsExecution() then 2224 SwitchToJazelleExecution(); 2225 else 2226 SUBARCHITECTURE_DEFINED handler call; 2227 } 2228 #endif 2229 2230 if (ConditionPassed(opcode)) { 2231 EmulateInstruction::Context context; 2232 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2233 uint32_t Rm; // the register with the target address 2234 switch (encoding) { 2235 case eEncodingT1: 2236 Rm = Bits32(opcode, 19, 16); 2237 if (BadReg(Rm)) 2238 return false; 2239 if (InITBlock() && !LastInITBlock()) 2240 return false; 2241 break; 2242 case eEncodingA1: 2243 Rm = Bits32(opcode, 3, 0); 2244 if (Rm == 15) 2245 return false; 2246 break; 2247 default: 2248 return false; 2249 } 2250 bool success = false; 2251 addr_t target = ReadCoreReg(Rm, &success); 2252 if (!success) 2253 return false; 2254 2255 RegisterInfo dwarf_reg; 2256 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2257 context.SetRegister(dwarf_reg); 2258 if (!BXWritePC(context, target)) 2259 return false; 2260 } 2261 return true; 2262 } 2263 2264 // Set r7 to point to some ip offset. 2265 // SUB (immediate) 2266 bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode, 2267 const ARMEncoding encoding) { 2268 #if 0 2269 // ARM pseudo code... 2270 if (ConditionPassed()) 2271 { 2272 EncodingSpecificOperations(); 2273 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2274 if d == 15 then // Can only occur for ARM encoding 2275 ALUWritePC(result); // setflags is always FALSE here 2276 else 2277 R[d] = result; 2278 if setflags then 2279 APSR.N = result<31>; 2280 APSR.Z = IsZeroBit(result); 2281 APSR.C = carry; 2282 APSR.V = overflow; 2283 } 2284 #endif 2285 2286 if (ConditionPassed(opcode)) { 2287 bool success = false; 2288 const addr_t ip = ReadCoreReg(12, &success); 2289 if (!success) 2290 return false; 2291 uint32_t imm32; 2292 switch (encoding) { 2293 case eEncodingA1: 2294 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2295 break; 2296 default: 2297 return false; 2298 } 2299 addr_t ip_offset = imm32; 2300 addr_t addr = ip - ip_offset; // the adjusted ip value 2301 2302 EmulateInstruction::Context context; 2303 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2304 RegisterInfo dwarf_reg; 2305 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg); 2306 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset); 2307 2308 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr)) 2309 return false; 2310 } 2311 return true; 2312 } 2313 2314 // Set ip to point to some stack offset. 2315 // SUB (SP minus immediate) 2316 bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode, 2317 const ARMEncoding encoding) { 2318 #if 0 2319 // ARM pseudo code... 2320 if (ConditionPassed()) 2321 { 2322 EncodingSpecificOperations(); 2323 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2324 if d == 15 then // Can only occur for ARM encoding 2325 ALUWritePC(result); // setflags is always FALSE here 2326 else 2327 R[d] = result; 2328 if setflags then 2329 APSR.N = result<31>; 2330 APSR.Z = IsZeroBit(result); 2331 APSR.C = carry; 2332 APSR.V = overflow; 2333 } 2334 #endif 2335 2336 if (ConditionPassed(opcode)) { 2337 bool success = false; 2338 const addr_t sp = ReadCoreReg(SP_REG, &success); 2339 if (!success) 2340 return false; 2341 uint32_t imm32; 2342 switch (encoding) { 2343 case eEncodingA1: 2344 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2345 break; 2346 default: 2347 return false; 2348 } 2349 addr_t sp_offset = imm32; 2350 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 2351 2352 EmulateInstruction::Context context; 2353 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2354 RegisterInfo dwarf_reg; 2355 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 2356 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset); 2357 2358 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr)) 2359 return false; 2360 } 2361 return true; 2362 } 2363 2364 // This instruction subtracts an immediate value from the SP value, and writes 2365 // the result to the destination register. 2366 // 2367 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local 2368 // storage. 2369 bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode, 2370 const ARMEncoding encoding) { 2371 #if 0 2372 // ARM pseudo code... 2373 if (ConditionPassed()) 2374 { 2375 EncodingSpecificOperations(); 2376 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2377 if d == 15 then // Can only occur for ARM encoding 2378 ALUWritePC(result); // setflags is always FALSE here 2379 else 2380 R[d] = result; 2381 if setflags then 2382 APSR.N = result<31>; 2383 APSR.Z = IsZeroBit(result); 2384 APSR.C = carry; 2385 APSR.V = overflow; 2386 } 2387 #endif 2388 2389 bool success = false; 2390 if (ConditionPassed(opcode)) { 2391 const addr_t sp = ReadCoreReg(SP_REG, &success); 2392 if (!success) 2393 return false; 2394 2395 uint32_t Rd; 2396 bool setflags; 2397 uint32_t imm32; 2398 switch (encoding) { 2399 case eEncodingT1: 2400 Rd = 13; 2401 setflags = false; 2402 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 2403 break; 2404 case eEncodingT2: 2405 Rd = Bits32(opcode, 11, 8); 2406 setflags = BitIsSet(opcode, 20); 2407 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2408 if (Rd == 15 && setflags) 2409 return EmulateCMPImm(opcode, eEncodingT2); 2410 if (Rd == 15 && !setflags) 2411 return false; 2412 break; 2413 case eEncodingT3: 2414 Rd = Bits32(opcode, 11, 8); 2415 setflags = false; 2416 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 2417 if (Rd == 15) 2418 return false; 2419 break; 2420 case eEncodingA1: 2421 Rd = Bits32(opcode, 15, 12); 2422 setflags = BitIsSet(opcode, 20); 2423 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2424 2425 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 2426 // instructions; 2427 if (Rd == 15 && setflags) 2428 return EmulateSUBSPcLrEtc(opcode, encoding); 2429 break; 2430 default: 2431 return false; 2432 } 2433 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 2434 2435 EmulateInstruction::Context context; 2436 if (Rd == 13) { 2437 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting 2438 // to negate it, or the wrong 2439 // value gets passed down to context.SetImmediateSigned. 2440 context.type = EmulateInstruction::eContextAdjustStackPointer; 2441 context.SetImmediateSigned(-imm64); // the stack pointer offset 2442 } else { 2443 context.type = EmulateInstruction::eContextImmediate; 2444 context.SetNoArgs(); 2445 } 2446 2447 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 2448 res.carry_out, res.overflow)) 2449 return false; 2450 } 2451 return true; 2452 } 2453 2454 // A store operation to the stack that also updates the SP. 2455 bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode, 2456 const ARMEncoding encoding) { 2457 #if 0 2458 // ARM pseudo code... 2459 if (ConditionPassed()) 2460 { 2461 EncodingSpecificOperations(); 2462 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2463 address = if index then offset_addr else R[n]; 2464 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 2465 if wback then R[n] = offset_addr; 2466 } 2467 #endif 2468 2469 bool success = false; 2470 if (ConditionPassed(opcode)) { 2471 const uint32_t addr_byte_size = GetAddressByteSize(); 2472 const addr_t sp = ReadCoreReg(SP_REG, &success); 2473 if (!success) 2474 return false; 2475 uint32_t Rt; // the source register 2476 uint32_t imm12; 2477 uint32_t 2478 Rn; // This function assumes Rn is the SP, but we should verify that. 2479 2480 bool index; 2481 bool add; 2482 bool wback; 2483 switch (encoding) { 2484 case eEncodingA1: 2485 Rt = Bits32(opcode, 15, 12); 2486 imm12 = Bits32(opcode, 11, 0); 2487 Rn = Bits32(opcode, 19, 16); 2488 2489 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 2490 return false; 2491 2492 index = BitIsSet(opcode, 24); 2493 add = BitIsSet(opcode, 23); 2494 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 2495 2496 if (wback && ((Rn == 15) || (Rn == Rt))) 2497 return false; 2498 break; 2499 default: 2500 return false; 2501 } 2502 addr_t offset_addr; 2503 if (add) 2504 offset_addr = sp + imm12; 2505 else 2506 offset_addr = sp - imm12; 2507 2508 addr_t addr; 2509 if (index) 2510 addr = offset_addr; 2511 else 2512 addr = sp; 2513 2514 EmulateInstruction::Context context; 2515 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2516 RegisterInfo sp_reg; 2517 RegisterInfo dwarf_reg; 2518 2519 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2520 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2521 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2522 if (Rt != 15) { 2523 uint32_t reg_value = ReadCoreReg(Rt, &success); 2524 if (!success) 2525 return false; 2526 if (!MemUWrite(context, addr, reg_value, addr_byte_size)) 2527 return false; 2528 } else { 2529 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2530 if (!success) 2531 return false; 2532 if (!MemUWrite(context, addr, pc, addr_byte_size)) 2533 return false; 2534 } 2535 2536 if (wback) { 2537 context.type = EmulateInstruction::eContextAdjustStackPointer; 2538 context.SetImmediateSigned(addr - sp); 2539 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2540 LLDB_REGNUM_GENERIC_SP, offset_addr)) 2541 return false; 2542 } 2543 } 2544 return true; 2545 } 2546 2547 // Vector Push stores multiple extension registers to the stack. It also 2548 // updates SP to point to the start of the stored data. 2549 bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode, 2550 const ARMEncoding encoding) { 2551 #if 0 2552 // ARM pseudo code... 2553 if (ConditionPassed()) 2554 { 2555 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2556 address = SP - imm32; 2557 SP = SP - imm32; 2558 if single_regs then 2559 for r = 0 to regs-1 2560 MemA[address,4] = S[d+r]; address = address+4; 2561 else 2562 for r = 0 to regs-1 2563 // Store as two word-aligned words in the correct order for 2564 // current endianness. 2565 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2566 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2567 address = address+8; 2568 } 2569 #endif 2570 2571 bool success = false; 2572 if (ConditionPassed(opcode)) { 2573 const uint32_t addr_byte_size = GetAddressByteSize(); 2574 const addr_t sp = ReadCoreReg(SP_REG, &success); 2575 if (!success) 2576 return false; 2577 bool single_regs; 2578 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2579 uint32_t imm32; // stack offset 2580 uint32_t regs; // number of registers 2581 switch (encoding) { 2582 case eEncodingT1: 2583 case eEncodingA1: 2584 single_regs = false; 2585 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2586 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2587 // If UInt(imm8) is odd, see "FSTMX". 2588 regs = Bits32(opcode, 7, 0) / 2; 2589 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2590 if (regs == 0 || regs > 16 || (d + regs) > 32) 2591 return false; 2592 break; 2593 case eEncodingT2: 2594 case eEncodingA2: 2595 single_regs = true; 2596 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2597 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2598 regs = Bits32(opcode, 7, 0); 2599 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2600 if (regs == 0 || regs > 16 || (d + regs) > 32) 2601 return false; 2602 break; 2603 default: 2604 return false; 2605 } 2606 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2607 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2608 addr_t sp_offset = imm32; 2609 addr_t addr = sp - sp_offset; 2610 uint32_t i; 2611 2612 EmulateInstruction::Context context; 2613 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2614 2615 RegisterInfo dwarf_reg; 2616 RegisterInfo sp_reg; 2617 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2618 for (i = 0; i < regs; ++i) { 2619 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2620 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2621 // uint64_t to accommodate 64-bit registers. 2622 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success); 2623 if (!success) 2624 return false; 2625 if (!MemAWrite(context, addr, reg_value, reg_byte_size)) 2626 return false; 2627 addr += reg_byte_size; 2628 } 2629 2630 context.type = EmulateInstruction::eContextAdjustStackPointer; 2631 context.SetImmediateSigned(-sp_offset); 2632 2633 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2634 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2635 return false; 2636 } 2637 return true; 2638 } 2639 2640 // Vector Pop loads multiple extension registers from the stack. It also 2641 // updates SP to point just above the loaded data. 2642 bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode, 2643 const ARMEncoding encoding) { 2644 #if 0 2645 // ARM pseudo code... 2646 if (ConditionPassed()) 2647 { 2648 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2649 address = SP; 2650 SP = SP + imm32; 2651 if single_regs then 2652 for r = 0 to regs-1 2653 S[d+r] = MemA[address,4]; address = address+4; 2654 else 2655 for r = 0 to regs-1 2656 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2657 // Combine the word-aligned words in the correct order for 2658 // current endianness. 2659 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2660 } 2661 #endif 2662 2663 bool success = false; 2664 if (ConditionPassed(opcode)) { 2665 const uint32_t addr_byte_size = GetAddressByteSize(); 2666 const addr_t sp = ReadCoreReg(SP_REG, &success); 2667 if (!success) 2668 return false; 2669 bool single_regs; 2670 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2671 uint32_t imm32; // stack offset 2672 uint32_t regs; // number of registers 2673 switch (encoding) { 2674 case eEncodingT1: 2675 case eEncodingA1: 2676 single_regs = false; 2677 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2678 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2679 // If UInt(imm8) is odd, see "FLDMX". 2680 regs = Bits32(opcode, 7, 0) / 2; 2681 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2682 if (regs == 0 || regs > 16 || (d + regs) > 32) 2683 return false; 2684 break; 2685 case eEncodingT2: 2686 case eEncodingA2: 2687 single_regs = true; 2688 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2689 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2690 regs = Bits32(opcode, 7, 0); 2691 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2692 if (regs == 0 || regs > 16 || (d + regs) > 32) 2693 return false; 2694 break; 2695 default: 2696 return false; 2697 } 2698 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2699 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2700 addr_t sp_offset = imm32; 2701 addr_t addr = sp; 2702 uint32_t i; 2703 uint64_t data; // uint64_t to accommodate 64-bit registers. 2704 2705 EmulateInstruction::Context context; 2706 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2707 2708 RegisterInfo dwarf_reg; 2709 RegisterInfo sp_reg; 2710 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2711 for (i = 0; i < regs; ++i) { 2712 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2713 context.SetAddress(addr); 2714 data = MemARead(context, addr, reg_byte_size, 0, &success); 2715 if (!success) 2716 return false; 2717 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2718 return false; 2719 addr += reg_byte_size; 2720 } 2721 2722 context.type = EmulateInstruction::eContextAdjustStackPointer; 2723 context.SetImmediateSigned(sp_offset); 2724 2725 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2726 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2727 return false; 2728 } 2729 return true; 2730 } 2731 2732 // SVC (previously SWI) 2733 bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode, 2734 const ARMEncoding encoding) { 2735 #if 0 2736 // ARM pseudo code... 2737 if (ConditionPassed()) 2738 { 2739 EncodingSpecificOperations(); 2740 CallSupervisor(); 2741 } 2742 #endif 2743 2744 bool success = false; 2745 2746 if (ConditionPassed(opcode)) { 2747 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2748 addr_t lr; // next instruction address 2749 if (!success) 2750 return false; 2751 uint32_t imm32; // the immediate constant 2752 uint32_t mode; // ARM or Thumb mode 2753 switch (encoding) { 2754 case eEncodingT1: 2755 lr = (pc + 2) | 1u; // return address 2756 imm32 = Bits32(opcode, 7, 0); 2757 mode = eModeThumb; 2758 break; 2759 case eEncodingA1: 2760 lr = pc + 4; // return address 2761 imm32 = Bits32(opcode, 23, 0); 2762 mode = eModeARM; 2763 break; 2764 default: 2765 return false; 2766 } 2767 2768 EmulateInstruction::Context context; 2769 context.type = EmulateInstruction::eContextSupervisorCall; 2770 context.SetISAAndImmediate(mode, imm32); 2771 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2772 LLDB_REGNUM_GENERIC_RA, lr)) 2773 return false; 2774 } 2775 return true; 2776 } 2777 2778 // If Then makes up to four following instructions (the IT block) conditional. 2779 bool EmulateInstructionARM::EmulateIT(const uint32_t opcode, 2780 const ARMEncoding encoding) { 2781 #if 0 2782 // ARM pseudo code... 2783 EncodingSpecificOperations(); 2784 ITSTATE.IT<7:0> = firstcond:mask; 2785 #endif 2786 2787 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2788 return true; 2789 } 2790 2791 bool EmulateInstructionARM::EmulateNop(const uint32_t opcode, 2792 const ARMEncoding encoding) { 2793 // NOP, nothing to do... 2794 return true; 2795 } 2796 2797 // Branch causes a branch to a target address. 2798 bool EmulateInstructionARM::EmulateB(const uint32_t opcode, 2799 const ARMEncoding encoding) { 2800 #if 0 2801 // ARM pseudo code... 2802 if (ConditionPassed()) 2803 { 2804 EncodingSpecificOperations(); 2805 BranchWritePC(PC + imm32); 2806 } 2807 #endif 2808 2809 bool success = false; 2810 2811 if (ConditionPassed(opcode)) { 2812 EmulateInstruction::Context context; 2813 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2814 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2815 if (!success) 2816 return false; 2817 addr_t target; // target address 2818 int32_t imm32; // PC-relative offset 2819 switch (encoding) { 2820 case eEncodingT1: 2821 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2822 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2823 target = pc + imm32; 2824 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2825 break; 2826 case eEncodingT2: 2827 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2828 target = pc + imm32; 2829 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2830 break; 2831 case eEncodingT3: 2832 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2833 { 2834 if (Bits32(opcode, 25, 23) == 7) 2835 return false; // See Branches and miscellaneous control on page 2836 // A6-235. 2837 2838 uint32_t S = Bit32(opcode, 26); 2839 uint32_t imm6 = Bits32(opcode, 21, 16); 2840 uint32_t J1 = Bit32(opcode, 13); 2841 uint32_t J2 = Bit32(opcode, 11); 2842 uint32_t imm11 = Bits32(opcode, 10, 0); 2843 uint32_t imm21 = 2844 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2845 imm32 = llvm::SignExtend32<21>(imm21); 2846 target = pc + imm32; 2847 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2848 break; 2849 } 2850 case eEncodingT4: { 2851 uint32_t S = Bit32(opcode, 26); 2852 uint32_t imm10 = Bits32(opcode, 25, 16); 2853 uint32_t J1 = Bit32(opcode, 13); 2854 uint32_t J2 = Bit32(opcode, 11); 2855 uint32_t imm11 = Bits32(opcode, 10, 0); 2856 uint32_t I1 = !(J1 ^ S); 2857 uint32_t I2 = !(J2 ^ S); 2858 uint32_t imm25 = 2859 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2860 imm32 = llvm::SignExtend32<25>(imm25); 2861 target = pc + imm32; 2862 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2863 break; 2864 } 2865 case eEncodingA1: 2866 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2867 target = pc + imm32; 2868 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2869 break; 2870 default: 2871 return false; 2872 } 2873 if (!BranchWritePC(context, target)) 2874 return false; 2875 } 2876 return true; 2877 } 2878 2879 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the 2880 // value in a register with zero and conditionally branch forward a constant 2881 // value. They do not affect the condition flags. CBNZ, CBZ 2882 bool EmulateInstructionARM::EmulateCB(const uint32_t opcode, 2883 const ARMEncoding encoding) { 2884 #if 0 2885 // ARM pseudo code... 2886 EncodingSpecificOperations(); 2887 if nonzero ^ IsZero(R[n]) then 2888 BranchWritePC(PC + imm32); 2889 #endif 2890 2891 bool success = false; 2892 2893 // Read the register value from the operand register Rn. 2894 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2895 if (!success) 2896 return false; 2897 2898 EmulateInstruction::Context context; 2899 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2900 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2901 if (!success) 2902 return false; 2903 2904 addr_t target; // target address 2905 uint32_t imm32; // PC-relative offset to branch forward 2906 bool nonzero; 2907 switch (encoding) { 2908 case eEncodingT1: 2909 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2910 nonzero = BitIsSet(opcode, 11); 2911 target = pc + imm32; 2912 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2913 break; 2914 default: 2915 return false; 2916 } 2917 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2918 if (!BranchWritePC(context, target)) 2919 return false; 2920 2921 return true; 2922 } 2923 2924 // Table Branch Byte causes a PC-relative forward branch using a table of 2925 // single byte offsets. 2926 // A base register provides a pointer to the table, and a second register 2927 // supplies an index into the table. 2928 // The branch length is twice the value of the byte returned from the table. 2929 // 2930 // Table Branch Halfword causes a PC-relative forward branch using a table of 2931 // single halfword offsets. 2932 // A base register provides a pointer to the table, and a second register 2933 // supplies an index into the table. 2934 // The branch length is twice the value of the halfword returned from the 2935 // table. TBB, TBH 2936 bool EmulateInstructionARM::EmulateTB(const uint32_t opcode, 2937 const ARMEncoding encoding) { 2938 #if 0 2939 // ARM pseudo code... 2940 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2941 if is_tbh then 2942 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2943 else 2944 halfwords = UInt(MemU[R[n]+R[m], 1]); 2945 BranchWritePC(PC + 2*halfwords); 2946 #endif 2947 2948 bool success = false; 2949 2950 if (ConditionPassed(opcode)) { 2951 uint32_t Rn; // the base register which contains the address of the table of 2952 // branch lengths 2953 uint32_t Rm; // the index register which contains an integer pointing to a 2954 // byte/halfword in the table 2955 bool is_tbh; // true if table branch halfword 2956 switch (encoding) { 2957 case eEncodingT1: 2958 Rn = Bits32(opcode, 19, 16); 2959 Rm = Bits32(opcode, 3, 0); 2960 is_tbh = BitIsSet(opcode, 4); 2961 if (Rn == 13 || BadReg(Rm)) 2962 return false; 2963 if (InITBlock() && !LastInITBlock()) 2964 return false; 2965 break; 2966 default: 2967 return false; 2968 } 2969 2970 // Read the address of the table from the operand register Rn. The PC can 2971 // be used, in which case the table immediately follows this instruction. 2972 uint32_t base = ReadCoreReg(Rn, &success); 2973 if (!success) 2974 return false; 2975 2976 // the table index 2977 uint32_t index = ReadCoreReg(Rm, &success); 2978 if (!success) 2979 return false; 2980 2981 // the offsetted table address 2982 addr_t addr = base + (is_tbh ? index * 2 : index); 2983 2984 // PC-relative offset to branch forward 2985 EmulateInstruction::Context context; 2986 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2987 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2988 if (!success) 2989 return false; 2990 2991 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2992 if (!success) 2993 return false; 2994 2995 // target address 2996 addr_t target = pc + offset; 2997 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2998 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset); 2999 3000 if (!BranchWritePC(context, target)) 3001 return false; 3002 } 3003 3004 return true; 3005 } 3006 3007 // This instruction adds an immediate value to a register value, and writes the 3008 // result to the destination register. It can optionally update the condition 3009 // flags based on the result. 3010 bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode, 3011 const ARMEncoding encoding) { 3012 #if 0 3013 if ConditionPassed() then 3014 EncodingSpecificOperations(); 3015 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3016 R[d] = result; 3017 if setflags then 3018 APSR.N = result<31>; 3019 APSR.Z = IsZeroBit(result); 3020 APSR.C = carry; 3021 APSR.V = overflow; 3022 #endif 3023 3024 bool success = false; 3025 3026 if (ConditionPassed(opcode)) { 3027 uint32_t d; 3028 uint32_t n; 3029 bool setflags; 3030 uint32_t imm32; 3031 uint32_t carry_out; 3032 3033 // EncodingSpecificOperations(); 3034 switch (encoding) { 3035 case eEncodingT1: 3036 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = 3037 // ZeroExtend(imm3, 32); 3038 d = Bits32(opcode, 2, 0); 3039 n = Bits32(opcode, 5, 3); 3040 setflags = !InITBlock(); 3041 imm32 = Bits32(opcode, 8, 6); 3042 3043 break; 3044 3045 case eEncodingT2: 3046 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = 3047 // ZeroExtend(imm8, 32); 3048 d = Bits32(opcode, 10, 8); 3049 n = Bits32(opcode, 10, 8); 3050 setflags = !InITBlock(); 3051 imm32 = Bits32(opcode, 7, 0); 3052 3053 break; 3054 3055 case eEncodingT3: 3056 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 3057 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = 3058 // ThumbExpandImm(i:imm3:imm8); 3059 d = Bits32(opcode, 11, 8); 3060 n = Bits32(opcode, 19, 16); 3061 setflags = BitIsSet(opcode, 20); 3062 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out); 3063 3064 // if Rn == '1101' then SEE ADD (SP plus immediate); 3065 if (n == 13) 3066 return EmulateADDSPImm(opcode, eEncodingT3); 3067 3068 // if BadReg(d) || n == 15 then UNPREDICTABLE; 3069 if (BadReg(d) || (n == 15)) 3070 return false; 3071 3072 break; 3073 3074 case eEncodingT4: { 3075 // if Rn == '1111' then SEE ADR; 3076 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = 3077 // ZeroExtend(i:imm3:imm8, 32); 3078 d = Bits32(opcode, 11, 8); 3079 n = Bits32(opcode, 19, 16); 3080 setflags = false; 3081 uint32_t i = Bit32(opcode, 26); 3082 uint32_t imm3 = Bits32(opcode, 14, 12); 3083 uint32_t imm8 = Bits32(opcode, 7, 0); 3084 imm32 = (i << 11) | (imm3 << 8) | imm8; 3085 3086 // if Rn == '1101' then SEE ADD (SP plus immediate); 3087 if (n == 13) 3088 return EmulateADDSPImm(opcode, eEncodingT4); 3089 3090 // if BadReg(d) then UNPREDICTABLE; 3091 if (BadReg(d)) 3092 return false; 3093 3094 break; 3095 } 3096 3097 default: 3098 return false; 3099 } 3100 3101 uint64_t Rn = 3102 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3103 if (!success) 3104 return false; 3105 3106 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3107 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0); 3108 3109 RegisterInfo reg_n; 3110 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 3111 3112 EmulateInstruction::Context context; 3113 context.type = eContextArithmetic; 3114 context.SetRegisterPlusOffset(reg_n, imm32); 3115 3116 // R[d] = result; 3117 // if setflags then 3118 // APSR.N = result<31>; 3119 // APSR.Z = IsZeroBit(result); 3120 // APSR.C = carry; 3121 // APSR.V = overflow; 3122 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 3123 res.carry_out, res.overflow)) 3124 return false; 3125 } 3126 return true; 3127 } 3128 3129 // This instruction adds an immediate value to a register value, and writes the 3130 // result to the destination register. It can optionally update the condition 3131 // flags based on the result. 3132 bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode, 3133 const ARMEncoding encoding) { 3134 #if 0 3135 // ARM pseudo code... 3136 if ConditionPassed() then 3137 EncodingSpecificOperations(); 3138 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3139 if d == 15 then 3140 ALUWritePC(result); // setflags is always FALSE here 3141 else 3142 R[d] = result; 3143 if setflags then 3144 APSR.N = result<31>; 3145 APSR.Z = IsZeroBit(result); 3146 APSR.C = carry; 3147 APSR.V = overflow; 3148 #endif 3149 3150 bool success = false; 3151 3152 if (ConditionPassed(opcode)) { 3153 uint32_t Rd, Rn; 3154 uint32_t 3155 imm32; // the immediate value to be added to the value obtained from Rn 3156 bool setflags; 3157 switch (encoding) { 3158 case eEncodingA1: 3159 Rd = Bits32(opcode, 15, 12); 3160 Rn = Bits32(opcode, 19, 16); 3161 setflags = BitIsSet(opcode, 20); 3162 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3163 break; 3164 default: 3165 return false; 3166 } 3167 3168 // Read the first operand. 3169 uint32_t val1 = ReadCoreReg(Rn, &success); 3170 if (!success) 3171 return false; 3172 3173 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 3174 3175 EmulateInstruction::Context context; 3176 if (Rd == 13) 3177 context.type = EmulateInstruction::eContextAdjustStackPointer; 3178 else if (Rd == GetFramePointerRegisterNumber()) 3179 context.type = EmulateInstruction::eContextSetFramePointer; 3180 else 3181 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3182 3183 RegisterInfo dwarf_reg; 3184 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 3185 context.SetRegisterPlusOffset(dwarf_reg, imm32); 3186 3187 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3188 res.carry_out, res.overflow)) 3189 return false; 3190 } 3191 return true; 3192 } 3193 3194 // This instruction adds a register value and an optionally-shifted register 3195 // value, and writes the result to the destination register. It can optionally 3196 // update the condition flags based on the result. 3197 bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode, 3198 const ARMEncoding encoding) { 3199 #if 0 3200 // ARM pseudo code... 3201 if ConditionPassed() then 3202 EncodingSpecificOperations(); 3203 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3204 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3205 if d == 15 then 3206 ALUWritePC(result); // setflags is always FALSE here 3207 else 3208 R[d] = result; 3209 if setflags then 3210 APSR.N = result<31>; 3211 APSR.Z = IsZeroBit(result); 3212 APSR.C = carry; 3213 APSR.V = overflow; 3214 #endif 3215 3216 bool success = false; 3217 3218 if (ConditionPassed(opcode)) { 3219 uint32_t Rd, Rn, Rm; 3220 ARM_ShifterType shift_t; 3221 uint32_t shift_n; // the shift applied to the value read from Rm 3222 bool setflags; 3223 switch (encoding) { 3224 case eEncodingT1: 3225 Rd = Bits32(opcode, 2, 0); 3226 Rn = Bits32(opcode, 5, 3); 3227 Rm = Bits32(opcode, 8, 6); 3228 setflags = !InITBlock(); 3229 shift_t = SRType_LSL; 3230 shift_n = 0; 3231 break; 3232 case eEncodingT2: 3233 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3234 Rm = Bits32(opcode, 6, 3); 3235 setflags = false; 3236 shift_t = SRType_LSL; 3237 shift_n = 0; 3238 if (Rn == 15 && Rm == 15) 3239 return false; 3240 if (Rd == 15 && InITBlock() && !LastInITBlock()) 3241 return false; 3242 break; 3243 case eEncodingA1: 3244 Rd = Bits32(opcode, 15, 12); 3245 Rn = Bits32(opcode, 19, 16); 3246 Rm = Bits32(opcode, 3, 0); 3247 setflags = BitIsSet(opcode, 20); 3248 shift_n = DecodeImmShiftARM(opcode, shift_t); 3249 break; 3250 default: 3251 return false; 3252 } 3253 3254 // Read the first operand. 3255 uint32_t val1 = ReadCoreReg(Rn, &success); 3256 if (!success) 3257 return false; 3258 3259 // Read the second operand. 3260 uint32_t val2 = ReadCoreReg(Rm, &success); 3261 if (!success) 3262 return false; 3263 3264 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3265 if (!success) 3266 return false; 3267 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3268 3269 EmulateInstruction::Context context; 3270 context.type = eContextArithmetic; 3271 RegisterInfo op1_reg; 3272 RegisterInfo op2_reg; 3273 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 3274 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 3275 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 3276 3277 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3278 res.carry_out, res.overflow)) 3279 return false; 3280 } 3281 return true; 3282 } 3283 3284 // Compare Negative (immediate) adds a register value and an immediate value. 3285 // It updates the condition flags based on the result, and discards the result. 3286 bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode, 3287 const ARMEncoding encoding) { 3288 #if 0 3289 // ARM pseudo code... 3290 if ConditionPassed() then 3291 EncodingSpecificOperations(); 3292 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3293 APSR.N = result<31>; 3294 APSR.Z = IsZeroBit(result); 3295 APSR.C = carry; 3296 APSR.V = overflow; 3297 #endif 3298 3299 bool success = false; 3300 3301 uint32_t Rn; // the first operand 3302 uint32_t imm32; // the immediate value to be compared with 3303 switch (encoding) { 3304 case eEncodingT1: 3305 Rn = Bits32(opcode, 19, 16); 3306 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3307 if (Rn == 15) 3308 return false; 3309 break; 3310 case eEncodingA1: 3311 Rn = Bits32(opcode, 19, 16); 3312 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3313 break; 3314 default: 3315 return false; 3316 } 3317 // Read the register value from the operand register Rn. 3318 uint32_t reg_val = ReadCoreReg(Rn, &success); 3319 if (!success) 3320 return false; 3321 3322 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 3323 3324 EmulateInstruction::Context context; 3325 context.type = EmulateInstruction::eContextImmediate; 3326 context.SetNoArgs(); 3327 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3328 } 3329 3330 // Compare Negative (register) adds a register value and an optionally-shifted 3331 // register value. It updates the condition flags based on the result, and 3332 // discards the result. 3333 bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode, 3334 const ARMEncoding encoding) { 3335 #if 0 3336 // ARM pseudo code... 3337 if ConditionPassed() then 3338 EncodingSpecificOperations(); 3339 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3340 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3341 APSR.N = result<31>; 3342 APSR.Z = IsZeroBit(result); 3343 APSR.C = carry; 3344 APSR.V = overflow; 3345 #endif 3346 3347 bool success = false; 3348 3349 uint32_t Rn; // the first operand 3350 uint32_t Rm; // the second operand 3351 ARM_ShifterType shift_t; 3352 uint32_t shift_n; // the shift applied to the value read from Rm 3353 switch (encoding) { 3354 case eEncodingT1: 3355 Rn = Bits32(opcode, 2, 0); 3356 Rm = Bits32(opcode, 5, 3); 3357 shift_t = SRType_LSL; 3358 shift_n = 0; 3359 break; 3360 case eEncodingT2: 3361 Rn = Bits32(opcode, 19, 16); 3362 Rm = Bits32(opcode, 3, 0); 3363 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3364 // if n == 15 || BadReg(m) then UNPREDICTABLE; 3365 if (Rn == 15 || BadReg(Rm)) 3366 return false; 3367 break; 3368 case eEncodingA1: 3369 Rn = Bits32(opcode, 19, 16); 3370 Rm = Bits32(opcode, 3, 0); 3371 shift_n = DecodeImmShiftARM(opcode, shift_t); 3372 break; 3373 default: 3374 return false; 3375 } 3376 // Read the register value from register Rn. 3377 uint32_t val1 = ReadCoreReg(Rn, &success); 3378 if (!success) 3379 return false; 3380 3381 // Read the register value from register Rm. 3382 uint32_t val2 = ReadCoreReg(Rm, &success); 3383 if (!success) 3384 return false; 3385 3386 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3387 if (!success) 3388 return false; 3389 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3390 3391 EmulateInstruction::Context context; 3392 context.type = EmulateInstruction::eContextImmediate; 3393 context.SetNoArgs(); 3394 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3395 } 3396 3397 // Compare (immediate) subtracts an immediate value from a register value. It 3398 // updates the condition flags based on the result, and discards the result. 3399 bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode, 3400 const ARMEncoding encoding) { 3401 #if 0 3402 // ARM pseudo code... 3403 if ConditionPassed() then 3404 EncodingSpecificOperations(); 3405 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 3406 APSR.N = result<31>; 3407 APSR.Z = IsZeroBit(result); 3408 APSR.C = carry; 3409 APSR.V = overflow; 3410 #endif 3411 3412 bool success = false; 3413 3414 uint32_t Rn; // the first operand 3415 uint32_t imm32; // the immediate value to be compared with 3416 switch (encoding) { 3417 case eEncodingT1: 3418 Rn = Bits32(opcode, 10, 8); 3419 imm32 = Bits32(opcode, 7, 0); 3420 break; 3421 case eEncodingT2: 3422 Rn = Bits32(opcode, 19, 16); 3423 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3424 if (Rn == 15) 3425 return false; 3426 break; 3427 case eEncodingA1: 3428 Rn = Bits32(opcode, 19, 16); 3429 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3430 break; 3431 default: 3432 return false; 3433 } 3434 // Read the register value from the operand register Rn. 3435 uint32_t reg_val = ReadCoreReg(Rn, &success); 3436 if (!success) 3437 return false; 3438 3439 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 3440 3441 EmulateInstruction::Context context; 3442 context.type = EmulateInstruction::eContextImmediate; 3443 context.SetNoArgs(); 3444 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3445 } 3446 3447 // Compare (register) subtracts an optionally-shifted register value from a 3448 // register value. It updates the condition flags based on the result, and 3449 // discards the result. 3450 bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode, 3451 const ARMEncoding encoding) { 3452 #if 0 3453 // ARM pseudo code... 3454 if ConditionPassed() then 3455 EncodingSpecificOperations(); 3456 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3457 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 3458 APSR.N = result<31>; 3459 APSR.Z = IsZeroBit(result); 3460 APSR.C = carry; 3461 APSR.V = overflow; 3462 #endif 3463 3464 bool success = false; 3465 3466 uint32_t Rn; // the first operand 3467 uint32_t Rm; // the second operand 3468 ARM_ShifterType shift_t; 3469 uint32_t shift_n; // the shift applied to the value read from Rm 3470 switch (encoding) { 3471 case eEncodingT1: 3472 Rn = Bits32(opcode, 2, 0); 3473 Rm = Bits32(opcode, 5, 3); 3474 shift_t = SRType_LSL; 3475 shift_n = 0; 3476 break; 3477 case eEncodingT2: 3478 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3479 Rm = Bits32(opcode, 6, 3); 3480 shift_t = SRType_LSL; 3481 shift_n = 0; 3482 if (Rn < 8 && Rm < 8) 3483 return false; 3484 if (Rn == 15 || Rm == 15) 3485 return false; 3486 break; 3487 case eEncodingT3: 3488 Rn = Bits32(opcode, 19, 16); 3489 Rm = Bits32(opcode, 3, 0); 3490 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3491 if (Rn == 15 || BadReg(Rm)) 3492 return false; 3493 break; 3494 case eEncodingA1: 3495 Rn = Bits32(opcode, 19, 16); 3496 Rm = Bits32(opcode, 3, 0); 3497 shift_n = DecodeImmShiftARM(opcode, shift_t); 3498 break; 3499 default: 3500 return false; 3501 } 3502 // Read the register value from register Rn. 3503 uint32_t val1 = ReadCoreReg(Rn, &success); 3504 if (!success) 3505 return false; 3506 3507 // Read the register value from register Rm. 3508 uint32_t val2 = ReadCoreReg(Rm, &success); 3509 if (!success) 3510 return false; 3511 3512 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3513 if (!success) 3514 return false; 3515 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3516 3517 EmulateInstruction::Context context; 3518 context.type = EmulateInstruction::eContextImmediate; 3519 context.SetNoArgs(); 3520 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3521 } 3522 3523 // Arithmetic Shift Right (immediate) shifts a register value right by an 3524 // immediate number of bits, shifting in copies of its sign bit, and writes the 3525 // result to the destination register. It can optionally update the condition 3526 // flags based on the result. 3527 bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode, 3528 const ARMEncoding encoding) { 3529 #if 0 3530 // ARM pseudo code... 3531 if ConditionPassed() then 3532 EncodingSpecificOperations(); 3533 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3534 if d == 15 then // Can only occur for ARM encoding 3535 ALUWritePC(result); // setflags is always FALSE here 3536 else 3537 R[d] = result; 3538 if setflags then 3539 APSR.N = result<31>; 3540 APSR.Z = IsZeroBit(result); 3541 APSR.C = carry; 3542 // APSR.V unchanged 3543 #endif 3544 3545 return EmulateShiftImm(opcode, encoding, SRType_ASR); 3546 } 3547 3548 // Arithmetic Shift Right (register) shifts a register value right by a 3549 // variable number of bits, shifting in copies of its sign bit, and writes the 3550 // result to the destination register. The variable number of bits is read from 3551 // the bottom byte of a register. It can optionally update the condition flags 3552 // based on the result. 3553 bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode, 3554 const ARMEncoding encoding) { 3555 #if 0 3556 // ARM pseudo code... 3557 if ConditionPassed() then 3558 EncodingSpecificOperations(); 3559 shift_n = UInt(R[m]<7:0>); 3560 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3561 R[d] = result; 3562 if setflags then 3563 APSR.N = result<31>; 3564 APSR.Z = IsZeroBit(result); 3565 APSR.C = carry; 3566 // APSR.V unchanged 3567 #endif 3568 3569 return EmulateShiftReg(opcode, encoding, SRType_ASR); 3570 } 3571 3572 // Logical Shift Left (immediate) shifts a register value left by an immediate 3573 // number of bits, shifting in zeros, and writes the result to the destination 3574 // register. It can optionally update the condition flags based on the result. 3575 bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode, 3576 const ARMEncoding encoding) { 3577 #if 0 3578 // ARM pseudo code... 3579 if ConditionPassed() then 3580 EncodingSpecificOperations(); 3581 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3582 if d == 15 then // Can only occur for ARM encoding 3583 ALUWritePC(result); // setflags is always FALSE here 3584 else 3585 R[d] = result; 3586 if setflags then 3587 APSR.N = result<31>; 3588 APSR.Z = IsZeroBit(result); 3589 APSR.C = carry; 3590 // APSR.V unchanged 3591 #endif 3592 3593 return EmulateShiftImm(opcode, encoding, SRType_LSL); 3594 } 3595 3596 // Logical Shift Left (register) shifts a register value left by a variable 3597 // number of bits, shifting in zeros, and writes the result to the destination 3598 // register. The variable number of bits is read from the bottom byte of a 3599 // register. It can optionally update the condition flags based on the result. 3600 bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode, 3601 const ARMEncoding encoding) { 3602 #if 0 3603 // ARM pseudo code... 3604 if ConditionPassed() then 3605 EncodingSpecificOperations(); 3606 shift_n = UInt(R[m]<7:0>); 3607 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3608 R[d] = result; 3609 if setflags then 3610 APSR.N = result<31>; 3611 APSR.Z = IsZeroBit(result); 3612 APSR.C = carry; 3613 // APSR.V unchanged 3614 #endif 3615 3616 return EmulateShiftReg(opcode, encoding, SRType_LSL); 3617 } 3618 3619 // Logical Shift Right (immediate) shifts a register value right by an 3620 // immediate number of bits, shifting in zeros, and writes the result to the 3621 // destination register. It can optionally update the condition flags based on 3622 // the result. 3623 bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode, 3624 const ARMEncoding encoding) { 3625 #if 0 3626 // ARM pseudo code... 3627 if ConditionPassed() then 3628 EncodingSpecificOperations(); 3629 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3630 if d == 15 then // Can only occur for ARM encoding 3631 ALUWritePC(result); // setflags is always FALSE here 3632 else 3633 R[d] = result; 3634 if setflags then 3635 APSR.N = result<31>; 3636 APSR.Z = IsZeroBit(result); 3637 APSR.C = carry; 3638 // APSR.V unchanged 3639 #endif 3640 3641 return EmulateShiftImm(opcode, encoding, SRType_LSR); 3642 } 3643 3644 // Logical Shift Right (register) shifts a register value right by a variable 3645 // number of bits, shifting in zeros, and writes the result to the destination 3646 // register. The variable number of bits is read from the bottom byte of a 3647 // register. It can optionally update the condition flags based on the result. 3648 bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode, 3649 const ARMEncoding encoding) { 3650 #if 0 3651 // ARM pseudo code... 3652 if ConditionPassed() then 3653 EncodingSpecificOperations(); 3654 shift_n = UInt(R[m]<7:0>); 3655 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3656 R[d] = result; 3657 if setflags then 3658 APSR.N = result<31>; 3659 APSR.Z = IsZeroBit(result); 3660 APSR.C = carry; 3661 // APSR.V unchanged 3662 #endif 3663 3664 return EmulateShiftReg(opcode, encoding, SRType_LSR); 3665 } 3666 3667 // Rotate Right (immediate) provides the value of the contents of a register 3668 // rotated by a constant value. The bits that are rotated off the right end are 3669 // inserted into the vacated bit positions on the left. It can optionally 3670 // update the condition flags based on the result. 3671 bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode, 3672 const ARMEncoding encoding) { 3673 #if 0 3674 // ARM pseudo code... 3675 if ConditionPassed() then 3676 EncodingSpecificOperations(); 3677 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3678 if d == 15 then // Can only occur for ARM encoding 3679 ALUWritePC(result); // setflags is always FALSE here 3680 else 3681 R[d] = result; 3682 if setflags then 3683 APSR.N = result<31>; 3684 APSR.Z = IsZeroBit(result); 3685 APSR.C = carry; 3686 // APSR.V unchanged 3687 #endif 3688 3689 return EmulateShiftImm(opcode, encoding, SRType_ROR); 3690 } 3691 3692 // Rotate Right (register) provides the value of the contents of a register 3693 // rotated by a variable number of bits. The bits that are rotated off the 3694 // right end are inserted into the vacated bit positions on the left. The 3695 // variable number of bits is read from the bottom byte of a register. It can 3696 // optionally update the condition flags based on the result. 3697 bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode, 3698 const ARMEncoding encoding) { 3699 #if 0 3700 // ARM pseudo code... 3701 if ConditionPassed() then 3702 EncodingSpecificOperations(); 3703 shift_n = UInt(R[m]<7:0>); 3704 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3705 R[d] = result; 3706 if setflags then 3707 APSR.N = result<31>; 3708 APSR.Z = IsZeroBit(result); 3709 APSR.C = carry; 3710 // APSR.V unchanged 3711 #endif 3712 3713 return EmulateShiftReg(opcode, encoding, SRType_ROR); 3714 } 3715 3716 // Rotate Right with Extend provides the value of the contents of a register 3717 // shifted right by one place, with the carry flag shifted into bit [31]. 3718 // 3719 // RRX can optionally update the condition flags based on the result. 3720 // In that case, bit [0] is shifted into the carry flag. 3721 bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode, 3722 const ARMEncoding encoding) { 3723 #if 0 3724 // ARM pseudo code... 3725 if ConditionPassed() then 3726 EncodingSpecificOperations(); 3727 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3728 if d == 15 then // Can only occur for ARM encoding 3729 ALUWritePC(result); // setflags is always FALSE here 3730 else 3731 R[d] = result; 3732 if setflags then 3733 APSR.N = result<31>; 3734 APSR.Z = IsZeroBit(result); 3735 APSR.C = carry; 3736 // APSR.V unchanged 3737 #endif 3738 3739 return EmulateShiftImm(opcode, encoding, SRType_RRX); 3740 } 3741 3742 bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode, 3743 const ARMEncoding encoding, 3744 ARM_ShifterType shift_type) { 3745 // assert(shift_type == SRType_ASR 3746 // || shift_type == SRType_LSL 3747 // || shift_type == SRType_LSR 3748 // || shift_type == SRType_ROR 3749 // || shift_type == SRType_RRX); 3750 3751 bool success = false; 3752 3753 if (ConditionPassed(opcode)) { 3754 uint32_t Rd; // the destination register 3755 uint32_t Rm; // the first operand register 3756 uint32_t imm5; // encoding for the shift amount 3757 uint32_t carry; // the carry bit after the shift operation 3758 bool setflags; 3759 3760 // Special case handling! 3761 // A8.6.139 ROR (immediate) -- Encoding T1 3762 ARMEncoding use_encoding = encoding; 3763 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) { 3764 // Morph the T1 encoding from the ARM Architecture Manual into T2 3765 // encoding to have the same decoding of bit fields as the other Thumb2 3766 // shift operations. 3767 use_encoding = eEncodingT2; 3768 } 3769 3770 switch (use_encoding) { 3771 case eEncodingT1: 3772 // Due to the above special case handling! 3773 if (shift_type == SRType_ROR) 3774 return false; 3775 3776 Rd = Bits32(opcode, 2, 0); 3777 Rm = Bits32(opcode, 5, 3); 3778 setflags = !InITBlock(); 3779 imm5 = Bits32(opcode, 10, 6); 3780 break; 3781 case eEncodingT2: 3782 // A8.6.141 RRX 3783 // There's no imm form of RRX instructions. 3784 if (shift_type == SRType_RRX) 3785 return false; 3786 3787 Rd = Bits32(opcode, 11, 8); 3788 Rm = Bits32(opcode, 3, 0); 3789 setflags = BitIsSet(opcode, 20); 3790 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3791 if (BadReg(Rd) || BadReg(Rm)) 3792 return false; 3793 break; 3794 case eEncodingA1: 3795 Rd = Bits32(opcode, 15, 12); 3796 Rm = Bits32(opcode, 3, 0); 3797 setflags = BitIsSet(opcode, 20); 3798 imm5 = Bits32(opcode, 11, 7); 3799 break; 3800 default: 3801 return false; 3802 } 3803 3804 // A8.6.139 ROR (immediate) 3805 if (shift_type == SRType_ROR && imm5 == 0) 3806 shift_type = SRType_RRX; 3807 3808 // Get the first operand. 3809 uint32_t value = ReadCoreReg(Rm, &success); 3810 if (!success) 3811 return false; 3812 3813 // Decode the shift amount if not RRX. 3814 uint32_t amt = 3815 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3816 3817 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3818 if (!success) 3819 return false; 3820 3821 // The context specifies that an immediate is to be moved into Rd. 3822 EmulateInstruction::Context context; 3823 context.type = EmulateInstruction::eContextImmediate; 3824 context.SetNoArgs(); 3825 3826 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3827 return false; 3828 } 3829 return true; 3830 } 3831 3832 bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode, 3833 const ARMEncoding encoding, 3834 ARM_ShifterType shift_type) { 3835 // assert(shift_type == SRType_ASR 3836 // || shift_type == SRType_LSL 3837 // || shift_type == SRType_LSR 3838 // || shift_type == SRType_ROR); 3839 3840 bool success = false; 3841 3842 if (ConditionPassed(opcode)) { 3843 uint32_t Rd; // the destination register 3844 uint32_t Rn; // the first operand register 3845 uint32_t 3846 Rm; // the register whose bottom byte contains the amount to shift by 3847 uint32_t carry; // the carry bit after the shift operation 3848 bool setflags; 3849 switch (encoding) { 3850 case eEncodingT1: 3851 Rd = Bits32(opcode, 2, 0); 3852 Rn = Rd; 3853 Rm = Bits32(opcode, 5, 3); 3854 setflags = !InITBlock(); 3855 break; 3856 case eEncodingT2: 3857 Rd = Bits32(opcode, 11, 8); 3858 Rn = Bits32(opcode, 19, 16); 3859 Rm = Bits32(opcode, 3, 0); 3860 setflags = BitIsSet(opcode, 20); 3861 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3862 return false; 3863 break; 3864 case eEncodingA1: 3865 Rd = Bits32(opcode, 15, 12); 3866 Rn = Bits32(opcode, 3, 0); 3867 Rm = Bits32(opcode, 11, 8); 3868 setflags = BitIsSet(opcode, 20); 3869 if (Rd == 15 || Rn == 15 || Rm == 15) 3870 return false; 3871 break; 3872 default: 3873 return false; 3874 } 3875 3876 // Get the first operand. 3877 uint32_t value = ReadCoreReg(Rn, &success); 3878 if (!success) 3879 return false; 3880 // Get the Rm register content. 3881 uint32_t val = ReadCoreReg(Rm, &success); 3882 if (!success) 3883 return false; 3884 3885 // Get the shift amount. 3886 uint32_t amt = Bits32(val, 7, 0); 3887 3888 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3889 if (!success) 3890 return false; 3891 3892 // The context specifies that an immediate is to be moved into Rd. 3893 EmulateInstruction::Context context; 3894 context.type = EmulateInstruction::eContextImmediate; 3895 context.SetNoArgs(); 3896 3897 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3898 return false; 3899 } 3900 return true; 3901 } 3902 3903 // LDM loads multiple registers from consecutive memory locations, using an 3904 // address from a base register. Optionally the address just above the highest 3905 // of those locations can be written back to the base register. 3906 bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode, 3907 const ARMEncoding encoding) { 3908 #if 0 3909 // ARM pseudo code... 3910 if ConditionPassed() 3911 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3912 address = R[n]; 3913 3914 for i = 0 to 14 3915 if registers<i> == '1' then 3916 R[i] = MemA[address, 4]; address = address + 4; 3917 if registers<15> == '1' then 3918 LoadWritePC (MemA[address, 4]); 3919 3920 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3921 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3922 3923 #endif 3924 3925 bool success = false; 3926 if (ConditionPassed(opcode)) { 3927 uint32_t n; 3928 uint32_t registers = 0; 3929 bool wback; 3930 const uint32_t addr_byte_size = GetAddressByteSize(); 3931 switch (encoding) { 3932 case eEncodingT1: 3933 // n = UInt(Rn); registers = '00000000':register_list; wback = 3934 // (registers<n> == '0'); 3935 n = Bits32(opcode, 10, 8); 3936 registers = Bits32(opcode, 7, 0); 3937 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3938 wback = BitIsClear(registers, n); 3939 // if BitCount(registers) < 1 then UNPREDICTABLE; 3940 if (BitCount(registers) < 1) 3941 return false; 3942 break; 3943 case eEncodingT2: 3944 // if W == '1' && Rn == '1101' then SEE POP; 3945 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3946 n = Bits32(opcode, 19, 16); 3947 registers = Bits32(opcode, 15, 0); 3948 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3949 wback = BitIsSet(opcode, 21); 3950 3951 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 3952 // UNPREDICTABLE; 3953 if ((n == 15) || (BitCount(registers) < 2) || 3954 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 3955 return false; 3956 3957 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 3958 // UNPREDICTABLE; 3959 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 3960 return false; 3961 3962 // if wback && registers<n> == '1' then UNPREDICTABLE; 3963 if (wback && BitIsSet(registers, n)) 3964 return false; 3965 break; 3966 3967 case eEncodingA1: 3968 n = Bits32(opcode, 19, 16); 3969 registers = Bits32(opcode, 15, 0); 3970 wback = BitIsSet(opcode, 21); 3971 if ((n == 15) || (BitCount(registers) < 1)) 3972 return false; 3973 break; 3974 default: 3975 return false; 3976 } 3977 3978 int32_t offset = 0; 3979 const addr_t base_address = 3980 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3981 if (!success) 3982 return false; 3983 3984 EmulateInstruction::Context context; 3985 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3986 RegisterInfo dwarf_reg; 3987 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3988 context.SetRegisterPlusOffset(dwarf_reg, offset); 3989 3990 for (int i = 0; i < 14; ++i) { 3991 if (BitIsSet(registers, i)) { 3992 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3993 context.SetRegisterPlusOffset(dwarf_reg, offset); 3994 if (wback && (n == 13)) // Pop Instruction 3995 { 3996 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3997 context.SetAddress(base_address + offset); 3998 } 3999 4000 // R[i] = MemA [address, 4]; address = address + 4; 4001 uint32_t data = MemARead(context, base_address + offset, addr_byte_size, 4002 0, &success); 4003 if (!success) 4004 return false; 4005 4006 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4007 data)) 4008 return false; 4009 4010 offset += addr_byte_size; 4011 } 4012 } 4013 4014 if (BitIsSet(registers, 15)) { 4015 // LoadWritePC (MemA [address, 4]); 4016 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4017 context.SetRegisterPlusOffset(dwarf_reg, offset); 4018 uint32_t data = 4019 MemARead(context, base_address + offset, addr_byte_size, 0, &success); 4020 if (!success) 4021 return false; 4022 // In ARMv5T and above, this is an interworking branch. 4023 if (!LoadWritePC(context, data)) 4024 return false; 4025 } 4026 4027 if (wback && BitIsClear(registers, n)) { 4028 // R[n] = R[n] + 4 * BitCount (registers) 4029 int32_t offset = addr_byte_size * BitCount(registers); 4030 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4031 context.SetRegisterPlusOffset(dwarf_reg, offset); 4032 4033 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4034 base_address + offset)) 4035 return false; 4036 } 4037 if (wback && BitIsSet(registers, n)) 4038 // R[n] bits(32) UNKNOWN; 4039 return WriteBits32Unknown(n); 4040 } 4041 return true; 4042 } 4043 4044 // LDMDA loads multiple registers from consecutive memory locations using an 4045 // address from a base register. 4046 // The consecutive memory locations end at this address and the address just 4047 // below the lowest of those locations can optionally be written back to the 4048 // base register. 4049 bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode, 4050 const ARMEncoding encoding) { 4051 #if 0 4052 // ARM pseudo code... 4053 if ConditionPassed() then 4054 EncodingSpecificOperations(); 4055 address = R[n] - 4*BitCount(registers) + 4; 4056 4057 for i = 0 to 14 4058 if registers<i> == '1' then 4059 R[i] = MemA[address,4]; address = address + 4; 4060 4061 if registers<15> == '1' then 4062 LoadWritePC(MemA[address,4]); 4063 4064 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4065 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4066 #endif 4067 4068 bool success = false; 4069 4070 if (ConditionPassed(opcode)) { 4071 uint32_t n; 4072 uint32_t registers = 0; 4073 bool wback; 4074 const uint32_t addr_byte_size = GetAddressByteSize(); 4075 4076 // EncodingSpecificOperations(); 4077 switch (encoding) { 4078 case eEncodingA1: 4079 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4080 n = Bits32(opcode, 19, 16); 4081 registers = Bits32(opcode, 15, 0); 4082 wback = BitIsSet(opcode, 21); 4083 4084 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4085 if ((n == 15) || (BitCount(registers) < 1)) 4086 return false; 4087 4088 break; 4089 4090 default: 4091 return false; 4092 } 4093 // address = R[n] - 4*BitCount(registers) + 4; 4094 4095 int32_t offset = 0; 4096 addr_t Rn = ReadCoreReg(n, &success); 4097 4098 if (!success) 4099 return false; 4100 4101 addr_t address = 4102 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size; 4103 4104 EmulateInstruction::Context context; 4105 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4106 RegisterInfo dwarf_reg; 4107 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4108 context.SetRegisterPlusOffset(dwarf_reg, offset); 4109 4110 // for i = 0 to 14 4111 for (int i = 0; i < 14; ++i) { 4112 // if registers<i> == '1' then 4113 if (BitIsSet(registers, i)) { 4114 // R[i] = MemA[address,4]; address = address + 4; 4115 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4116 uint32_t data = 4117 MemARead(context, address + offset, addr_byte_size, 0, &success); 4118 if (!success) 4119 return false; 4120 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4121 data)) 4122 return false; 4123 offset += addr_byte_size; 4124 } 4125 } 4126 4127 // if registers<15> == '1' then 4128 // LoadWritePC(MemA[address,4]); 4129 if (BitIsSet(registers, 15)) { 4130 context.SetRegisterPlusOffset(dwarf_reg, offset); 4131 uint32_t data = 4132 MemARead(context, address + offset, addr_byte_size, 0, &success); 4133 if (!success) 4134 return false; 4135 // In ARMv5T and above, this is an interworking branch. 4136 if (!LoadWritePC(context, data)) 4137 return false; 4138 } 4139 4140 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4141 if (wback && BitIsClear(registers, n)) { 4142 if (!success) 4143 return false; 4144 4145 offset = (addr_byte_size * BitCount(registers)) * -1; 4146 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4147 context.SetImmediateSigned(offset); 4148 addr_t addr = Rn + offset; 4149 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4150 addr)) 4151 return false; 4152 } 4153 4154 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4155 if (wback && BitIsSet(registers, n)) 4156 return WriteBits32Unknown(n); 4157 } 4158 return true; 4159 } 4160 4161 // LDMDB loads multiple registers from consecutive memory locations using an 4162 // address from a base register. The 4163 // consecutive memory locations end just below this address, and the address of 4164 // the lowest of those locations can be optionally written back to the base 4165 // register. 4166 bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode, 4167 const ARMEncoding encoding) { 4168 #if 0 4169 // ARM pseudo code... 4170 if ConditionPassed() then 4171 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4172 address = R[n] - 4*BitCount(registers); 4173 4174 for i = 0 to 14 4175 if registers<i> == '1' then 4176 R[i] = MemA[address,4]; address = address + 4; 4177 if registers<15> == '1' then 4178 LoadWritePC(MemA[address,4]); 4179 4180 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4181 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 4182 #endif 4183 4184 bool success = false; 4185 4186 if (ConditionPassed(opcode)) { 4187 uint32_t n; 4188 uint32_t registers = 0; 4189 bool wback; 4190 const uint32_t addr_byte_size = GetAddressByteSize(); 4191 switch (encoding) { 4192 case eEncodingT1: 4193 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 4194 n = Bits32(opcode, 19, 16); 4195 registers = Bits32(opcode, 15, 0); 4196 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 4197 wback = BitIsSet(opcode, 21); 4198 4199 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 4200 // UNPREDICTABLE; 4201 if ((n == 15) || (BitCount(registers) < 2) || 4202 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 4203 return false; 4204 4205 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 4206 // UNPREDICTABLE; 4207 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 4208 return false; 4209 4210 // if wback && registers<n> == '1' then UNPREDICTABLE; 4211 if (wback && BitIsSet(registers, n)) 4212 return false; 4213 4214 break; 4215 4216 case eEncodingA1: 4217 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4218 n = Bits32(opcode, 19, 16); 4219 registers = Bits32(opcode, 15, 0); 4220 wback = BitIsSet(opcode, 21); 4221 4222 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4223 if ((n == 15) || (BitCount(registers) < 1)) 4224 return false; 4225 4226 break; 4227 4228 default: 4229 return false; 4230 } 4231 4232 // address = R[n] - 4*BitCount(registers); 4233 4234 int32_t offset = 0; 4235 addr_t Rn = 4236 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4237 4238 if (!success) 4239 return false; 4240 4241 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4242 EmulateInstruction::Context context; 4243 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4244 RegisterInfo dwarf_reg; 4245 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4246 context.SetRegisterPlusOffset(dwarf_reg, Rn - address); 4247 4248 for (int i = 0; i < 14; ++i) { 4249 if (BitIsSet(registers, i)) { 4250 // R[i] = MemA[address,4]; address = address + 4; 4251 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4252 uint32_t data = 4253 MemARead(context, address + offset, addr_byte_size, 0, &success); 4254 if (!success) 4255 return false; 4256 4257 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4258 data)) 4259 return false; 4260 4261 offset += addr_byte_size; 4262 } 4263 } 4264 4265 // if registers<15> == '1' then 4266 // LoadWritePC(MemA[address,4]); 4267 if (BitIsSet(registers, 15)) { 4268 context.SetRegisterPlusOffset(dwarf_reg, offset); 4269 uint32_t data = 4270 MemARead(context, address + offset, addr_byte_size, 0, &success); 4271 if (!success) 4272 return false; 4273 // In ARMv5T and above, this is an interworking branch. 4274 if (!LoadWritePC(context, data)) 4275 return false; 4276 } 4277 4278 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4279 if (wback && BitIsClear(registers, n)) { 4280 if (!success) 4281 return false; 4282 4283 offset = (addr_byte_size * BitCount(registers)) * -1; 4284 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4285 context.SetImmediateSigned(offset); 4286 addr_t addr = Rn + offset; 4287 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4288 addr)) 4289 return false; 4290 } 4291 4292 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4293 // possible for encoding A1 4294 if (wback && BitIsSet(registers, n)) 4295 return WriteBits32Unknown(n); 4296 } 4297 return true; 4298 } 4299 4300 // LDMIB loads multiple registers from consecutive memory locations using an 4301 // address from a base register. The 4302 // consecutive memory locations start just above this address, and thea ddress 4303 // of the last of those locations can optinoally be written back to the base 4304 // register. 4305 bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode, 4306 const ARMEncoding encoding) { 4307 #if 0 4308 if ConditionPassed() then 4309 EncodingSpecificOperations(); 4310 address = R[n] + 4; 4311 4312 for i = 0 to 14 4313 if registers<i> == '1' then 4314 R[i] = MemA[address,4]; address = address + 4; 4315 if registers<15> == '1' then 4316 LoadWritePC(MemA[address,4]); 4317 4318 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4319 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4320 #endif 4321 4322 bool success = false; 4323 4324 if (ConditionPassed(opcode)) { 4325 uint32_t n; 4326 uint32_t registers = 0; 4327 bool wback; 4328 const uint32_t addr_byte_size = GetAddressByteSize(); 4329 switch (encoding) { 4330 case eEncodingA1: 4331 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4332 n = Bits32(opcode, 19, 16); 4333 registers = Bits32(opcode, 15, 0); 4334 wback = BitIsSet(opcode, 21); 4335 4336 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4337 if ((n == 15) || (BitCount(registers) < 1)) 4338 return false; 4339 4340 break; 4341 default: 4342 return false; 4343 } 4344 // address = R[n] + 4; 4345 4346 int32_t offset = 0; 4347 addr_t Rn = 4348 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4349 4350 if (!success) 4351 return false; 4352 4353 addr_t address = Rn + addr_byte_size; 4354 4355 EmulateInstruction::Context context; 4356 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4357 RegisterInfo dwarf_reg; 4358 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4359 context.SetRegisterPlusOffset(dwarf_reg, offset); 4360 4361 for (int i = 0; i < 14; ++i) { 4362 if (BitIsSet(registers, i)) { 4363 // R[i] = MemA[address,4]; address = address + 4; 4364 4365 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size); 4366 uint32_t data = 4367 MemARead(context, address + offset, addr_byte_size, 0, &success); 4368 if (!success) 4369 return false; 4370 4371 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4372 data)) 4373 return false; 4374 4375 offset += addr_byte_size; 4376 } 4377 } 4378 4379 // if registers<15> == '1' then 4380 // LoadWritePC(MemA[address,4]); 4381 if (BitIsSet(registers, 15)) { 4382 context.SetRegisterPlusOffset(dwarf_reg, offset); 4383 uint32_t data = 4384 MemARead(context, address + offset, addr_byte_size, 0, &success); 4385 if (!success) 4386 return false; 4387 // In ARMv5T and above, this is an interworking branch. 4388 if (!LoadWritePC(context, data)) 4389 return false; 4390 } 4391 4392 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4393 if (wback && BitIsClear(registers, n)) { 4394 if (!success) 4395 return false; 4396 4397 offset = addr_byte_size * BitCount(registers); 4398 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4399 context.SetImmediateSigned(offset); 4400 addr_t addr = Rn + offset; 4401 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4402 addr)) 4403 return false; 4404 } 4405 4406 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4407 // possible for encoding A1 4408 if (wback && BitIsSet(registers, n)) 4409 return WriteBits32Unknown(n); 4410 } 4411 return true; 4412 } 4413 4414 // Load Register (immediate) calculates an address from a base register value 4415 // and an immediate offset, loads a word from memory, and writes to a register. 4416 // LDR (immediate, Thumb) 4417 bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode, 4418 const ARMEncoding encoding) { 4419 #if 0 4420 // ARM pseudo code... 4421 if (ConditionPassed()) 4422 { 4423 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 4424 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4425 address = if index then offset_addr else R[n]; 4426 data = MemU[address,4]; 4427 if wback then R[n] = offset_addr; 4428 if t == 15 then 4429 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 4430 elsif UnalignedSupport() || address<1:0> = '00' then 4431 R[t] = data; 4432 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 4433 } 4434 #endif 4435 4436 bool success = false; 4437 4438 if (ConditionPassed(opcode)) { 4439 uint32_t Rt; // the destination register 4440 uint32_t Rn; // the base register 4441 uint32_t imm32; // the immediate offset used to form the address 4442 addr_t offset_addr; // the offset address 4443 addr_t address; // the calculated address 4444 uint32_t data; // the literal data value from memory load 4445 bool add, index, wback; 4446 switch (encoding) { 4447 case eEncodingT1: 4448 Rt = Bits32(opcode, 2, 0); 4449 Rn = Bits32(opcode, 5, 3); 4450 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 4451 // index = TRUE; add = TRUE; wback = FALSE 4452 add = true; 4453 index = true; 4454 wback = false; 4455 4456 break; 4457 4458 case eEncodingT2: 4459 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4460 Rt = Bits32(opcode, 10, 8); 4461 Rn = 13; 4462 imm32 = Bits32(opcode, 7, 0) << 2; 4463 4464 // index = TRUE; add = TRUE; wback = FALSE; 4465 index = true; 4466 add = true; 4467 wback = false; 4468 4469 break; 4470 4471 case eEncodingT3: 4472 // if Rn == '1111' then SEE LDR (literal); 4473 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4474 Rt = Bits32(opcode, 15, 12); 4475 Rn = Bits32(opcode, 19, 16); 4476 imm32 = Bits32(opcode, 11, 0); 4477 4478 // index = TRUE; add = TRUE; wback = FALSE; 4479 index = true; 4480 add = true; 4481 wback = false; 4482 4483 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4484 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4485 return false; 4486 4487 break; 4488 4489 case eEncodingT4: 4490 // if Rn == '1111' then SEE LDR (literal); 4491 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4492 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == 4493 // '00000100' then SEE POP; 4494 // if P == '0' && W == '0' then UNDEFINED; 4495 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 4496 return false; 4497 4498 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4499 Rt = Bits32(opcode, 15, 12); 4500 Rn = Bits32(opcode, 19, 16); 4501 imm32 = Bits32(opcode, 7, 0); 4502 4503 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4504 index = BitIsSet(opcode, 10); 4505 add = BitIsSet(opcode, 9); 4506 wback = BitIsSet(opcode, 8); 4507 4508 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) 4509 // then UNPREDICTABLE; 4510 if ((wback && (Rn == Rt)) || 4511 ((Rt == 15) && InITBlock() && !LastInITBlock())) 4512 return false; 4513 4514 break; 4515 4516 default: 4517 return false; 4518 } 4519 uint32_t base = ReadCoreReg(Rn, &success); 4520 if (!success) 4521 return false; 4522 if (add) 4523 offset_addr = base + imm32; 4524 else 4525 offset_addr = base - imm32; 4526 4527 address = (index ? offset_addr : base); 4528 4529 RegisterInfo base_reg; 4530 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4531 if (wback) { 4532 EmulateInstruction::Context ctx; 4533 if (Rn == 13) { 4534 ctx.type = eContextAdjustStackPointer; 4535 ctx.SetImmediateSigned((int32_t)(offset_addr - base)); 4536 } else if (Rn == GetFramePointerRegisterNumber()) { 4537 ctx.type = eContextSetFramePointer; 4538 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4539 } else { 4540 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4541 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4542 } 4543 4544 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn, 4545 offset_addr)) 4546 return false; 4547 } 4548 4549 // Prepare to write to the Rt register. 4550 EmulateInstruction::Context context; 4551 context.type = EmulateInstruction::eContextRegisterLoad; 4552 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4553 4554 // Read memory from the address. 4555 data = MemURead(context, address, 4, 0, &success); 4556 if (!success) 4557 return false; 4558 4559 if (Rt == 15) { 4560 if (Bits32(address, 1, 0) == 0) { 4561 if (!LoadWritePC(context, data)) 4562 return false; 4563 } else 4564 return false; 4565 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 4566 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 4567 data)) 4568 return false; 4569 } else 4570 WriteBits32Unknown(Rt); 4571 } 4572 return true; 4573 } 4574 4575 // STM (Store Multiple Increment After) stores multiple registers to consecutive 4576 // memory locations using an address 4577 // from a base register. The consecutive memory locations start at this 4578 // address, and the address just above the last of those locations can 4579 // optionally be written back to the base register. 4580 bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode, 4581 const ARMEncoding encoding) { 4582 #if 0 4583 if ConditionPassed() then 4584 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4585 address = R[n]; 4586 4587 for i = 0 to 14 4588 if registers<i> == '1' then 4589 if i == n && wback && i != LowestSetBit(registers) then 4590 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4591 else 4592 MemA[address,4] = R[i]; 4593 address = address + 4; 4594 4595 if registers<15> == '1' then // Only possible for encoding A1 4596 MemA[address,4] = PCStoreValue(); 4597 if wback then R[n] = R[n] + 4*BitCount(registers); 4598 #endif 4599 4600 bool success = false; 4601 4602 if (ConditionPassed(opcode)) { 4603 uint32_t n; 4604 uint32_t registers = 0; 4605 bool wback; 4606 const uint32_t addr_byte_size = GetAddressByteSize(); 4607 4608 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4609 switch (encoding) { 4610 case eEncodingT1: 4611 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4612 n = Bits32(opcode, 10, 8); 4613 registers = Bits32(opcode, 7, 0); 4614 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4615 wback = true; 4616 4617 // if BitCount(registers) < 1 then UNPREDICTABLE; 4618 if (BitCount(registers) < 1) 4619 return false; 4620 4621 break; 4622 4623 case eEncodingT2: 4624 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4625 n = Bits32(opcode, 19, 16); 4626 registers = Bits32(opcode, 15, 0); 4627 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4628 wback = BitIsSet(opcode, 21); 4629 4630 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4631 if ((n == 15) || (BitCount(registers) < 2)) 4632 return false; 4633 4634 // if wback && registers<n> == '1' then UNPREDICTABLE; 4635 if (wback && BitIsSet(registers, n)) 4636 return false; 4637 4638 break; 4639 4640 case eEncodingA1: 4641 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4642 n = Bits32(opcode, 19, 16); 4643 registers = Bits32(opcode, 15, 0); 4644 wback = BitIsSet(opcode, 21); 4645 4646 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4647 if ((n == 15) || (BitCount(registers) < 1)) 4648 return false; 4649 4650 break; 4651 4652 default: 4653 return false; 4654 } 4655 4656 // address = R[n]; 4657 int32_t offset = 0; 4658 const addr_t address = 4659 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4660 if (!success) 4661 return false; 4662 4663 EmulateInstruction::Context context; 4664 context.type = EmulateInstruction::eContextRegisterStore; 4665 RegisterInfo base_reg; 4666 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4667 4668 // for i = 0 to 14 4669 uint32_t lowest_set_bit = 14; 4670 for (uint32_t i = 0; i < 14; ++i) { 4671 // if registers<i> == '1' then 4672 if (BitIsSet(registers, i)) { 4673 if (i < lowest_set_bit) 4674 lowest_set_bit = i; 4675 // if i == n && wback && i != LowestSetBit(registers) then 4676 if ((i == n) && wback && (i != lowest_set_bit)) 4677 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings 4678 // T1 and A1 4679 WriteBits32UnknownToMemory(address + offset); 4680 else { 4681 // MemA[address,4] = R[i]; 4682 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4683 0, &success); 4684 if (!success) 4685 return false; 4686 4687 RegisterInfo data_reg; 4688 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4689 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 4690 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4691 return false; 4692 } 4693 4694 // address = address + 4; 4695 offset += addr_byte_size; 4696 } 4697 } 4698 4699 // if registers<15> == '1' then // Only possible for encoding A1 4700 // MemA[address,4] = PCStoreValue(); 4701 if (BitIsSet(registers, 15)) { 4702 RegisterInfo pc_reg; 4703 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4704 context.SetRegisterPlusOffset(pc_reg, 8); 4705 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4706 if (!success) 4707 return false; 4708 4709 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4710 return false; 4711 } 4712 4713 // if wback then R[n] = R[n] + 4*BitCount(registers); 4714 if (wback) { 4715 offset = addr_byte_size * BitCount(registers); 4716 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4717 context.SetImmediateSigned(offset); 4718 addr_t data = address + offset; 4719 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4720 data)) 4721 return false; 4722 } 4723 } 4724 return true; 4725 } 4726 4727 // STMDA (Store Multiple Decrement After) stores multiple registers to 4728 // consecutive memory locations using an address from a base register. The 4729 // consecutive memory locations end at this address, and the address just below 4730 // the lowest of those locations can optionally be written back to the base 4731 // register. 4732 bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode, 4733 const ARMEncoding encoding) { 4734 #if 0 4735 if ConditionPassed() then 4736 EncodingSpecificOperations(); 4737 address = R[n] - 4*BitCount(registers) + 4; 4738 4739 for i = 0 to 14 4740 if registers<i> == '1' then 4741 if i == n && wback && i != LowestSetBit(registers) then 4742 MemA[address,4] = bits(32) UNKNOWN; 4743 else 4744 MemA[address,4] = R[i]; 4745 address = address + 4; 4746 4747 if registers<15> == '1' then 4748 MemA[address,4] = PCStoreValue(); 4749 4750 if wback then R[n] = R[n] - 4*BitCount(registers); 4751 #endif 4752 4753 bool success = false; 4754 4755 if (ConditionPassed(opcode)) { 4756 uint32_t n; 4757 uint32_t registers = 0; 4758 bool wback; 4759 const uint32_t addr_byte_size = GetAddressByteSize(); 4760 4761 // EncodingSpecificOperations(); 4762 switch (encoding) { 4763 case eEncodingA1: 4764 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4765 n = Bits32(opcode, 19, 16); 4766 registers = Bits32(opcode, 15, 0); 4767 wback = BitIsSet(opcode, 21); 4768 4769 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4770 if ((n == 15) || (BitCount(registers) < 1)) 4771 return false; 4772 break; 4773 default: 4774 return false; 4775 } 4776 4777 // address = R[n] - 4*BitCount(registers) + 4; 4778 int32_t offset = 0; 4779 addr_t Rn = ReadCoreReg(n, &success); 4780 if (!success) 4781 return false; 4782 4783 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4; 4784 4785 EmulateInstruction::Context context; 4786 context.type = EmulateInstruction::eContextRegisterStore; 4787 RegisterInfo base_reg; 4788 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4789 4790 // for i = 0 to 14 4791 uint32_t lowest_bit_set = 14; 4792 for (uint32_t i = 0; i < 14; ++i) { 4793 // if registers<i> == '1' then 4794 if (BitIsSet(registers, i)) { 4795 if (i < lowest_bit_set) 4796 lowest_bit_set = i; 4797 // if i == n && wback && i != LowestSetBit(registers) then 4798 if ((i == n) && wback && (i != lowest_bit_set)) 4799 // MemA[address,4] = bits(32) UNKNOWN; 4800 WriteBits32UnknownToMemory(address + offset); 4801 else { 4802 // MemA[address,4] = R[i]; 4803 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4804 0, &success); 4805 if (!success) 4806 return false; 4807 4808 RegisterInfo data_reg; 4809 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4810 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4811 Rn - (address + offset)); 4812 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4813 return false; 4814 } 4815 4816 // address = address + 4; 4817 offset += addr_byte_size; 4818 } 4819 } 4820 4821 // if registers<15> == '1' then 4822 // MemA[address,4] = PCStoreValue(); 4823 if (BitIsSet(registers, 15)) { 4824 RegisterInfo pc_reg; 4825 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4826 context.SetRegisterPlusOffset(pc_reg, 8); 4827 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4828 if (!success) 4829 return false; 4830 4831 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4832 return false; 4833 } 4834 4835 // if wback then R[n] = R[n] - 4*BitCount(registers); 4836 if (wback) { 4837 offset = (addr_byte_size * BitCount(registers)) * -1; 4838 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4839 context.SetImmediateSigned(offset); 4840 addr_t data = Rn + offset; 4841 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4842 data)) 4843 return false; 4844 } 4845 } 4846 return true; 4847 } 4848 4849 // STMDB (Store Multiple Decrement Before) stores multiple registers to 4850 // consecutive memory locations using an address from a base register. The 4851 // consecutive memory locations end just below this address, and the address of 4852 // the first of those locations can optionally be written back to the base 4853 // register. 4854 bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode, 4855 const ARMEncoding encoding) { 4856 #if 0 4857 if ConditionPassed() then 4858 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4859 address = R[n] - 4*BitCount(registers); 4860 4861 for i = 0 to 14 4862 if registers<i> == '1' then 4863 if i == n && wback && i != LowestSetBit(registers) then 4864 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4865 else 4866 MemA[address,4] = R[i]; 4867 address = address + 4; 4868 4869 if registers<15> == '1' then // Only possible for encoding A1 4870 MemA[address,4] = PCStoreValue(); 4871 4872 if wback then R[n] = R[n] - 4*BitCount(registers); 4873 #endif 4874 4875 bool success = false; 4876 4877 if (ConditionPassed(opcode)) { 4878 uint32_t n; 4879 uint32_t registers = 0; 4880 bool wback; 4881 const uint32_t addr_byte_size = GetAddressByteSize(); 4882 4883 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4884 switch (encoding) { 4885 case eEncodingT1: 4886 // if W == '1' && Rn == '1101' then SEE PUSH; 4887 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) { 4888 // See PUSH 4889 } 4890 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4891 n = Bits32(opcode, 19, 16); 4892 registers = Bits32(opcode, 15, 0); 4893 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4894 wback = BitIsSet(opcode, 21); 4895 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4896 if ((n == 15) || BitCount(registers) < 2) 4897 return false; 4898 // if wback && registers<n> == '1' then UNPREDICTABLE; 4899 if (wback && BitIsSet(registers, n)) 4900 return false; 4901 break; 4902 4903 case eEncodingA1: 4904 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE 4905 // PUSH; 4906 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) && 4907 BitCount(Bits32(opcode, 15, 0)) >= 2) { 4908 // See Push 4909 } 4910 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4911 n = Bits32(opcode, 19, 16); 4912 registers = Bits32(opcode, 15, 0); 4913 wback = BitIsSet(opcode, 21); 4914 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4915 if ((n == 15) || BitCount(registers) < 1) 4916 return false; 4917 break; 4918 4919 default: 4920 return false; 4921 } 4922 4923 // address = R[n] - 4*BitCount(registers); 4924 4925 int32_t offset = 0; 4926 addr_t Rn = 4927 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4928 if (!success) 4929 return false; 4930 4931 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4932 4933 EmulateInstruction::Context context; 4934 context.type = EmulateInstruction::eContextRegisterStore; 4935 RegisterInfo base_reg; 4936 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4937 4938 // for i = 0 to 14 4939 uint32_t lowest_set_bit = 14; 4940 for (uint32_t i = 0; i < 14; ++i) { 4941 // if registers<i> == '1' then 4942 if (BitIsSet(registers, i)) { 4943 if (i < lowest_set_bit) 4944 lowest_set_bit = i; 4945 // if i == n && wback && i != LowestSetBit(registers) then 4946 if ((i == n) && wback && (i != lowest_set_bit)) 4947 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding 4948 // A1 4949 WriteBits32UnknownToMemory(address + offset); 4950 else { 4951 // MemA[address,4] = R[i]; 4952 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4953 0, &success); 4954 if (!success) 4955 return false; 4956 4957 RegisterInfo data_reg; 4958 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4959 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4960 Rn - (address + offset)); 4961 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4962 return false; 4963 } 4964 4965 // address = address + 4; 4966 offset += addr_byte_size; 4967 } 4968 } 4969 4970 // if registers<15> == '1' then // Only possible for encoding A1 4971 // MemA[address,4] = PCStoreValue(); 4972 if (BitIsSet(registers, 15)) { 4973 RegisterInfo pc_reg; 4974 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4975 context.SetRegisterPlusOffset(pc_reg, 8); 4976 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4977 if (!success) 4978 return false; 4979 4980 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4981 return false; 4982 } 4983 4984 // if wback then R[n] = R[n] - 4*BitCount(registers); 4985 if (wback) { 4986 offset = (addr_byte_size * BitCount(registers)) * -1; 4987 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4988 context.SetImmediateSigned(offset); 4989 addr_t data = Rn + offset; 4990 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4991 data)) 4992 return false; 4993 } 4994 } 4995 return true; 4996 } 4997 4998 // STMIB (Store Multiple Increment Before) stores multiple registers to 4999 // consecutive memory locations using an address from a base register. The 5000 // consecutive memory locations start just above this address, and the address 5001 // of the last of those locations can optionally be written back to the base 5002 // register. 5003 bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode, 5004 const ARMEncoding encoding) { 5005 #if 0 5006 if ConditionPassed() then 5007 EncodingSpecificOperations(); 5008 address = R[n] + 4; 5009 5010 for i = 0 to 14 5011 if registers<i> == '1' then 5012 if i == n && wback && i != LowestSetBit(registers) then 5013 MemA[address,4] = bits(32) UNKNOWN; 5014 else 5015 MemA[address,4] = R[i]; 5016 address = address + 4; 5017 5018 if registers<15> == '1' then 5019 MemA[address,4] = PCStoreValue(); 5020 5021 if wback then R[n] = R[n] + 4*BitCount(registers); 5022 #endif 5023 5024 bool success = false; 5025 5026 if (ConditionPassed(opcode)) { 5027 uint32_t n; 5028 uint32_t registers = 0; 5029 bool wback; 5030 const uint32_t addr_byte_size = GetAddressByteSize(); 5031 5032 // EncodingSpecificOperations(); 5033 switch (encoding) { 5034 case eEncodingA1: 5035 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 5036 n = Bits32(opcode, 19, 16); 5037 registers = Bits32(opcode, 15, 0); 5038 wback = BitIsSet(opcode, 21); 5039 5040 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 5041 if ((n == 15) && (BitCount(registers) < 1)) 5042 return false; 5043 break; 5044 default: 5045 return false; 5046 } 5047 // address = R[n] + 4; 5048 5049 int32_t offset = 0; 5050 addr_t Rn = ReadCoreReg(n, &success); 5051 if (!success) 5052 return false; 5053 5054 addr_t address = Rn + addr_byte_size; 5055 5056 EmulateInstruction::Context context; 5057 context.type = EmulateInstruction::eContextRegisterStore; 5058 RegisterInfo base_reg; 5059 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5060 5061 uint32_t lowest_set_bit = 14; 5062 // for i = 0 to 14 5063 for (uint32_t i = 0; i < 14; ++i) { 5064 // if registers<i> == '1' then 5065 if (BitIsSet(registers, i)) { 5066 if (i < lowest_set_bit) 5067 lowest_set_bit = i; 5068 // if i == n && wback && i != LowestSetBit(registers) then 5069 if ((i == n) && wback && (i != lowest_set_bit)) 5070 // MemA[address,4] = bits(32) UNKNOWN; 5071 WriteBits32UnknownToMemory(address + offset); 5072 // else 5073 else { 5074 // MemA[address,4] = R[i]; 5075 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5076 0, &success); 5077 if (!success) 5078 return false; 5079 5080 RegisterInfo data_reg; 5081 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5082 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5083 offset + addr_byte_size); 5084 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5085 return false; 5086 } 5087 5088 // address = address + 4; 5089 offset += addr_byte_size; 5090 } 5091 } 5092 5093 // if registers<15> == '1' then 5094 // MemA[address,4] = PCStoreValue(); 5095 if (BitIsSet(registers, 15)) { 5096 RegisterInfo pc_reg; 5097 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5098 context.SetRegisterPlusOffset(pc_reg, 8); 5099 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5100 if (!success) 5101 return false; 5102 5103 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5104 return false; 5105 } 5106 5107 // if wback then R[n] = R[n] + 4*BitCount(registers); 5108 if (wback) { 5109 offset = addr_byte_size * BitCount(registers); 5110 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5111 context.SetImmediateSigned(offset); 5112 addr_t data = Rn + offset; 5113 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5114 data)) 5115 return false; 5116 } 5117 } 5118 return true; 5119 } 5120 5121 // STR (store immediate) calculates an address from a base register value and an 5122 // immediate offset, and stores a word 5123 // from a register to memory. It can use offset, post-indexed, or pre-indexed 5124 // addressing. 5125 bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode, 5126 const ARMEncoding encoding) { 5127 #if 0 5128 if ConditionPassed() then 5129 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5130 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5131 address = if index then offset_addr else R[n]; 5132 if UnalignedSupport() || address<1:0> == '00' then 5133 MemU[address,4] = R[t]; 5134 else // Can only occur before ARMv7 5135 MemU[address,4] = bits(32) UNKNOWN; 5136 if wback then R[n] = offset_addr; 5137 #endif 5138 5139 bool success = false; 5140 5141 if (ConditionPassed(opcode)) { 5142 const uint32_t addr_byte_size = GetAddressByteSize(); 5143 5144 uint32_t t; 5145 uint32_t n; 5146 uint32_t imm32; 5147 bool index; 5148 bool add; 5149 bool wback; 5150 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5151 switch (encoding) { 5152 case eEncodingT1: 5153 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 5154 t = Bits32(opcode, 2, 0); 5155 n = Bits32(opcode, 5, 3); 5156 imm32 = Bits32(opcode, 10, 6) << 2; 5157 5158 // index = TRUE; add = TRUE; wback = FALSE; 5159 index = true; 5160 add = false; 5161 wback = false; 5162 break; 5163 5164 case eEncodingT2: 5165 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 5166 t = Bits32(opcode, 10, 8); 5167 n = 13; 5168 imm32 = Bits32(opcode, 7, 0) << 2; 5169 5170 // index = TRUE; add = TRUE; wback = FALSE; 5171 index = true; 5172 add = true; 5173 wback = false; 5174 break; 5175 5176 case eEncodingT3: 5177 // if Rn == '1111' then UNDEFINED; 5178 if (Bits32(opcode, 19, 16) == 15) 5179 return false; 5180 5181 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5182 t = Bits32(opcode, 15, 12); 5183 n = Bits32(opcode, 19, 16); 5184 imm32 = Bits32(opcode, 11, 0); 5185 5186 // index = TRUE; add = TRUE; wback = FALSE; 5187 index = true; 5188 add = true; 5189 wback = false; 5190 5191 // if t == 15 then UNPREDICTABLE; 5192 if (t == 15) 5193 return false; 5194 break; 5195 5196 case eEncodingT4: 5197 // if P == '1' && U == '1' && W == '0' then SEE STRT; 5198 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == 5199 // '00000100' then SEE PUSH; 5200 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5201 if ((Bits32(opcode, 19, 16) == 15) || 5202 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))) 5203 return false; 5204 5205 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5206 t = Bits32(opcode, 15, 12); 5207 n = Bits32(opcode, 19, 16); 5208 imm32 = Bits32(opcode, 7, 0); 5209 5210 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5211 index = BitIsSet(opcode, 10); 5212 add = BitIsSet(opcode, 9); 5213 wback = BitIsSet(opcode, 8); 5214 5215 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 5216 if ((t == 15) || (wback && (n == t))) 5217 return false; 5218 break; 5219 5220 default: 5221 return false; 5222 } 5223 5224 addr_t offset_addr; 5225 addr_t address; 5226 5227 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5228 uint32_t base_address = ReadCoreReg(n, &success); 5229 if (!success) 5230 return false; 5231 5232 if (add) 5233 offset_addr = base_address + imm32; 5234 else 5235 offset_addr = base_address - imm32; 5236 5237 // address = if index then offset_addr else R[n]; 5238 if (index) 5239 address = offset_addr; 5240 else 5241 address = base_address; 5242 5243 EmulateInstruction::Context context; 5244 if (n == 13) 5245 context.type = eContextPushRegisterOnStack; 5246 else 5247 context.type = eContextRegisterStore; 5248 5249 RegisterInfo base_reg; 5250 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5251 5252 // if UnalignedSupport() || address<1:0> == '00' then 5253 if (UnalignedSupport() || 5254 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 5255 // MemU[address,4] = R[t]; 5256 uint32_t data = 5257 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5258 if (!success) 5259 return false; 5260 5261 RegisterInfo data_reg; 5262 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5263 int32_t offset = address - base_address; 5264 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 5265 if (!MemUWrite(context, address, data, addr_byte_size)) 5266 return false; 5267 } else { 5268 // MemU[address,4] = bits(32) UNKNOWN; 5269 WriteBits32UnknownToMemory(address); 5270 } 5271 5272 // if wback then R[n] = offset_addr; 5273 if (wback) { 5274 if (n == 13) 5275 context.type = eContextAdjustStackPointer; 5276 else 5277 context.type = eContextAdjustBaseRegister; 5278 context.SetAddress(offset_addr); 5279 5280 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5281 offset_addr)) 5282 return false; 5283 } 5284 } 5285 return true; 5286 } 5287 5288 // STR (Store Register) calculates an address from a base register value and an 5289 // offset register value, stores a 5290 // word from a register to memory. The offset register value can optionally 5291 // be shifted. 5292 bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode, 5293 const ARMEncoding encoding) { 5294 #if 0 5295 if ConditionPassed() then 5296 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5297 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5298 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5299 address = if index then offset_addr else R[n]; 5300 if t == 15 then // Only possible for encoding A1 5301 data = PCStoreValue(); 5302 else 5303 data = R[t]; 5304 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 5305 MemU[address,4] = data; 5306 else // Can only occur before ARMv7 5307 MemU[address,4] = bits(32) UNKNOWN; 5308 if wback then R[n] = offset_addr; 5309 #endif 5310 5311 bool success = false; 5312 5313 if (ConditionPassed(opcode)) { 5314 const uint32_t addr_byte_size = GetAddressByteSize(); 5315 5316 uint32_t t; 5317 uint32_t n; 5318 uint32_t m; 5319 ARM_ShifterType shift_t; 5320 uint32_t shift_n; 5321 bool index; 5322 bool add; 5323 bool wback; 5324 5325 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5326 switch (encoding) { 5327 case eEncodingT1: 5328 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5329 // in ThumbEE"; 5330 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5331 t = Bits32(opcode, 2, 0); 5332 n = Bits32(opcode, 5, 3); 5333 m = Bits32(opcode, 8, 6); 5334 5335 // index = TRUE; add = TRUE; wback = FALSE; 5336 index = true; 5337 add = true; 5338 wback = false; 5339 5340 // (shift_t, shift_n) = (SRType_LSL, 0); 5341 shift_t = SRType_LSL; 5342 shift_n = 0; 5343 break; 5344 5345 case eEncodingT2: 5346 // if Rn == '1111' then UNDEFINED; 5347 if (Bits32(opcode, 19, 16) == 15) 5348 return false; 5349 5350 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5351 t = Bits32(opcode, 15, 12); 5352 n = Bits32(opcode, 19, 16); 5353 m = Bits32(opcode, 3, 0); 5354 5355 // index = TRUE; add = TRUE; wback = FALSE; 5356 index = true; 5357 add = true; 5358 wback = false; 5359 5360 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5361 shift_t = SRType_LSL; 5362 shift_n = Bits32(opcode, 5, 4); 5363 5364 // if t == 15 || BadReg(m) then UNPREDICTABLE; 5365 if ((t == 15) || (BadReg(m))) 5366 return false; 5367 break; 5368 5369 case eEncodingA1: { 5370 // if P == '0' && W == '1' then SEE STRT; 5371 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5372 t = Bits32(opcode, 15, 12); 5373 n = Bits32(opcode, 19, 16); 5374 m = Bits32(opcode, 3, 0); 5375 5376 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5377 // (W == '1'); 5378 index = BitIsSet(opcode, 24); 5379 add = BitIsSet(opcode, 23); 5380 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5381 5382 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5383 uint32_t typ = Bits32(opcode, 6, 5); 5384 uint32_t imm5 = Bits32(opcode, 11, 7); 5385 shift_n = DecodeImmShift(typ, imm5, shift_t); 5386 5387 // if m == 15 then UNPREDICTABLE; 5388 if (m == 15) 5389 return false; 5390 5391 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5392 if (wback && ((n == 15) || (n == t))) 5393 return false; 5394 5395 break; 5396 } 5397 default: 5398 return false; 5399 } 5400 5401 addr_t offset_addr; 5402 addr_t address; 5403 int32_t offset = 0; 5404 5405 addr_t base_address = 5406 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5407 if (!success) 5408 return false; 5409 5410 uint32_t Rm_data = 5411 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5412 if (!success) 5413 return false; 5414 5415 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5416 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success); 5417 if (!success) 5418 return false; 5419 5420 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5421 if (add) 5422 offset_addr = base_address + offset; 5423 else 5424 offset_addr = base_address - offset; 5425 5426 // address = if index then offset_addr else R[n]; 5427 if (index) 5428 address = offset_addr; 5429 else 5430 address = base_address; 5431 5432 uint32_t data; 5433 // if t == 15 then // Only possible for encoding A1 5434 if (t == 15) 5435 // data = PCStoreValue(); 5436 data = ReadCoreReg(PC_REG, &success); 5437 else 5438 // data = R[t]; 5439 data = 5440 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5441 5442 if (!success) 5443 return false; 5444 5445 EmulateInstruction::Context context; 5446 context.type = eContextRegisterStore; 5447 5448 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == 5449 // InstrSet_ARM then 5450 if (UnalignedSupport() || 5451 (BitIsClear(address, 1) && BitIsClear(address, 0)) || 5452 CurrentInstrSet() == eModeARM) { 5453 // MemU[address,4] = data; 5454 5455 RegisterInfo base_reg; 5456 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5457 5458 RegisterInfo data_reg; 5459 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5460 5461 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5462 address - base_address); 5463 if (!MemUWrite(context, address, data, addr_byte_size)) 5464 return false; 5465 5466 } else 5467 // MemU[address,4] = bits(32) UNKNOWN; 5468 WriteBits32UnknownToMemory(address); 5469 5470 // if wback then R[n] = offset_addr; 5471 if (wback) { 5472 context.type = eContextRegisterLoad; 5473 context.SetAddress(offset_addr); 5474 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5475 offset_addr)) 5476 return false; 5477 } 5478 } 5479 return true; 5480 } 5481 5482 bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode, 5483 const ARMEncoding encoding) { 5484 #if 0 5485 if ConditionPassed() then 5486 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5487 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5488 address = if index then offset_addr else R[n]; 5489 MemU[address,1] = R[t]<7:0>; 5490 if wback then R[n] = offset_addr; 5491 #endif 5492 5493 bool success = false; 5494 5495 if (ConditionPassed(opcode)) { 5496 uint32_t t; 5497 uint32_t n; 5498 uint32_t imm32; 5499 bool index; 5500 bool add; 5501 bool wback; 5502 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5503 switch (encoding) { 5504 case eEncodingT1: 5505 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5506 t = Bits32(opcode, 2, 0); 5507 n = Bits32(opcode, 5, 3); 5508 imm32 = Bits32(opcode, 10, 6); 5509 5510 // index = TRUE; add = TRUE; wback = FALSE; 5511 index = true; 5512 add = true; 5513 wback = false; 5514 break; 5515 5516 case eEncodingT2: 5517 // if Rn == '1111' then UNDEFINED; 5518 if (Bits32(opcode, 19, 16) == 15) 5519 return false; 5520 5521 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5522 t = Bits32(opcode, 15, 12); 5523 n = Bits32(opcode, 19, 16); 5524 imm32 = Bits32(opcode, 11, 0); 5525 5526 // index = TRUE; add = TRUE; wback = FALSE; 5527 index = true; 5528 add = true; 5529 wback = false; 5530 5531 // if BadReg(t) then UNPREDICTABLE; 5532 if (BadReg(t)) 5533 return false; 5534 break; 5535 5536 case eEncodingT3: 5537 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5538 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5539 if (Bits32(opcode, 19, 16) == 15) 5540 return false; 5541 5542 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5543 t = Bits32(opcode, 15, 12); 5544 n = Bits32(opcode, 19, 16); 5545 imm32 = Bits32(opcode, 7, 0); 5546 5547 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5548 index = BitIsSet(opcode, 10); 5549 add = BitIsSet(opcode, 9); 5550 wback = BitIsSet(opcode, 8); 5551 5552 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5553 if ((BadReg(t)) || (wback && (n == t))) 5554 return false; 5555 break; 5556 5557 default: 5558 return false; 5559 } 5560 5561 addr_t offset_addr; 5562 addr_t address; 5563 addr_t base_address = 5564 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5565 if (!success) 5566 return false; 5567 5568 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5569 if (add) 5570 offset_addr = base_address + imm32; 5571 else 5572 offset_addr = base_address - imm32; 5573 5574 // address = if index then offset_addr else R[n]; 5575 if (index) 5576 address = offset_addr; 5577 else 5578 address = base_address; 5579 5580 // MemU[address,1] = R[t]<7:0> 5581 RegisterInfo base_reg; 5582 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5583 5584 RegisterInfo data_reg; 5585 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5586 5587 EmulateInstruction::Context context; 5588 context.type = eContextRegisterStore; 5589 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5590 address - base_address); 5591 5592 uint32_t data = 5593 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5594 if (!success) 5595 return false; 5596 5597 data = Bits32(data, 7, 0); 5598 5599 if (!MemUWrite(context, address, data, 1)) 5600 return false; 5601 5602 // if wback then R[n] = offset_addr; 5603 if (wback) { 5604 context.type = eContextRegisterLoad; 5605 context.SetAddress(offset_addr); 5606 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5607 offset_addr)) 5608 return false; 5609 } 5610 } 5611 5612 return true; 5613 } 5614 5615 // STRH (register) calculates an address from a base register value and an 5616 // offset register value, and stores a 5617 // halfword from a register to memory. The offset register value can be 5618 // shifted left by 0, 1, 2, or 3 bits. 5619 bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode, 5620 const ARMEncoding encoding) { 5621 #if 0 5622 if ConditionPassed() then 5623 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5624 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5625 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5626 address = if index then offset_addr else R[n]; 5627 if UnalignedSupport() || address<0> == '0' then 5628 MemU[address,2] = R[t]<15:0>; 5629 else // Can only occur before ARMv7 5630 MemU[address,2] = bits(16) UNKNOWN; 5631 if wback then R[n] = offset_addr; 5632 #endif 5633 5634 bool success = false; 5635 5636 if (ConditionPassed(opcode)) { 5637 uint32_t t; 5638 uint32_t n; 5639 uint32_t m; 5640 bool index; 5641 bool add; 5642 bool wback; 5643 ARM_ShifterType shift_t; 5644 uint32_t shift_n; 5645 5646 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5647 switch (encoding) { 5648 case eEncodingT1: 5649 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5650 // in ThumbEE"; 5651 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5652 t = Bits32(opcode, 2, 0); 5653 n = Bits32(opcode, 5, 3); 5654 m = Bits32(opcode, 8, 6); 5655 5656 // index = TRUE; add = TRUE; wback = FALSE; 5657 index = true; 5658 add = true; 5659 wback = false; 5660 5661 // (shift_t, shift_n) = (SRType_LSL, 0); 5662 shift_t = SRType_LSL; 5663 shift_n = 0; 5664 5665 break; 5666 5667 case eEncodingT2: 5668 // if Rn == '1111' then UNDEFINED; 5669 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5670 t = Bits32(opcode, 15, 12); 5671 n = Bits32(opcode, 19, 16); 5672 m = Bits32(opcode, 3, 0); 5673 if (n == 15) 5674 return false; 5675 5676 // index = TRUE; add = TRUE; wback = FALSE; 5677 index = true; 5678 add = true; 5679 wback = false; 5680 5681 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5682 shift_t = SRType_LSL; 5683 shift_n = Bits32(opcode, 5, 4); 5684 5685 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5686 if (BadReg(t) || BadReg(m)) 5687 return false; 5688 5689 break; 5690 5691 case eEncodingA1: 5692 // if P == '0' && W == '1' then SEE STRHT; 5693 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5694 t = Bits32(opcode, 15, 12); 5695 n = Bits32(opcode, 19, 16); 5696 m = Bits32(opcode, 3, 0); 5697 5698 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5699 // (W == '1'); 5700 index = BitIsSet(opcode, 24); 5701 add = BitIsSet(opcode, 23); 5702 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5703 5704 // (shift_t, shift_n) = (SRType_LSL, 0); 5705 shift_t = SRType_LSL; 5706 shift_n = 0; 5707 5708 // if t == 15 || m == 15 then UNPREDICTABLE; 5709 if ((t == 15) || (m == 15)) 5710 return false; 5711 5712 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5713 if (wback && ((n == 15) || (n == t))) 5714 return false; 5715 5716 break; 5717 5718 default: 5719 return false; 5720 } 5721 5722 uint32_t Rm = ReadCoreReg(m, &success); 5723 if (!success) 5724 return false; 5725 5726 uint32_t Rn = ReadCoreReg(n, &success); 5727 if (!success) 5728 return false; 5729 5730 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5731 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 5732 if (!success) 5733 return false; 5734 5735 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5736 addr_t offset_addr; 5737 if (add) 5738 offset_addr = Rn + offset; 5739 else 5740 offset_addr = Rn - offset; 5741 5742 // address = if index then offset_addr else R[n]; 5743 addr_t address; 5744 if (index) 5745 address = offset_addr; 5746 else 5747 address = Rn; 5748 5749 EmulateInstruction::Context context; 5750 context.type = eContextRegisterStore; 5751 RegisterInfo base_reg; 5752 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5753 RegisterInfo offset_reg; 5754 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5755 5756 // if UnalignedSupport() || address<0> == '0' then 5757 if (UnalignedSupport() || BitIsClear(address, 0)) { 5758 // MemU[address,2] = R[t]<15:0>; 5759 uint32_t Rt = ReadCoreReg(t, &success); 5760 if (!success) 5761 return false; 5762 5763 EmulateInstruction::Context context; 5764 context.type = eContextRegisterStore; 5765 RegisterInfo base_reg; 5766 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5767 RegisterInfo offset_reg; 5768 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5769 RegisterInfo data_reg; 5770 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5771 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 5772 data_reg); 5773 5774 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2)) 5775 return false; 5776 } else // Can only occur before ARMv7 5777 { 5778 // MemU[address,2] = bits(16) UNKNOWN; 5779 } 5780 5781 // if wback then R[n] = offset_addr; 5782 if (wback) { 5783 context.type = eContextAdjustBaseRegister; 5784 context.SetAddress(offset_addr); 5785 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5786 offset_addr)) 5787 return false; 5788 } 5789 } 5790 5791 return true; 5792 } 5793 5794 // Add with Carry (immediate) adds an immediate value and the carry flag value 5795 // to a register value, and writes the result to the destination register. It 5796 // can optionally update the condition flags based on the result. 5797 bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode, 5798 const ARMEncoding encoding) { 5799 #if 0 5800 // ARM pseudo code... 5801 if ConditionPassed() then 5802 EncodingSpecificOperations(); 5803 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5804 if d == 15 then // Can only occur for ARM encoding 5805 ALUWritePC(result); // setflags is always FALSE here 5806 else 5807 R[d] = result; 5808 if setflags then 5809 APSR.N = result<31>; 5810 APSR.Z = IsZeroBit(result); 5811 APSR.C = carry; 5812 APSR.V = overflow; 5813 #endif 5814 5815 bool success = false; 5816 5817 if (ConditionPassed(opcode)) { 5818 uint32_t Rd, Rn; 5819 uint32_t 5820 imm32; // the immediate value to be added to the value obtained from Rn 5821 bool setflags; 5822 switch (encoding) { 5823 case eEncodingT1: 5824 Rd = Bits32(opcode, 11, 8); 5825 Rn = Bits32(opcode, 19, 16); 5826 setflags = BitIsSet(opcode, 20); 5827 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5828 if (BadReg(Rd) || BadReg(Rn)) 5829 return false; 5830 break; 5831 case eEncodingA1: 5832 Rd = Bits32(opcode, 15, 12); 5833 Rn = Bits32(opcode, 19, 16); 5834 setflags = BitIsSet(opcode, 20); 5835 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5836 5837 if (Rd == 15 && setflags) 5838 return EmulateSUBSPcLrEtc(opcode, encoding); 5839 break; 5840 default: 5841 return false; 5842 } 5843 5844 // Read the first operand. 5845 int32_t val1 = ReadCoreReg(Rn, &success); 5846 if (!success) 5847 return false; 5848 5849 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5850 5851 EmulateInstruction::Context context; 5852 context.type = EmulateInstruction::eContextImmediate; 5853 context.SetNoArgs(); 5854 5855 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5856 res.carry_out, res.overflow)) 5857 return false; 5858 } 5859 return true; 5860 } 5861 5862 // Add with Carry (register) adds a register value, the carry flag value, and 5863 // an optionally-shifted register value, and writes the result to the 5864 // destination register. It can optionally update the condition flags based on 5865 // the result. 5866 bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode, 5867 const ARMEncoding encoding) { 5868 #if 0 5869 // ARM pseudo code... 5870 if ConditionPassed() then 5871 EncodingSpecificOperations(); 5872 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5873 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5874 if d == 15 then // Can only occur for ARM encoding 5875 ALUWritePC(result); // setflags is always FALSE here 5876 else 5877 R[d] = result; 5878 if setflags then 5879 APSR.N = result<31>; 5880 APSR.Z = IsZeroBit(result); 5881 APSR.C = carry; 5882 APSR.V = overflow; 5883 #endif 5884 5885 bool success = false; 5886 5887 if (ConditionPassed(opcode)) { 5888 uint32_t Rd, Rn, Rm; 5889 ARM_ShifterType shift_t; 5890 uint32_t shift_n; // the shift applied to the value read from Rm 5891 bool setflags; 5892 switch (encoding) { 5893 case eEncodingT1: 5894 Rd = Rn = Bits32(opcode, 2, 0); 5895 Rm = Bits32(opcode, 5, 3); 5896 setflags = !InITBlock(); 5897 shift_t = SRType_LSL; 5898 shift_n = 0; 5899 break; 5900 case eEncodingT2: 5901 Rd = Bits32(opcode, 11, 8); 5902 Rn = Bits32(opcode, 19, 16); 5903 Rm = Bits32(opcode, 3, 0); 5904 setflags = BitIsSet(opcode, 20); 5905 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5906 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5907 return false; 5908 break; 5909 case eEncodingA1: 5910 Rd = Bits32(opcode, 15, 12); 5911 Rn = Bits32(opcode, 19, 16); 5912 Rm = Bits32(opcode, 3, 0); 5913 setflags = BitIsSet(opcode, 20); 5914 shift_n = DecodeImmShiftARM(opcode, shift_t); 5915 5916 if (Rd == 15 && setflags) 5917 return EmulateSUBSPcLrEtc(opcode, encoding); 5918 break; 5919 default: 5920 return false; 5921 } 5922 5923 // Read the first operand. 5924 int32_t val1 = ReadCoreReg(Rn, &success); 5925 if (!success) 5926 return false; 5927 5928 // Read the second operand. 5929 int32_t val2 = ReadCoreReg(Rm, &success); 5930 if (!success) 5931 return false; 5932 5933 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5934 if (!success) 5935 return false; 5936 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5937 5938 EmulateInstruction::Context context; 5939 context.type = EmulateInstruction::eContextImmediate; 5940 context.SetNoArgs(); 5941 5942 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5943 res.carry_out, res.overflow)) 5944 return false; 5945 } 5946 return true; 5947 } 5948 5949 // This instruction adds an immediate value to the PC value to form a PC- 5950 // relative address, and writes the result to the destination register. 5951 bool EmulateInstructionARM::EmulateADR(const uint32_t opcode, 5952 const ARMEncoding encoding) { 5953 #if 0 5954 // ARM pseudo code... 5955 if ConditionPassed() then 5956 EncodingSpecificOperations(); 5957 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5958 if d == 15 then // Can only occur for ARM encodings 5959 ALUWritePC(result); 5960 else 5961 R[d] = result; 5962 #endif 5963 5964 bool success = false; 5965 5966 if (ConditionPassed(opcode)) { 5967 uint32_t Rd; 5968 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5969 bool add; 5970 switch (encoding) { 5971 case eEncodingT1: 5972 Rd = Bits32(opcode, 10, 8); 5973 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5974 add = true; 5975 break; 5976 case eEncodingT2: 5977 case eEncodingT3: 5978 Rd = Bits32(opcode, 11, 8); 5979 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5980 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5981 if (BadReg(Rd)) 5982 return false; 5983 break; 5984 case eEncodingA1: 5985 case eEncodingA2: 5986 Rd = Bits32(opcode, 15, 12); 5987 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5988 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5989 break; 5990 default: 5991 return false; 5992 } 5993 5994 // Read the PC value. 5995 uint32_t pc = ReadCoreReg(PC_REG, &success); 5996 if (!success) 5997 return false; 5998 5999 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 6000 6001 EmulateInstruction::Context context; 6002 context.type = EmulateInstruction::eContextImmediate; 6003 context.SetNoArgs(); 6004 6005 if (!WriteCoreReg(context, result, Rd)) 6006 return false; 6007 } 6008 return true; 6009 } 6010 6011 // This instruction performs a bitwise AND of a register value and an immediate 6012 // value, and writes the result to the destination register. It can optionally 6013 // update the condition flags based on the result. 6014 bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode, 6015 const ARMEncoding encoding) { 6016 #if 0 6017 // ARM pseudo code... 6018 if ConditionPassed() then 6019 EncodingSpecificOperations(); 6020 result = R[n] AND imm32; 6021 if d == 15 then // Can only occur for ARM encoding 6022 ALUWritePC(result); // setflags is always FALSE here 6023 else 6024 R[d] = result; 6025 if setflags then 6026 APSR.N = result<31>; 6027 APSR.Z = IsZeroBit(result); 6028 APSR.C = carry; 6029 // APSR.V unchanged 6030 #endif 6031 6032 bool success = false; 6033 6034 if (ConditionPassed(opcode)) { 6035 uint32_t Rd, Rn; 6036 uint32_t 6037 imm32; // the immediate value to be ANDed to the value obtained from Rn 6038 bool setflags; 6039 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6040 switch (encoding) { 6041 case eEncodingT1: 6042 Rd = Bits32(opcode, 11, 8); 6043 Rn = Bits32(opcode, 19, 16); 6044 setflags = BitIsSet(opcode, 20); 6045 imm32 = ThumbExpandImm_C( 6046 opcode, APSR_C, 6047 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6048 // if Rd == '1111' && S == '1' then SEE TST (immediate); 6049 if (Rd == 15 && setflags) 6050 return EmulateTSTImm(opcode, eEncodingT1); 6051 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 6052 return false; 6053 break; 6054 case eEncodingA1: 6055 Rd = Bits32(opcode, 15, 12); 6056 Rn = Bits32(opcode, 19, 16); 6057 setflags = BitIsSet(opcode, 20); 6058 imm32 = 6059 ARMExpandImm_C(opcode, APSR_C, 6060 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6061 6062 if (Rd == 15 && setflags) 6063 return EmulateSUBSPcLrEtc(opcode, encoding); 6064 break; 6065 default: 6066 return false; 6067 } 6068 6069 // Read the first operand. 6070 uint32_t val1 = ReadCoreReg(Rn, &success); 6071 if (!success) 6072 return false; 6073 6074 uint32_t result = val1 & imm32; 6075 6076 EmulateInstruction::Context context; 6077 context.type = EmulateInstruction::eContextImmediate; 6078 context.SetNoArgs(); 6079 6080 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6081 return false; 6082 } 6083 return true; 6084 } 6085 6086 // This instruction performs a bitwise AND of a register value and an 6087 // optionally-shifted register value, and writes the result to the destination 6088 // register. It can optionally update the condition flags based on the result. 6089 bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode, 6090 const ARMEncoding encoding) { 6091 #if 0 6092 // ARM pseudo code... 6093 if ConditionPassed() then 6094 EncodingSpecificOperations(); 6095 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6096 result = R[n] AND shifted; 6097 if d == 15 then // Can only occur for ARM encoding 6098 ALUWritePC(result); // setflags is always FALSE here 6099 else 6100 R[d] = result; 6101 if setflags then 6102 APSR.N = result<31>; 6103 APSR.Z = IsZeroBit(result); 6104 APSR.C = carry; 6105 // APSR.V unchanged 6106 #endif 6107 6108 bool success = false; 6109 6110 if (ConditionPassed(opcode)) { 6111 uint32_t Rd, Rn, Rm; 6112 ARM_ShifterType shift_t; 6113 uint32_t shift_n; // the shift applied to the value read from Rm 6114 bool setflags; 6115 uint32_t carry; 6116 switch (encoding) { 6117 case eEncodingT1: 6118 Rd = Rn = Bits32(opcode, 2, 0); 6119 Rm = Bits32(opcode, 5, 3); 6120 setflags = !InITBlock(); 6121 shift_t = SRType_LSL; 6122 shift_n = 0; 6123 break; 6124 case eEncodingT2: 6125 Rd = Bits32(opcode, 11, 8); 6126 Rn = Bits32(opcode, 19, 16); 6127 Rm = Bits32(opcode, 3, 0); 6128 setflags = BitIsSet(opcode, 20); 6129 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6130 // if Rd == '1111' && S == '1' then SEE TST (register); 6131 if (Rd == 15 && setflags) 6132 return EmulateTSTReg(opcode, eEncodingT2); 6133 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 6134 return false; 6135 break; 6136 case eEncodingA1: 6137 Rd = Bits32(opcode, 15, 12); 6138 Rn = Bits32(opcode, 19, 16); 6139 Rm = Bits32(opcode, 3, 0); 6140 setflags = BitIsSet(opcode, 20); 6141 shift_n = DecodeImmShiftARM(opcode, shift_t); 6142 6143 if (Rd == 15 && setflags) 6144 return EmulateSUBSPcLrEtc(opcode, encoding); 6145 break; 6146 default: 6147 return false; 6148 } 6149 6150 // Read the first operand. 6151 uint32_t val1 = ReadCoreReg(Rn, &success); 6152 if (!success) 6153 return false; 6154 6155 // Read the second operand. 6156 uint32_t val2 = ReadCoreReg(Rm, &success); 6157 if (!success) 6158 return false; 6159 6160 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6161 if (!success) 6162 return false; 6163 uint32_t result = val1 & shifted; 6164 6165 EmulateInstruction::Context context; 6166 context.type = EmulateInstruction::eContextImmediate; 6167 context.SetNoArgs(); 6168 6169 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6170 return false; 6171 } 6172 return true; 6173 } 6174 6175 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and 6176 // the complement of an immediate value, and writes the result to the 6177 // destination register. It can optionally update the condition flags based on 6178 // the result. 6179 bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode, 6180 const ARMEncoding encoding) { 6181 #if 0 6182 // ARM pseudo code... 6183 if ConditionPassed() then 6184 EncodingSpecificOperations(); 6185 result = R[n] AND NOT(imm32); 6186 if d == 15 then // Can only occur for ARM encoding 6187 ALUWritePC(result); // setflags is always FALSE here 6188 else 6189 R[d] = result; 6190 if setflags then 6191 APSR.N = result<31>; 6192 APSR.Z = IsZeroBit(result); 6193 APSR.C = carry; 6194 // APSR.V unchanged 6195 #endif 6196 6197 bool success = false; 6198 6199 if (ConditionPassed(opcode)) { 6200 uint32_t Rd, Rn; 6201 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to 6202 // the value obtained from Rn 6203 bool setflags; 6204 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6205 switch (encoding) { 6206 case eEncodingT1: 6207 Rd = Bits32(opcode, 11, 8); 6208 Rn = Bits32(opcode, 19, 16); 6209 setflags = BitIsSet(opcode, 20); 6210 imm32 = ThumbExpandImm_C( 6211 opcode, APSR_C, 6212 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6213 if (BadReg(Rd) || BadReg(Rn)) 6214 return false; 6215 break; 6216 case eEncodingA1: 6217 Rd = Bits32(opcode, 15, 12); 6218 Rn = Bits32(opcode, 19, 16); 6219 setflags = BitIsSet(opcode, 20); 6220 imm32 = 6221 ARMExpandImm_C(opcode, APSR_C, 6222 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6223 6224 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6225 // instructions; 6226 if (Rd == 15 && setflags) 6227 return EmulateSUBSPcLrEtc(opcode, encoding); 6228 break; 6229 default: 6230 return false; 6231 } 6232 6233 // Read the first operand. 6234 uint32_t val1 = ReadCoreReg(Rn, &success); 6235 if (!success) 6236 return false; 6237 6238 uint32_t result = val1 & ~imm32; 6239 6240 EmulateInstruction::Context context; 6241 context.type = EmulateInstruction::eContextImmediate; 6242 context.SetNoArgs(); 6243 6244 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6245 return false; 6246 } 6247 return true; 6248 } 6249 6250 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and 6251 // the complement of an optionally-shifted register value, and writes the 6252 // result to the destination register. It can optionally update the condition 6253 // flags based on the result. 6254 bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode, 6255 const ARMEncoding encoding) { 6256 #if 0 6257 // ARM pseudo code... 6258 if ConditionPassed() then 6259 EncodingSpecificOperations(); 6260 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6261 result = R[n] AND NOT(shifted); 6262 if d == 15 then // Can only occur for ARM encoding 6263 ALUWritePC(result); // setflags is always FALSE here 6264 else 6265 R[d] = result; 6266 if setflags then 6267 APSR.N = result<31>; 6268 APSR.Z = IsZeroBit(result); 6269 APSR.C = carry; 6270 // APSR.V unchanged 6271 #endif 6272 6273 bool success = false; 6274 6275 if (ConditionPassed(opcode)) { 6276 uint32_t Rd, Rn, Rm; 6277 ARM_ShifterType shift_t; 6278 uint32_t shift_n; // the shift applied to the value read from Rm 6279 bool setflags; 6280 uint32_t carry; 6281 switch (encoding) { 6282 case eEncodingT1: 6283 Rd = Rn = Bits32(opcode, 2, 0); 6284 Rm = Bits32(opcode, 5, 3); 6285 setflags = !InITBlock(); 6286 shift_t = SRType_LSL; 6287 shift_n = 0; 6288 break; 6289 case eEncodingT2: 6290 Rd = Bits32(opcode, 11, 8); 6291 Rn = Bits32(opcode, 19, 16); 6292 Rm = Bits32(opcode, 3, 0); 6293 setflags = BitIsSet(opcode, 20); 6294 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6295 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 6296 return false; 6297 break; 6298 case eEncodingA1: 6299 Rd = Bits32(opcode, 15, 12); 6300 Rn = Bits32(opcode, 19, 16); 6301 Rm = Bits32(opcode, 3, 0); 6302 setflags = BitIsSet(opcode, 20); 6303 shift_n = DecodeImmShiftARM(opcode, shift_t); 6304 6305 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6306 // instructions; 6307 if (Rd == 15 && setflags) 6308 return EmulateSUBSPcLrEtc(opcode, encoding); 6309 break; 6310 default: 6311 return false; 6312 } 6313 6314 // Read the first operand. 6315 uint32_t val1 = ReadCoreReg(Rn, &success); 6316 if (!success) 6317 return false; 6318 6319 // Read the second operand. 6320 uint32_t val2 = ReadCoreReg(Rm, &success); 6321 if (!success) 6322 return false; 6323 6324 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6325 if (!success) 6326 return false; 6327 uint32_t result = val1 & ~shifted; 6328 6329 EmulateInstruction::Context context; 6330 context.type = EmulateInstruction::eContextImmediate; 6331 context.SetNoArgs(); 6332 6333 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6334 return false; 6335 } 6336 return true; 6337 } 6338 6339 // LDR (immediate, ARM) calculates an address from a base register value and an 6340 // immediate offset, loads a word 6341 // from memory, and writes it to a register. It can use offset, post-indexed, 6342 // or pre-indexed addressing. 6343 bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode, 6344 const ARMEncoding encoding) { 6345 #if 0 6346 if ConditionPassed() then 6347 EncodingSpecificOperations(); 6348 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6349 address = if index then offset_addr else R[n]; 6350 data = MemU[address,4]; 6351 if wback then R[n] = offset_addr; 6352 if t == 15 then 6353 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6354 elsif UnalignedSupport() || address<1:0> = '00' then 6355 R[t] = data; 6356 else // Can only apply before ARMv7 6357 R[t] = ROR(data, 8*UInt(address<1:0>)); 6358 #endif 6359 6360 bool success = false; 6361 6362 if (ConditionPassed(opcode)) { 6363 const uint32_t addr_byte_size = GetAddressByteSize(); 6364 6365 uint32_t t; 6366 uint32_t n; 6367 uint32_t imm32; 6368 bool index; 6369 bool add; 6370 bool wback; 6371 6372 switch (encoding) { 6373 case eEncodingA1: 6374 // if Rn == '1111' then SEE LDR (literal); 6375 // if P == '0' && W == '1' then SEE LDRT; 6376 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == 6377 // '000000000100' then SEE POP; 6378 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6379 t = Bits32(opcode, 15, 12); 6380 n = Bits32(opcode, 19, 16); 6381 imm32 = Bits32(opcode, 11, 0); 6382 6383 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6384 // (W == '1'); 6385 index = BitIsSet(opcode, 24); 6386 add = BitIsSet(opcode, 23); 6387 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6388 6389 // if wback && n == t then UNPREDICTABLE; 6390 if (wback && (n == t)) 6391 return false; 6392 6393 break; 6394 6395 default: 6396 return false; 6397 } 6398 6399 addr_t address; 6400 addr_t offset_addr; 6401 addr_t base_address = ReadCoreReg(n, &success); 6402 if (!success) 6403 return false; 6404 6405 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6406 if (add) 6407 offset_addr = base_address + imm32; 6408 else 6409 offset_addr = base_address - imm32; 6410 6411 // address = if index then offset_addr else R[n]; 6412 if (index) 6413 address = offset_addr; 6414 else 6415 address = base_address; 6416 6417 // data = MemU[address,4]; 6418 6419 RegisterInfo base_reg; 6420 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6421 6422 EmulateInstruction::Context context; 6423 context.type = eContextRegisterLoad; 6424 context.SetRegisterPlusOffset(base_reg, address - base_address); 6425 6426 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6427 if (!success) 6428 return false; 6429 6430 // if wback then R[n] = offset_addr; 6431 if (wback) { 6432 context.type = eContextAdjustBaseRegister; 6433 context.SetAddress(offset_addr); 6434 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6435 offset_addr)) 6436 return false; 6437 } 6438 6439 // if t == 15 then 6440 if (t == 15) { 6441 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6442 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6443 // LoadWritePC (data); 6444 context.type = eContextRegisterLoad; 6445 context.SetRegisterPlusOffset(base_reg, address - base_address); 6446 LoadWritePC(context, data); 6447 } else 6448 return false; 6449 } 6450 // elsif UnalignedSupport() || address<1:0> = '00' then 6451 else if (UnalignedSupport() || 6452 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6453 // R[t] = data; 6454 context.type = eContextRegisterLoad; 6455 context.SetRegisterPlusOffset(base_reg, address - base_address); 6456 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6457 data)) 6458 return false; 6459 } 6460 // else // Can only apply before ARMv7 6461 else { 6462 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6463 data = ROR(data, Bits32(address, 1, 0), &success); 6464 if (!success) 6465 return false; 6466 context.type = eContextRegisterLoad; 6467 context.SetImmediate(data); 6468 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6469 data)) 6470 return false; 6471 } 6472 } 6473 return true; 6474 } 6475 6476 // LDR (register) calculates an address from a base register value and an offset 6477 // register value, loads a word 6478 // from memory, and writes it to a register. The offset register value can 6479 // optionally be shifted. 6480 bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode, 6481 const ARMEncoding encoding) { 6482 #if 0 6483 if ConditionPassed() then 6484 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6485 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6486 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6487 address = if index then offset_addr else R[n]; 6488 data = MemU[address,4]; 6489 if wback then R[n] = offset_addr; 6490 if t == 15 then 6491 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6492 elsif UnalignedSupport() || address<1:0> = '00' then 6493 R[t] = data; 6494 else // Can only apply before ARMv7 6495 if CurrentInstrSet() == InstrSet_ARM then 6496 R[t] = ROR(data, 8*UInt(address<1:0>)); 6497 else 6498 R[t] = bits(32) UNKNOWN; 6499 #endif 6500 6501 bool success = false; 6502 6503 if (ConditionPassed(opcode)) { 6504 const uint32_t addr_byte_size = GetAddressByteSize(); 6505 6506 uint32_t t; 6507 uint32_t n; 6508 uint32_t m; 6509 bool index; 6510 bool add; 6511 bool wback; 6512 ARM_ShifterType shift_t; 6513 uint32_t shift_n; 6514 6515 switch (encoding) { 6516 case eEncodingT1: 6517 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 6518 // in ThumbEE"; 6519 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6520 t = Bits32(opcode, 2, 0); 6521 n = Bits32(opcode, 5, 3); 6522 m = Bits32(opcode, 8, 6); 6523 6524 // index = TRUE; add = TRUE; wback = FALSE; 6525 index = true; 6526 add = true; 6527 wback = false; 6528 6529 // (shift_t, shift_n) = (SRType_LSL, 0); 6530 shift_t = SRType_LSL; 6531 shift_n = 0; 6532 6533 break; 6534 6535 case eEncodingT2: 6536 // if Rn == '1111' then SEE LDR (literal); 6537 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6538 t = Bits32(opcode, 15, 12); 6539 n = Bits32(opcode, 19, 16); 6540 m = Bits32(opcode, 3, 0); 6541 6542 // index = TRUE; add = TRUE; wback = FALSE; 6543 index = true; 6544 add = true; 6545 wback = false; 6546 6547 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6548 shift_t = SRType_LSL; 6549 shift_n = Bits32(opcode, 5, 4); 6550 6551 // if BadReg(m) then UNPREDICTABLE; 6552 if (BadReg(m)) 6553 return false; 6554 6555 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6556 if ((t == 15) && InITBlock() && !LastInITBlock()) 6557 return false; 6558 6559 break; 6560 6561 case eEncodingA1: { 6562 // if P == '0' && W == '1' then SEE LDRT; 6563 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6564 t = Bits32(opcode, 15, 12); 6565 n = Bits32(opcode, 19, 16); 6566 m = Bits32(opcode, 3, 0); 6567 6568 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6569 // (W == '1'); 6570 index = BitIsSet(opcode, 24); 6571 add = BitIsSet(opcode, 23); 6572 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6573 6574 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6575 uint32_t type = Bits32(opcode, 6, 5); 6576 uint32_t imm5 = Bits32(opcode, 11, 7); 6577 shift_n = DecodeImmShift(type, imm5, shift_t); 6578 6579 // if m == 15 then UNPREDICTABLE; 6580 if (m == 15) 6581 return false; 6582 6583 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6584 if (wback && ((n == 15) || (n == t))) 6585 return false; 6586 } break; 6587 6588 default: 6589 return false; 6590 } 6591 6592 uint32_t Rm = 6593 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6594 if (!success) 6595 return false; 6596 6597 uint32_t Rn = 6598 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6599 if (!success) 6600 return false; 6601 6602 addr_t offset_addr; 6603 addr_t address; 6604 6605 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is 6606 // an application level alias for the CPSR". 6607 addr_t offset = 6608 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success); 6609 if (!success) 6610 return false; 6611 6612 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6613 if (add) 6614 offset_addr = Rn + offset; 6615 else 6616 offset_addr = Rn - offset; 6617 6618 // address = if index then offset_addr else R[n]; 6619 if (index) 6620 address = offset_addr; 6621 else 6622 address = Rn; 6623 6624 // data = MemU[address,4]; 6625 RegisterInfo base_reg; 6626 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6627 6628 EmulateInstruction::Context context; 6629 context.type = eContextRegisterLoad; 6630 context.SetRegisterPlusOffset(base_reg, address - Rn); 6631 6632 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6633 if (!success) 6634 return false; 6635 6636 // if wback then R[n] = offset_addr; 6637 if (wback) { 6638 context.type = eContextAdjustBaseRegister; 6639 context.SetAddress(offset_addr); 6640 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6641 offset_addr)) 6642 return false; 6643 } 6644 6645 // if t == 15 then 6646 if (t == 15) { 6647 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6648 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6649 context.type = eContextRegisterLoad; 6650 context.SetRegisterPlusOffset(base_reg, address - Rn); 6651 LoadWritePC(context, data); 6652 } else 6653 return false; 6654 } 6655 // elsif UnalignedSupport() || address<1:0> = '00' then 6656 else if (UnalignedSupport() || 6657 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6658 // R[t] = data; 6659 context.type = eContextRegisterLoad; 6660 context.SetRegisterPlusOffset(base_reg, address - Rn); 6661 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6662 data)) 6663 return false; 6664 } else // Can only apply before ARMv7 6665 { 6666 // if CurrentInstrSet() == InstrSet_ARM then 6667 if (CurrentInstrSet() == eModeARM) { 6668 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6669 data = ROR(data, Bits32(address, 1, 0), &success); 6670 if (!success) 6671 return false; 6672 context.type = eContextRegisterLoad; 6673 context.SetImmediate(data); 6674 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6675 data)) 6676 return false; 6677 } else { 6678 // R[t] = bits(32) UNKNOWN; 6679 WriteBits32Unknown(t); 6680 } 6681 } 6682 } 6683 return true; 6684 } 6685 6686 // LDRB (immediate, Thumb) 6687 bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode, 6688 const ARMEncoding encoding) { 6689 #if 0 6690 if ConditionPassed() then 6691 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6692 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6693 address = if index then offset_addr else R[n]; 6694 R[t] = ZeroExtend(MemU[address,1], 32); 6695 if wback then R[n] = offset_addr; 6696 #endif 6697 6698 bool success = false; 6699 6700 if (ConditionPassed(opcode)) { 6701 uint32_t t; 6702 uint32_t n; 6703 uint32_t imm32; 6704 bool index; 6705 bool add; 6706 bool wback; 6707 6708 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6709 switch (encoding) { 6710 case eEncodingT1: 6711 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6712 t = Bits32(opcode, 2, 0); 6713 n = Bits32(opcode, 5, 3); 6714 imm32 = Bits32(opcode, 10, 6); 6715 6716 // index = TRUE; add = TRUE; wback = FALSE; 6717 index = true; 6718 add = true; 6719 wback = false; 6720 6721 break; 6722 6723 case eEncodingT2: 6724 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6725 t = Bits32(opcode, 15, 12); 6726 n = Bits32(opcode, 19, 16); 6727 imm32 = Bits32(opcode, 11, 0); 6728 6729 // index = TRUE; add = TRUE; wback = FALSE; 6730 index = true; 6731 add = true; 6732 wback = false; 6733 6734 // if Rt == '1111' then SEE PLD; 6735 if (t == 15) 6736 return false; // PLD is not implemented yet 6737 6738 // if Rn == '1111' then SEE LDRB (literal); 6739 if (n == 15) 6740 return EmulateLDRBLiteral(opcode, eEncodingT1); 6741 6742 // if t == 13 then UNPREDICTABLE; 6743 if (t == 13) 6744 return false; 6745 6746 break; 6747 6748 case eEncodingT3: 6749 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6750 // if P == '0' && W == '0' then UNDEFINED; 6751 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 6752 return false; 6753 6754 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6755 t = Bits32(opcode, 15, 12); 6756 n = Bits32(opcode, 19, 16); 6757 imm32 = Bits32(opcode, 7, 0); 6758 6759 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6760 index = BitIsSet(opcode, 10); 6761 add = BitIsSet(opcode, 9); 6762 wback = BitIsSet(opcode, 8); 6763 6764 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6765 if (t == 15) 6766 return false; // PLD is not implemented yet 6767 6768 // if Rn == '1111' then SEE LDRB (literal); 6769 if (n == 15) 6770 return EmulateLDRBLiteral(opcode, eEncodingT1); 6771 6772 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6773 if (BadReg(t) || (wback && (n == t))) 6774 return false; 6775 6776 break; 6777 6778 default: 6779 return false; 6780 } 6781 6782 uint32_t Rn = 6783 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6784 if (!success) 6785 return false; 6786 6787 addr_t address; 6788 addr_t offset_addr; 6789 6790 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6791 if (add) 6792 offset_addr = Rn + imm32; 6793 else 6794 offset_addr = Rn - imm32; 6795 6796 // address = if index then offset_addr else R[n]; 6797 if (index) 6798 address = offset_addr; 6799 else 6800 address = Rn; 6801 6802 // R[t] = ZeroExtend(MemU[address,1], 32); 6803 RegisterInfo base_reg; 6804 RegisterInfo data_reg; 6805 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6806 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6807 6808 EmulateInstruction::Context context; 6809 context.type = eContextRegisterLoad; 6810 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 6811 6812 uint64_t data = MemURead(context, address, 1, 0, &success); 6813 if (!success) 6814 return false; 6815 6816 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6817 return false; 6818 6819 // if wback then R[n] = offset_addr; 6820 if (wback) { 6821 context.type = eContextAdjustBaseRegister; 6822 context.SetAddress(offset_addr); 6823 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6824 offset_addr)) 6825 return false; 6826 } 6827 } 6828 return true; 6829 } 6830 6831 // LDRB (literal) calculates an address from the PC value and an immediate 6832 // offset, loads a byte from memory, 6833 // zero-extends it to form a 32-bit word and writes it to a register. 6834 bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode, 6835 const ARMEncoding encoding) { 6836 #if 0 6837 if ConditionPassed() then 6838 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6839 base = Align(PC,4); 6840 address = if add then (base + imm32) else (base - imm32); 6841 R[t] = ZeroExtend(MemU[address,1], 32); 6842 #endif 6843 6844 bool success = false; 6845 6846 if (ConditionPassed(opcode)) { 6847 uint32_t t; 6848 uint32_t imm32; 6849 bool add; 6850 switch (encoding) { 6851 case eEncodingT1: 6852 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6853 t = Bits32(opcode, 15, 12); 6854 imm32 = Bits32(opcode, 11, 0); 6855 add = BitIsSet(opcode, 23); 6856 6857 // if Rt == '1111' then SEE PLD; 6858 if (t == 15) 6859 return false; // PLD is not implemented yet 6860 6861 // if t == 13 then UNPREDICTABLE; 6862 if (t == 13) 6863 return false; 6864 6865 break; 6866 6867 case eEncodingA1: 6868 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6869 t = Bits32(opcode, 15, 12); 6870 imm32 = Bits32(opcode, 11, 0); 6871 add = BitIsSet(opcode, 23); 6872 6873 // if t == 15 then UNPREDICTABLE; 6874 if (t == 15) 6875 return false; 6876 break; 6877 6878 default: 6879 return false; 6880 } 6881 6882 // base = Align(PC,4); 6883 uint32_t pc_val = ReadCoreReg(PC_REG, &success); 6884 if (!success) 6885 return false; 6886 6887 uint32_t base = AlignPC(pc_val); 6888 6889 addr_t address; 6890 // address = if add then (base + imm32) else (base - imm32); 6891 if (add) 6892 address = base + imm32; 6893 else 6894 address = base - imm32; 6895 6896 // R[t] = ZeroExtend(MemU[address,1], 32); 6897 EmulateInstruction::Context context; 6898 context.type = eContextRelativeBranchImmediate; 6899 context.SetImmediate(address - base); 6900 6901 uint64_t data = MemURead(context, address, 1, 0, &success); 6902 if (!success) 6903 return false; 6904 6905 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6906 return false; 6907 } 6908 return true; 6909 } 6910 6911 // LDRB (register) calculates an address from a base register value and an 6912 // offset rigister value, loads a byte from memory, zero-extends it to form a 6913 // 32-bit word, and writes it to a register. The offset register value can 6914 // optionally be shifted. 6915 bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode, 6916 const ARMEncoding encoding) { 6917 #if 0 6918 if ConditionPassed() then 6919 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6920 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6921 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6922 address = if index then offset_addr else R[n]; 6923 R[t] = ZeroExtend(MemU[address,1],32); 6924 if wback then R[n] = offset_addr; 6925 #endif 6926 6927 bool success = false; 6928 6929 if (ConditionPassed(opcode)) { 6930 uint32_t t; 6931 uint32_t n; 6932 uint32_t m; 6933 bool index; 6934 bool add; 6935 bool wback; 6936 ARM_ShifterType shift_t; 6937 uint32_t shift_n; 6938 6939 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6940 switch (encoding) { 6941 case eEncodingT1: 6942 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6943 t = Bits32(opcode, 2, 0); 6944 n = Bits32(opcode, 5, 3); 6945 m = Bits32(opcode, 8, 6); 6946 6947 // index = TRUE; add = TRUE; wback = FALSE; 6948 index = true; 6949 add = true; 6950 wback = false; 6951 6952 // (shift_t, shift_n) = (SRType_LSL, 0); 6953 shift_t = SRType_LSL; 6954 shift_n = 0; 6955 break; 6956 6957 case eEncodingT2: 6958 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6959 t = Bits32(opcode, 15, 12); 6960 n = Bits32(opcode, 19, 16); 6961 m = Bits32(opcode, 3, 0); 6962 6963 // index = TRUE; add = TRUE; wback = FALSE; 6964 index = true; 6965 add = true; 6966 wback = false; 6967 6968 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6969 shift_t = SRType_LSL; 6970 shift_n = Bits32(opcode, 5, 4); 6971 6972 // if Rt == '1111' then SEE PLD; 6973 if (t == 15) 6974 return false; // PLD is not implemented yet 6975 6976 // if Rn == '1111' then SEE LDRB (literal); 6977 if (n == 15) 6978 return EmulateLDRBLiteral(opcode, eEncodingT1); 6979 6980 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6981 if ((t == 13) || BadReg(m)) 6982 return false; 6983 break; 6984 6985 case eEncodingA1: { 6986 // if P == '0' && W == '1' then SEE LDRBT; 6987 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6988 t = Bits32(opcode, 15, 12); 6989 n = Bits32(opcode, 19, 16); 6990 m = Bits32(opcode, 3, 0); 6991 6992 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6993 // (W == '1'); 6994 index = BitIsSet(opcode, 24); 6995 add = BitIsSet(opcode, 23); 6996 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6997 6998 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6999 uint32_t type = Bits32(opcode, 6, 5); 7000 uint32_t imm5 = Bits32(opcode, 11, 7); 7001 shift_n = DecodeImmShift(type, imm5, shift_t); 7002 7003 // if t == 15 || m == 15 then UNPREDICTABLE; 7004 if ((t == 15) || (m == 15)) 7005 return false; 7006 7007 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7008 if (wback && ((n == 15) || (n == t))) 7009 return false; 7010 } break; 7011 7012 default: 7013 return false; 7014 } 7015 7016 addr_t offset_addr; 7017 addr_t address; 7018 7019 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7020 uint32_t Rm = 7021 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7022 if (!success) 7023 return false; 7024 7025 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7026 if (!success) 7027 return false; 7028 7029 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7030 uint32_t Rn = 7031 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7032 if (!success) 7033 return false; 7034 7035 if (add) 7036 offset_addr = Rn + offset; 7037 else 7038 offset_addr = Rn - offset; 7039 7040 // address = if index then offset_addr else R[n]; 7041 if (index) 7042 address = offset_addr; 7043 else 7044 address = Rn; 7045 7046 // R[t] = ZeroExtend(MemU[address,1],32); 7047 RegisterInfo base_reg; 7048 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7049 7050 EmulateInstruction::Context context; 7051 context.type = eContextRegisterLoad; 7052 context.SetRegisterPlusOffset(base_reg, address - Rn); 7053 7054 uint64_t data = MemURead(context, address, 1, 0, &success); 7055 if (!success) 7056 return false; 7057 7058 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7059 return false; 7060 7061 // if wback then R[n] = offset_addr; 7062 if (wback) { 7063 context.type = eContextAdjustBaseRegister; 7064 context.SetAddress(offset_addr); 7065 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7066 offset_addr)) 7067 return false; 7068 } 7069 } 7070 return true; 7071 } 7072 7073 // LDRH (immediate, Thumb) calculates an address from a base register value and 7074 // an immediate offset, loads a 7075 // halfword from memory, zero-extends it to form a 32-bit word, and writes it 7076 // to a register. It can use offset, post-indexed, or pre-indexed addressing. 7077 bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode, 7078 const ARMEncoding encoding) { 7079 #if 0 7080 if ConditionPassed() then 7081 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7082 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7083 address = if index then offset_addr else R[n]; 7084 data = MemU[address,2]; 7085 if wback then R[n] = offset_addr; 7086 if UnalignedSupport() || address<0> = '0' then 7087 R[t] = ZeroExtend(data, 32); 7088 else // Can only apply before ARMv7 7089 R[t] = bits(32) UNKNOWN; 7090 #endif 7091 7092 bool success = false; 7093 7094 if (ConditionPassed(opcode)) { 7095 uint32_t t; 7096 uint32_t n; 7097 uint32_t imm32; 7098 bool index; 7099 bool add; 7100 bool wback; 7101 7102 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7103 switch (encoding) { 7104 case eEncodingT1: 7105 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 7106 t = Bits32(opcode, 2, 0); 7107 n = Bits32(opcode, 5, 3); 7108 imm32 = Bits32(opcode, 10, 6) << 1; 7109 7110 // index = TRUE; add = TRUE; wback = FALSE; 7111 index = true; 7112 add = true; 7113 wback = false; 7114 7115 break; 7116 7117 case eEncodingT2: 7118 // if Rt == '1111' then SEE "Unallocated memory hints"; 7119 // if Rn == '1111' then SEE LDRH (literal); 7120 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7121 t = Bits32(opcode, 15, 12); 7122 n = Bits32(opcode, 19, 16); 7123 imm32 = Bits32(opcode, 11, 0); 7124 7125 // index = TRUE; add = TRUE; wback = FALSE; 7126 index = true; 7127 add = true; 7128 wback = false; 7129 7130 // if t == 13 then UNPREDICTABLE; 7131 if (t == 13) 7132 return false; 7133 break; 7134 7135 case eEncodingT3: 7136 // if Rn == '1111' then SEE LDRH (literal); 7137 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7138 // "Unallocated memory hints"; 7139 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 7140 // if P == '0' && W == '0' then UNDEFINED; 7141 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7142 return false; 7143 7144 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7145 t = Bits32(opcode, 15, 12); 7146 n = Bits32(opcode, 19, 16); 7147 imm32 = Bits32(opcode, 7, 0); 7148 7149 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7150 index = BitIsSet(opcode, 10); 7151 add = BitIsSet(opcode, 9); 7152 wback = BitIsSet(opcode, 8); 7153 7154 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7155 if (BadReg(t) || (wback && (n == t))) 7156 return false; 7157 break; 7158 7159 default: 7160 return false; 7161 } 7162 7163 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7164 uint32_t Rn = 7165 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7166 if (!success) 7167 return false; 7168 7169 addr_t offset_addr; 7170 addr_t address; 7171 7172 if (add) 7173 offset_addr = Rn + imm32; 7174 else 7175 offset_addr = Rn - imm32; 7176 7177 // address = if index then offset_addr else R[n]; 7178 if (index) 7179 address = offset_addr; 7180 else 7181 address = Rn; 7182 7183 // data = MemU[address,2]; 7184 RegisterInfo base_reg; 7185 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7186 7187 EmulateInstruction::Context context; 7188 context.type = eContextRegisterLoad; 7189 context.SetRegisterPlusOffset(base_reg, address - Rn); 7190 7191 uint64_t data = MemURead(context, address, 2, 0, &success); 7192 if (!success) 7193 return false; 7194 7195 // if wback then R[n] = offset_addr; 7196 if (wback) { 7197 context.type = eContextAdjustBaseRegister; 7198 context.SetAddress(offset_addr); 7199 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7200 offset_addr)) 7201 return false; 7202 } 7203 7204 // if UnalignedSupport() || address<0> = '0' then 7205 if (UnalignedSupport() || BitIsClear(address, 0)) { 7206 // R[t] = ZeroExtend(data, 32); 7207 context.type = eContextRegisterLoad; 7208 context.SetRegisterPlusOffset(base_reg, address - Rn); 7209 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7210 data)) 7211 return false; 7212 } else // Can only apply before ARMv7 7213 { 7214 // R[t] = bits(32) UNKNOWN; 7215 WriteBits32Unknown(t); 7216 } 7217 } 7218 return true; 7219 } 7220 7221 // LDRH (literal) calculates an address from the PC value and an immediate 7222 // offset, loads a halfword from memory, 7223 // zero-extends it to form a 32-bit word, and writes it to a register. 7224 bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode, 7225 const ARMEncoding encoding) { 7226 #if 0 7227 if ConditionPassed() then 7228 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7229 base = Align(PC,4); 7230 address = if add then (base + imm32) else (base - imm32); 7231 data = MemU[address,2]; 7232 if UnalignedSupport() || address<0> = '0' then 7233 R[t] = ZeroExtend(data, 32); 7234 else // Can only apply before ARMv7 7235 R[t] = bits(32) UNKNOWN; 7236 #endif 7237 7238 bool success = false; 7239 7240 if (ConditionPassed(opcode)) { 7241 uint32_t t; 7242 uint32_t imm32; 7243 bool add; 7244 7245 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7246 switch (encoding) { 7247 case eEncodingT1: 7248 // if Rt == '1111' then SEE "Unallocated memory hints"; 7249 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7250 t = Bits32(opcode, 15, 12); 7251 imm32 = Bits32(opcode, 11, 0); 7252 add = BitIsSet(opcode, 23); 7253 7254 // if t == 13 then UNPREDICTABLE; 7255 if (t == 13) 7256 return false; 7257 7258 break; 7259 7260 case eEncodingA1: { 7261 uint32_t imm4H = Bits32(opcode, 11, 8); 7262 uint32_t imm4L = Bits32(opcode, 3, 0); 7263 7264 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7265 t = Bits32(opcode, 15, 12); 7266 imm32 = (imm4H << 4) | imm4L; 7267 add = BitIsSet(opcode, 23); 7268 7269 // if t == 15 then UNPREDICTABLE; 7270 if (t == 15) 7271 return false; 7272 break; 7273 } 7274 7275 default: 7276 return false; 7277 } 7278 7279 // base = Align(PC,4); 7280 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7281 if (!success) 7282 return false; 7283 7284 addr_t base = AlignPC(pc_value); 7285 addr_t address; 7286 7287 // address = if add then (base + imm32) else (base - imm32); 7288 if (add) 7289 address = base + imm32; 7290 else 7291 address = base - imm32; 7292 7293 // data = MemU[address,2]; 7294 RegisterInfo base_reg; 7295 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7296 7297 EmulateInstruction::Context context; 7298 context.type = eContextRegisterLoad; 7299 context.SetRegisterPlusOffset(base_reg, address - base); 7300 7301 uint64_t data = MemURead(context, address, 2, 0, &success); 7302 if (!success) 7303 return false; 7304 7305 // if UnalignedSupport() || address<0> = '0' then 7306 if (UnalignedSupport() || BitIsClear(address, 0)) { 7307 // R[t] = ZeroExtend(data, 32); 7308 context.type = eContextRegisterLoad; 7309 context.SetRegisterPlusOffset(base_reg, address - base); 7310 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7311 data)) 7312 return false; 7313 7314 } else // Can only apply before ARMv7 7315 { 7316 // R[t] = bits(32) UNKNOWN; 7317 WriteBits32Unknown(t); 7318 } 7319 } 7320 return true; 7321 } 7322 7323 // LDRH (literal) calculates an address from a base register value and an offset 7324 // register value, loads a halfword 7325 // from memory, zero-extends it to form a 32-bit word, and writes it to a 7326 // register. The offset register value can be shifted left by 0, 1, 2, or 3 7327 // bits. 7328 bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode, 7329 const ARMEncoding encoding) { 7330 #if 0 7331 if ConditionPassed() then 7332 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7333 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7334 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7335 address = if index then offset_addr else R[n]; 7336 data = MemU[address,2]; 7337 if wback then R[n] = offset_addr; 7338 if UnalignedSupport() || address<0> = '0' then 7339 R[t] = ZeroExtend(data, 32); 7340 else // Can only apply before ARMv7 7341 R[t] = bits(32) UNKNOWN; 7342 #endif 7343 7344 bool success = false; 7345 7346 if (ConditionPassed(opcode)) { 7347 uint32_t t; 7348 uint32_t n; 7349 uint32_t m; 7350 bool index; 7351 bool add; 7352 bool wback; 7353 ARM_ShifterType shift_t; 7354 uint32_t shift_n; 7355 7356 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7357 switch (encoding) { 7358 case eEncodingT1: 7359 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 7360 // in ThumbEE"; 7361 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7362 t = Bits32(opcode, 2, 0); 7363 n = Bits32(opcode, 5, 3); 7364 m = Bits32(opcode, 8, 6); 7365 7366 // index = TRUE; add = TRUE; wback = FALSE; 7367 index = true; 7368 add = true; 7369 wback = false; 7370 7371 // (shift_t, shift_n) = (SRType_LSL, 0); 7372 shift_t = SRType_LSL; 7373 shift_n = 0; 7374 7375 break; 7376 7377 case eEncodingT2: 7378 // if Rn == '1111' then SEE LDRH (literal); 7379 // if Rt == '1111' then SEE "Unallocated memory hints"; 7380 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7381 t = Bits32(opcode, 15, 12); 7382 n = Bits32(opcode, 19, 16); 7383 m = Bits32(opcode, 3, 0); 7384 7385 // index = TRUE; add = TRUE; wback = FALSE; 7386 index = true; 7387 add = true; 7388 wback = false; 7389 7390 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7391 shift_t = SRType_LSL; 7392 shift_n = Bits32(opcode, 5, 4); 7393 7394 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7395 if ((t == 13) || BadReg(m)) 7396 return false; 7397 break; 7398 7399 case eEncodingA1: 7400 // if P == '0' && W == '1' then SEE LDRHT; 7401 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7402 t = Bits32(opcode, 15, 12); 7403 n = Bits32(opcode, 19, 16); 7404 m = Bits32(opcode, 3, 0); 7405 7406 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7407 // (W == '1'); 7408 index = BitIsSet(opcode, 24); 7409 add = BitIsSet(opcode, 23); 7410 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7411 7412 // (shift_t, shift_n) = (SRType_LSL, 0); 7413 shift_t = SRType_LSL; 7414 shift_n = 0; 7415 7416 // if t == 15 || m == 15 then UNPREDICTABLE; 7417 if ((t == 15) || (m == 15)) 7418 return false; 7419 7420 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7421 if (wback && ((n == 15) || (n == t))) 7422 return false; 7423 7424 break; 7425 7426 default: 7427 return false; 7428 } 7429 7430 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7431 7432 uint64_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 addr_t offset_addr; 7442 addr_t address; 7443 7444 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7445 uint64_t Rn = 7446 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7447 if (!success) 7448 return false; 7449 7450 if (add) 7451 offset_addr = Rn + offset; 7452 else 7453 offset_addr = Rn - offset; 7454 7455 // address = if index then offset_addr else R[n]; 7456 if (index) 7457 address = offset_addr; 7458 else 7459 address = Rn; 7460 7461 // data = MemU[address,2]; 7462 RegisterInfo base_reg; 7463 RegisterInfo offset_reg; 7464 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7465 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7466 7467 EmulateInstruction::Context context; 7468 context.type = eContextRegisterLoad; 7469 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7470 uint64_t data = MemURead(context, address, 2, 0, &success); 7471 if (!success) 7472 return false; 7473 7474 // if wback then R[n] = offset_addr; 7475 if (wback) { 7476 context.type = eContextAdjustBaseRegister; 7477 context.SetAddress(offset_addr); 7478 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7479 offset_addr)) 7480 return false; 7481 } 7482 7483 // if UnalignedSupport() || address<0> = '0' then 7484 if (UnalignedSupport() || BitIsClear(address, 0)) { 7485 // R[t] = ZeroExtend(data, 32); 7486 context.type = eContextRegisterLoad; 7487 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7488 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7489 data)) 7490 return false; 7491 } else // Can only apply before ARMv7 7492 { 7493 // R[t] = bits(32) UNKNOWN; 7494 WriteBits32Unknown(t); 7495 } 7496 } 7497 return true; 7498 } 7499 7500 // LDRSB (immediate) calculates an address from a base register value and an 7501 // immediate offset, loads a byte from 7502 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7503 // It can use offset, post-indexed, or pre-indexed addressing. 7504 bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode, 7505 const ARMEncoding encoding) { 7506 #if 0 7507 if ConditionPassed() then 7508 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7509 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7510 address = if index then offset_addr else R[n]; 7511 R[t] = SignExtend(MemU[address,1], 32); 7512 if wback then R[n] = offset_addr; 7513 #endif 7514 7515 bool success = false; 7516 7517 if (ConditionPassed(opcode)) { 7518 uint32_t t; 7519 uint32_t n; 7520 uint32_t imm32; 7521 bool index; 7522 bool add; 7523 bool wback; 7524 7525 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7526 switch (encoding) { 7527 case eEncodingT1: 7528 // if Rt == '1111' then SEE PLI; 7529 // if Rn == '1111' then SEE LDRSB (literal); 7530 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7531 t = Bits32(opcode, 15, 12); 7532 n = Bits32(opcode, 19, 16); 7533 imm32 = Bits32(opcode, 11, 0); 7534 7535 // index = TRUE; add = TRUE; wback = FALSE; 7536 index = true; 7537 add = true; 7538 wback = false; 7539 7540 // if t == 13 then UNPREDICTABLE; 7541 if (t == 13) 7542 return false; 7543 7544 break; 7545 7546 case eEncodingT2: 7547 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7548 // if Rn == '1111' then SEE LDRSB (literal); 7549 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7550 // if P == '0' && W == '0' then UNDEFINED; 7551 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7552 return false; 7553 7554 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7555 t = Bits32(opcode, 15, 12); 7556 n = Bits32(opcode, 19, 16); 7557 imm32 = Bits32(opcode, 7, 0); 7558 7559 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7560 index = BitIsSet(opcode, 10); 7561 add = BitIsSet(opcode, 9); 7562 wback = BitIsSet(opcode, 8); 7563 7564 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7565 if (((t == 13) || 7566 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) || 7567 BitIsSet(opcode, 8)))) || 7568 (wback && (n == t))) 7569 return false; 7570 7571 break; 7572 7573 case eEncodingA1: { 7574 // if Rn == '1111' then SEE LDRSB (literal); 7575 // if P == '0' && W == '1' then SEE LDRSBT; 7576 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7577 t = Bits32(opcode, 15, 12); 7578 n = Bits32(opcode, 19, 16); 7579 7580 uint32_t imm4H = Bits32(opcode, 11, 8); 7581 uint32_t imm4L = Bits32(opcode, 3, 0); 7582 imm32 = (imm4H << 4) | imm4L; 7583 7584 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7585 // (W == '1'); 7586 index = BitIsSet(opcode, 24); 7587 add = BitIsSet(opcode, 23); 7588 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7589 7590 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7591 if ((t == 15) || (wback && (n == t))) 7592 return false; 7593 7594 break; 7595 } 7596 7597 default: 7598 return false; 7599 } 7600 7601 uint64_t Rn = ReadCoreReg(n, &success); 7602 if (!success) 7603 return false; 7604 7605 addr_t offset_addr; 7606 addr_t address; 7607 7608 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7609 if (add) 7610 offset_addr = Rn + imm32; 7611 else 7612 offset_addr = Rn - imm32; 7613 7614 // address = if index then offset_addr else R[n]; 7615 if (index) 7616 address = offset_addr; 7617 else 7618 address = Rn; 7619 7620 // R[t] = SignExtend(MemU[address,1], 32); 7621 RegisterInfo base_reg; 7622 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7623 7624 EmulateInstruction::Context context; 7625 context.type = eContextRegisterLoad; 7626 context.SetRegisterPlusOffset(base_reg, address - Rn); 7627 7628 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7629 if (!success) 7630 return false; 7631 7632 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7633 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7634 (uint64_t)signed_data)) 7635 return false; 7636 7637 // if wback then R[n] = offset_addr; 7638 if (wback) { 7639 context.type = eContextAdjustBaseRegister; 7640 context.SetAddress(offset_addr); 7641 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7642 offset_addr)) 7643 return false; 7644 } 7645 } 7646 7647 return true; 7648 } 7649 7650 // LDRSB (literal) calculates an address from the PC value and an immediate 7651 // offset, loads a byte from memory, 7652 // sign-extends it to form a 32-bit word, and writes tit to a register. 7653 bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode, 7654 const ARMEncoding encoding) { 7655 #if 0 7656 if ConditionPassed() then 7657 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7658 base = Align(PC,4); 7659 address = if add then (base + imm32) else (base - imm32); 7660 R[t] = SignExtend(MemU[address,1], 32); 7661 #endif 7662 7663 bool success = false; 7664 7665 if (ConditionPassed(opcode)) { 7666 uint32_t t; 7667 uint32_t imm32; 7668 bool add; 7669 7670 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7671 switch (encoding) { 7672 case eEncodingT1: 7673 // if Rt == '1111' then SEE PLI; 7674 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7675 t = Bits32(opcode, 15, 12); 7676 imm32 = Bits32(opcode, 11, 0); 7677 add = BitIsSet(opcode, 23); 7678 7679 // if t == 13 then UNPREDICTABLE; 7680 if (t == 13) 7681 return false; 7682 7683 break; 7684 7685 case eEncodingA1: { 7686 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7687 t = Bits32(opcode, 15, 12); 7688 uint32_t imm4H = Bits32(opcode, 11, 8); 7689 uint32_t imm4L = Bits32(opcode, 3, 0); 7690 imm32 = (imm4H << 4) | imm4L; 7691 add = BitIsSet(opcode, 23); 7692 7693 // if t == 15 then UNPREDICTABLE; 7694 if (t == 15) 7695 return false; 7696 7697 break; 7698 } 7699 7700 default: 7701 return false; 7702 } 7703 7704 // base = Align(PC,4); 7705 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7706 if (!success) 7707 return false; 7708 uint64_t base = AlignPC(pc_value); 7709 7710 // address = if add then (base + imm32) else (base - imm32); 7711 addr_t address; 7712 if (add) 7713 address = base + imm32; 7714 else 7715 address = base - imm32; 7716 7717 // R[t] = SignExtend(MemU[address,1], 32); 7718 RegisterInfo base_reg; 7719 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7720 7721 EmulateInstruction::Context context; 7722 context.type = eContextRegisterLoad; 7723 context.SetRegisterPlusOffset(base_reg, address - base); 7724 7725 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7726 if (!success) 7727 return false; 7728 7729 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7730 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7731 (uint64_t)signed_data)) 7732 return false; 7733 } 7734 return true; 7735 } 7736 7737 // LDRSB (register) calculates an address from a base register value and an 7738 // offset register value, loadsa byte from 7739 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7740 // The offset register value can be shifted left by 0, 1, 2, or 3 bits. 7741 bool EmulateInstructionARM::EmulateLDRSBRegister(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 R[t] = SignExtend(MemU[address,1], 32); 7750 if wback then R[n] = offset_addr; 7751 #endif 7752 7753 bool success = false; 7754 7755 if (ConditionPassed(opcode)) { 7756 uint32_t t; 7757 uint32_t n; 7758 uint32_t m; 7759 bool index; 7760 bool add; 7761 bool wback; 7762 ARM_ShifterType shift_t; 7763 uint32_t shift_n; 7764 7765 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7766 switch (encoding) { 7767 case eEncodingT1: 7768 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7769 t = Bits32(opcode, 2, 0); 7770 n = Bits32(opcode, 5, 3); 7771 m = Bits32(opcode, 8, 6); 7772 7773 // index = TRUE; add = TRUE; wback = FALSE; 7774 index = true; 7775 add = true; 7776 wback = false; 7777 7778 // (shift_t, shift_n) = (SRType_LSL, 0); 7779 shift_t = SRType_LSL; 7780 shift_n = 0; 7781 7782 break; 7783 7784 case eEncodingT2: 7785 // if Rt == '1111' then SEE PLI; 7786 // if Rn == '1111' then SEE LDRSB (literal); 7787 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7788 t = Bits32(opcode, 15, 12); 7789 n = Bits32(opcode, 19, 16); 7790 m = Bits32(opcode, 3, 0); 7791 7792 // index = TRUE; add = TRUE; wback = FALSE; 7793 index = true; 7794 add = true; 7795 wback = false; 7796 7797 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7798 shift_t = SRType_LSL; 7799 shift_n = Bits32(opcode, 5, 4); 7800 7801 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7802 if ((t == 13) || BadReg(m)) 7803 return false; 7804 break; 7805 7806 case eEncodingA1: 7807 // if P == '0' && W == '1' then SEE LDRSBT; 7808 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7809 t = Bits32(opcode, 15, 12); 7810 n = Bits32(opcode, 19, 16); 7811 m = Bits32(opcode, 3, 0); 7812 7813 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7814 // (W == '1'); 7815 index = BitIsSet(opcode, 24); 7816 add = BitIsSet(opcode, 23); 7817 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7818 7819 // (shift_t, shift_n) = (SRType_LSL, 0); 7820 shift_t = SRType_LSL; 7821 shift_n = 0; 7822 7823 // if t == 15 || m == 15 then UNPREDICTABLE; 7824 if ((t == 15) || (m == 15)) 7825 return false; 7826 7827 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7828 if (wback && ((n == 15) || (n == t))) 7829 return false; 7830 break; 7831 7832 default: 7833 return false; 7834 } 7835 7836 uint64_t Rm = 7837 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7838 if (!success) 7839 return false; 7840 7841 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7842 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7843 if (!success) 7844 return false; 7845 7846 addr_t offset_addr; 7847 addr_t address; 7848 7849 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7850 uint64_t Rn = 7851 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7852 if (!success) 7853 return false; 7854 7855 if (add) 7856 offset_addr = Rn + offset; 7857 else 7858 offset_addr = Rn - offset; 7859 7860 // address = if index then offset_addr else R[n]; 7861 if (index) 7862 address = offset_addr; 7863 else 7864 address = Rn; 7865 7866 // R[t] = SignExtend(MemU[address,1], 32); 7867 RegisterInfo base_reg; 7868 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7869 RegisterInfo offset_reg; 7870 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7871 7872 EmulateInstruction::Context context; 7873 context.type = eContextRegisterLoad; 7874 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7875 7876 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7877 if (!success) 7878 return false; 7879 7880 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7881 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7882 (uint64_t)signed_data)) 7883 return false; 7884 7885 // if wback then R[n] = offset_addr; 7886 if (wback) { 7887 context.type = eContextAdjustBaseRegister; 7888 context.SetAddress(offset_addr); 7889 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7890 offset_addr)) 7891 return false; 7892 } 7893 } 7894 return true; 7895 } 7896 7897 // LDRSH (immediate) calculates an address from a base register value and an 7898 // immediate offset, loads a halfword from 7899 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7900 // It can use offset, post-indexed, or pre-indexed addressing. 7901 bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode, 7902 const ARMEncoding encoding) { 7903 #if 0 7904 if ConditionPassed() then 7905 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7906 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7907 address = if index then offset_addr else R[n]; 7908 data = MemU[address,2]; 7909 if wback then R[n] = offset_addr; 7910 if UnalignedSupport() || address<0> = '0' then 7911 R[t] = SignExtend(data, 32); 7912 else // Can only apply before ARMv7 7913 R[t] = bits(32) UNKNOWN; 7914 #endif 7915 7916 bool success = false; 7917 7918 if (ConditionPassed(opcode)) { 7919 uint32_t t; 7920 uint32_t n; 7921 uint32_t imm32; 7922 bool index; 7923 bool add; 7924 bool wback; 7925 7926 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7927 switch (encoding) { 7928 case eEncodingT1: 7929 // if Rn == '1111' then SEE LDRSH (literal); 7930 // if Rt == '1111' then SEE "Unallocated memory hints"; 7931 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7932 t = Bits32(opcode, 15, 12); 7933 n = Bits32(opcode, 19, 16); 7934 imm32 = Bits32(opcode, 11, 0); 7935 7936 // index = TRUE; add = TRUE; wback = FALSE; 7937 index = true; 7938 add = true; 7939 wback = false; 7940 7941 // if t == 13 then UNPREDICTABLE; 7942 if (t == 13) 7943 return false; 7944 7945 break; 7946 7947 case eEncodingT2: 7948 // if Rn == '1111' then SEE LDRSH (literal); 7949 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7950 // "Unallocated memory hints"; 7951 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7952 // if P == '0' && W == '0' then UNDEFINED; 7953 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7954 return false; 7955 7956 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7957 t = Bits32(opcode, 15, 12); 7958 n = Bits32(opcode, 19, 16); 7959 imm32 = Bits32(opcode, 7, 0); 7960 7961 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7962 index = BitIsSet(opcode, 10); 7963 add = BitIsSet(opcode, 9); 7964 wback = BitIsSet(opcode, 8); 7965 7966 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7967 if (BadReg(t) || (wback && (n == t))) 7968 return false; 7969 7970 break; 7971 7972 case eEncodingA1: { 7973 // if Rn == '1111' then SEE LDRSH (literal); 7974 // if P == '0' && W == '1' then SEE LDRSHT; 7975 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7976 t = Bits32(opcode, 15, 12); 7977 n = Bits32(opcode, 19, 16); 7978 uint32_t imm4H = Bits32(opcode, 11, 8); 7979 uint32_t imm4L = Bits32(opcode, 3, 0); 7980 imm32 = (imm4H << 4) | imm4L; 7981 7982 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7983 // (W == '1'); 7984 index = BitIsSet(opcode, 24); 7985 add = BitIsSet(opcode, 23); 7986 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7987 7988 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7989 if ((t == 15) || (wback && (n == t))) 7990 return false; 7991 7992 break; 7993 } 7994 7995 default: 7996 return false; 7997 } 7998 7999 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 8000 uint64_t Rn = 8001 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8002 if (!success) 8003 return false; 8004 8005 addr_t offset_addr; 8006 if (add) 8007 offset_addr = Rn + imm32; 8008 else 8009 offset_addr = Rn - imm32; 8010 8011 // address = if index then offset_addr else R[n]; 8012 addr_t address; 8013 if (index) 8014 address = offset_addr; 8015 else 8016 address = Rn; 8017 8018 // data = MemU[address,2]; 8019 RegisterInfo base_reg; 8020 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8021 8022 EmulateInstruction::Context context; 8023 context.type = eContextRegisterLoad; 8024 context.SetRegisterPlusOffset(base_reg, address - Rn); 8025 8026 uint64_t data = MemURead(context, address, 2, 0, &success); 8027 if (!success) 8028 return false; 8029 8030 // if wback then R[n] = offset_addr; 8031 if (wback) { 8032 context.type = eContextAdjustBaseRegister; 8033 context.SetAddress(offset_addr); 8034 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8035 offset_addr)) 8036 return false; 8037 } 8038 8039 // if UnalignedSupport() || address<0> = '0' then 8040 if (UnalignedSupport() || BitIsClear(address, 0)) { 8041 // R[t] = SignExtend(data, 32); 8042 int64_t signed_data = llvm::SignExtend64<16>(data); 8043 context.type = eContextRegisterLoad; 8044 context.SetRegisterPlusOffset(base_reg, address - Rn); 8045 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8046 (uint64_t)signed_data)) 8047 return false; 8048 } else // Can only apply before ARMv7 8049 { 8050 // R[t] = bits(32) UNKNOWN; 8051 WriteBits32Unknown(t); 8052 } 8053 } 8054 return true; 8055 } 8056 8057 // LDRSH (literal) calculates an address from the PC value and an immediate 8058 // offset, loads a halfword from memory, 8059 // sign-extends it to from a 32-bit word, and writes it to a register. 8060 bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode, 8061 const ARMEncoding encoding) { 8062 #if 0 8063 if ConditionPassed() then 8064 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8065 base = Align(PC,4); 8066 address = if add then (base + imm32) else (base - imm32); 8067 data = MemU[address,2]; 8068 if UnalignedSupport() || address<0> = '0' then 8069 R[t] = SignExtend(data, 32); 8070 else // Can only apply before ARMv7 8071 R[t] = bits(32) UNKNOWN; 8072 #endif 8073 8074 bool success = false; 8075 8076 if (ConditionPassed(opcode)) { 8077 uint32_t t; 8078 uint32_t imm32; 8079 bool add; 8080 8081 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8082 switch (encoding) { 8083 case eEncodingT1: 8084 // if Rt == '1111' then SEE "Unallocated memory hints"; 8085 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 8086 t = Bits32(opcode, 15, 12); 8087 imm32 = Bits32(opcode, 11, 0); 8088 add = BitIsSet(opcode, 23); 8089 8090 // if t == 13 then UNPREDICTABLE; 8091 if (t == 13) 8092 return false; 8093 8094 break; 8095 8096 case eEncodingA1: { 8097 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 8098 t = Bits32(opcode, 15, 12); 8099 uint32_t imm4H = Bits32(opcode, 11, 8); 8100 uint32_t imm4L = Bits32(opcode, 3, 0); 8101 imm32 = (imm4H << 4) | imm4L; 8102 add = BitIsSet(opcode, 23); 8103 8104 // if t == 15 then UNPREDICTABLE; 8105 if (t == 15) 8106 return false; 8107 8108 break; 8109 } 8110 default: 8111 return false; 8112 } 8113 8114 // base = Align(PC,4); 8115 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 8116 if (!success) 8117 return false; 8118 8119 uint64_t base = AlignPC(pc_value); 8120 8121 addr_t address; 8122 // address = if add then (base + imm32) else (base - imm32); 8123 if (add) 8124 address = base + imm32; 8125 else 8126 address = base - imm32; 8127 8128 // data = MemU[address,2]; 8129 RegisterInfo base_reg; 8130 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 8131 8132 EmulateInstruction::Context context; 8133 context.type = eContextRegisterLoad; 8134 context.SetRegisterPlusOffset(base_reg, imm32); 8135 8136 uint64_t data = MemURead(context, address, 2, 0, &success); 8137 if (!success) 8138 return false; 8139 8140 // if UnalignedSupport() || address<0> = '0' then 8141 if (UnalignedSupport() || BitIsClear(address, 0)) { 8142 // R[t] = SignExtend(data, 32); 8143 int64_t signed_data = llvm::SignExtend64<16>(data); 8144 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8145 (uint64_t)signed_data)) 8146 return false; 8147 } else // Can only apply before ARMv7 8148 { 8149 // R[t] = bits(32) UNKNOWN; 8150 WriteBits32Unknown(t); 8151 } 8152 } 8153 return true; 8154 } 8155 8156 // LDRSH (register) calculates an address from a base register value and an 8157 // offset register value, loads a halfword 8158 // from memory, sign-extends it to form a 32-bit word, and writes it to a 8159 // register. The offset register value can be shifted left by 0, 1, 2, or 3 8160 // bits. 8161 bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode, 8162 const ARMEncoding encoding) { 8163 #if 0 8164 if ConditionPassed() then 8165 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8166 offset = Shift(R[m], shift_t, shift_n, APSR.C); 8167 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8168 address = if index then offset_addr else R[n]; 8169 data = MemU[address,2]; 8170 if wback then R[n] = offset_addr; 8171 if UnalignedSupport() || address<0> = '0' then 8172 R[t] = SignExtend(data, 32); 8173 else // Can only apply before ARMv7 8174 R[t] = bits(32) UNKNOWN; 8175 #endif 8176 8177 bool success = false; 8178 8179 if (ConditionPassed(opcode)) { 8180 uint32_t t; 8181 uint32_t n; 8182 uint32_t m; 8183 bool index; 8184 bool add; 8185 bool wback; 8186 ARM_ShifterType shift_t; 8187 uint32_t shift_n; 8188 8189 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8190 switch (encoding) { 8191 case eEncodingT1: 8192 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 8193 // in ThumbEE"; 8194 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8195 t = Bits32(opcode, 2, 0); 8196 n = Bits32(opcode, 5, 3); 8197 m = Bits32(opcode, 8, 6); 8198 8199 // index = TRUE; add = TRUE; wback = FALSE; 8200 index = true; 8201 add = true; 8202 wback = false; 8203 8204 // (shift_t, shift_n) = (SRType_LSL, 0); 8205 shift_t = SRType_LSL; 8206 shift_n = 0; 8207 8208 break; 8209 8210 case eEncodingT2: 8211 // if Rn == '1111' then SEE LDRSH (literal); 8212 // if Rt == '1111' then SEE "Unallocated memory hints"; 8213 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8214 t = Bits32(opcode, 15, 12); 8215 n = Bits32(opcode, 19, 16); 8216 m = Bits32(opcode, 3, 0); 8217 8218 // index = TRUE; add = TRUE; wback = FALSE; 8219 index = true; 8220 add = true; 8221 wback = false; 8222 8223 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 8224 shift_t = SRType_LSL; 8225 shift_n = Bits32(opcode, 5, 4); 8226 8227 // if t == 13 || BadReg(m) then UNPREDICTABLE; 8228 if ((t == 13) || BadReg(m)) 8229 return false; 8230 8231 break; 8232 8233 case eEncodingA1: 8234 // if P == '0' && W == '1' then SEE LDRSHT; 8235 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8236 t = Bits32(opcode, 15, 12); 8237 n = Bits32(opcode, 19, 16); 8238 m = Bits32(opcode, 3, 0); 8239 8240 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8241 // (W == '1'); 8242 index = BitIsSet(opcode, 24); 8243 add = BitIsSet(opcode, 23); 8244 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8245 8246 // (shift_t, shift_n) = (SRType_LSL, 0); 8247 shift_t = SRType_LSL; 8248 shift_n = 0; 8249 8250 // if t == 15 || m == 15 then UNPREDICTABLE; 8251 if ((t == 15) || (m == 15)) 8252 return false; 8253 8254 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 8255 if (wback && ((n == 15) || (n == t))) 8256 return false; 8257 8258 break; 8259 8260 default: 8261 return false; 8262 } 8263 8264 uint64_t Rm = 8265 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8266 if (!success) 8267 return false; 8268 8269 uint64_t Rn = 8270 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8271 if (!success) 8272 return false; 8273 8274 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 8275 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 8276 if (!success) 8277 return false; 8278 8279 addr_t offset_addr; 8280 addr_t address; 8281 8282 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8283 if (add) 8284 offset_addr = Rn + offset; 8285 else 8286 offset_addr = Rn - offset; 8287 8288 // address = if index then offset_addr else R[n]; 8289 if (index) 8290 address = offset_addr; 8291 else 8292 address = Rn; 8293 8294 // data = MemU[address,2]; 8295 RegisterInfo base_reg; 8296 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8297 8298 RegisterInfo offset_reg; 8299 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 8300 8301 EmulateInstruction::Context context; 8302 context.type = eContextRegisterLoad; 8303 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8304 8305 uint64_t data = MemURead(context, address, 2, 0, &success); 8306 if (!success) 8307 return false; 8308 8309 // if wback then R[n] = offset_addr; 8310 if (wback) { 8311 context.type = eContextAdjustBaseRegister; 8312 context.SetAddress(offset_addr); 8313 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8314 offset_addr)) 8315 return false; 8316 } 8317 8318 // if UnalignedSupport() || address<0> = '0' then 8319 if (UnalignedSupport() || BitIsClear(address, 0)) { 8320 // R[t] = SignExtend(data, 32); 8321 context.type = eContextRegisterLoad; 8322 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8323 8324 int64_t signed_data = llvm::SignExtend64<16>(data); 8325 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8326 (uint64_t)signed_data)) 8327 return false; 8328 } else // Can only apply before ARMv7 8329 { 8330 // R[t] = bits(32) UNKNOWN; 8331 WriteBits32Unknown(t); 8332 } 8333 } 8334 return true; 8335 } 8336 8337 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and 8338 // writes the result to the destination 8339 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before 8340 // extracting the 8-bit value. 8341 bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode, 8342 const ARMEncoding encoding) { 8343 #if 0 8344 if ConditionPassed() then 8345 EncodingSpecificOperations(); 8346 rotated = ROR(R[m], rotation); 8347 R[d] = SignExtend(rotated<7:0>, 32); 8348 #endif 8349 8350 bool success = false; 8351 8352 if (ConditionPassed(opcode)) { 8353 uint32_t d; 8354 uint32_t m; 8355 uint32_t rotation; 8356 8357 // EncodingSpecificOperations(); 8358 switch (encoding) { 8359 case eEncodingT1: 8360 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8361 d = Bits32(opcode, 2, 0); 8362 m = Bits32(opcode, 5, 3); 8363 rotation = 0; 8364 8365 break; 8366 8367 case eEncodingT2: 8368 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8369 d = Bits32(opcode, 11, 8); 8370 m = Bits32(opcode, 3, 0); 8371 rotation = Bits32(opcode, 5, 4) << 3; 8372 8373 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8374 if (BadReg(d) || BadReg(m)) 8375 return false; 8376 8377 break; 8378 8379 case eEncodingA1: 8380 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8381 d = Bits32(opcode, 15, 12); 8382 m = Bits32(opcode, 3, 0); 8383 rotation = Bits32(opcode, 11, 10) << 3; 8384 8385 // if d == 15 || m == 15 then UNPREDICTABLE; 8386 if ((d == 15) || (m == 15)) 8387 return false; 8388 8389 break; 8390 8391 default: 8392 return false; 8393 } 8394 8395 uint64_t Rm = 8396 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8397 if (!success) 8398 return false; 8399 8400 // rotated = ROR(R[m], rotation); 8401 uint64_t rotated = ROR(Rm, rotation, &success); 8402 if (!success) 8403 return false; 8404 8405 // R[d] = SignExtend(rotated<7:0>, 32); 8406 int64_t data = llvm::SignExtend64<8>(rotated); 8407 8408 RegisterInfo source_reg; 8409 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8410 8411 EmulateInstruction::Context context; 8412 context.type = eContextRegisterLoad; 8413 context.SetRegister(source_reg); 8414 8415 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8416 (uint64_t)data)) 8417 return false; 8418 } 8419 return true; 8420 } 8421 8422 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and 8423 // writes the result to the destination 8424 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8425 // extracting the 16-bit value. 8426 bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode, 8427 const ARMEncoding encoding) { 8428 #if 0 8429 if ConditionPassed() then 8430 EncodingSpecificOperations(); 8431 rotated = ROR(R[m], rotation); 8432 R[d] = SignExtend(rotated<15:0>, 32); 8433 #endif 8434 8435 bool success = false; 8436 8437 if (ConditionPassed(opcode)) { 8438 uint32_t d; 8439 uint32_t m; 8440 uint32_t rotation; 8441 8442 // EncodingSpecificOperations(); 8443 switch (encoding) { 8444 case eEncodingT1: 8445 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8446 d = Bits32(opcode, 2, 0); 8447 m = Bits32(opcode, 5, 3); 8448 rotation = 0; 8449 8450 break; 8451 8452 case eEncodingT2: 8453 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8454 d = Bits32(opcode, 11, 8); 8455 m = Bits32(opcode, 3, 0); 8456 rotation = Bits32(opcode, 5, 4) << 3; 8457 8458 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8459 if (BadReg(d) || BadReg(m)) 8460 return false; 8461 8462 break; 8463 8464 case eEncodingA1: 8465 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8466 d = Bits32(opcode, 15, 12); 8467 m = Bits32(opcode, 3, 0); 8468 rotation = Bits32(opcode, 11, 10) << 3; 8469 8470 // if d == 15 || m == 15 then UNPREDICTABLE; 8471 if ((d == 15) || (m == 15)) 8472 return false; 8473 8474 break; 8475 8476 default: 8477 return false; 8478 } 8479 8480 uint64_t Rm = 8481 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8482 if (!success) 8483 return false; 8484 8485 // rotated = ROR(R[m], rotation); 8486 uint64_t rotated = ROR(Rm, rotation, &success); 8487 if (!success) 8488 return false; 8489 8490 // R[d] = SignExtend(rotated<15:0>, 32); 8491 RegisterInfo source_reg; 8492 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8493 8494 EmulateInstruction::Context context; 8495 context.type = eContextRegisterLoad; 8496 context.SetRegister(source_reg); 8497 8498 int64_t data = llvm::SignExtend64<16>(rotated); 8499 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8500 (uint64_t)data)) 8501 return false; 8502 } 8503 8504 return true; 8505 } 8506 8507 // UXTB extracts an 8-bit value from a register, zero-extends it to 32 bits, and 8508 // writes the result to the destination 8509 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8510 // extracting the 8-bit value. 8511 bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode, 8512 const ARMEncoding encoding) { 8513 #if 0 8514 if ConditionPassed() then 8515 EncodingSpecificOperations(); 8516 rotated = ROR(R[m], rotation); 8517 R[d] = ZeroExtend(rotated<7:0>, 32); 8518 #endif 8519 8520 bool success = false; 8521 8522 if (ConditionPassed(opcode)) { 8523 uint32_t d; 8524 uint32_t m; 8525 uint32_t rotation; 8526 8527 // EncodingSpecificOperations(); 8528 switch (encoding) { 8529 case eEncodingT1: 8530 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8531 d = Bits32(opcode, 2, 0); 8532 m = Bits32(opcode, 5, 3); 8533 rotation = 0; 8534 8535 break; 8536 8537 case eEncodingT2: 8538 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8539 d = Bits32(opcode, 11, 8); 8540 m = Bits32(opcode, 3, 0); 8541 rotation = Bits32(opcode, 5, 4) << 3; 8542 8543 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8544 if (BadReg(d) || BadReg(m)) 8545 return false; 8546 8547 break; 8548 8549 case eEncodingA1: 8550 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8551 d = Bits32(opcode, 15, 12); 8552 m = Bits32(opcode, 3, 0); 8553 rotation = Bits32(opcode, 11, 10) << 3; 8554 8555 // if d == 15 || m == 15 then UNPREDICTABLE; 8556 if ((d == 15) || (m == 15)) 8557 return false; 8558 8559 break; 8560 8561 default: 8562 return false; 8563 } 8564 8565 uint64_t Rm = 8566 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8567 if (!success) 8568 return false; 8569 8570 // rotated = ROR(R[m], rotation); 8571 uint64_t rotated = ROR(Rm, rotation, &success); 8572 if (!success) 8573 return false; 8574 8575 // R[d] = ZeroExtend(rotated<7:0>, 32); 8576 RegisterInfo source_reg; 8577 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8578 8579 EmulateInstruction::Context context; 8580 context.type = eContextRegisterLoad; 8581 context.SetRegister(source_reg); 8582 8583 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8584 Bits32(rotated, 7, 0))) 8585 return false; 8586 } 8587 return true; 8588 } 8589 8590 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and 8591 // writes the result to the destination 8592 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8593 // extracting the 16-bit value. 8594 bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode, 8595 const ARMEncoding encoding) { 8596 #if 0 8597 if ConditionPassed() then 8598 EncodingSpecificOperations(); 8599 rotated = ROR(R[m], rotation); 8600 R[d] = ZeroExtend(rotated<15:0>, 32); 8601 #endif 8602 8603 bool success = false; 8604 8605 if (ConditionPassed(opcode)) { 8606 uint32_t d; 8607 uint32_t m; 8608 uint32_t rotation; 8609 8610 switch (encoding) { 8611 case eEncodingT1: 8612 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8613 d = Bits32(opcode, 2, 0); 8614 m = Bits32(opcode, 5, 3); 8615 rotation = 0; 8616 8617 break; 8618 8619 case eEncodingT2: 8620 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8621 d = Bits32(opcode, 11, 8); 8622 m = Bits32(opcode, 3, 0); 8623 rotation = Bits32(opcode, 5, 4) << 3; 8624 8625 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8626 if (BadReg(d) || BadReg(m)) 8627 return false; 8628 8629 break; 8630 8631 case eEncodingA1: 8632 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8633 d = Bits32(opcode, 15, 12); 8634 m = Bits32(opcode, 3, 0); 8635 rotation = Bits32(opcode, 11, 10) << 3; 8636 8637 // if d == 15 || m == 15 then UNPREDICTABLE; 8638 if ((d == 15) || (m == 15)) 8639 return false; 8640 8641 break; 8642 8643 default: 8644 return false; 8645 } 8646 8647 uint64_t Rm = 8648 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8649 if (!success) 8650 return false; 8651 8652 // rotated = ROR(R[m], rotation); 8653 uint64_t rotated = ROR(Rm, rotation, &success); 8654 if (!success) 8655 return false; 8656 8657 // R[d] = ZeroExtend(rotated<15:0>, 32); 8658 RegisterInfo source_reg; 8659 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8660 8661 EmulateInstruction::Context context; 8662 context.type = eContextRegisterLoad; 8663 context.SetRegister(source_reg); 8664 8665 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8666 Bits32(rotated, 15, 0))) 8667 return false; 8668 } 8669 return true; 8670 } 8671 8672 // RFE (Return From Exception) loads the PC and the CPSR from the word at the 8673 // specified address and the following 8674 // word respectively. 8675 bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode, 8676 const ARMEncoding encoding) { 8677 #if 0 8678 if ConditionPassed() then 8679 EncodingSpecificOperations(); 8680 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8681 UNPREDICTABLE; 8682 else 8683 address = if increment then R[n] else R[n]-8; 8684 if wordhigher then address = address+4; 8685 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8686 BranchWritePC(MemA[address,4]); 8687 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8688 #endif 8689 8690 bool success = false; 8691 8692 if (ConditionPassed(opcode)) { 8693 uint32_t n; 8694 bool wback; 8695 bool increment; 8696 bool wordhigher; 8697 8698 // EncodingSpecificOperations(); 8699 switch (encoding) { 8700 case eEncodingT1: 8701 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = 8702 // FALSE; 8703 n = Bits32(opcode, 19, 16); 8704 wback = BitIsSet(opcode, 21); 8705 increment = false; 8706 wordhigher = false; 8707 8708 // if n == 15 then UNPREDICTABLE; 8709 if (n == 15) 8710 return false; 8711 8712 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8713 if (InITBlock() && !LastInITBlock()) 8714 return false; 8715 8716 break; 8717 8718 case eEncodingT2: 8719 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8720 n = Bits32(opcode, 19, 16); 8721 wback = BitIsSet(opcode, 21); 8722 increment = true; 8723 wordhigher = false; 8724 8725 // if n == 15 then UNPREDICTABLE; 8726 if (n == 15) 8727 return false; 8728 8729 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8730 if (InITBlock() && !LastInITBlock()) 8731 return false; 8732 8733 break; 8734 8735 case eEncodingA1: 8736 // n = UInt(Rn); 8737 n = Bits32(opcode, 19, 16); 8738 8739 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8740 wback = BitIsSet(opcode, 21); 8741 increment = BitIsSet(opcode, 23); 8742 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23)); 8743 8744 // if n == 15 then UNPREDICTABLE; 8745 if (n == 15) 8746 return false; 8747 8748 break; 8749 8750 default: 8751 return false; 8752 } 8753 8754 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE 8755 // then 8756 if (!CurrentModeIsPrivileged()) 8757 // UNPREDICTABLE; 8758 return false; 8759 else { 8760 uint64_t Rn = 8761 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8762 if (!success) 8763 return false; 8764 8765 addr_t address; 8766 // address = if increment then R[n] else R[n]-8; 8767 if (increment) 8768 address = Rn; 8769 else 8770 address = Rn - 8; 8771 8772 // if wordhigher then address = address+4; 8773 if (wordhigher) 8774 address = address + 4; 8775 8776 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8777 RegisterInfo base_reg; 8778 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8779 8780 EmulateInstruction::Context context; 8781 context.type = eContextReturnFromException; 8782 context.SetRegisterPlusOffset(base_reg, address - Rn); 8783 8784 uint64_t data = MemARead(context, address + 4, 4, 0, &success); 8785 if (!success) 8786 return false; 8787 8788 CPSRWriteByInstr(data, 15, true); 8789 8790 // BranchWritePC(MemA[address,4]); 8791 uint64_t data2 = MemARead(context, address, 4, 0, &success); 8792 if (!success) 8793 return false; 8794 8795 BranchWritePC(context, data2); 8796 8797 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8798 if (wback) { 8799 context.type = eContextAdjustBaseRegister; 8800 if (increment) { 8801 context.SetOffset(8); 8802 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8803 Rn + 8)) 8804 return false; 8805 } else { 8806 context.SetOffset(-8); 8807 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8808 Rn - 8)) 8809 return false; 8810 } 8811 } // if wback 8812 } 8813 } // if ConditionPassed() 8814 return true; 8815 } 8816 8817 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a 8818 // register value and an immediate value, and writes the result to the 8819 // destination register. It can optionally update the condition flags based on 8820 // the result. 8821 bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode, 8822 const ARMEncoding encoding) { 8823 #if 0 8824 // ARM pseudo code... 8825 if ConditionPassed() then 8826 EncodingSpecificOperations(); 8827 result = R[n] EOR imm32; 8828 if d == 15 then // Can only occur for ARM encoding 8829 ALUWritePC(result); // setflags is always FALSE here 8830 else 8831 R[d] = result; 8832 if setflags then 8833 APSR.N = result<31>; 8834 APSR.Z = IsZeroBit(result); 8835 APSR.C = carry; 8836 // APSR.V unchanged 8837 #endif 8838 8839 bool success = false; 8840 8841 if (ConditionPassed(opcode)) { 8842 uint32_t Rd, Rn; 8843 uint32_t 8844 imm32; // the immediate value to be ORed to the value obtained from Rn 8845 bool setflags; 8846 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8847 switch (encoding) { 8848 case eEncodingT1: 8849 Rd = Bits32(opcode, 11, 8); 8850 Rn = Bits32(opcode, 19, 16); 8851 setflags = BitIsSet(opcode, 20); 8852 imm32 = ThumbExpandImm_C( 8853 opcode, APSR_C, 8854 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8855 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8856 if (Rd == 15 && setflags) 8857 return EmulateTEQImm(opcode, eEncodingT1); 8858 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8859 return false; 8860 break; 8861 case eEncodingA1: 8862 Rd = Bits32(opcode, 15, 12); 8863 Rn = Bits32(opcode, 19, 16); 8864 setflags = BitIsSet(opcode, 20); 8865 imm32 = 8866 ARMExpandImm_C(opcode, APSR_C, 8867 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8868 8869 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8870 // instructions; 8871 if (Rd == 15 && setflags) 8872 return EmulateSUBSPcLrEtc(opcode, encoding); 8873 break; 8874 default: 8875 return false; 8876 } 8877 8878 // Read the first operand. 8879 uint32_t val1 = ReadCoreReg(Rn, &success); 8880 if (!success) 8881 return false; 8882 8883 uint32_t result = val1 ^ imm32; 8884 8885 EmulateInstruction::Context context; 8886 context.type = EmulateInstruction::eContextImmediate; 8887 context.SetNoArgs(); 8888 8889 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8890 return false; 8891 } 8892 return true; 8893 } 8894 8895 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a 8896 // register value and an optionally-shifted register value, and writes the 8897 // result to the destination register. It can optionally update the condition 8898 // flags based on the result. 8899 bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode, 8900 const ARMEncoding encoding) { 8901 #if 0 8902 // ARM pseudo code... 8903 if ConditionPassed() then 8904 EncodingSpecificOperations(); 8905 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8906 result = R[n] EOR shifted; 8907 if d == 15 then // Can only occur for ARM encoding 8908 ALUWritePC(result); // setflags is always FALSE here 8909 else 8910 R[d] = result; 8911 if setflags then 8912 APSR.N = result<31>; 8913 APSR.Z = IsZeroBit(result); 8914 APSR.C = carry; 8915 // APSR.V unchanged 8916 #endif 8917 8918 bool success = false; 8919 8920 if (ConditionPassed(opcode)) { 8921 uint32_t Rd, Rn, Rm; 8922 ARM_ShifterType shift_t; 8923 uint32_t shift_n; // the shift applied to the value read from Rm 8924 bool setflags; 8925 uint32_t carry; 8926 switch (encoding) { 8927 case eEncodingT1: 8928 Rd = Rn = Bits32(opcode, 2, 0); 8929 Rm = Bits32(opcode, 5, 3); 8930 setflags = !InITBlock(); 8931 shift_t = SRType_LSL; 8932 shift_n = 0; 8933 break; 8934 case eEncodingT2: 8935 Rd = Bits32(opcode, 11, 8); 8936 Rn = Bits32(opcode, 19, 16); 8937 Rm = Bits32(opcode, 3, 0); 8938 setflags = BitIsSet(opcode, 20); 8939 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8940 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8941 if (Rd == 15 && setflags) 8942 return EmulateTEQReg(opcode, eEncodingT1); 8943 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8944 return false; 8945 break; 8946 case eEncodingA1: 8947 Rd = Bits32(opcode, 15, 12); 8948 Rn = Bits32(opcode, 19, 16); 8949 Rm = Bits32(opcode, 3, 0); 8950 setflags = BitIsSet(opcode, 20); 8951 shift_n = DecodeImmShiftARM(opcode, shift_t); 8952 8953 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8954 // instructions; 8955 if (Rd == 15 && setflags) 8956 return EmulateSUBSPcLrEtc(opcode, encoding); 8957 break; 8958 default: 8959 return false; 8960 } 8961 8962 // Read the first operand. 8963 uint32_t val1 = ReadCoreReg(Rn, &success); 8964 if (!success) 8965 return false; 8966 8967 // Read the second operand. 8968 uint32_t val2 = ReadCoreReg(Rm, &success); 8969 if (!success) 8970 return false; 8971 8972 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8973 if (!success) 8974 return false; 8975 uint32_t result = val1 ^ shifted; 8976 8977 EmulateInstruction::Context context; 8978 context.type = EmulateInstruction::eContextImmediate; 8979 context.SetNoArgs(); 8980 8981 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8982 return false; 8983 } 8984 return true; 8985 } 8986 8987 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value 8988 // and an immediate value, and writes the result to the destination register. 8989 // It can optionally update the condition flags based on the result. 8990 bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode, 8991 const ARMEncoding encoding) { 8992 #if 0 8993 // ARM pseudo code... 8994 if ConditionPassed() then 8995 EncodingSpecificOperations(); 8996 result = R[n] OR imm32; 8997 if d == 15 then // Can only occur for ARM encoding 8998 ALUWritePC(result); // setflags is always FALSE here 8999 else 9000 R[d] = result; 9001 if setflags then 9002 APSR.N = result<31>; 9003 APSR.Z = IsZeroBit(result); 9004 APSR.C = carry; 9005 // APSR.V unchanged 9006 #endif 9007 9008 bool success = false; 9009 9010 if (ConditionPassed(opcode)) { 9011 uint32_t Rd, Rn; 9012 uint32_t 9013 imm32; // the immediate value to be ORed to the value obtained from Rn 9014 bool setflags; 9015 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9016 switch (encoding) { 9017 case eEncodingT1: 9018 Rd = Bits32(opcode, 11, 8); 9019 Rn = Bits32(opcode, 19, 16); 9020 setflags = BitIsSet(opcode, 20); 9021 imm32 = ThumbExpandImm_C( 9022 opcode, APSR_C, 9023 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9024 // if Rn == '1111' then SEE MOV (immediate); 9025 if (Rn == 15) 9026 return EmulateMOVRdImm(opcode, eEncodingT2); 9027 if (BadReg(Rd) || Rn == 13) 9028 return false; 9029 break; 9030 case eEncodingA1: 9031 Rd = Bits32(opcode, 15, 12); 9032 Rn = Bits32(opcode, 19, 16); 9033 setflags = BitIsSet(opcode, 20); 9034 imm32 = 9035 ARMExpandImm_C(opcode, APSR_C, 9036 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9037 9038 if (Rd == 15 && setflags) 9039 return EmulateSUBSPcLrEtc(opcode, encoding); 9040 break; 9041 default: 9042 return false; 9043 } 9044 9045 // Read the first operand. 9046 uint32_t val1 = ReadCoreReg(Rn, &success); 9047 if (!success) 9048 return false; 9049 9050 uint32_t result = val1 | imm32; 9051 9052 EmulateInstruction::Context context; 9053 context.type = EmulateInstruction::eContextImmediate; 9054 context.SetNoArgs(); 9055 9056 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9057 return false; 9058 } 9059 return true; 9060 } 9061 9062 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value 9063 // and an optionally-shifted register value, and writes the result to the 9064 // destination register. It can optionally update the condition flags based on 9065 // the result. 9066 bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode, 9067 const ARMEncoding encoding) { 9068 #if 0 9069 // ARM pseudo code... 9070 if ConditionPassed() then 9071 EncodingSpecificOperations(); 9072 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9073 result = R[n] OR shifted; 9074 if d == 15 then // Can only occur for ARM encoding 9075 ALUWritePC(result); // setflags is always FALSE here 9076 else 9077 R[d] = result; 9078 if setflags then 9079 APSR.N = result<31>; 9080 APSR.Z = IsZeroBit(result); 9081 APSR.C = carry; 9082 // APSR.V unchanged 9083 #endif 9084 9085 bool success = false; 9086 9087 if (ConditionPassed(opcode)) { 9088 uint32_t Rd, Rn, Rm; 9089 ARM_ShifterType shift_t; 9090 uint32_t shift_n; // the shift applied to the value read from Rm 9091 bool setflags; 9092 uint32_t carry; 9093 switch (encoding) { 9094 case eEncodingT1: 9095 Rd = Rn = Bits32(opcode, 2, 0); 9096 Rm = Bits32(opcode, 5, 3); 9097 setflags = !InITBlock(); 9098 shift_t = SRType_LSL; 9099 shift_n = 0; 9100 break; 9101 case eEncodingT2: 9102 Rd = Bits32(opcode, 11, 8); 9103 Rn = Bits32(opcode, 19, 16); 9104 Rm = Bits32(opcode, 3, 0); 9105 setflags = BitIsSet(opcode, 20); 9106 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9107 // if Rn == '1111' then SEE MOV (register); 9108 if (Rn == 15) 9109 return EmulateMOVRdRm(opcode, eEncodingT3); 9110 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 9111 return false; 9112 break; 9113 case eEncodingA1: 9114 Rd = Bits32(opcode, 15, 12); 9115 Rn = Bits32(opcode, 19, 16); 9116 Rm = Bits32(opcode, 3, 0); 9117 setflags = BitIsSet(opcode, 20); 9118 shift_n = DecodeImmShiftARM(opcode, shift_t); 9119 9120 if (Rd == 15 && setflags) 9121 return EmulateSUBSPcLrEtc(opcode, encoding); 9122 break; 9123 default: 9124 return false; 9125 } 9126 9127 // Read the first operand. 9128 uint32_t val1 = ReadCoreReg(Rn, &success); 9129 if (!success) 9130 return false; 9131 9132 // Read the second operand. 9133 uint32_t val2 = ReadCoreReg(Rm, &success); 9134 if (!success) 9135 return false; 9136 9137 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9138 if (!success) 9139 return false; 9140 uint32_t result = val1 | shifted; 9141 9142 EmulateInstruction::Context context; 9143 context.type = EmulateInstruction::eContextImmediate; 9144 context.SetNoArgs(); 9145 9146 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9147 return false; 9148 } 9149 return true; 9150 } 9151 9152 // Reverse Subtract (immediate) subtracts a register value from an immediate 9153 // value, and writes the result to the destination register. It can optionally 9154 // update the condition flags based on the result. 9155 bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode, 9156 const ARMEncoding encoding) { 9157 #if 0 9158 // ARM pseudo code... 9159 if ConditionPassed() then 9160 EncodingSpecificOperations(); 9161 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 9162 if d == 15 then // Can only occur for ARM encoding 9163 ALUWritePC(result); // setflags is always FALSE here 9164 else 9165 R[d] = result; 9166 if setflags then 9167 APSR.N = result<31>; 9168 APSR.Z = IsZeroBit(result); 9169 APSR.C = carry; 9170 APSR.V = overflow; 9171 #endif 9172 9173 bool success = false; 9174 9175 uint32_t Rd; // the destination register 9176 uint32_t Rn; // the first operand 9177 bool setflags; 9178 uint32_t 9179 imm32; // the immediate value to be added to the value obtained from Rn 9180 switch (encoding) { 9181 case eEncodingT1: 9182 Rd = Bits32(opcode, 2, 0); 9183 Rn = Bits32(opcode, 5, 3); 9184 setflags = !InITBlock(); 9185 imm32 = 0; 9186 break; 9187 case eEncodingT2: 9188 Rd = Bits32(opcode, 11, 8); 9189 Rn = Bits32(opcode, 19, 16); 9190 setflags = BitIsSet(opcode, 20); 9191 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9192 if (BadReg(Rd) || BadReg(Rn)) 9193 return false; 9194 break; 9195 case eEncodingA1: 9196 Rd = Bits32(opcode, 15, 12); 9197 Rn = Bits32(opcode, 19, 16); 9198 setflags = BitIsSet(opcode, 20); 9199 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9200 9201 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9202 // instructions; 9203 if (Rd == 15 && setflags) 9204 return EmulateSUBSPcLrEtc(opcode, encoding); 9205 break; 9206 default: 9207 return false; 9208 } 9209 // Read the register value from the operand register Rn. 9210 uint32_t reg_val = ReadCoreReg(Rn, &success); 9211 if (!success) 9212 return false; 9213 9214 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 9215 9216 EmulateInstruction::Context context; 9217 context.type = EmulateInstruction::eContextImmediate; 9218 context.SetNoArgs(); 9219 9220 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9221 res.carry_out, res.overflow); 9222 } 9223 9224 // Reverse Subtract (register) subtracts a register value from an optionally- 9225 // shifted register value, and writes the result to the destination register. 9226 // It can optionally update the condition flags based on the result. 9227 bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode, 9228 const ARMEncoding encoding) { 9229 #if 0 9230 // ARM pseudo code... 9231 if ConditionPassed() then 9232 EncodingSpecificOperations(); 9233 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9234 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 9235 if d == 15 then // Can only occur for ARM encoding 9236 ALUWritePC(result); // setflags is always FALSE here 9237 else 9238 R[d] = result; 9239 if setflags then 9240 APSR.N = result<31>; 9241 APSR.Z = IsZeroBit(result); 9242 APSR.C = carry; 9243 APSR.V = overflow; 9244 #endif 9245 9246 bool success = false; 9247 9248 uint32_t Rd; // the destination register 9249 uint32_t Rn; // the first operand 9250 uint32_t Rm; // the second operand 9251 bool setflags; 9252 ARM_ShifterType shift_t; 9253 uint32_t shift_n; // the shift applied to the value read from Rm 9254 switch (encoding) { 9255 case eEncodingT1: 9256 Rd = Bits32(opcode, 11, 8); 9257 Rn = Bits32(opcode, 19, 16); 9258 Rm = Bits32(opcode, 3, 0); 9259 setflags = BitIsSet(opcode, 20); 9260 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9261 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 9262 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9263 return false; 9264 break; 9265 case eEncodingA1: 9266 Rd = Bits32(opcode, 15, 12); 9267 Rn = Bits32(opcode, 19, 16); 9268 Rm = Bits32(opcode, 3, 0); 9269 setflags = BitIsSet(opcode, 20); 9270 shift_n = DecodeImmShiftARM(opcode, shift_t); 9271 9272 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9273 // instructions; 9274 if (Rd == 15 && setflags) 9275 return EmulateSUBSPcLrEtc(opcode, encoding); 9276 break; 9277 default: 9278 return false; 9279 } 9280 // Read the register value from register Rn. 9281 uint32_t val1 = ReadCoreReg(Rn, &success); 9282 if (!success) 9283 return false; 9284 9285 // Read the register value from register Rm. 9286 uint32_t val2 = ReadCoreReg(Rm, &success); 9287 if (!success) 9288 return false; 9289 9290 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9291 if (!success) 9292 return false; 9293 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 9294 9295 EmulateInstruction::Context context; 9296 context.type = EmulateInstruction::eContextImmediate; 9297 context.SetNoArgs(); 9298 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9299 res.carry_out, res.overflow); 9300 } 9301 9302 // Reverse Subtract with Carry (immediate) subtracts a register value and the 9303 // value of NOT (Carry flag) from an immediate value, and writes the result to 9304 // the destination register. It can optionally update the condition flags based 9305 // on the result. 9306 bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode, 9307 const ARMEncoding encoding) { 9308 #if 0 9309 // ARM pseudo code... 9310 if ConditionPassed() then 9311 EncodingSpecificOperations(); 9312 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 9313 if d == 15 then 9314 ALUWritePC(result); // setflags is always FALSE here 9315 else 9316 R[d] = result; 9317 if setflags then 9318 APSR.N = result<31>; 9319 APSR.Z = IsZeroBit(result); 9320 APSR.C = carry; 9321 APSR.V = overflow; 9322 #endif 9323 9324 bool success = false; 9325 9326 uint32_t Rd; // the destination register 9327 uint32_t Rn; // the first operand 9328 bool setflags; 9329 uint32_t 9330 imm32; // the immediate value to be added to the value obtained from Rn 9331 switch (encoding) { 9332 case eEncodingA1: 9333 Rd = Bits32(opcode, 15, 12); 9334 Rn = Bits32(opcode, 19, 16); 9335 setflags = BitIsSet(opcode, 20); 9336 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9337 9338 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9339 // instructions; 9340 if (Rd == 15 && setflags) 9341 return EmulateSUBSPcLrEtc(opcode, encoding); 9342 break; 9343 default: 9344 return false; 9345 } 9346 // Read the register value from the operand register Rn. 9347 uint32_t reg_val = ReadCoreReg(Rn, &success); 9348 if (!success) 9349 return false; 9350 9351 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 9352 9353 EmulateInstruction::Context context; 9354 context.type = EmulateInstruction::eContextImmediate; 9355 context.SetNoArgs(); 9356 9357 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9358 res.carry_out, res.overflow); 9359 } 9360 9361 // Reverse Subtract with Carry (register) subtracts a register value and the 9362 // value of NOT (Carry flag) from an optionally-shifted register value, and 9363 // writes the result to the destination register. It can optionally update the 9364 // condition flags based on the result. 9365 bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode, 9366 const ARMEncoding encoding) { 9367 #if 0 9368 // ARM pseudo code... 9369 if ConditionPassed() then 9370 EncodingSpecificOperations(); 9371 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9372 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 9373 if d == 15 then 9374 ALUWritePC(result); // setflags is always FALSE here 9375 else 9376 R[d] = result; 9377 if setflags then 9378 APSR.N = result<31>; 9379 APSR.Z = IsZeroBit(result); 9380 APSR.C = carry; 9381 APSR.V = overflow; 9382 #endif 9383 9384 bool success = false; 9385 9386 uint32_t Rd; // the destination register 9387 uint32_t Rn; // the first operand 9388 uint32_t Rm; // the second operand 9389 bool setflags; 9390 ARM_ShifterType shift_t; 9391 uint32_t shift_n; // the shift applied to the value read from Rm 9392 switch (encoding) { 9393 case eEncodingA1: 9394 Rd = Bits32(opcode, 15, 12); 9395 Rn = Bits32(opcode, 19, 16); 9396 Rm = Bits32(opcode, 3, 0); 9397 setflags = BitIsSet(opcode, 20); 9398 shift_n = DecodeImmShiftARM(opcode, shift_t); 9399 9400 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9401 // instructions; 9402 if (Rd == 15 && setflags) 9403 return EmulateSUBSPcLrEtc(opcode, encoding); 9404 break; 9405 default: 9406 return false; 9407 } 9408 // Read the register value from register Rn. 9409 uint32_t val1 = ReadCoreReg(Rn, &success); 9410 if (!success) 9411 return false; 9412 9413 // Read the register value from register Rm. 9414 uint32_t val2 = ReadCoreReg(Rm, &success); 9415 if (!success) 9416 return false; 9417 9418 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9419 if (!success) 9420 return false; 9421 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 9422 9423 EmulateInstruction::Context context; 9424 context.type = EmulateInstruction::eContextImmediate; 9425 context.SetNoArgs(); 9426 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9427 res.carry_out, res.overflow); 9428 } 9429 9430 // Subtract with Carry (immediate) subtracts an immediate value and the value 9431 // of 9432 // NOT (Carry flag) from a register value, and writes the result to the 9433 // destination register. 9434 // It can optionally update the condition flags based on the result. 9435 bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode, 9436 const ARMEncoding encoding) { 9437 #if 0 9438 // ARM pseudo code... 9439 if ConditionPassed() then 9440 EncodingSpecificOperations(); 9441 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 9442 if d == 15 then // Can only occur for ARM encoding 9443 ALUWritePC(result); // setflags is always FALSE here 9444 else 9445 R[d] = result; 9446 if setflags then 9447 APSR.N = result<31>; 9448 APSR.Z = IsZeroBit(result); 9449 APSR.C = carry; 9450 APSR.V = overflow; 9451 #endif 9452 9453 bool success = false; 9454 9455 uint32_t Rd; // the destination register 9456 uint32_t Rn; // the first operand 9457 bool setflags; 9458 uint32_t 9459 imm32; // the immediate value to be added to the value obtained from Rn 9460 switch (encoding) { 9461 case eEncodingT1: 9462 Rd = Bits32(opcode, 11, 8); 9463 Rn = Bits32(opcode, 19, 16); 9464 setflags = BitIsSet(opcode, 20); 9465 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9466 if (BadReg(Rd) || BadReg(Rn)) 9467 return false; 9468 break; 9469 case eEncodingA1: 9470 Rd = Bits32(opcode, 15, 12); 9471 Rn = Bits32(opcode, 19, 16); 9472 setflags = BitIsSet(opcode, 20); 9473 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9474 9475 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9476 // instructions; 9477 if (Rd == 15 && setflags) 9478 return EmulateSUBSPcLrEtc(opcode, encoding); 9479 break; 9480 default: 9481 return false; 9482 } 9483 // Read the register value from the operand register Rn. 9484 uint32_t reg_val = ReadCoreReg(Rn, &success); 9485 if (!success) 9486 return false; 9487 9488 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9489 9490 EmulateInstruction::Context context; 9491 context.type = EmulateInstruction::eContextImmediate; 9492 context.SetNoArgs(); 9493 9494 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9495 res.carry_out, res.overflow); 9496 } 9497 9498 // Subtract with Carry (register) subtracts an optionally-shifted register 9499 // value and the value of 9500 // NOT (Carry flag) from a register value, and writes the result to the 9501 // destination register. 9502 // It can optionally update the condition flags based on the result. 9503 bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode, 9504 const ARMEncoding encoding) { 9505 #if 0 9506 // ARM pseudo code... 9507 if ConditionPassed() then 9508 EncodingSpecificOperations(); 9509 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9510 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9511 if d == 15 then // Can only occur for ARM encoding 9512 ALUWritePC(result); // setflags is always FALSE here 9513 else 9514 R[d] = result; 9515 if setflags then 9516 APSR.N = result<31>; 9517 APSR.Z = IsZeroBit(result); 9518 APSR.C = carry; 9519 APSR.V = overflow; 9520 #endif 9521 9522 bool success = false; 9523 9524 uint32_t Rd; // the destination register 9525 uint32_t Rn; // the first operand 9526 uint32_t Rm; // the second operand 9527 bool setflags; 9528 ARM_ShifterType shift_t; 9529 uint32_t shift_n; // the shift applied to the value read from Rm 9530 switch (encoding) { 9531 case eEncodingT1: 9532 Rd = Rn = Bits32(opcode, 2, 0); 9533 Rm = Bits32(opcode, 5, 3); 9534 setflags = !InITBlock(); 9535 shift_t = SRType_LSL; 9536 shift_n = 0; 9537 break; 9538 case eEncodingT2: 9539 Rd = Bits32(opcode, 11, 8); 9540 Rn = Bits32(opcode, 19, 16); 9541 Rm = Bits32(opcode, 3, 0); 9542 setflags = BitIsSet(opcode, 20); 9543 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9544 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9545 return false; 9546 break; 9547 case eEncodingA1: 9548 Rd = Bits32(opcode, 15, 12); 9549 Rn = Bits32(opcode, 19, 16); 9550 Rm = Bits32(opcode, 3, 0); 9551 setflags = BitIsSet(opcode, 20); 9552 shift_n = DecodeImmShiftARM(opcode, shift_t); 9553 9554 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9555 // instructions; 9556 if (Rd == 15 && setflags) 9557 return EmulateSUBSPcLrEtc(opcode, encoding); 9558 break; 9559 default: 9560 return false; 9561 } 9562 // Read the register value from register Rn. 9563 uint32_t val1 = ReadCoreReg(Rn, &success); 9564 if (!success) 9565 return false; 9566 9567 // Read the register value from register Rm. 9568 uint32_t val2 = ReadCoreReg(Rm, &success); 9569 if (!success) 9570 return false; 9571 9572 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9573 if (!success) 9574 return false; 9575 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9576 9577 EmulateInstruction::Context context; 9578 context.type = EmulateInstruction::eContextImmediate; 9579 context.SetNoArgs(); 9580 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9581 res.carry_out, res.overflow); 9582 } 9583 9584 // This instruction subtracts an immediate value from a register value, and 9585 // writes the result to the destination register. It can optionally update the 9586 // condition flags based on the result. 9587 bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode, 9588 const ARMEncoding encoding) { 9589 #if 0 9590 // ARM pseudo code... 9591 if ConditionPassed() then 9592 EncodingSpecificOperations(); 9593 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9594 R[d] = result; 9595 if setflags then 9596 APSR.N = result<31>; 9597 APSR.Z = IsZeroBit(result); 9598 APSR.C = carry; 9599 APSR.V = overflow; 9600 #endif 9601 9602 bool success = false; 9603 9604 uint32_t Rd; // the destination register 9605 uint32_t Rn; // the first operand 9606 bool setflags; 9607 uint32_t imm32; // the immediate value to be subtracted from the value 9608 // obtained from Rn 9609 switch (encoding) { 9610 case eEncodingT1: 9611 Rd = Bits32(opcode, 2, 0); 9612 Rn = Bits32(opcode, 5, 3); 9613 setflags = !InITBlock(); 9614 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9615 break; 9616 case eEncodingT2: 9617 Rd = Rn = Bits32(opcode, 10, 8); 9618 setflags = !InITBlock(); 9619 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9620 break; 9621 case eEncodingT3: 9622 Rd = Bits32(opcode, 11, 8); 9623 Rn = Bits32(opcode, 19, 16); 9624 setflags = BitIsSet(opcode, 20); 9625 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9626 9627 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9628 if (Rd == 15 && setflags) 9629 return EmulateCMPImm(opcode, eEncodingT2); 9630 9631 // if Rn == '1101' then SEE SUB (SP minus immediate); 9632 if (Rn == 13) 9633 return EmulateSUBSPImm(opcode, eEncodingT2); 9634 9635 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9636 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9637 return false; 9638 break; 9639 case eEncodingT4: 9640 Rd = Bits32(opcode, 11, 8); 9641 Rn = Bits32(opcode, 19, 16); 9642 setflags = BitIsSet(opcode, 20); 9643 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9644 9645 // if Rn == '1111' then SEE ADR; 9646 if (Rn == 15) 9647 return EmulateADR(opcode, eEncodingT2); 9648 9649 // if Rn == '1101' then SEE SUB (SP minus immediate); 9650 if (Rn == 13) 9651 return EmulateSUBSPImm(opcode, eEncodingT3); 9652 9653 if (BadReg(Rd)) 9654 return false; 9655 break; 9656 default: 9657 return false; 9658 } 9659 // Read the register value from the operand register Rn. 9660 uint32_t reg_val = ReadCoreReg(Rn, &success); 9661 if (!success) 9662 return false; 9663 9664 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9665 9666 EmulateInstruction::Context context; 9667 context.type = EmulateInstruction::eContextImmediate; 9668 context.SetNoArgs(); 9669 9670 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9671 res.carry_out, res.overflow); 9672 } 9673 9674 // This instruction subtracts an immediate value from a register value, and 9675 // writes the result to the destination register. It can optionally update the 9676 // condition flags based on the result. 9677 bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode, 9678 const ARMEncoding encoding) { 9679 #if 0 9680 // ARM pseudo code... 9681 if ConditionPassed() then 9682 EncodingSpecificOperations(); 9683 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9684 if d == 15 then 9685 ALUWritePC(result); // setflags is always FALSE here 9686 else 9687 R[d] = result; 9688 if setflags then 9689 APSR.N = result<31>; 9690 APSR.Z = IsZeroBit(result); 9691 APSR.C = carry; 9692 APSR.V = overflow; 9693 #endif 9694 9695 bool success = false; 9696 9697 if (ConditionPassed(opcode)) { 9698 uint32_t Rd; // the destination register 9699 uint32_t Rn; // the first operand 9700 bool setflags; 9701 uint32_t imm32; // the immediate value to be subtracted from the value 9702 // obtained from Rn 9703 switch (encoding) { 9704 case eEncodingA1: 9705 Rd = Bits32(opcode, 15, 12); 9706 Rn = Bits32(opcode, 19, 16); 9707 setflags = BitIsSet(opcode, 20); 9708 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9709 9710 // if Rn == '1111' && S == '0' then SEE ADR; 9711 if (Rn == 15 && !setflags) 9712 return EmulateADR(opcode, eEncodingA2); 9713 9714 // if Rn == '1101' then SEE SUB (SP minus immediate); 9715 if (Rn == 13) 9716 return EmulateSUBSPImm(opcode, eEncodingA1); 9717 9718 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9719 // instructions; 9720 if (Rd == 15 && setflags) 9721 return EmulateSUBSPcLrEtc(opcode, encoding); 9722 break; 9723 default: 9724 return false; 9725 } 9726 // Read the register value from the operand register Rn. 9727 uint32_t reg_val = ReadCoreReg(Rn, &success); 9728 if (!success) 9729 return false; 9730 9731 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9732 9733 EmulateInstruction::Context context; 9734 if (Rd == 13) 9735 context.type = EmulateInstruction::eContextAdjustStackPointer; 9736 else 9737 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9738 9739 RegisterInfo dwarf_reg; 9740 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 9741 int64_t imm32_signed = imm32; 9742 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed); 9743 9744 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9745 res.carry_out, res.overflow)) 9746 return false; 9747 } 9748 return true; 9749 } 9750 9751 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a 9752 // register value and an immediate value. It updates the condition flags based 9753 // on the result, and discards the result. 9754 bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode, 9755 const ARMEncoding encoding) { 9756 #if 0 9757 // ARM pseudo code... 9758 if ConditionPassed() then 9759 EncodingSpecificOperations(); 9760 result = R[n] EOR imm32; 9761 APSR.N = result<31>; 9762 APSR.Z = IsZeroBit(result); 9763 APSR.C = carry; 9764 // APSR.V unchanged 9765 #endif 9766 9767 bool success = false; 9768 9769 if (ConditionPassed(opcode)) { 9770 uint32_t Rn; 9771 uint32_t 9772 imm32; // the immediate value to be ANDed to the value obtained from Rn 9773 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9774 switch (encoding) { 9775 case eEncodingT1: 9776 Rn = Bits32(opcode, 19, 16); 9777 imm32 = ThumbExpandImm_C( 9778 opcode, APSR_C, 9779 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9780 if (BadReg(Rn)) 9781 return false; 9782 break; 9783 case eEncodingA1: 9784 Rn = Bits32(opcode, 19, 16); 9785 imm32 = 9786 ARMExpandImm_C(opcode, APSR_C, 9787 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9788 break; 9789 default: 9790 return false; 9791 } 9792 9793 // Read the first operand. 9794 uint32_t val1 = ReadCoreReg(Rn, &success); 9795 if (!success) 9796 return false; 9797 9798 uint32_t result = val1 ^ imm32; 9799 9800 EmulateInstruction::Context context; 9801 context.type = EmulateInstruction::eContextImmediate; 9802 context.SetNoArgs(); 9803 9804 if (!WriteFlags(context, result, carry)) 9805 return false; 9806 } 9807 return true; 9808 } 9809 9810 // Test Equivalence (register) performs a bitwise exclusive OR operation on a 9811 // register value and an optionally-shifted register value. It updates the 9812 // condition flags based on the result, and discards the result. 9813 bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode, 9814 const ARMEncoding encoding) { 9815 #if 0 9816 // ARM pseudo code... 9817 if ConditionPassed() then 9818 EncodingSpecificOperations(); 9819 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9820 result = R[n] EOR shifted; 9821 APSR.N = result<31>; 9822 APSR.Z = IsZeroBit(result); 9823 APSR.C = carry; 9824 // APSR.V unchanged 9825 #endif 9826 9827 bool success = false; 9828 9829 if (ConditionPassed(opcode)) { 9830 uint32_t Rn, Rm; 9831 ARM_ShifterType shift_t; 9832 uint32_t shift_n; // the shift applied to the value read from Rm 9833 uint32_t carry; 9834 switch (encoding) { 9835 case eEncodingT1: 9836 Rn = Bits32(opcode, 19, 16); 9837 Rm = Bits32(opcode, 3, 0); 9838 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9839 if (BadReg(Rn) || BadReg(Rm)) 9840 return false; 9841 break; 9842 case eEncodingA1: 9843 Rn = Bits32(opcode, 19, 16); 9844 Rm = Bits32(opcode, 3, 0); 9845 shift_n = DecodeImmShiftARM(opcode, shift_t); 9846 break; 9847 default: 9848 return false; 9849 } 9850 9851 // Read the first operand. 9852 uint32_t val1 = ReadCoreReg(Rn, &success); 9853 if (!success) 9854 return false; 9855 9856 // Read the second operand. 9857 uint32_t val2 = ReadCoreReg(Rm, &success); 9858 if (!success) 9859 return false; 9860 9861 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9862 if (!success) 9863 return false; 9864 uint32_t result = val1 ^ shifted; 9865 9866 EmulateInstruction::Context context; 9867 context.type = EmulateInstruction::eContextImmediate; 9868 context.SetNoArgs(); 9869 9870 if (!WriteFlags(context, result, carry)) 9871 return false; 9872 } 9873 return true; 9874 } 9875 9876 // Test (immediate) performs a bitwise AND operation on a register value and an 9877 // immediate value. It updates the condition flags based on the result, and 9878 // discards the result. 9879 bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode, 9880 const ARMEncoding encoding) { 9881 #if 0 9882 // ARM pseudo code... 9883 if ConditionPassed() then 9884 EncodingSpecificOperations(); 9885 result = R[n] AND imm32; 9886 APSR.N = result<31>; 9887 APSR.Z = IsZeroBit(result); 9888 APSR.C = carry; 9889 // APSR.V unchanged 9890 #endif 9891 9892 bool success = false; 9893 9894 if (ConditionPassed(opcode)) { 9895 uint32_t Rn; 9896 uint32_t 9897 imm32; // the immediate value to be ANDed to the value obtained from Rn 9898 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9899 switch (encoding) { 9900 case eEncodingT1: 9901 Rn = Bits32(opcode, 19, 16); 9902 imm32 = ThumbExpandImm_C( 9903 opcode, APSR_C, 9904 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9905 if (BadReg(Rn)) 9906 return false; 9907 break; 9908 case eEncodingA1: 9909 Rn = Bits32(opcode, 19, 16); 9910 imm32 = 9911 ARMExpandImm_C(opcode, APSR_C, 9912 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9913 break; 9914 default: 9915 return false; 9916 } 9917 9918 // Read the first operand. 9919 uint32_t val1 = ReadCoreReg(Rn, &success); 9920 if (!success) 9921 return false; 9922 9923 uint32_t result = val1 & imm32; 9924 9925 EmulateInstruction::Context context; 9926 context.type = EmulateInstruction::eContextImmediate; 9927 context.SetNoArgs(); 9928 9929 if (!WriteFlags(context, result, carry)) 9930 return false; 9931 } 9932 return true; 9933 } 9934 9935 // Test (register) performs a bitwise AND operation on a register value and an 9936 // optionally-shifted register value. It updates the condition flags based on 9937 // the result, and discards the result. 9938 bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode, 9939 const ARMEncoding encoding) { 9940 #if 0 9941 // ARM pseudo code... 9942 if ConditionPassed() then 9943 EncodingSpecificOperations(); 9944 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9945 result = R[n] AND shifted; 9946 APSR.N = result<31>; 9947 APSR.Z = IsZeroBit(result); 9948 APSR.C = carry; 9949 // APSR.V unchanged 9950 #endif 9951 9952 bool success = false; 9953 9954 if (ConditionPassed(opcode)) { 9955 uint32_t Rn, Rm; 9956 ARM_ShifterType shift_t; 9957 uint32_t shift_n; // the shift applied to the value read from Rm 9958 uint32_t carry; 9959 switch (encoding) { 9960 case eEncodingT1: 9961 Rn = Bits32(opcode, 2, 0); 9962 Rm = Bits32(opcode, 5, 3); 9963 shift_t = SRType_LSL; 9964 shift_n = 0; 9965 break; 9966 case eEncodingT2: 9967 Rn = Bits32(opcode, 19, 16); 9968 Rm = Bits32(opcode, 3, 0); 9969 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9970 if (BadReg(Rn) || BadReg(Rm)) 9971 return false; 9972 break; 9973 case eEncodingA1: 9974 Rn = Bits32(opcode, 19, 16); 9975 Rm = Bits32(opcode, 3, 0); 9976 shift_n = DecodeImmShiftARM(opcode, shift_t); 9977 break; 9978 default: 9979 return false; 9980 } 9981 9982 // Read the first operand. 9983 uint32_t val1 = ReadCoreReg(Rn, &success); 9984 if (!success) 9985 return false; 9986 9987 // Read the second operand. 9988 uint32_t val2 = ReadCoreReg(Rm, &success); 9989 if (!success) 9990 return false; 9991 9992 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9993 if (!success) 9994 return false; 9995 uint32_t result = val1 & shifted; 9996 9997 EmulateInstruction::Context context; 9998 context.type = EmulateInstruction::eContextImmediate; 9999 context.SetNoArgs(); 10000 10001 if (!WriteFlags(context, result, carry)) 10002 return false; 10003 } 10004 return true; 10005 } 10006 10007 // A8.6.216 SUB (SP minus register) 10008 bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode, 10009 const ARMEncoding encoding) { 10010 #if 0 10011 if ConditionPassed() then 10012 EncodingSpecificOperations(); 10013 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10014 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10015 if d == 15 then // Can only occur for ARM encoding 10016 ALUWritePC(result); // setflags is always FALSE here 10017 else 10018 R[d] = result; 10019 if setflags then 10020 APSR.N = result<31>; 10021 APSR.Z = IsZeroBit(result); 10022 APSR.C = carry; 10023 APSR.V = overflow; 10024 #endif 10025 10026 bool success = false; 10027 10028 if (ConditionPassed(opcode)) { 10029 uint32_t d; 10030 uint32_t m; 10031 bool setflags; 10032 ARM_ShifterType shift_t; 10033 uint32_t shift_n; 10034 10035 switch (encoding) { 10036 case eEncodingT1: 10037 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10038 d = Bits32(opcode, 11, 8); 10039 m = Bits32(opcode, 3, 0); 10040 setflags = BitIsSet(opcode, 20); 10041 10042 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10043 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10044 10045 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then 10046 // UNPREDICTABLE; 10047 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 10048 return false; 10049 10050 // if d == 15 || BadReg(m) then UNPREDICTABLE; 10051 if ((d == 15) || BadReg(m)) 10052 return false; 10053 break; 10054 10055 case eEncodingA1: 10056 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10057 d = Bits32(opcode, 15, 12); 10058 m = Bits32(opcode, 3, 0); 10059 setflags = BitIsSet(opcode, 20); 10060 10061 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10062 // instructions; 10063 if (d == 15 && setflags) 10064 EmulateSUBSPcLrEtc(opcode, encoding); 10065 10066 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10067 shift_n = DecodeImmShiftARM(opcode, shift_t); 10068 break; 10069 10070 default: 10071 return false; 10072 } 10073 10074 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10075 uint32_t Rm = ReadCoreReg(m, &success); 10076 if (!success) 10077 return false; 10078 10079 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10080 if (!success) 10081 return false; 10082 10083 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10084 uint32_t sp_val = ReadCoreReg(SP_REG, &success); 10085 if (!success) 10086 return false; 10087 10088 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1); 10089 10090 EmulateInstruction::Context context; 10091 context.type = eContextArithmetic; 10092 RegisterInfo sp_reg; 10093 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 10094 RegisterInfo dwarf_reg; 10095 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 10096 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg); 10097 10098 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10099 res.carry_out, res.overflow)) 10100 return false; 10101 } 10102 return true; 10103 } 10104 10105 // A8.6.7 ADD (register-shifted register) 10106 bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode, 10107 const ARMEncoding encoding) { 10108 #if 0 10109 if ConditionPassed() then 10110 EncodingSpecificOperations(); 10111 shift_n = UInt(R[s]<7:0>); 10112 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10113 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10114 R[d] = result; 10115 if setflags then 10116 APSR.N = result<31>; 10117 APSR.Z = IsZeroBit(result); 10118 APSR.C = carry; 10119 APSR.V = overflow; 10120 #endif 10121 10122 bool success = false; 10123 10124 if (ConditionPassed(opcode)) { 10125 uint32_t d; 10126 uint32_t n; 10127 uint32_t m; 10128 uint32_t s; 10129 bool setflags; 10130 ARM_ShifterType shift_t; 10131 10132 switch (encoding) { 10133 case eEncodingA1: 10134 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 10135 d = Bits32(opcode, 15, 12); 10136 n = Bits32(opcode, 19, 16); 10137 m = Bits32(opcode, 3, 0); 10138 s = Bits32(opcode, 11, 8); 10139 10140 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 10141 setflags = BitIsSet(opcode, 20); 10142 shift_t = DecodeRegShift(Bits32(opcode, 6, 5)); 10143 10144 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 10145 if ((d == 15) || (n == 15) || (m == 15) || (s == 15)) 10146 return false; 10147 break; 10148 10149 default: 10150 return false; 10151 } 10152 10153 // shift_n = UInt(R[s]<7:0>); 10154 uint32_t Rs = ReadCoreReg(s, &success); 10155 if (!success) 10156 return false; 10157 10158 uint32_t shift_n = Bits32(Rs, 7, 0); 10159 10160 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10161 uint32_t Rm = ReadCoreReg(m, &success); 10162 if (!success) 10163 return false; 10164 10165 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10166 if (!success) 10167 return false; 10168 10169 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10170 uint32_t Rn = ReadCoreReg(n, &success); 10171 if (!success) 10172 return false; 10173 10174 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0); 10175 10176 // R[d] = result; 10177 EmulateInstruction::Context context; 10178 context.type = eContextArithmetic; 10179 RegisterInfo reg_n; 10180 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10181 RegisterInfo reg_m; 10182 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10183 10184 context.SetRegisterRegisterOperands(reg_n, reg_m); 10185 10186 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 10187 res.result)) 10188 return false; 10189 10190 // if setflags then 10191 // APSR.N = result<31>; 10192 // APSR.Z = IsZeroBit(result); 10193 // APSR.C = carry; 10194 // APSR.V = overflow; 10195 if (setflags) 10196 return WriteFlags(context, res.result, res.carry_out, res.overflow); 10197 } 10198 return true; 10199 } 10200 10201 // A8.6.213 SUB (register) 10202 bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode, 10203 const ARMEncoding encoding) { 10204 #if 0 10205 if ConditionPassed() then 10206 EncodingSpecificOperations(); 10207 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10208 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10209 if d == 15 then // Can only occur for ARM encoding 10210 ALUWritePC(result); // setflags is always FALSE here 10211 else 10212 R[d] = result; 10213 if setflags then 10214 APSR.N = result<31>; 10215 APSR.Z = IsZeroBit(result); 10216 APSR.C = carry; 10217 APSR.V = overflow; 10218 #endif 10219 10220 bool success = false; 10221 10222 if (ConditionPassed(opcode)) { 10223 uint32_t d; 10224 uint32_t n; 10225 uint32_t m; 10226 bool setflags; 10227 ARM_ShifterType shift_t; 10228 uint32_t shift_n; 10229 10230 switch (encoding) { 10231 case eEncodingT1: 10232 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 10233 d = Bits32(opcode, 2, 0); 10234 n = Bits32(opcode, 5, 3); 10235 m = Bits32(opcode, 8, 6); 10236 setflags = !InITBlock(); 10237 10238 // (shift_t, shift_n) = (SRType_LSL, 0); 10239 shift_t = SRType_LSL; 10240 shift_n = 0; 10241 10242 break; 10243 10244 case eEncodingT2: 10245 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 10246 d = Bits32(opcode, 11, 8); 10247 n = Bits32(opcode, 19, 16); 10248 m = Bits32(opcode, 3, 0); 10249 setflags = BitIsSet(opcode, 20); 10250 10251 // if Rd == "1111" && S == "1" then SEE CMP (register); 10252 if (d == 15 && setflags == 1) 10253 return EmulateCMPImm(opcode, eEncodingT3); 10254 10255 // if Rn == "1101" then SEE SUB (SP minus register); 10256 if (n == 13) 10257 return EmulateSUBSPReg(opcode, eEncodingT1); 10258 10259 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10260 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10261 10262 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then 10263 // UNPREDICTABLE; 10264 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) || 10265 BadReg(m)) 10266 return false; 10267 10268 break; 10269 10270 case eEncodingA1: 10271 // if Rn == '1101' then SEE SUB (SP minus register); 10272 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 10273 d = Bits32(opcode, 15, 12); 10274 n = Bits32(opcode, 19, 16); 10275 m = Bits32(opcode, 3, 0); 10276 setflags = BitIsSet(opcode, 20); 10277 10278 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10279 // instructions; 10280 if ((d == 15) && setflags) 10281 EmulateSUBSPcLrEtc(opcode, encoding); 10282 10283 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10284 shift_n = DecodeImmShiftARM(opcode, shift_t); 10285 10286 break; 10287 10288 default: 10289 return false; 10290 } 10291 10292 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10293 uint32_t Rm = ReadCoreReg(m, &success); 10294 if (!success) 10295 return false; 10296 10297 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10298 if (!success) 10299 return false; 10300 10301 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10302 uint32_t Rn = ReadCoreReg(n, &success); 10303 if (!success) 10304 return false; 10305 10306 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1); 10307 10308 // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result); 10309 // // setflags is always FALSE here else 10310 // R[d] = result; 10311 // if setflags then 10312 // APSR.N = result<31>; 10313 // APSR.Z = IsZeroBit(result); 10314 // APSR.C = carry; 10315 // APSR.V = overflow; 10316 10317 EmulateInstruction::Context context; 10318 context.type = eContextArithmetic; 10319 RegisterInfo reg_n; 10320 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10321 RegisterInfo reg_m; 10322 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10323 context.SetRegisterRegisterOperands(reg_n, reg_m); 10324 10325 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10326 res.carry_out, res.overflow)) 10327 return false; 10328 } 10329 return true; 10330 } 10331 10332 // A8.6.202 STREX 10333 // Store Register Exclusive calculates an address from a base register value 10334 // and an immediate offset, and stores a word from a register to memory if the 10335 // executing processor has exclusive access to the memory addressed. 10336 bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode, 10337 const ARMEncoding encoding) { 10338 #if 0 10339 if ConditionPassed() then 10340 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10341 address = R[n] + imm32; 10342 if ExclusiveMonitorsPass(address,4) then 10343 MemA[address,4] = R[t]; 10344 R[d] = 0; 10345 else 10346 R[d] = 1; 10347 #endif 10348 10349 bool success = false; 10350 10351 if (ConditionPassed(opcode)) { 10352 uint32_t d; 10353 uint32_t t; 10354 uint32_t n; 10355 uint32_t imm32; 10356 const uint32_t addr_byte_size = GetAddressByteSize(); 10357 10358 switch (encoding) { 10359 case eEncodingT1: 10360 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = 10361 // ZeroExtend(imm8:'00', 10362 // 32); 10363 d = Bits32(opcode, 11, 8); 10364 t = Bits32(opcode, 15, 12); 10365 n = Bits32(opcode, 19, 16); 10366 imm32 = Bits32(opcode, 7, 0) << 2; 10367 10368 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 10369 if (BadReg(d) || BadReg(t) || (n == 15)) 10370 return false; 10371 10372 // if d == n || d == t then UNPREDICTABLE; 10373 if ((d == n) || (d == t)) 10374 return false; 10375 10376 break; 10377 10378 case eEncodingA1: 10379 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero 10380 // offset 10381 d = Bits32(opcode, 15, 12); 10382 t = Bits32(opcode, 3, 0); 10383 n = Bits32(opcode, 19, 16); 10384 imm32 = 0; 10385 10386 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 10387 if ((d == 15) || (t == 15) || (n == 15)) 10388 return false; 10389 10390 // if d == n || d == t then UNPREDICTABLE; 10391 if ((d == n) || (d == t)) 10392 return false; 10393 10394 break; 10395 10396 default: 10397 return false; 10398 } 10399 10400 // address = R[n] + imm32; 10401 uint32_t Rn = ReadCoreReg(n, &success); 10402 if (!success) 10403 return false; 10404 10405 addr_t address = Rn + imm32; 10406 10407 RegisterInfo base_reg; 10408 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10409 RegisterInfo data_reg; 10410 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10411 EmulateInstruction::Context context; 10412 context.type = eContextRegisterStore; 10413 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32); 10414 10415 // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass 10416 // (address, addr_byte_size)) -- For now, for the sake of emulation, we 10417 // will say this 10418 // always return 10419 // true. 10420 if (true) { 10421 // MemA[address,4] = R[t]; 10422 uint32_t Rt = 10423 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 10424 if (!success) 10425 return false; 10426 10427 if (!MemAWrite(context, address, Rt, addr_byte_size)) 10428 return false; 10429 10430 // R[d] = 0; 10431 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 10432 return false; 10433 } 10434 #if 0 // unreachable because if true 10435 else 10436 { 10437 // R[d] = 1; 10438 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 10439 return false; 10440 } 10441 #endif // unreachable because if true 10442 } 10443 return true; 10444 } 10445 10446 // A8.6.197 STRB (immediate, ARM) 10447 bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode, 10448 const ARMEncoding encoding) { 10449 #if 0 10450 if ConditionPassed() then 10451 EncodingSpecificOperations(); 10452 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10453 address = if index then offset_addr else R[n]; 10454 MemU[address,1] = R[t]<7:0>; 10455 if wback then R[n] = offset_addr; 10456 #endif 10457 10458 bool success = false; 10459 10460 if (ConditionPassed(opcode)) { 10461 uint32_t t; 10462 uint32_t n; 10463 uint32_t imm32; 10464 bool index; 10465 bool add; 10466 bool wback; 10467 10468 switch (encoding) { 10469 case eEncodingA1: 10470 // if P == '0' && W == '1' then SEE STRBT; 10471 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10472 t = Bits32(opcode, 15, 12); 10473 n = Bits32(opcode, 19, 16); 10474 imm32 = Bits32(opcode, 11, 0); 10475 10476 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10477 index = BitIsSet(opcode, 24); 10478 add = BitIsSet(opcode, 23); 10479 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10480 10481 // if t == 15 then UNPREDICTABLE; 10482 if (t == 15) 10483 return false; 10484 10485 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10486 if (wback && ((n == 15) || (n == t))) 10487 return false; 10488 10489 break; 10490 10491 default: 10492 return false; 10493 } 10494 10495 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10496 uint32_t Rn = ReadCoreReg(n, &success); 10497 if (!success) 10498 return false; 10499 10500 addr_t offset_addr; 10501 if (add) 10502 offset_addr = Rn + imm32; 10503 else 10504 offset_addr = Rn - imm32; 10505 10506 // address = if index then offset_addr else R[n]; 10507 addr_t address; 10508 if (index) 10509 address = offset_addr; 10510 else 10511 address = Rn; 10512 10513 // MemU[address,1] = R[t]<7:0>; 10514 uint32_t Rt = ReadCoreReg(t, &success); 10515 if (!success) 10516 return false; 10517 10518 RegisterInfo base_reg; 10519 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10520 RegisterInfo data_reg; 10521 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10522 EmulateInstruction::Context context; 10523 context.type = eContextRegisterStore; 10524 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10525 10526 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1)) 10527 return false; 10528 10529 // if wback then R[n] = offset_addr; 10530 if (wback) { 10531 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10532 offset_addr)) 10533 return false; 10534 } 10535 } 10536 return true; 10537 } 10538 10539 // A8.6.194 STR (immediate, ARM) 10540 bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode, 10541 const ARMEncoding encoding) { 10542 #if 0 10543 if ConditionPassed() then 10544 EncodingSpecificOperations(); 10545 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10546 address = if index then offset_addr else R[n]; 10547 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10548 if wback then R[n] = offset_addr; 10549 #endif 10550 10551 bool success = false; 10552 10553 if (ConditionPassed(opcode)) { 10554 uint32_t t; 10555 uint32_t n; 10556 uint32_t imm32; 10557 bool index; 10558 bool add; 10559 bool wback; 10560 10561 const uint32_t addr_byte_size = GetAddressByteSize(); 10562 10563 switch (encoding) { 10564 case eEncodingA1: 10565 // if P == '0' && W == '1' then SEE STRT; 10566 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == 10567 // '000000000100' then SEE PUSH; 10568 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10569 t = Bits32(opcode, 15, 12); 10570 n = Bits32(opcode, 19, 16); 10571 imm32 = Bits32(opcode, 11, 0); 10572 10573 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10574 index = BitIsSet(opcode, 24); 10575 add = BitIsSet(opcode, 23); 10576 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10577 10578 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10579 if (wback && ((n == 15) || (n == t))) 10580 return false; 10581 10582 break; 10583 10584 default: 10585 return false; 10586 } 10587 10588 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10589 uint32_t Rn = ReadCoreReg(n, &success); 10590 if (!success) 10591 return false; 10592 10593 addr_t offset_addr; 10594 if (add) 10595 offset_addr = Rn + imm32; 10596 else 10597 offset_addr = Rn - imm32; 10598 10599 // address = if index then offset_addr else R[n]; 10600 addr_t address; 10601 if (index) 10602 address = offset_addr; 10603 else 10604 address = Rn; 10605 10606 RegisterInfo base_reg; 10607 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10608 RegisterInfo data_reg; 10609 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10610 EmulateInstruction::Context context; 10611 context.type = eContextRegisterStore; 10612 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10613 10614 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10615 uint32_t Rt = ReadCoreReg(t, &success); 10616 if (!success) 10617 return false; 10618 10619 if (t == 15) { 10620 uint32_t pc_value = ReadCoreReg(PC_REG, &success); 10621 if (!success) 10622 return false; 10623 10624 if (!MemUWrite(context, address, pc_value, addr_byte_size)) 10625 return false; 10626 } else { 10627 if (!MemUWrite(context, address, Rt, addr_byte_size)) 10628 return false; 10629 } 10630 10631 // if wback then R[n] = offset_addr; 10632 if (wback) { 10633 context.type = eContextAdjustBaseRegister; 10634 context.SetImmediate(offset_addr); 10635 10636 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10637 offset_addr)) 10638 return false; 10639 } 10640 } 10641 return true; 10642 } 10643 10644 // A8.6.66 LDRD (immediate) 10645 // Load Register Dual (immediate) calculates an address from a base register 10646 // value and an immediate offset, loads two words from memory, and writes them 10647 // to two registers. It can use offset, post-indexed, or pre-indexed 10648 // addressing. 10649 bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode, 10650 const ARMEncoding encoding) { 10651 #if 0 10652 if ConditionPassed() then 10653 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10654 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10655 address = if index then offset_addr else R[n]; 10656 R[t] = MemA[address,4]; 10657 R[t2] = MemA[address+4,4]; 10658 if wback then R[n] = offset_addr; 10659 #endif 10660 10661 bool success = false; 10662 10663 if (ConditionPassed(opcode)) { 10664 uint32_t t; 10665 uint32_t t2; 10666 uint32_t n; 10667 uint32_t imm32; 10668 bool index; 10669 bool add; 10670 bool wback; 10671 10672 switch (encoding) { 10673 case eEncodingT1: 10674 // if P == '0' && W == '0' then SEE 'Related encodings'; 10675 // if Rn == '1111' then SEE LDRD (literal); 10676 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10677 // ZeroExtend(imm8:'00', 32); 10678 t = Bits32(opcode, 15, 12); 10679 t2 = Bits32(opcode, 11, 8); 10680 n = Bits32(opcode, 19, 16); 10681 imm32 = Bits32(opcode, 7, 0) << 2; 10682 10683 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10684 index = BitIsSet(opcode, 24); 10685 add = BitIsSet(opcode, 23); 10686 wback = BitIsSet(opcode, 21); 10687 10688 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10689 if (wback && ((n == t) || (n == t2))) 10690 return false; 10691 10692 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10693 if (BadReg(t) || BadReg(t2) || (t == t2)) 10694 return false; 10695 10696 break; 10697 10698 case eEncodingA1: 10699 // if Rn == '1111' then SEE LDRD (literal); 10700 // if Rt<0> == '1' then UNPREDICTABLE; 10701 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10702 // 32); 10703 t = Bits32(opcode, 15, 12); 10704 if (BitIsSet(t, 0)) 10705 return false; 10706 t2 = t + 1; 10707 n = Bits32(opcode, 19, 16); 10708 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10709 10710 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10711 index = BitIsSet(opcode, 24); 10712 add = BitIsSet(opcode, 23); 10713 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10714 10715 // if P == '0' && W == '1' then UNPREDICTABLE; 10716 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10717 return false; 10718 10719 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10720 if (wback && ((n == t) || (n == t2))) 10721 return false; 10722 10723 // if t2 == 15 then UNPREDICTABLE; 10724 if (t2 == 15) 10725 return false; 10726 10727 break; 10728 10729 default: 10730 return false; 10731 } 10732 10733 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10734 uint32_t Rn = ReadCoreReg(n, &success); 10735 if (!success) 10736 return false; 10737 10738 addr_t offset_addr; 10739 if (add) 10740 offset_addr = Rn + imm32; 10741 else 10742 offset_addr = Rn - imm32; 10743 10744 // address = if index then offset_addr else R[n]; 10745 addr_t address; 10746 if (index) 10747 address = offset_addr; 10748 else 10749 address = Rn; 10750 10751 // R[t] = MemA[address,4]; 10752 RegisterInfo base_reg; 10753 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10754 10755 EmulateInstruction::Context context; 10756 if (n == 13) 10757 context.type = eContextPopRegisterOffStack; 10758 else 10759 context.type = eContextRegisterLoad; 10760 context.SetAddress(address); 10761 10762 const uint32_t addr_byte_size = GetAddressByteSize(); 10763 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10764 if (!success) 10765 return false; 10766 10767 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10768 return false; 10769 10770 // R[t2] = MemA[address+4,4]; 10771 context.SetAddress(address + 4); 10772 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10773 if (!success) 10774 return false; 10775 10776 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10777 data)) 10778 return false; 10779 10780 // if wback then R[n] = offset_addr; 10781 if (wback) { 10782 context.type = eContextAdjustBaseRegister; 10783 context.SetAddress(offset_addr); 10784 10785 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10786 offset_addr)) 10787 return false; 10788 } 10789 } 10790 return true; 10791 } 10792 10793 // A8.6.68 LDRD (register) 10794 // Load Register Dual (register) calculates an address from a base register 10795 // value and a register offset, loads two words from memory, and writes them to 10796 // two registers. It can use offset, post-indexed or pre-indexed addressing. 10797 bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode, 10798 const ARMEncoding encoding) { 10799 #if 0 10800 if ConditionPassed() then 10801 EncodingSpecificOperations(); 10802 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10803 address = if index then offset_addr else R[n]; 10804 R[t] = MemA[address,4]; 10805 R[t2] = MemA[address+4,4]; 10806 if wback then R[n] = offset_addr; 10807 #endif 10808 10809 bool success = false; 10810 10811 if (ConditionPassed(opcode)) { 10812 uint32_t t; 10813 uint32_t t2; 10814 uint32_t n; 10815 uint32_t m; 10816 bool index; 10817 bool add; 10818 bool wback; 10819 10820 switch (encoding) { 10821 case eEncodingA1: 10822 // if Rt<0> == '1' then UNPREDICTABLE; 10823 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10824 t = Bits32(opcode, 15, 12); 10825 if (BitIsSet(t, 0)) 10826 return false; 10827 t2 = t + 1; 10828 n = Bits32(opcode, 19, 16); 10829 m = Bits32(opcode, 3, 0); 10830 10831 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10832 index = BitIsSet(opcode, 24); 10833 add = BitIsSet(opcode, 23); 10834 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10835 10836 // if P == '0' && W == '1' then UNPREDICTABLE; 10837 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10838 return false; 10839 10840 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10841 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10842 return false; 10843 10844 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10845 if (wback && ((n == 15) || (n == t) || (n == t2))) 10846 return false; 10847 10848 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10849 if ((ArchVersion() < 6) && wback && (m == n)) 10850 return false; 10851 break; 10852 10853 default: 10854 return false; 10855 } 10856 10857 uint32_t Rn = ReadCoreReg(n, &success); 10858 if (!success) 10859 return false; 10860 RegisterInfo base_reg; 10861 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10862 10863 uint32_t Rm = ReadCoreReg(m, &success); 10864 if (!success) 10865 return false; 10866 RegisterInfo offset_reg; 10867 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10868 10869 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10870 addr_t offset_addr; 10871 if (add) 10872 offset_addr = Rn + Rm; 10873 else 10874 offset_addr = Rn - Rm; 10875 10876 // address = if index then offset_addr else R[n]; 10877 addr_t address; 10878 if (index) 10879 address = offset_addr; 10880 else 10881 address = Rn; 10882 10883 EmulateInstruction::Context context; 10884 if (n == 13) 10885 context.type = eContextPopRegisterOffStack; 10886 else 10887 context.type = eContextRegisterLoad; 10888 context.SetAddress(address); 10889 10890 // R[t] = MemA[address,4]; 10891 const uint32_t addr_byte_size = GetAddressByteSize(); 10892 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10893 if (!success) 10894 return false; 10895 10896 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10897 return false; 10898 10899 // R[t2] = MemA[address+4,4]; 10900 10901 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10902 if (!success) 10903 return false; 10904 10905 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10906 data)) 10907 return false; 10908 10909 // if wback then R[n] = offset_addr; 10910 if (wback) { 10911 context.type = eContextAdjustBaseRegister; 10912 context.SetAddress(offset_addr); 10913 10914 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10915 offset_addr)) 10916 return false; 10917 } 10918 } 10919 return true; 10920 } 10921 10922 // A8.6.200 STRD (immediate) 10923 // Store Register Dual (immediate) calculates an address from a base register 10924 // value and an immediate offset, and stores two words from two registers to 10925 // memory. It can use offset, post-indexed, or pre-indexed addressing. 10926 bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode, 10927 const ARMEncoding encoding) { 10928 #if 0 10929 if ConditionPassed() then 10930 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10931 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10932 address = if index then offset_addr else R[n]; 10933 MemA[address,4] = R[t]; 10934 MemA[address+4,4] = R[t2]; 10935 if wback then R[n] = offset_addr; 10936 #endif 10937 10938 bool success = false; 10939 10940 if (ConditionPassed(opcode)) { 10941 uint32_t t; 10942 uint32_t t2; 10943 uint32_t n; 10944 uint32_t imm32; 10945 bool index; 10946 bool add; 10947 bool wback; 10948 10949 switch (encoding) { 10950 case eEncodingT1: 10951 // if P == '0' && W == '0' then SEE 'Related encodings'; 10952 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10953 // ZeroExtend(imm8:'00', 32); 10954 t = Bits32(opcode, 15, 12); 10955 t2 = Bits32(opcode, 11, 8); 10956 n = Bits32(opcode, 19, 16); 10957 imm32 = Bits32(opcode, 7, 0) << 2; 10958 10959 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10960 index = BitIsSet(opcode, 24); 10961 add = BitIsSet(opcode, 23); 10962 wback = BitIsSet(opcode, 21); 10963 10964 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10965 if (wback && ((n == t) || (n == t2))) 10966 return false; 10967 10968 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10969 if ((n == 15) || BadReg(t) || BadReg(t2)) 10970 return false; 10971 10972 break; 10973 10974 case eEncodingA1: 10975 // if Rt<0> == '1' then UNPREDICTABLE; 10976 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10977 // 32); 10978 t = Bits32(opcode, 15, 12); 10979 if (BitIsSet(t, 0)) 10980 return false; 10981 10982 t2 = t + 1; 10983 n = Bits32(opcode, 19, 16); 10984 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10985 10986 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10987 index = BitIsSet(opcode, 24); 10988 add = BitIsSet(opcode, 23); 10989 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10990 10991 // if P == '0' && W == '1' then UNPREDICTABLE; 10992 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10993 return false; 10994 10995 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10996 if (wback && ((n == 15) || (n == t) || (n == t2))) 10997 return false; 10998 10999 // if t2 == 15 then UNPREDICTABLE; 11000 if (t2 == 15) 11001 return false; 11002 11003 break; 11004 11005 default: 11006 return false; 11007 } 11008 11009 RegisterInfo base_reg; 11010 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11011 11012 uint32_t Rn = ReadCoreReg(n, &success); 11013 if (!success) 11014 return false; 11015 11016 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11017 addr_t offset_addr; 11018 if (add) 11019 offset_addr = Rn + imm32; 11020 else 11021 offset_addr = Rn - imm32; 11022 11023 // address = if index then offset_addr else R[n]; 11024 addr_t address; 11025 if (index) 11026 address = offset_addr; 11027 else 11028 address = Rn; 11029 11030 // MemA[address,4] = R[t]; 11031 RegisterInfo data_reg; 11032 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11033 11034 uint32_t data = ReadCoreReg(t, &success); 11035 if (!success) 11036 return false; 11037 11038 EmulateInstruction::Context context; 11039 if (n == 13) 11040 context.type = eContextPushRegisterOnStack; 11041 else 11042 context.type = eContextRegisterStore; 11043 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11044 11045 const uint32_t addr_byte_size = GetAddressByteSize(); 11046 11047 if (!MemAWrite(context, address, data, addr_byte_size)) 11048 return false; 11049 11050 // MemA[address+4,4] = R[t2]; 11051 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11052 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11053 (address + 4) - Rn); 11054 11055 data = ReadCoreReg(t2, &success); 11056 if (!success) 11057 return false; 11058 11059 if (!MemAWrite(context, address + 4, data, addr_byte_size)) 11060 return false; 11061 11062 // if wback then R[n] = offset_addr; 11063 if (wback) { 11064 if (n == 13) 11065 context.type = eContextAdjustStackPointer; 11066 else 11067 context.type = eContextAdjustBaseRegister; 11068 context.SetAddress(offset_addr); 11069 11070 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11071 offset_addr)) 11072 return false; 11073 } 11074 } 11075 return true; 11076 } 11077 11078 // A8.6.201 STRD (register) 11079 bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode, 11080 const ARMEncoding encoding) { 11081 #if 0 11082 if ConditionPassed() then 11083 EncodingSpecificOperations(); 11084 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11085 address = if index then offset_addr else R[n]; 11086 MemA[address,4] = R[t]; 11087 MemA[address+4,4] = R[t2]; 11088 if wback then R[n] = offset_addr; 11089 #endif 11090 11091 bool success = false; 11092 11093 if (ConditionPassed(opcode)) { 11094 uint32_t t; 11095 uint32_t t2; 11096 uint32_t n; 11097 uint32_t m; 11098 bool index; 11099 bool add; 11100 bool wback; 11101 11102 switch (encoding) { 11103 case eEncodingA1: 11104 // if Rt<0> == '1' then UNPREDICTABLE; 11105 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 11106 t = Bits32(opcode, 15, 12); 11107 if (BitIsSet(t, 0)) 11108 return false; 11109 11110 t2 = t + 1; 11111 n = Bits32(opcode, 19, 16); 11112 m = Bits32(opcode, 3, 0); 11113 11114 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11115 index = BitIsSet(opcode, 24); 11116 add = BitIsSet(opcode, 23); 11117 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11118 11119 // if P == '0' && W == '1' then UNPREDICTABLE; 11120 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11121 return false; 11122 11123 // if t2 == 15 || m == 15 then UNPREDICTABLE; 11124 if ((t2 == 15) || (m == 15)) 11125 return false; 11126 11127 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11128 if (wback && ((n == 15) || (n == t) || (n == t2))) 11129 return false; 11130 11131 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 11132 if ((ArchVersion() < 6) && wback && (m == n)) 11133 return false; 11134 11135 break; 11136 11137 default: 11138 return false; 11139 } 11140 11141 RegisterInfo base_reg; 11142 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11143 RegisterInfo offset_reg; 11144 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 11145 RegisterInfo data_reg; 11146 11147 uint32_t Rn = ReadCoreReg(n, &success); 11148 if (!success) 11149 return false; 11150 11151 uint32_t Rm = ReadCoreReg(m, &success); 11152 if (!success) 11153 return false; 11154 11155 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11156 addr_t offset_addr; 11157 if (add) 11158 offset_addr = Rn + Rm; 11159 else 11160 offset_addr = Rn - Rm; 11161 11162 // address = if index then offset_addr else R[n]; 11163 addr_t address; 11164 if (index) 11165 address = offset_addr; 11166 else 11167 address = Rn; 11168 // MemA[address,4] = R[t]; 11169 uint32_t Rt = ReadCoreReg(t, &success); 11170 if (!success) 11171 return false; 11172 11173 EmulateInstruction::Context context; 11174 if (t == 13) 11175 context.type = eContextPushRegisterOnStack; 11176 else 11177 context.type = eContextRegisterStore; 11178 11179 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11180 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11181 data_reg); 11182 11183 const uint32_t addr_byte_size = GetAddressByteSize(); 11184 11185 if (!MemAWrite(context, address, Rt, addr_byte_size)) 11186 return false; 11187 11188 // MemA[address+4,4] = R[t2]; 11189 uint32_t Rt2 = ReadCoreReg(t2, &success); 11190 if (!success) 11191 return false; 11192 11193 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11194 11195 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11196 data_reg); 11197 11198 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size)) 11199 return false; 11200 11201 // if wback then R[n] = offset_addr; 11202 if (wback) { 11203 context.type = eContextAdjustBaseRegister; 11204 context.SetAddress(offset_addr); 11205 11206 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11207 offset_addr)) 11208 return false; 11209 } 11210 } 11211 return true; 11212 } 11213 11214 // A8.6.319 VLDM 11215 // Vector Load Multiple loads multiple extension registers from consecutive 11216 // memory locations using an address from an ARM core register. 11217 bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode, 11218 const ARMEncoding encoding) { 11219 #if 0 11220 if ConditionPassed() then 11221 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11222 address = if add then R[n] else R[n]-imm32; 11223 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11224 for r = 0 to regs-1 11225 if single_regs then 11226 S[d+r] = MemA[address,4]; address = address+4; 11227 else 11228 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 11229 // Combine the word-aligned words in the correct order for 11230 // current endianness. 11231 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11232 #endif 11233 11234 bool success = false; 11235 11236 if (ConditionPassed(opcode)) { 11237 bool single_regs; 11238 bool add; 11239 bool wback; 11240 uint32_t d; 11241 uint32_t n; 11242 uint32_t imm32; 11243 uint32_t regs; 11244 11245 switch (encoding) { 11246 case eEncodingT1: 11247 case eEncodingA1: 11248 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11249 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11250 // if P == '1' && W == '0' then SEE VLDR; 11251 // if P == U && W == '1' then UNDEFINED; 11252 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11253 return false; 11254 11255 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11256 // !), 101 (DB with !) 11257 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11258 single_regs = false; 11259 add = BitIsSet(opcode, 23); 11260 wback = BitIsSet(opcode, 21); 11261 11262 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11263 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11264 n = Bits32(opcode, 19, 16); 11265 imm32 = Bits32(opcode, 7, 0) << 2; 11266 11267 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 11268 regs = Bits32(opcode, 7, 0) / 2; 11269 11270 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11271 // UNPREDICTABLE; 11272 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 11273 return false; 11274 11275 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11276 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11277 return false; 11278 11279 break; 11280 11281 case eEncodingT2: 11282 case eEncodingA2: 11283 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11284 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11285 // if P == '1' && W == '0' then SEE VLDR; 11286 // if P == U && W == '1' then UNDEFINED; 11287 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11288 return false; 11289 11290 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11291 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11292 // == '1'); d = 11293 // UInt(Vd:D); n = UInt(Rn); 11294 single_regs = true; 11295 add = BitIsSet(opcode, 23); 11296 wback = BitIsSet(opcode, 21); 11297 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11298 n = Bits32(opcode, 19, 16); 11299 11300 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11301 imm32 = Bits32(opcode, 7, 0) << 2; 11302 regs = Bits32(opcode, 7, 0); 11303 11304 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11305 // UNPREDICTABLE; 11306 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11307 return false; 11308 11309 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11310 if ((regs == 0) || ((d + regs) > 32)) 11311 return false; 11312 break; 11313 11314 default: 11315 return false; 11316 } 11317 11318 RegisterInfo base_reg; 11319 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11320 11321 uint32_t Rn = ReadCoreReg(n, &success); 11322 if (!success) 11323 return false; 11324 11325 // address = if add then R[n] else R[n]-imm32; 11326 addr_t address; 11327 if (add) 11328 address = Rn; 11329 else 11330 address = Rn - imm32; 11331 11332 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11333 EmulateInstruction::Context context; 11334 11335 if (wback) { 11336 uint32_t value; 11337 if (add) 11338 value = Rn + imm32; 11339 else 11340 value = Rn - imm32; 11341 11342 context.type = eContextAdjustBaseRegister; 11343 context.SetImmediateSigned(value - Rn); 11344 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11345 value)) 11346 return false; 11347 } 11348 11349 const uint32_t addr_byte_size = GetAddressByteSize(); 11350 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11351 11352 context.type = eContextRegisterLoad; 11353 11354 // for r = 0 to regs-1 11355 for (uint32_t r = 0; r < regs; ++r) { 11356 if (single_regs) { 11357 // S[d+r] = MemA[address,4]; address = address+4; 11358 context.SetRegisterPlusOffset(base_reg, address - Rn); 11359 11360 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11361 if (!success) 11362 return false; 11363 11364 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11365 start_reg + d + r, data)) 11366 return false; 11367 11368 address = address + 4; 11369 } else { 11370 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = 11371 // address+8; 11372 context.SetRegisterPlusOffset(base_reg, address - Rn); 11373 uint32_t word1 = 11374 MemARead(context, address, addr_byte_size, 0, &success); 11375 if (!success) 11376 return false; 11377 11378 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn); 11379 uint32_t word2 = 11380 MemARead(context, address + 4, addr_byte_size, 0, &success); 11381 if (!success) 11382 return false; 11383 11384 address = address + 8; 11385 // // Combine the word-aligned words in the correct order for current 11386 // endianness. 11387 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11388 uint64_t data; 11389 if (GetByteOrder() == eByteOrderBig) { 11390 data = word1; 11391 data = (data << 32) | word2; 11392 } else { 11393 data = word2; 11394 data = (data << 32) | word1; 11395 } 11396 11397 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11398 start_reg + d + r, data)) 11399 return false; 11400 } 11401 } 11402 } 11403 return true; 11404 } 11405 11406 // A8.6.399 VSTM 11407 // Vector Store Multiple stores multiple extension registers to consecutive 11408 // memory locations using an address from an 11409 // ARM core register. 11410 bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode, 11411 const ARMEncoding encoding) { 11412 #if 0 11413 if ConditionPassed() then 11414 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11415 address = if add then R[n] else R[n]-imm32; 11416 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11417 for r = 0 to regs-1 11418 if single_regs then 11419 MemA[address,4] = S[d+r]; address = address+4; 11420 else 11421 // Store as two word-aligned words in the correct order for 11422 // current endianness. 11423 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11424 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11425 address = address+8; 11426 #endif 11427 11428 bool success = false; 11429 11430 if (ConditionPassed(opcode)) { 11431 bool single_regs; 11432 bool add; 11433 bool wback; 11434 uint32_t d; 11435 uint32_t n; 11436 uint32_t imm32; 11437 uint32_t regs; 11438 11439 switch (encoding) { 11440 case eEncodingT1: 11441 case eEncodingA1: 11442 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11443 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11444 // if P == '1' && W == '0' then SEE VSTR; 11445 // if P == U && W == '1' then UNDEFINED; 11446 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11447 return false; 11448 11449 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11450 // !), 101 (DB with !) 11451 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11452 single_regs = false; 11453 add = BitIsSet(opcode, 23); 11454 wback = BitIsSet(opcode, 21); 11455 11456 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11457 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11458 n = Bits32(opcode, 19, 16); 11459 imm32 = Bits32(opcode, 7, 0) << 2; 11460 11461 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11462 regs = Bits32(opcode, 7, 0) / 2; 11463 11464 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11465 // UNPREDICTABLE; 11466 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11467 return false; 11468 11469 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11470 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11471 return false; 11472 11473 break; 11474 11475 case eEncodingT2: 11476 case eEncodingA2: 11477 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11478 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11479 // if P == '1' && W == '0' then SEE VSTR; 11480 // if P == U && W == '1' then UNDEFINED; 11481 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11482 return false; 11483 11484 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11485 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11486 // == '1'); d = 11487 // UInt(Vd:D); n = UInt(Rn); 11488 single_regs = true; 11489 add = BitIsSet(opcode, 23); 11490 wback = BitIsSet(opcode, 21); 11491 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11492 n = Bits32(opcode, 19, 16); 11493 11494 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11495 imm32 = Bits32(opcode, 7, 0) << 2; 11496 regs = Bits32(opcode, 7, 0); 11497 11498 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11499 // UNPREDICTABLE; 11500 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11501 return false; 11502 11503 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11504 if ((regs == 0) || ((d + regs) > 32)) 11505 return false; 11506 11507 break; 11508 11509 default: 11510 return false; 11511 } 11512 11513 RegisterInfo base_reg; 11514 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11515 11516 uint32_t Rn = ReadCoreReg(n, &success); 11517 if (!success) 11518 return false; 11519 11520 // address = if add then R[n] else R[n]-imm32; 11521 addr_t address; 11522 if (add) 11523 address = Rn; 11524 else 11525 address = Rn - imm32; 11526 11527 EmulateInstruction::Context context; 11528 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11529 if (wback) { 11530 uint32_t value; 11531 if (add) 11532 value = Rn + imm32; 11533 else 11534 value = Rn - imm32; 11535 11536 context.type = eContextAdjustBaseRegister; 11537 context.SetRegisterPlusOffset(base_reg, value - Rn); 11538 11539 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11540 value)) 11541 return false; 11542 } 11543 11544 const uint32_t addr_byte_size = GetAddressByteSize(); 11545 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11546 11547 context.type = eContextRegisterStore; 11548 // for r = 0 to regs-1 11549 for (uint32_t r = 0; r < regs; ++r) { 11550 11551 if (single_regs) { 11552 // MemA[address,4] = S[d+r]; address = address+4; 11553 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11554 start_reg + d + r, 0, &success); 11555 if (!success) 11556 return false; 11557 11558 RegisterInfo data_reg; 11559 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11560 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11561 address - Rn); 11562 if (!MemAWrite(context, address, data, addr_byte_size)) 11563 return false; 11564 11565 address = address + 4; 11566 } else { 11567 // // Store as two word-aligned words in the correct order for current 11568 // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else 11569 // D[d+r]<31:0>; 11570 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else 11571 // D[d+r]<63:32>; 11572 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11573 start_reg + d + r, 0, &success); 11574 if (!success) 11575 return false; 11576 11577 RegisterInfo data_reg; 11578 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11579 11580 if (GetByteOrder() == eByteOrderBig) { 11581 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11582 address - Rn); 11583 if (!MemAWrite(context, address, Bits64(data, 63, 32), 11584 addr_byte_size)) 11585 return false; 11586 11587 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11588 (address + 4) - Rn); 11589 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11590 addr_byte_size)) 11591 return false; 11592 } else { 11593 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11594 address - Rn); 11595 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11596 return false; 11597 11598 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11599 (address + 4) - Rn); 11600 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11601 addr_byte_size)) 11602 return false; 11603 } 11604 // address = address+8; 11605 address = address + 8; 11606 } 11607 } 11608 } 11609 return true; 11610 } 11611 11612 // A8.6.320 11613 // This instruction loads a single extension register from memory, using an 11614 // address from an ARM core register, with an optional offset. 11615 bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode, 11616 ARMEncoding encoding) { 11617 #if 0 11618 if ConditionPassed() then 11619 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11620 base = if n == 15 then Align(PC,4) else R[n]; 11621 address = if add then (base + imm32) else (base - imm32); 11622 if single_reg then 11623 S[d] = MemA[address,4]; 11624 else 11625 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11626 // Combine the word-aligned words in the correct order for current 11627 // endianness. 11628 D[d] = if BigEndian() then word1:word2 else word2:word1; 11629 #endif 11630 11631 bool success = false; 11632 11633 if (ConditionPassed(opcode)) { 11634 bool single_reg; 11635 bool add; 11636 uint32_t imm32; 11637 uint32_t d; 11638 uint32_t n; 11639 11640 switch (encoding) { 11641 case eEncodingT1: 11642 case eEncodingA1: 11643 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11644 // 32); 11645 single_reg = false; 11646 add = BitIsSet(opcode, 23); 11647 imm32 = Bits32(opcode, 7, 0) << 2; 11648 11649 // d = UInt(D:Vd); n = UInt(Rn); 11650 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11651 n = Bits32(opcode, 19, 16); 11652 11653 break; 11654 11655 case eEncodingT2: 11656 case eEncodingA2: 11657 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11658 single_reg = true; 11659 add = BitIsSet(opcode, 23); 11660 imm32 = Bits32(opcode, 7, 0) << 2; 11661 11662 // d = UInt(Vd:D); n = UInt(Rn); 11663 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11664 n = Bits32(opcode, 19, 16); 11665 11666 break; 11667 11668 default: 11669 return false; 11670 } 11671 RegisterInfo base_reg; 11672 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11673 11674 uint32_t Rn = ReadCoreReg(n, &success); 11675 if (!success) 11676 return false; 11677 11678 // base = if n == 15 then Align(PC,4) else R[n]; 11679 uint32_t base; 11680 if (n == 15) 11681 base = AlignPC(Rn); 11682 else 11683 base = Rn; 11684 11685 // address = if add then (base + imm32) else (base - imm32); 11686 addr_t address; 11687 if (add) 11688 address = base + imm32; 11689 else 11690 address = base - imm32; 11691 11692 const uint32_t addr_byte_size = GetAddressByteSize(); 11693 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11694 11695 EmulateInstruction::Context context; 11696 context.type = eContextRegisterLoad; 11697 context.SetRegisterPlusOffset(base_reg, address - base); 11698 11699 if (single_reg) { 11700 // S[d] = MemA[address,4]; 11701 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11702 if (!success) 11703 return false; 11704 11705 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11706 data)) 11707 return false; 11708 } else { 11709 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11710 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success); 11711 if (!success) 11712 return false; 11713 11714 context.SetRegisterPlusOffset(base_reg, (address + 4) - base); 11715 uint32_t word2 = 11716 MemARead(context, address + 4, addr_byte_size, 0, &success); 11717 if (!success) 11718 return false; 11719 // // Combine the word-aligned words in the correct order for current 11720 // endianness. 11721 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11722 uint64_t data64; 11723 if (GetByteOrder() == eByteOrderBig) { 11724 data64 = word1; 11725 data64 = (data64 << 32) | word2; 11726 } else { 11727 data64 = word2; 11728 data64 = (data64 << 32) | word1; 11729 } 11730 11731 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11732 data64)) 11733 return false; 11734 } 11735 } 11736 return true; 11737 } 11738 11739 // A8.6.400 VSTR 11740 // This instruction stores a signle extension register to memory, using an 11741 // address from an ARM core register, with an optional offset. 11742 bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode, 11743 ARMEncoding encoding) { 11744 #if 0 11745 if ConditionPassed() then 11746 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11747 address = if add then (R[n] + imm32) else (R[n] - imm32); 11748 if single_reg then 11749 MemA[address,4] = S[d]; 11750 else 11751 // Store as two word-aligned words in the correct order for current 11752 // endianness. 11753 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11754 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11755 #endif 11756 11757 bool success = false; 11758 11759 if (ConditionPassed(opcode)) { 11760 bool single_reg; 11761 bool add; 11762 uint32_t imm32; 11763 uint32_t d; 11764 uint32_t n; 11765 11766 switch (encoding) { 11767 case eEncodingT1: 11768 case eEncodingA1: 11769 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11770 // 32); 11771 single_reg = false; 11772 add = BitIsSet(opcode, 23); 11773 imm32 = Bits32(opcode, 7, 0) << 2; 11774 11775 // d = UInt(D:Vd); n = UInt(Rn); 11776 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11777 n = Bits32(opcode, 19, 16); 11778 11779 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11780 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11781 return false; 11782 11783 break; 11784 11785 case eEncodingT2: 11786 case eEncodingA2: 11787 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11788 single_reg = true; 11789 add = BitIsSet(opcode, 23); 11790 imm32 = Bits32(opcode, 7, 0) << 2; 11791 11792 // d = UInt(Vd:D); n = UInt(Rn); 11793 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11794 n = Bits32(opcode, 19, 16); 11795 11796 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11797 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11798 return false; 11799 11800 break; 11801 11802 default: 11803 return false; 11804 } 11805 11806 RegisterInfo base_reg; 11807 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11808 11809 uint32_t Rn = ReadCoreReg(n, &success); 11810 if (!success) 11811 return false; 11812 11813 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11814 addr_t address; 11815 if (add) 11816 address = Rn + imm32; 11817 else 11818 address = Rn - imm32; 11819 11820 const uint32_t addr_byte_size = GetAddressByteSize(); 11821 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11822 11823 RegisterInfo data_reg; 11824 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg); 11825 EmulateInstruction::Context context; 11826 context.type = eContextRegisterStore; 11827 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11828 11829 if (single_reg) { 11830 // MemA[address,4] = S[d]; 11831 uint32_t data = 11832 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11833 if (!success) 11834 return false; 11835 11836 if (!MemAWrite(context, address, data, addr_byte_size)) 11837 return false; 11838 } else { 11839 // // Store as two word-aligned words in the correct order for current 11840 // endianness. 11841 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11842 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11843 uint64_t data = 11844 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11845 if (!success) 11846 return false; 11847 11848 if (GetByteOrder() == eByteOrderBig) { 11849 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size)) 11850 return false; 11851 11852 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11853 (address + 4) - Rn); 11854 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11855 addr_byte_size)) 11856 return false; 11857 } else { 11858 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11859 return false; 11860 11861 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11862 (address + 4) - Rn); 11863 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11864 addr_byte_size)) 11865 return false; 11866 } 11867 } 11868 } 11869 return true; 11870 } 11871 11872 // A8.6.307 VLDI1 (multiple single elements) This instruction loads elements 11873 // from memory into one, two, three or four registers, without de-interleaving. 11874 // Every element of each register is loaded. 11875 bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode, 11876 ARMEncoding encoding) { 11877 #if 0 11878 if ConditionPassed() then 11879 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11880 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11881 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11882 for r = 0 to regs-1 11883 for e = 0 to elements-1 11884 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11885 address = address + ebytes; 11886 #endif 11887 11888 bool success = false; 11889 11890 if (ConditionPassed(opcode)) { 11891 uint32_t regs; 11892 uint32_t alignment; 11893 uint32_t ebytes; 11894 uint32_t esize; 11895 uint32_t elements; 11896 uint32_t d; 11897 uint32_t n; 11898 uint32_t m; 11899 bool wback; 11900 bool register_index; 11901 11902 switch (encoding) { 11903 case eEncodingT1: 11904 case eEncodingA1: { 11905 // case type of 11906 // when '0111' 11907 // regs = 1; if align<1> == '1' then UNDEFINED; 11908 // when '1010' 11909 // regs = 2; if align == '11' then UNDEFINED; 11910 // when '0110' 11911 // regs = 3; if align<1> == '1' then UNDEFINED; 11912 // when '0010' 11913 // regs = 4; 11914 // otherwise 11915 // SEE 'Related encodings'; 11916 uint32_t type = Bits32(opcode, 11, 8); 11917 uint32_t align = Bits32(opcode, 5, 4); 11918 if (type == 7) // '0111' 11919 { 11920 regs = 1; 11921 if (BitIsSet(align, 1)) 11922 return false; 11923 } else if (type == 10) // '1010' 11924 { 11925 regs = 2; 11926 if (align == 3) 11927 return false; 11928 11929 } else if (type == 6) // '0110' 11930 { 11931 regs = 3; 11932 if (BitIsSet(align, 1)) 11933 return false; 11934 } else if (type == 2) // '0010' 11935 { 11936 regs = 4; 11937 } else 11938 return false; 11939 11940 // alignment = if align == '00' then 1 else 4 << UInt(align); 11941 if (align == 0) 11942 alignment = 1; 11943 else 11944 alignment = 4 << align; 11945 11946 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11947 ebytes = 1 << Bits32(opcode, 7, 6); 11948 esize = 8 * ebytes; 11949 elements = 8 / ebytes; 11950 11951 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11952 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11953 n = Bits32(opcode, 19, 15); 11954 m = Bits32(opcode, 3, 0); 11955 11956 // wback = (m != 15); register_index = (m != 15 && m != 13); 11957 wback = (m != 15); 11958 register_index = ((m != 15) && (m != 13)); 11959 11960 // if d+regs > 32 then UNPREDICTABLE; 11961 if ((d + regs) > 32) 11962 return false; 11963 } break; 11964 11965 default: 11966 return false; 11967 } 11968 11969 RegisterInfo base_reg; 11970 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11971 11972 uint32_t Rn = ReadCoreReg(n, &success); 11973 if (!success) 11974 return false; 11975 11976 // address = R[n]; if (address MOD alignment) != 0 then 11977 // GenerateAlignmentException(); 11978 addr_t address = Rn; 11979 if ((address % alignment) != 0) 11980 return false; 11981 11982 EmulateInstruction::Context context; 11983 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11984 if (wback) { 11985 uint32_t Rm = ReadCoreReg(m, &success); 11986 if (!success) 11987 return false; 11988 11989 uint32_t offset; 11990 if (register_index) 11991 offset = Rm; 11992 else 11993 offset = 8 * regs; 11994 11995 uint32_t value = Rn + offset; 11996 context.type = eContextAdjustBaseRegister; 11997 context.SetRegisterPlusOffset(base_reg, offset); 11998 11999 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12000 value)) 12001 return false; 12002 } 12003 12004 // for r = 0 to regs-1 12005 for (uint32_t r = 0; r < regs; ++r) { 12006 // for e = 0 to elements-1 12007 uint64_t assembled_data = 0; 12008 for (uint32_t e = 0; e < elements; ++e) { 12009 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 12010 context.type = eContextRegisterLoad; 12011 context.SetRegisterPlusOffset(base_reg, address - Rn); 12012 uint64_t data = MemURead(context, address, ebytes, 0, &success); 12013 if (!success) 12014 return false; 12015 12016 assembled_data = 12017 (data << (e * esize)) | 12018 assembled_data; // New data goes to the left of existing data 12019 12020 // address = address + ebytes; 12021 address = address + ebytes; 12022 } 12023 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12024 assembled_data)) 12025 return false; 12026 } 12027 } 12028 return true; 12029 } 12030 12031 // A8.6.308 VLD1 (single element to one lane) 12032 // 12033 bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode, 12034 const ARMEncoding encoding) { 12035 #if 0 12036 if ConditionPassed() then 12037 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12038 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12039 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12040 Elem[D[d],index,esize] = MemU[address,ebytes]; 12041 #endif 12042 12043 bool success = false; 12044 12045 if (ConditionPassed(opcode)) { 12046 uint32_t ebytes; 12047 uint32_t esize; 12048 uint32_t index; 12049 uint32_t alignment; 12050 uint32_t d; 12051 uint32_t n; 12052 uint32_t m; 12053 bool wback; 12054 bool register_index; 12055 12056 switch (encoding) { 12057 case eEncodingT1: 12058 case eEncodingA1: { 12059 uint32_t size = Bits32(opcode, 11, 10); 12060 uint32_t index_align = Bits32(opcode, 7, 4); 12061 // if size == '11' then SEE VLD1 (single element to all lanes); 12062 if (size == 3) 12063 return EmulateVLD1SingleAll(opcode, encoding); 12064 // case size of 12065 if (size == 0) // when '00' 12066 { 12067 // if index_align<0> != '0' then UNDEFINED; 12068 if (BitIsClear(index_align, 0)) 12069 return false; 12070 12071 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12072 ebytes = 1; 12073 esize = 8; 12074 index = Bits32(index_align, 3, 1); 12075 alignment = 1; 12076 } else if (size == 1) // when '01' 12077 { 12078 // if index_align<1> != '0' then UNDEFINED; 12079 if (BitIsClear(index_align, 1)) 12080 return false; 12081 12082 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12083 ebytes = 2; 12084 esize = 16; 12085 index = Bits32(index_align, 3, 2); 12086 12087 // alignment = if index_align<0> == '0' then 1 else 2; 12088 if (BitIsClear(index_align, 0)) 12089 alignment = 1; 12090 else 12091 alignment = 2; 12092 } else if (size == 2) // when '10' 12093 { 12094 // if index_align<2> != '0' then UNDEFINED; 12095 if (BitIsClear(index_align, 2)) 12096 return false; 12097 12098 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12099 // UNDEFINED; 12100 if ((Bits32(index_align, 1, 0) != 0) && 12101 (Bits32(index_align, 1, 0) != 3)) 12102 return false; 12103 12104 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12105 ebytes = 4; 12106 esize = 32; 12107 index = Bit32(index_align, 3); 12108 12109 // alignment = if index_align<1:0> == '00' then 1 else 4; 12110 if (Bits32(index_align, 1, 0) == 0) 12111 alignment = 1; 12112 else 12113 alignment = 4; 12114 } else { 12115 return false; 12116 } 12117 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12118 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12119 n = Bits32(opcode, 19, 16); 12120 m = Bits32(opcode, 3, 0); 12121 12122 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12123 // then UNPREDICTABLE; 12124 wback = (m != 15); 12125 register_index = ((m != 15) && (m != 13)); 12126 12127 if (n == 15) 12128 return false; 12129 12130 } break; 12131 12132 default: 12133 return false; 12134 } 12135 12136 RegisterInfo base_reg; 12137 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12138 12139 uint32_t Rn = ReadCoreReg(n, &success); 12140 if (!success) 12141 return false; 12142 12143 // address = R[n]; if (address MOD alignment) != 0 then 12144 // GenerateAlignmentException(); 12145 addr_t address = Rn; 12146 if ((address % alignment) != 0) 12147 return false; 12148 12149 EmulateInstruction::Context context; 12150 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12151 if (wback) { 12152 uint32_t Rm = ReadCoreReg(m, &success); 12153 if (!success) 12154 return false; 12155 12156 uint32_t offset; 12157 if (register_index) 12158 offset = Rm; 12159 else 12160 offset = ebytes; 12161 12162 uint32_t value = Rn + offset; 12163 12164 context.type = eContextAdjustBaseRegister; 12165 context.SetRegisterPlusOffset(base_reg, offset); 12166 12167 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12168 value)) 12169 return false; 12170 } 12171 12172 // Elem[D[d],index,esize] = MemU[address,ebytes]; 12173 uint32_t element = MemURead(context, address, esize, 0, &success); 12174 if (!success) 12175 return false; 12176 12177 element = element << (index * esize); 12178 12179 uint64_t reg_data = 12180 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12181 if (!success) 12182 return false; 12183 12184 uint64_t all_ones = -1; 12185 uint64_t mask = all_ones 12186 << ((index + 1) * esize); // mask is all 1's to left of 12187 // where 'element' goes, & all 0's 12188 // at element & to the right of element. 12189 if (index > 0) 12190 mask = mask | Bits64(all_ones, (index * esize) - 1, 12191 0); // add 1's to the right of where 'element' goes. 12192 // now mask should be 0's where element goes & 1's everywhere else. 12193 12194 uint64_t masked_reg = 12195 reg_data & mask; // Take original reg value & zero out 'element' bits 12196 reg_data = 12197 masked_reg & element; // Put 'element' into those bits in reg_data. 12198 12199 context.type = eContextRegisterLoad; 12200 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 12201 reg_data)) 12202 return false; 12203 } 12204 return true; 12205 } 12206 12207 // A8.6.391 VST1 (multiple single elements) Vector Store (multiple single 12208 // elements) stores elements to memory from one, two, three, or four registers, 12209 // without interleaving. Every element of each register is stored. 12210 bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode, 12211 ARMEncoding encoding) { 12212 #if 0 12213 if ConditionPassed() then 12214 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12215 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12216 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12217 for r = 0 to regs-1 12218 for e = 0 to elements-1 12219 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12220 address = address + ebytes; 12221 #endif 12222 12223 bool success = false; 12224 12225 if (ConditionPassed(opcode)) { 12226 uint32_t regs; 12227 uint32_t alignment; 12228 uint32_t ebytes; 12229 uint32_t esize; 12230 uint32_t elements; 12231 uint32_t d; 12232 uint32_t n; 12233 uint32_t m; 12234 bool wback; 12235 bool register_index; 12236 12237 switch (encoding) { 12238 case eEncodingT1: 12239 case eEncodingA1: { 12240 uint32_t type = Bits32(opcode, 11, 8); 12241 uint32_t align = Bits32(opcode, 5, 4); 12242 12243 // case type of 12244 if (type == 7) // when '0111' 12245 { 12246 // regs = 1; if align<1> == '1' then UNDEFINED; 12247 regs = 1; 12248 if (BitIsSet(align, 1)) 12249 return false; 12250 } else if (type == 10) // when '1010' 12251 { 12252 // regs = 2; if align == '11' then UNDEFINED; 12253 regs = 2; 12254 if (align == 3) 12255 return false; 12256 } else if (type == 6) // when '0110' 12257 { 12258 // regs = 3; if align<1> == '1' then UNDEFINED; 12259 regs = 3; 12260 if (BitIsSet(align, 1)) 12261 return false; 12262 } else if (type == 2) // when '0010' 12263 // regs = 4; 12264 regs = 4; 12265 else // otherwise 12266 // SEE 'Related encodings'; 12267 return false; 12268 12269 // alignment = if align == '00' then 1 else 4 << UInt(align); 12270 if (align == 0) 12271 alignment = 1; 12272 else 12273 alignment = 4 << align; 12274 12275 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 12276 ebytes = 1 << Bits32(opcode, 7, 6); 12277 esize = 8 * ebytes; 12278 elements = 8 / ebytes; 12279 12280 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12281 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12282 n = Bits32(opcode, 19, 16); 12283 m = Bits32(opcode, 3, 0); 12284 12285 // wback = (m != 15); register_index = (m != 15 && m != 13); 12286 wback = (m != 15); 12287 register_index = ((m != 15) && (m != 13)); 12288 12289 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12290 if ((d + regs) > 32) 12291 return false; 12292 12293 if (n == 15) 12294 return false; 12295 12296 } break; 12297 12298 default: 12299 return false; 12300 } 12301 12302 RegisterInfo base_reg; 12303 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12304 12305 uint32_t Rn = ReadCoreReg(n, &success); 12306 if (!success) 12307 return false; 12308 12309 // address = R[n]; if (address MOD alignment) != 0 then 12310 // GenerateAlignmentException(); 12311 addr_t address = Rn; 12312 if ((address % alignment) != 0) 12313 return false; 12314 12315 EmulateInstruction::Context context; 12316 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12317 if (wback) { 12318 uint32_t Rm = ReadCoreReg(m, &success); 12319 if (!success) 12320 return false; 12321 12322 uint32_t offset; 12323 if (register_index) 12324 offset = Rm; 12325 else 12326 offset = 8 * regs; 12327 12328 context.type = eContextAdjustBaseRegister; 12329 context.SetRegisterPlusOffset(base_reg, offset); 12330 12331 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12332 Rn + offset)) 12333 return false; 12334 } 12335 12336 RegisterInfo data_reg; 12337 context.type = eContextRegisterStore; 12338 // for r = 0 to regs-1 12339 for (uint32_t r = 0; r < regs; ++r) { 12340 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 12341 uint64_t register_data = ReadRegisterUnsigned( 12342 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 12343 if (!success) 12344 return false; 12345 12346 // for e = 0 to elements-1 12347 for (uint32_t e = 0; e < elements; ++e) { 12348 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12349 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize); 12350 12351 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12352 address - Rn); 12353 if (!MemUWrite(context, address, word, ebytes)) 12354 return false; 12355 12356 // address = address + ebytes; 12357 address = address + ebytes; 12358 } 12359 } 12360 } 12361 return true; 12362 } 12363 12364 // A8.6.392 VST1 (single element from one lane) This instruction stores one 12365 // element to memory from one element of a register. 12366 bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode, 12367 ARMEncoding encoding) { 12368 #if 0 12369 if ConditionPassed() then 12370 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12371 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12372 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12373 MemU[address,ebytes] = Elem[D[d],index,esize]; 12374 #endif 12375 12376 bool success = false; 12377 12378 if (ConditionPassed(opcode)) { 12379 uint32_t ebytes; 12380 uint32_t esize; 12381 uint32_t index; 12382 uint32_t alignment; 12383 uint32_t d; 12384 uint32_t n; 12385 uint32_t m; 12386 bool wback; 12387 bool register_index; 12388 12389 switch (encoding) { 12390 case eEncodingT1: 12391 case eEncodingA1: { 12392 uint32_t size = Bits32(opcode, 11, 10); 12393 uint32_t index_align = Bits32(opcode, 7, 4); 12394 12395 // if size == '11' then UNDEFINED; 12396 if (size == 3) 12397 return false; 12398 12399 // case size of 12400 if (size == 0) // when '00' 12401 { 12402 // if index_align<0> != '0' then UNDEFINED; 12403 if (BitIsClear(index_align, 0)) 12404 return false; 12405 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12406 ebytes = 1; 12407 esize = 8; 12408 index = Bits32(index_align, 3, 1); 12409 alignment = 1; 12410 } else if (size == 1) // when '01' 12411 { 12412 // if index_align<1> != '0' then UNDEFINED; 12413 if (BitIsClear(index_align, 1)) 12414 return false; 12415 12416 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12417 ebytes = 2; 12418 esize = 16; 12419 index = Bits32(index_align, 3, 2); 12420 12421 // alignment = if index_align<0> == '0' then 1 else 2; 12422 if (BitIsClear(index_align, 0)) 12423 alignment = 1; 12424 else 12425 alignment = 2; 12426 } else if (size == 2) // when '10' 12427 { 12428 // if index_align<2> != '0' then UNDEFINED; 12429 if (BitIsClear(index_align, 2)) 12430 return false; 12431 12432 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12433 // UNDEFINED; 12434 if ((Bits32(index_align, 1, 0) != 0) && 12435 (Bits32(index_align, 1, 0) != 3)) 12436 return false; 12437 12438 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12439 ebytes = 4; 12440 esize = 32; 12441 index = Bit32(index_align, 3); 12442 12443 // alignment = if index_align<1:0> == '00' then 1 else 4; 12444 if (Bits32(index_align, 1, 0) == 0) 12445 alignment = 1; 12446 else 12447 alignment = 4; 12448 } else { 12449 return false; 12450 } 12451 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12452 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12453 n = Bits32(opcode, 19, 16); 12454 m = Bits32(opcode, 3, 0); 12455 12456 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12457 // then UNPREDICTABLE; 12458 wback = (m != 15); 12459 register_index = ((m != 15) && (m != 13)); 12460 12461 if (n == 15) 12462 return false; 12463 } break; 12464 12465 default: 12466 return false; 12467 } 12468 12469 RegisterInfo base_reg; 12470 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12471 12472 uint32_t Rn = ReadCoreReg(n, &success); 12473 if (!success) 12474 return false; 12475 12476 // address = R[n]; if (address MOD alignment) != 0 then 12477 // GenerateAlignmentException(); 12478 addr_t address = Rn; 12479 if ((address % alignment) != 0) 12480 return false; 12481 12482 EmulateInstruction::Context context; 12483 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12484 if (wback) { 12485 uint32_t Rm = ReadCoreReg(m, &success); 12486 if (!success) 12487 return false; 12488 12489 uint32_t offset; 12490 if (register_index) 12491 offset = Rm; 12492 else 12493 offset = ebytes; 12494 12495 context.type = eContextAdjustBaseRegister; 12496 context.SetRegisterPlusOffset(base_reg, offset); 12497 12498 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12499 Rn + offset)) 12500 return false; 12501 } 12502 12503 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12504 uint64_t register_data = 12505 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12506 if (!success) 12507 return false; 12508 12509 uint64_t word = 12510 Bits64(register_data, ((index + 1) * esize) - 1, index * esize); 12511 12512 RegisterInfo data_reg; 12513 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12514 context.type = eContextRegisterStore; 12515 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 12516 12517 if (!MemUWrite(context, address, word, ebytes)) 12518 return false; 12519 } 12520 return true; 12521 } 12522 12523 // A8.6.309 VLD1 (single element to all lanes) This instruction loads one 12524 // element from memory into every element of one or two vectors. 12525 bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode, 12526 const ARMEncoding encoding) { 12527 #if 0 12528 if ConditionPassed() then 12529 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12530 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12531 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12532 replicated_element = Replicate(MemU[address,ebytes], elements); 12533 for r = 0 to regs-1 12534 D[d+r] = replicated_element; 12535 #endif 12536 12537 bool success = false; 12538 12539 if (ConditionPassed(opcode)) { 12540 uint32_t ebytes; 12541 uint32_t elements; 12542 uint32_t regs; 12543 uint32_t alignment; 12544 uint32_t d; 12545 uint32_t n; 12546 uint32_t m; 12547 bool wback; 12548 bool register_index; 12549 12550 switch (encoding) { 12551 case eEncodingT1: 12552 case eEncodingA1: { 12553 // if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12554 uint32_t size = Bits32(opcode, 7, 6); 12555 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4))) 12556 return false; 12557 12558 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' 12559 // then 1 else 2; 12560 ebytes = 1 << size; 12561 elements = 8 / ebytes; 12562 if (BitIsClear(opcode, 5)) 12563 regs = 1; 12564 else 12565 regs = 2; 12566 12567 // alignment = if a == '0' then 1 else ebytes; 12568 if (BitIsClear(opcode, 4)) 12569 alignment = 1; 12570 else 12571 alignment = ebytes; 12572 12573 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12574 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12575 n = Bits32(opcode, 19, 16); 12576 m = Bits32(opcode, 3, 0); 12577 12578 // wback = (m != 15); register_index = (m != 15 && m != 13); 12579 wback = (m != 15); 12580 register_index = ((m != 15) && (m != 13)); 12581 12582 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12583 if ((d + regs) > 32) 12584 return false; 12585 12586 if (n == 15) 12587 return false; 12588 } break; 12589 12590 default: 12591 return false; 12592 } 12593 12594 RegisterInfo base_reg; 12595 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12596 12597 uint32_t Rn = ReadCoreReg(n, &success); 12598 if (!success) 12599 return false; 12600 12601 // address = R[n]; if (address MOD alignment) != 0 then 12602 // GenerateAlignmentException(); 12603 addr_t address = Rn; 12604 if ((address % alignment) != 0) 12605 return false; 12606 12607 EmulateInstruction::Context context; 12608 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12609 if (wback) { 12610 uint32_t Rm = ReadCoreReg(m, &success); 12611 if (!success) 12612 return false; 12613 12614 uint32_t offset; 12615 if (register_index) 12616 offset = Rm; 12617 else 12618 offset = ebytes; 12619 12620 context.type = eContextAdjustBaseRegister; 12621 context.SetRegisterPlusOffset(base_reg, offset); 12622 12623 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12624 Rn + offset)) 12625 return false; 12626 } 12627 12628 // replicated_element = Replicate(MemU[address,ebytes], elements); 12629 12630 context.type = eContextRegisterLoad; 12631 uint64_t word = MemURead(context, address, ebytes, 0, &success); 12632 if (!success) 12633 return false; 12634 12635 uint64_t replicated_element = 0; 12636 uint32_t esize = ebytes * 8; 12637 for (uint32_t e = 0; e < elements; ++e) 12638 replicated_element = 12639 (replicated_element << esize) | Bits64(word, esize - 1, 0); 12640 12641 // for r = 0 to regs-1 12642 for (uint32_t r = 0; r < regs; ++r) { 12643 // D[d+r] = replicated_element; 12644 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12645 replicated_element)) 12646 return false; 12647 } 12648 } 12649 return true; 12650 } 12651 12652 // B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const? 12653 // instruction provides an exception return without the use of the stack. It 12654 // subtracts the immediate constant from the LR, branches to the resulting 12655 // address, and also copies the SPSR to the CPSR. 12656 bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode, 12657 const ARMEncoding encoding) { 12658 #if 0 12659 if ConditionPassed() then 12660 EncodingSpecificOperations(); 12661 if CurrentInstrSet() == InstrSet_ThumbEE then 12662 UNPREDICTABLE; 12663 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12664 case opcode of 12665 when '0000' result = R[n] AND operand2; // AND 12666 when '0001' result = R[n] EOR operand2; // EOR 12667 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12668 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12669 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12670 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12671 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12672 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12673 when '1100' result = R[n] OR operand2; // ORR 12674 when '1101' result = operand2; // MOV 12675 when '1110' result = R[n] AND NOT(operand2); // BIC 12676 when '1111' result = NOT(operand2); // MVN 12677 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12678 BranchWritePC(result); 12679 #endif 12680 12681 bool success = false; 12682 12683 if (ConditionPassed(opcode)) { 12684 uint32_t n; 12685 uint32_t m; 12686 uint32_t imm32; 12687 bool register_form; 12688 ARM_ShifterType shift_t; 12689 uint32_t shift_n; 12690 uint32_t code; 12691 12692 switch (encoding) { 12693 case eEncodingT1: 12694 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14; 12695 // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; 12696 // // = SUB 12697 n = 14; 12698 imm32 = Bits32(opcode, 7, 0); 12699 register_form = false; 12700 code = 2; 12701 12702 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12703 if (InITBlock() && !LastInITBlock()) 12704 return false; 12705 12706 break; 12707 12708 case eEncodingA1: 12709 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12710 n = Bits32(opcode, 19, 16); 12711 imm32 = ARMExpandImm(opcode); 12712 register_form = false; 12713 code = Bits32(opcode, 24, 21); 12714 12715 break; 12716 12717 case eEncodingA2: 12718 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12719 n = Bits32(opcode, 19, 16); 12720 m = Bits32(opcode, 3, 0); 12721 register_form = true; 12722 12723 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12724 shift_n = DecodeImmShiftARM(opcode, shift_t); 12725 12726 break; 12727 12728 default: 12729 return false; 12730 } 12731 12732 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) 12733 // else imm32; 12734 uint32_t operand2; 12735 if (register_form) { 12736 uint32_t Rm = ReadCoreReg(m, &success); 12737 if (!success) 12738 return false; 12739 12740 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success); 12741 if (!success) 12742 return false; 12743 } else { 12744 operand2 = imm32; 12745 } 12746 12747 uint32_t Rn = ReadCoreReg(n, &success); 12748 if (!success) 12749 return false; 12750 12751 AddWithCarryResult result; 12752 12753 // case opcode of 12754 switch (code) { 12755 case 0: // when '0000' 12756 // result = R[n] AND operand2; // AND 12757 result.result = Rn & operand2; 12758 break; 12759 12760 case 1: // when '0001' 12761 // result = R[n] EOR operand2; // EOR 12762 result.result = Rn ^ operand2; 12763 break; 12764 12765 case 2: // when '0010' 12766 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12767 result = AddWithCarry(Rn, ~(operand2), 1); 12768 break; 12769 12770 case 3: // when '0011' 12771 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12772 result = AddWithCarry(~(Rn), operand2, 1); 12773 break; 12774 12775 case 4: // when '0100' 12776 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12777 result = AddWithCarry(Rn, operand2, 0); 12778 break; 12779 12780 case 5: // when '0101' 12781 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12782 result = AddWithCarry(Rn, operand2, APSR_C); 12783 break; 12784 12785 case 6: // when '0110' 12786 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12787 result = AddWithCarry(Rn, ~(operand2), APSR_C); 12788 break; 12789 12790 case 7: // when '0111' 12791 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12792 result = AddWithCarry(~(Rn), operand2, APSR_C); 12793 break; 12794 12795 case 10: // when '1100' 12796 // result = R[n] OR operand2; // ORR 12797 result.result = Rn | operand2; 12798 break; 12799 12800 case 11: // when '1101' 12801 // result = operand2; // MOV 12802 result.result = operand2; 12803 break; 12804 12805 case 12: // when '1110' 12806 // result = R[n] AND NOT(operand2); // BIC 12807 result.result = Rn & ~(operand2); 12808 break; 12809 12810 case 15: // when '1111' 12811 // result = NOT(operand2); // MVN 12812 result.result = ~(operand2); 12813 break; 12814 12815 default: 12816 return false; 12817 } 12818 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12819 12820 // For now, in emulation mode, we don't have access to the SPSR, so we will 12821 // use the CPSR instead, and hope for the best. 12822 uint32_t spsr = 12823 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12824 if (!success) 12825 return false; 12826 12827 CPSRWriteByInstr(spsr, 15, true); 12828 12829 // BranchWritePC(result); 12830 EmulateInstruction::Context context; 12831 context.type = eContextAdjustPC; 12832 context.SetImmediate(result.result); 12833 12834 BranchWritePC(context, result.result); 12835 } 12836 return true; 12837 } 12838 12839 EmulateInstructionARM::ARMOpcode * 12840 EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode, 12841 uint32_t arm_isa) { 12842 static ARMOpcode g_arm_opcodes[] = { 12843 // Prologue instructions 12844 12845 // push register(s) 12846 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12847 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 12848 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12849 &EmulateInstructionARM::EmulatePUSH, "push <register>"}, 12850 12851 // set r7 to point to a stack offset 12852 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12853 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"}, 12854 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12855 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12856 // copy the stack pointer to ip 12857 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, 12858 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"}, 12859 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12860 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"}, 12861 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12862 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12863 12864 // adjust the stack pointer 12865 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12866 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12867 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12868 &EmulateInstructionARM::EmulateSUBSPReg, 12869 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 12870 12871 // push one register 12872 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12873 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12874 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"}, 12875 12876 // vector push consecutive extension register(s) 12877 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12878 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12879 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12880 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12881 12882 // Epilogue instructions 12883 12884 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12885 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12886 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12887 &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12888 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12889 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12890 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12891 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12892 12893 // Supervisor Call (previously Software Interrupt) 12894 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12895 &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12896 12897 // Branch instructions 12898 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and 12899 // "bl <label>". 12900 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, 12901 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12902 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12903 &EmulateInstructionARM::EmulateB, "b #imm24"}, 12904 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12905 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12906 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, 12907 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12908 // for example, "bx lr" 12909 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, 12910 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12911 // bxj 12912 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, 12913 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12914 12915 // Data-processing instructions 12916 // adc (immediate) 12917 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12918 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12919 // adc (register) 12920 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12921 &EmulateInstructionARM::EmulateADCReg, 12922 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12923 // add (immediate) 12924 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12925 &EmulateInstructionARM::EmulateADDImmARM, 12926 "add{s}<c> <Rd>, <Rn>, #const"}, 12927 // add (register) 12928 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12929 &EmulateInstructionARM::EmulateADDReg, 12930 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12931 // add (register-shifted register) 12932 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, 12933 &EmulateInstructionARM::EmulateADDRegShift, 12934 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12935 // adr 12936 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12937 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12938 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, 12939 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12940 // and (immediate) 12941 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12942 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12943 // and (register) 12944 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12945 &EmulateInstructionARM::EmulateANDReg, 12946 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12947 // bic (immediate) 12948 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12949 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12950 // bic (register) 12951 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12952 &EmulateInstructionARM::EmulateBICReg, 12953 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12954 // eor (immediate) 12955 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12956 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12957 // eor (register) 12958 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12959 &EmulateInstructionARM::EmulateEORReg, 12960 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12961 // orr (immediate) 12962 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12963 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12964 // orr (register) 12965 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12966 &EmulateInstructionARM::EmulateORRReg, 12967 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12968 // rsb (immediate) 12969 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12970 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12971 // rsb (register) 12972 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12973 &EmulateInstructionARM::EmulateRSBReg, 12974 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12975 // rsc (immediate) 12976 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12977 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12978 // rsc (register) 12979 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12980 &EmulateInstructionARM::EmulateRSCReg, 12981 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12982 // sbc (immediate) 12983 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12984 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12985 // sbc (register) 12986 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12987 &EmulateInstructionARM::EmulateSBCReg, 12988 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12989 // sub (immediate, ARM) 12990 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12991 &EmulateInstructionARM::EmulateSUBImmARM, 12992 "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12993 // sub (sp minus immediate) 12994 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12995 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12996 // sub (register) 12997 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12998 &EmulateInstructionARM::EmulateSUBReg, 12999 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 13000 // teq (immediate) 13001 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13002 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 13003 // teq (register) 13004 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13005 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13006 // tst (immediate) 13007 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13008 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 13009 // tst (register) 13010 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13011 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 13012 13013 // mov (immediate) 13014 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13015 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 13016 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 13017 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"}, 13018 // mov (register) 13019 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13020 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 13021 // mvn (immediate) 13022 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13023 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 13024 // mvn (register) 13025 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13026 &EmulateInstructionARM::EmulateMVNReg, 13027 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 13028 // cmn (immediate) 13029 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13030 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13031 // cmn (register) 13032 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13033 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13034 // cmp (immediate) 13035 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13036 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 13037 // cmp (register) 13038 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13039 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 13040 // asr (immediate) 13041 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, 13042 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 13043 // asr (register) 13044 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13045 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 13046 // lsl (immediate) 13047 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13048 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 13049 // lsl (register) 13050 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, 13051 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 13052 // lsr (immediate) 13053 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, 13054 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 13055 // lsr (register) 13056 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13057 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 13058 // rrx is a special case encoding of ror (immediate) 13059 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13060 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 13061 // ror (immediate) 13062 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13063 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 13064 // ror (register) 13065 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, 13066 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 13067 // mul 13068 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, 13069 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"}, 13070 13071 // subs pc, lr and related instructions 13072 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13073 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13074 "<opc>S<c> PC,#<const> | <Rn>,#<const>"}, 13075 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, 13076 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13077 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"}, 13078 13079 // Load instructions 13080 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13081 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13082 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13083 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"}, 13084 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13085 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13086 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13087 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"}, 13088 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13089 &EmulateInstructionARM::EmulateLDRImmediateARM, 13090 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"}, 13091 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13092 &EmulateInstructionARM::EmulateLDRRegister, 13093 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"}, 13094 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13095 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 13096 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13097 &EmulateInstructionARM::EmulateLDRBRegister, 13098 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"}, 13099 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13100 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13101 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13102 &EmulateInstructionARM::EmulateLDRHRegister, 13103 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13104 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13105 &EmulateInstructionARM::EmulateLDRSBImmediate, 13106 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"}, 13107 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13108 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"}, 13109 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13110 &EmulateInstructionARM::EmulateLDRSBRegister, 13111 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13112 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13113 &EmulateInstructionARM::EmulateLDRSHImmediate, 13114 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 13115 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13116 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13117 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13118 &EmulateInstructionARM::EmulateLDRSHRegister, 13119 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13120 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13121 &EmulateInstructionARM::EmulateLDRDImmediate, 13122 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 13123 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13124 &EmulateInstructionARM::EmulateLDRDRegister, 13125 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13126 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13127 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13128 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13129 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13130 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13131 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13132 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13133 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13134 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13135 &EmulateInstructionARM::EmulateVLD1Multiple, 13136 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13137 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13138 &EmulateInstructionARM::EmulateVLD1Single, 13139 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13140 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13141 &EmulateInstructionARM::EmulateVLD1SingleAll, 13142 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13143 13144 // Store instructions 13145 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13146 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13147 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13148 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"}, 13149 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13150 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13151 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13152 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"}, 13153 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13154 &EmulateInstructionARM::EmulateSTRRegister, 13155 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"}, 13156 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13157 &EmulateInstructionARM::EmulateSTRHRegister, 13158 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"}, 13159 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13160 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 13161 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13162 &EmulateInstructionARM::EmulateSTRBImmARM, 13163 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13164 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13165 &EmulateInstructionARM::EmulateSTRImmARM, 13166 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13167 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13168 &EmulateInstructionARM::EmulateSTRDImm, 13169 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 13170 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13171 &EmulateInstructionARM::EmulateSTRDReg, 13172 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13173 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13174 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13175 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13176 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13177 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13178 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 13179 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13180 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 13181 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13182 &EmulateInstructionARM::EmulateVST1Multiple, 13183 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13184 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13185 &EmulateInstructionARM::EmulateVST1Single, 13186 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13187 13188 // Other instructions 13189 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13190 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13191 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13192 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"}, 13193 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13194 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13195 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13196 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"}, 13197 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13198 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"} 13199 13200 }; 13201 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 13202 13203 for (size_t i = 0; i < k_num_arm_opcodes; ++i) { 13204 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 13205 (g_arm_opcodes[i].variants & arm_isa) != 0) 13206 return &g_arm_opcodes[i]; 13207 } 13208 return nullptr; 13209 } 13210 13211 EmulateInstructionARM::ARMOpcode * 13212 EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode, 13213 uint32_t arm_isa) { 13214 13215 static ARMOpcode g_thumb_opcodes[] = { 13216 // Prologue instructions 13217 13218 // push register(s) 13219 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, 13220 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 13221 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13222 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"}, 13223 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13224 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"}, 13225 13226 // set r7 to point to a stack offset 13227 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13228 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"}, 13229 // copy the stack pointer to r7 13230 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, 13231 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"}, 13232 // move from high register to low register (comes after "mov r7, sp" to 13233 // resolve ambiguity) 13234 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, 13235 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"}, 13236 13237 // PC-relative load into register (see also EmulateADDSPRm) 13238 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13239 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 13240 13241 // adjust the stack pointer 13242 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, 13243 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 13244 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13245 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 13246 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13247 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 13248 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13249 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 13250 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13251 &EmulateInstructionARM::EmulateSUBSPReg, 13252 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 13253 13254 // vector push consecutive extension register(s) 13255 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13256 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 13257 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13258 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 13259 13260 // Epilogue instructions 13261 13262 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13263 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 13264 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13265 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 13266 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13267 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 13268 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13269 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"}, 13270 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13271 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"}, 13272 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13273 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 13274 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13275 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 13276 13277 // Supervisor Call (previously Software Interrupt) 13278 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13279 &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 13280 13281 // If Then makes up to four following instructions conditional. 13282 // The next 5 opcode _must_ come before the if then instruction 13283 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13284 &EmulateInstructionARM::EmulateNop, "nop"}, 13285 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13286 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 13287 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13288 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 13289 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13290 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 13291 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13292 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 13293 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13294 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 13295 13296 // Branch instructions 13297 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 13298 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13299 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 13300 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13301 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 13302 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13303 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 13304 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13305 &EmulateInstructionARM::EmulateB, 13306 "b<c>.w #imm8 (outside or last in IT)"}, 13307 // J1 == J2 == 1 13308 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, 13309 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 13310 // J1 == J2 == 1 13311 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, 13312 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 13313 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, 13314 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 13315 // for example, "bx lr" 13316 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, 13317 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 13318 // bxj 13319 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, 13320 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 13321 // compare and branch 13322 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13323 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 13324 // table branch byte 13325 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13326 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 13327 // table branch halfword 13328 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13329 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 13330 13331 // Data-processing instructions 13332 // adc (immediate) 13333 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13334 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 13335 // adc (register) 13336 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, 13337 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 13338 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13339 &EmulateInstructionARM::EmulateADCReg, 13340 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13341 // add (register) 13342 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13343 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 13344 // Make sure "add sp, <Rm>" comes before this instruction, so there's no 13345 // ambiguity decoding the two. 13346 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, 13347 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 13348 // adr 13349 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13350 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13351 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13352 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 13353 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13354 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13355 // and (immediate) 13356 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13357 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 13358 // and (register) 13359 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13360 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 13361 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13362 &EmulateInstructionARM::EmulateANDReg, 13363 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13364 // bic (immediate) 13365 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13366 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 13367 // bic (register) 13368 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, 13369 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 13370 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13371 &EmulateInstructionARM::EmulateBICReg, 13372 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13373 // eor (immediate) 13374 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13375 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 13376 // eor (register) 13377 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, 13378 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 13379 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13380 &EmulateInstructionARM::EmulateEORReg, 13381 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13382 // orr (immediate) 13383 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13384 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 13385 // orr (register) 13386 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, 13387 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 13388 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13389 &EmulateInstructionARM::EmulateORRReg, 13390 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13391 // rsb (immediate) 13392 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, 13393 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 13394 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13395 &EmulateInstructionARM::EmulateRSBImm, 13396 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 13397 // rsb (register) 13398 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13399 &EmulateInstructionARM::EmulateRSBReg, 13400 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13401 // sbc (immediate) 13402 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13403 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13404 // sbc (register) 13405 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, 13406 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 13407 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13408 &EmulateInstructionARM::EmulateSBCReg, 13409 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13410 // add (immediate, Thumb) 13411 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13412 &EmulateInstructionARM::EmulateADDImmThumb, 13413 "adds|add<c> <Rd>,<Rn>,#<imm3>"}, 13414 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13415 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"}, 13416 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13417 &EmulateInstructionARM::EmulateADDImmThumb, 13418 "add{s}<c>.w <Rd>,<Rn>,#<const>"}, 13419 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13420 &EmulateInstructionARM::EmulateADDImmThumb, 13421 "addw<c> <Rd>,<Rn>,#<imm12>"}, 13422 // sub (immediate, Thumb) 13423 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13424 &EmulateInstructionARM::EmulateSUBImmThumb, 13425 "subs|sub<c> <Rd>, <Rn> #imm3"}, 13426 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, 13427 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 13428 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13429 &EmulateInstructionARM::EmulateSUBImmThumb, 13430 "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 13431 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13432 &EmulateInstructionARM::EmulateSUBImmThumb, 13433 "subw<c> <Rd>, <Rn>, #imm12"}, 13434 // sub (sp minus immediate) 13435 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13436 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 13437 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13438 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 13439 // sub (register) 13440 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13441 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 13442 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13443 &EmulateInstructionARM::EmulateSUBReg, 13444 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 13445 // teq (immediate) 13446 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13447 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 13448 // teq (register) 13449 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13450 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13451 // tst (immediate) 13452 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13453 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 13454 // tst (register) 13455 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, 13456 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 13457 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13458 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 13459 13460 // move from high register to high register 13461 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, 13462 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 13463 // move from low register to low register 13464 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13465 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 13466 // mov{s}<c>.w <Rd>, <Rm> 13467 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13468 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 13469 // move immediate 13470 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13471 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 13472 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13473 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 13474 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13475 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 13476 // mvn (immediate) 13477 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13478 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 13479 // mvn (register) 13480 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13481 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 13482 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13483 &EmulateInstructionARM::EmulateMVNReg, 13484 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 13485 // cmn (immediate) 13486 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13487 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13488 // cmn (register) 13489 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13490 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 13491 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13492 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13493 // cmp (immediate) 13494 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13495 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 13496 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13497 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 13498 // cmp (register) (Rn and Rm both from r0-r7) 13499 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, 13500 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13501 // cmp (register) (Rn and Rm not both from r0-r7) 13502 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, 13503 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13504 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, 13505 &EmulateInstructionARM::EmulateCMPReg, 13506 "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 13507 // asr (immediate) 13508 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13509 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 13510 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13511 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 13512 // asr (register) 13513 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, 13514 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 13515 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13516 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13517 // lsl (immediate) 13518 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13519 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 13520 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13521 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 13522 // lsl (register) 13523 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13524 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 13525 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13526 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13527 // lsr (immediate) 13528 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13529 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 13530 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13531 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 13532 // lsr (register) 13533 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13534 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 13535 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13536 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13537 // rrx is a special case encoding of ror (immediate) 13538 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13539 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 13540 // ror (immediate) 13541 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13542 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 13543 // ror (register) 13544 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13545 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 13546 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13547 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13548 // mul 13549 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13550 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"}, 13551 // mul 13552 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13553 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"}, 13554 13555 // subs pc, lr and related instructions 13556 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13557 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"}, 13558 13559 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE 13560 // LDM.. Instructions in this table; 13561 // otherwise the wrong instructions will be selected. 13562 13563 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13564 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"}, 13565 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13566 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"}, 13567 13568 // Load instructions 13569 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13570 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13571 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13572 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"}, 13573 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13574 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13575 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13576 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 13577 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13578 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 13579 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13580 &EmulateInstructionARM::EmulateLDRRtRnImm, 13581 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 13582 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13583 &EmulateInstructionARM::EmulateLDRRtRnImm, 13584 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 13585 // Thumb2 PC-relative load into register 13586 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13587 &EmulateInstructionARM::EmulateLDRRtPCRelative, 13588 "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 13589 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13590 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"}, 13591 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13592 &EmulateInstructionARM::EmulateLDRRegister, 13593 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"}, 13594 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13595 &EmulateInstructionARM::EmulateLDRBImmediate, 13596 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"}, 13597 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13598 &EmulateInstructionARM::EmulateLDRBImmediate, 13599 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13600 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13601 &EmulateInstructionARM::EmulateLDRBImmediate, 13602 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"}, 13603 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13604 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"}, 13605 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13606 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"}, 13607 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13608 &EmulateInstructionARM::EmulateLDRBRegister, 13609 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13610 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13611 &EmulateInstructionARM::EmulateLDRHImmediate, 13612 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"}, 13613 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13614 &EmulateInstructionARM::EmulateLDRHImmediate, 13615 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13616 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13617 &EmulateInstructionARM::EmulateLDRHImmediate, 13618 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"}, 13619 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13620 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13621 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13622 &EmulateInstructionARM::EmulateLDRHRegister, 13623 "ldrh<c> <Rt>, [<Rn>,<Rm>]"}, 13624 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13625 &EmulateInstructionARM::EmulateLDRHRegister, 13626 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13627 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13628 &EmulateInstructionARM::EmulateLDRSBImmediate, 13629 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"}, 13630 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13631 &EmulateInstructionARM::EmulateLDRSBImmediate, 13632 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13633 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13634 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"}, 13635 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13636 &EmulateInstructionARM::EmulateLDRSBRegister, 13637 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"}, 13638 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13639 &EmulateInstructionARM::EmulateLDRSBRegister, 13640 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13641 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13642 &EmulateInstructionARM::EmulateLDRSHImmediate, 13643 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"}, 13644 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13645 &EmulateInstructionARM::EmulateLDRSHImmediate, 13646 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13647 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13648 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13649 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13650 &EmulateInstructionARM::EmulateLDRSHRegister, 13651 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"}, 13652 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13653 &EmulateInstructionARM::EmulateLDRSHRegister, 13654 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13655 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13656 &EmulateInstructionARM::EmulateLDRDImmediate, 13657 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 13658 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13659 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13660 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13661 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13662 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13663 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13664 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13665 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 13666 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13667 &EmulateInstructionARM::EmulateVLD1Multiple, 13668 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13669 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13670 &EmulateInstructionARM::EmulateVLD1Single, 13671 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13672 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13673 &EmulateInstructionARM::EmulateVLD1SingleAll, 13674 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13675 13676 // Store instructions 13677 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13678 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13679 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13680 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"}, 13681 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13682 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13683 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13684 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"}, 13685 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13686 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"}, 13687 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13688 &EmulateInstructionARM::EmulateSTRThumb, 13689 "str<c>.w <Rt>, [<Rn>,#<imm12>]"}, 13690 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13691 &EmulateInstructionARM::EmulateSTRThumb, 13692 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"}, 13693 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13694 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"}, 13695 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13696 &EmulateInstructionARM::EmulateSTRRegister, 13697 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"}, 13698 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13699 &EmulateInstructionARM::EmulateSTRBThumb, 13700 "strb<c> <Rt>, [<Rn>, #<imm5>]"}, 13701 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13702 &EmulateInstructionARM::EmulateSTRBThumb, 13703 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"}, 13704 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13705 &EmulateInstructionARM::EmulateSTRBThumb, 13706 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"}, 13707 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13708 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"}, 13709 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13710 &EmulateInstructionARM::EmulateSTRHRegister, 13711 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13712 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13713 &EmulateInstructionARM::EmulateSTREX, 13714 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"}, 13715 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13716 &EmulateInstructionARM::EmulateSTRDImm, 13717 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 13718 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13719 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13720 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13721 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13722 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13723 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13724 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13725 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13726 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13727 &EmulateInstructionARM::EmulateVST1Multiple, 13728 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13729 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13730 &EmulateInstructionARM::EmulateVST1Single, 13731 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13732 13733 // Other instructions 13734 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13735 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"}, 13736 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, 13737 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13738 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13739 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"}, 13740 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13741 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13742 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13743 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"}, 13744 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13745 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13746 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13747 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"}, 13748 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13749 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13750 }; 13751 13752 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 13753 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) { 13754 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 13755 (g_thumb_opcodes[i].variants & arm_isa) != 0) 13756 return &g_thumb_opcodes[i]; 13757 } 13758 return nullptr; 13759 } 13760 13761 bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) { 13762 m_arch = arch; 13763 m_arm_isa = 0; 13764 const char *arch_cstr = arch.GetArchitectureName(); 13765 if (arch_cstr) { 13766 if (0 == ::strcasecmp(arch_cstr, "armv4t")) 13767 m_arm_isa = ARMv4T; 13768 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) 13769 m_arm_isa = ARMv5TEJ; 13770 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) 13771 m_arm_isa = ARMv5TE; 13772 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) 13773 m_arm_isa = ARMv5T; 13774 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) 13775 m_arm_isa = ARMv6K; 13776 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) 13777 m_arm_isa = ARMv6T2; 13778 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) 13779 m_arm_isa = ARMv7S; 13780 else if (0 == ::strcasecmp(arch_cstr, "arm")) 13781 m_arm_isa = ARMvAll; 13782 else if (0 == ::strcasecmp(arch_cstr, "thumb")) 13783 m_arm_isa = ARMvAll; 13784 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5)) 13785 m_arm_isa = ARMv4; 13786 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5)) 13787 m_arm_isa = ARMv6; 13788 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5)) 13789 m_arm_isa = ARMv7; 13790 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5)) 13791 m_arm_isa = ARMv8; 13792 } 13793 return m_arm_isa != 0; 13794 } 13795 13796 bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode, 13797 const Address &inst_addr, 13798 Target *target) { 13799 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { 13800 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || 13801 m_arch.IsAlwaysThumbInstructions()) 13802 m_opcode_mode = eModeThumb; 13803 else { 13804 AddressClass addr_class = inst_addr.GetAddressClass(); 13805 13806 if ((addr_class == AddressClass::eCode) || 13807 (addr_class == AddressClass::eUnknown)) 13808 m_opcode_mode = eModeARM; 13809 else if (addr_class == AddressClass::eCodeAlternateISA) 13810 m_opcode_mode = eModeThumb; 13811 else 13812 return false; 13813 } 13814 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions()) 13815 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13816 else 13817 m_opcode_cpsr = CPSR_MODE_USR; 13818 return true; 13819 } 13820 return false; 13821 } 13822 13823 bool EmulateInstructionARM::ReadInstruction() { 13824 bool success = false; 13825 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric, 13826 LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13827 if (success) { 13828 addr_t pc = 13829 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 13830 LLDB_INVALID_ADDRESS, &success); 13831 if (success) { 13832 Context read_inst_context; 13833 read_inst_context.type = eContextReadOpcode; 13834 read_inst_context.SetNoArgs(); 13835 13836 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) { 13837 m_opcode_mode = eModeThumb; 13838 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13839 13840 if (success) { 13841 if ((thumb_opcode & 0xe000) != 0xe000 || 13842 ((thumb_opcode & 0x1800u) == 0)) { 13843 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder()); 13844 } else { 13845 m_opcode.SetOpcode32( 13846 (thumb_opcode << 16) | 13847 MemARead(read_inst_context, pc + 2, 2, 0, &success), 13848 GetByteOrder()); 13849 } 13850 } 13851 } else { 13852 m_opcode_mode = eModeARM; 13853 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success), 13854 GetByteOrder()); 13855 } 13856 13857 if (!m_ignore_conditions) { 13858 // If we are not ignoreing the conditions then init the it session from 13859 // the current value of cpsr. 13860 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | 13861 Bits32(m_opcode_cpsr, 26, 25); 13862 if (it != 0) 13863 m_it_session.InitIT(it); 13864 } 13865 } 13866 } 13867 if (!success) { 13868 m_opcode_mode = eModeInvalid; 13869 m_addr = LLDB_INVALID_ADDRESS; 13870 } 13871 return success; 13872 } 13873 13874 uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; } 13875 13876 bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) { 13877 // If we are ignoring conditions, then always return true. this allows us to 13878 // iterate over disassembly code and still emulate an instruction even if we 13879 // don't have all the right bits set in the CPSR register... 13880 if (m_ignore_conditions) 13881 return true; 13882 13883 const uint32_t cond = CurrentCond(opcode); 13884 if (cond == UINT32_MAX) 13885 return false; 13886 13887 bool result = false; 13888 switch (UnsignedBits(cond, 3, 1)) { 13889 case 0: 13890 if (m_opcode_cpsr == 0) 13891 result = true; 13892 else 13893 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13894 break; 13895 case 1: 13896 if (m_opcode_cpsr == 0) 13897 result = true; 13898 else 13899 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13900 break; 13901 case 2: 13902 if (m_opcode_cpsr == 0) 13903 result = true; 13904 else 13905 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13906 break; 13907 case 3: 13908 if (m_opcode_cpsr == 0) 13909 result = true; 13910 else 13911 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13912 break; 13913 case 4: 13914 if (m_opcode_cpsr == 0) 13915 result = true; 13916 else 13917 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && 13918 ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13919 break; 13920 case 5: 13921 if (m_opcode_cpsr == 0) 13922 result = true; 13923 else { 13924 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13925 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13926 result = n == v; 13927 } 13928 break; 13929 case 6: 13930 if (m_opcode_cpsr == 0) 13931 result = true; 13932 else { 13933 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13934 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13935 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13936 } 13937 break; 13938 case 7: 13939 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13940 // opcodes different meanings, but always means execution happens. 13941 return true; 13942 } 13943 13944 if (cond & 1) 13945 result = !result; 13946 return result; 13947 } 13948 13949 uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) { 13950 switch (m_opcode_mode) { 13951 case eModeInvalid: 13952 break; 13953 13954 case eModeARM: 13955 return UnsignedBits(opcode, 31, 28); 13956 13957 case eModeThumb: 13958 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13959 // 'cond' field of the encoding. 13960 { 13961 const uint32_t byte_size = m_opcode.GetByteSize(); 13962 if (byte_size == 2) { 13963 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 13964 return Bits32(opcode, 11, 8); 13965 } else if (byte_size == 4) { 13966 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 && 13967 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) { 13968 return Bits32(opcode, 25, 22); 13969 } 13970 } else 13971 // We have an invalid thumb instruction, let's bail out. 13972 break; 13973 13974 return m_it_session.GetCond(); 13975 } 13976 } 13977 return UINT32_MAX; // Return invalid value 13978 } 13979 13980 bool EmulateInstructionARM::InITBlock() { 13981 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13982 } 13983 13984 bool EmulateInstructionARM::LastInITBlock() { 13985 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13986 } 13987 13988 bool EmulateInstructionARM::BadMode(uint32_t mode) { 13989 13990 switch (mode) { 13991 case 16: 13992 return false; // '10000' 13993 case 17: 13994 return false; // '10001' 13995 case 18: 13996 return false; // '10010' 13997 case 19: 13998 return false; // '10011' 13999 case 22: 14000 return false; // '10110' 14001 case 23: 14002 return false; // '10111' 14003 case 27: 14004 return false; // '11011' 14005 case 31: 14006 return false; // '11111' 14007 default: 14008 return true; 14009 } 14010 return true; 14011 } 14012 14013 bool EmulateInstructionARM::CurrentModeIsPrivileged() { 14014 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0); 14015 14016 if (BadMode(mode)) 14017 return false; 14018 14019 if (mode == 16) 14020 return false; 14021 14022 return true; 14023 } 14024 14025 void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask, 14026 bool affect_execstate) { 14027 bool privileged = CurrentModeIsPrivileged(); 14028 14029 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20; 14030 14031 if (BitIsSet(bytemask, 3)) { 14032 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27); 14033 if (affect_execstate) 14034 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24); 14035 } 14036 14037 if (BitIsSet(bytemask, 2)) { 14038 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16); 14039 } 14040 14041 if (BitIsSet(bytemask, 1)) { 14042 if (affect_execstate) 14043 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10); 14044 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9); 14045 if (privileged) 14046 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8); 14047 } 14048 14049 if (BitIsSet(bytemask, 0)) { 14050 if (privileged) 14051 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6); 14052 if (affect_execstate) 14053 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5); 14054 if (privileged) 14055 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0); 14056 } 14057 14058 m_opcode_cpsr = tmp_cpsr; 14059 } 14060 14061 bool EmulateInstructionARM::BranchWritePC(const Context &context, 14062 uint32_t addr) { 14063 addr_t target; 14064 14065 // Check the current instruction set. 14066 if (CurrentInstrSet() == eModeARM) 14067 target = addr & 0xfffffffc; 14068 else 14069 target = addr & 0xfffffffe; 14070 14071 return WriteRegisterUnsigned(context, eRegisterKindGeneric, 14072 LLDB_REGNUM_GENERIC_PC, target); 14073 } 14074 14075 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by 14076 // inspecting addr. 14077 bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) { 14078 addr_t target; 14079 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 14080 // we want to record it and issue a WriteRegister callback so the clients can 14081 // track the mode changes accordingly. 14082 bool cpsr_changed = false; 14083 14084 if (BitIsSet(addr, 0)) { 14085 if (CurrentInstrSet() != eModeThumb) { 14086 SelectInstrSet(eModeThumb); 14087 cpsr_changed = true; 14088 } 14089 target = addr & 0xfffffffe; 14090 context.SetISA(eModeThumb); 14091 } else if (BitIsClear(addr, 1)) { 14092 if (CurrentInstrSet() != eModeARM) { 14093 SelectInstrSet(eModeARM); 14094 cpsr_changed = true; 14095 } 14096 target = addr & 0xfffffffc; 14097 context.SetISA(eModeARM); 14098 } else 14099 return false; // address<1:0> == '10' => UNPREDICTABLE 14100 14101 if (cpsr_changed) { 14102 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14103 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14104 return false; 14105 } 14106 return WriteRegisterUnsigned(context, eRegisterKindGeneric, 14107 LLDB_REGNUM_GENERIC_PC, target); 14108 } 14109 14110 // Dispatches to either BXWritePC or BranchWritePC based on architecture 14111 // versions. 14112 bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) { 14113 if (ArchVersion() >= ARMv5T) 14114 return BXWritePC(context, addr); 14115 else 14116 return BranchWritePC((const Context)context, addr); 14117 } 14118 14119 // Dispatches to either BXWritePC or BranchWritePC based on architecture 14120 // versions and current instruction set. 14121 bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) { 14122 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 14123 return BXWritePC(context, addr); 14124 else 14125 return BranchWritePC((const Context)context, addr); 14126 } 14127 14128 EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() { 14129 return m_opcode_mode; 14130 } 14131 14132 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 14133 // ReadInstruction() is performed. This function has a side effect of updating 14134 // the m_new_inst_cpsr member variable if necessary. 14135 bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) { 14136 m_new_inst_cpsr = m_opcode_cpsr; 14137 switch (arm_or_thumb) { 14138 default: 14139 return false; 14140 case eModeARM: 14141 // Clear the T bit. 14142 m_new_inst_cpsr &= ~MASK_CPSR_T; 14143 break; 14144 case eModeThumb: 14145 // Set the T bit. 14146 m_new_inst_cpsr |= MASK_CPSR_T; 14147 break; 14148 } 14149 return true; 14150 } 14151 14152 // This function returns TRUE if the processor currently provides support for 14153 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 14154 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 14155 bool EmulateInstructionARM::UnalignedSupport() { 14156 return (ArchVersion() >= ARMv7); 14157 } 14158 14159 // The main addition and subtraction instructions can produce status 14160 // information about both unsigned carry and signed overflow conditions. This 14161 // status information can be used to synthesize multi-word additions and 14162 // subtractions. 14163 EmulateInstructionARM::AddWithCarryResult 14164 EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) { 14165 uint32_t result; 14166 uint8_t carry_out; 14167 uint8_t overflow; 14168 14169 uint64_t unsigned_sum = x + y + carry_in; 14170 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 14171 14172 result = UnsignedBits(unsigned_sum, 31, 0); 14173 // carry_out = (result == unsigned_sum ? 0 : 1); 14174 overflow = ((int32_t)result == signed_sum ? 0 : 1); 14175 14176 if (carry_in) 14177 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0; 14178 else 14179 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0; 14180 14181 AddWithCarryResult res = {result, carry_out, overflow}; 14182 return res; 14183 } 14184 14185 uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) { 14186 lldb::RegisterKind reg_kind; 14187 uint32_t reg_num; 14188 switch (num) { 14189 case SP_REG: 14190 reg_kind = eRegisterKindGeneric; 14191 reg_num = LLDB_REGNUM_GENERIC_SP; 14192 break; 14193 case LR_REG: 14194 reg_kind = eRegisterKindGeneric; 14195 reg_num = LLDB_REGNUM_GENERIC_RA; 14196 break; 14197 case PC_REG: 14198 reg_kind = eRegisterKindGeneric; 14199 reg_num = LLDB_REGNUM_GENERIC_PC; 14200 break; 14201 default: 14202 if (num < SP_REG) { 14203 reg_kind = eRegisterKindDWARF; 14204 reg_num = dwarf_r0 + num; 14205 } else { 14206 // assert(0 && "Invalid register number"); 14207 *success = false; 14208 return UINT32_MAX; 14209 } 14210 break; 14211 } 14212 14213 // Read our register. 14214 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success); 14215 14216 // When executing an ARM instruction , PC reads as the address of the current 14217 // instruction plus 8. When executing a Thumb instruction , PC reads as the 14218 // address of the current instruction plus 4. 14219 if (num == 15) { 14220 if (CurrentInstrSet() == eModeARM) 14221 val += 8; 14222 else 14223 val += 4; 14224 } 14225 14226 return val; 14227 } 14228 14229 // Write the result to the ARM core register Rd, and optionally update the 14230 // condition flags based on the result. 14231 // 14232 // This helper method tries to encapsulate the following pseudocode from the 14233 // ARM Architecture Reference Manual: 14234 // 14235 // if d == 15 then // Can only occur for encoding A1 14236 // ALUWritePC(result); // setflags is always FALSE here 14237 // else 14238 // R[d] = result; 14239 // if setflags then 14240 // APSR.N = result<31>; 14241 // APSR.Z = IsZeroBit(result); 14242 // APSR.C = carry; 14243 // // APSR.V unchanged 14244 // 14245 // In the above case, the API client does not pass in the overflow arg, which 14246 // defaults to ~0u. 14247 bool EmulateInstructionARM::WriteCoreRegOptionalFlags( 14248 Context &context, const uint32_t result, const uint32_t Rd, bool setflags, 14249 const uint32_t carry, const uint32_t overflow) { 14250 if (Rd == 15) { 14251 if (!ALUWritePC(context, result)) 14252 return false; 14253 } else { 14254 lldb::RegisterKind reg_kind; 14255 uint32_t reg_num; 14256 switch (Rd) { 14257 case SP_REG: 14258 reg_kind = eRegisterKindGeneric; 14259 reg_num = LLDB_REGNUM_GENERIC_SP; 14260 break; 14261 case LR_REG: 14262 reg_kind = eRegisterKindGeneric; 14263 reg_num = LLDB_REGNUM_GENERIC_RA; 14264 break; 14265 default: 14266 reg_kind = eRegisterKindDWARF; 14267 reg_num = dwarf_r0 + Rd; 14268 } 14269 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result)) 14270 return false; 14271 if (setflags) 14272 return WriteFlags(context, result, carry, overflow); 14273 } 14274 return true; 14275 } 14276 14277 // This helper method tries to encapsulate the following pseudocode from the 14278 // ARM Architecture Reference Manual: 14279 // 14280 // APSR.N = result<31>; 14281 // APSR.Z = IsZeroBit(result); 14282 // APSR.C = carry; 14283 // APSR.V = overflow 14284 // 14285 // Default arguments can be specified for carry and overflow parameters, which 14286 // means not to update the respective flags. 14287 bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result, 14288 const uint32_t carry, 14289 const uint32_t overflow) { 14290 m_new_inst_cpsr = m_opcode_cpsr; 14291 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 14292 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 14293 if (carry != ~0u) 14294 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 14295 if (overflow != ~0u) 14296 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 14297 if (m_new_inst_cpsr != m_opcode_cpsr) { 14298 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14299 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14300 return false; 14301 } 14302 return true; 14303 } 14304 14305 bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) { 14306 ARMOpcode *opcode_data = nullptr; 14307 14308 if (m_opcode_mode == eModeThumb) 14309 opcode_data = 14310 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14311 else if (m_opcode_mode == eModeARM) 14312 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14313 14314 const bool auto_advance_pc = 14315 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 14316 m_ignore_conditions = 14317 evaluate_options & eEmulateInstructionOptionIgnoreConditions; 14318 14319 bool success = false; 14320 if (m_opcode_cpsr == 0 || !m_ignore_conditions) { 14321 m_opcode_cpsr = 14322 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 14323 } 14324 14325 // Only return false if we are unable to read the CPSR if we care about 14326 // conditions 14327 if (!success && !m_ignore_conditions) 14328 return false; 14329 14330 uint32_t orig_pc_value = 0; 14331 if (auto_advance_pc) { 14332 orig_pc_value = 14333 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14334 if (!success) 14335 return false; 14336 } 14337 14338 // Call the Emulate... function if we managed to decode the opcode. 14339 if (opcode_data) { 14340 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(), 14341 opcode_data->encoding); 14342 if (!success) 14343 return false; 14344 } 14345 14346 // Advance the ITSTATE bits to their values for the next instruction if we 14347 // haven't just executed an IT instruction what initialized it. 14348 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() && 14349 (opcode_data == nullptr || 14350 opcode_data->callback != &EmulateInstructionARM::EmulateIT)) 14351 m_it_session.ITAdvance(); 14352 14353 if (auto_advance_pc) { 14354 uint32_t after_pc_value = 14355 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14356 if (!success) 14357 return false; 14358 14359 if (after_pc_value == orig_pc_value) { 14360 after_pc_value += m_opcode.GetByteSize(); 14361 14362 EmulateInstruction::Context context; 14363 context.type = eContextAdvancePC; 14364 context.SetNoArgs(); 14365 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc, 14366 after_pc_value)) 14367 return false; 14368 } 14369 } 14370 return true; 14371 } 14372 14373 EmulateInstruction::InstructionCondition 14374 EmulateInstructionARM::GetInstructionCondition() { 14375 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32()); 14376 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX) 14377 return EmulateInstruction::UnconditionalCondition; 14378 return cond; 14379 } 14380 14381 bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, 14382 OptionValueDictionary *test_data) { 14383 if (!test_data) { 14384 out_stream->Printf("TestEmulation: Missing test data.\n"); 14385 return false; 14386 } 14387 14388 static ConstString opcode_key("opcode"); 14389 static ConstString before_key("before_state"); 14390 static ConstString after_key("after_state"); 14391 14392 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key); 14393 14394 uint32_t test_opcode; 14395 if ((value_sp.get() == nullptr) || 14396 (value_sp->GetType() != OptionValue::eTypeUInt64)) { 14397 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n"); 14398 return false; 14399 } 14400 test_opcode = value_sp->GetUInt64Value(); 14401 14402 if (arch.GetTriple().getArch() == llvm::Triple::thumb || 14403 arch.IsAlwaysThumbInstructions()) { 14404 m_opcode_mode = eModeThumb; 14405 if (test_opcode < 0x10000) 14406 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder()); 14407 else 14408 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14409 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) { 14410 m_opcode_mode = eModeARM; 14411 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14412 } else { 14413 out_stream->Printf("TestEmulation: Invalid arch.\n"); 14414 return false; 14415 } 14416 14417 EmulationStateARM before_state; 14418 EmulationStateARM after_state; 14419 14420 value_sp = test_data->GetValueForKey(before_key); 14421 if ((value_sp.get() == nullptr) || 14422 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14423 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n"); 14424 return false; 14425 } 14426 14427 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary(); 14428 if (!before_state.LoadStateFromDictionary(state_dictionary)) { 14429 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n"); 14430 return false; 14431 } 14432 14433 value_sp = test_data->GetValueForKey(after_key); 14434 if ((value_sp.get() == nullptr) || 14435 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14436 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n"); 14437 return false; 14438 } 14439 14440 state_dictionary = value_sp->GetAsDictionary(); 14441 if (!after_state.LoadStateFromDictionary(state_dictionary)) { 14442 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n"); 14443 return false; 14444 } 14445 14446 SetBaton((void *)&before_state); 14447 SetCallbacks(&EmulationStateARM::ReadPseudoMemory, 14448 &EmulationStateARM::WritePseudoMemory, 14449 &EmulationStateARM::ReadPseudoRegister, 14450 &EmulationStateARM::WritePseudoRegister); 14451 14452 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 14453 if (!success) { 14454 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n"); 14455 return false; 14456 } 14457 14458 success = before_state.CompareState(after_state); 14459 if (!success) 14460 out_stream->Printf( 14461 "TestEmulation: 'before' and 'after' states do not match.\n"); 14462 14463 return success; 14464 } 14465 // 14466 // 14467 // const char * 14468 // EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 14469 //{ 14470 // if (reg_kind == eRegisterKindGeneric) 14471 // { 14472 // switch (reg_num) 14473 // { 14474 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 14475 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 14476 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 14477 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 14478 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 14479 // default: return NULL; 14480 // } 14481 // } 14482 // else if (reg_kind == eRegisterKindDWARF) 14483 // { 14484 // return GetARMDWARFRegisterName (reg_num); 14485 // } 14486 // return NULL; 14487 //} 14488 // 14489 bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { 14490 unwind_plan.Clear(); 14491 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 14492 14493 UnwindPlan::RowSP row(new UnwindPlan::Row); 14494 14495 // Our previous Call Frame Address is the stack pointer 14496 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0); 14497 14498 unwind_plan.AppendRow(row); 14499 unwind_plan.SetSourceName("EmulateInstructionARM"); 14500 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 14501 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 14502 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 14503 unwind_plan.SetReturnAddressRegister(dwarf_lr); 14504 return true; 14505 } 14506