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) { NameSearchContextNameSearchContext64 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: GetASTContextNameSearchContext117 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 ConstString EmulateInstructionARM::GetPluginNameStatic() { 717 static ConstString g_name("arm"); 718 return g_name; 719 } 720 721 const char *EmulateInstructionARM::GetPluginDescriptionStatic() { 722 return "Emulate instructions for the ARM architecture."; 723 } 724 725 EmulateInstruction * 726 EmulateInstructionARM::CreateInstance(const ArchSpec &arch, 727 InstructionType inst_type) { 728 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic( 729 inst_type)) { 730 if (arch.GetTriple().getArch() == llvm::Triple::arm) { 731 std::unique_ptr<EmulateInstructionARM> emulate_insn_up( 732 new EmulateInstructionARM(arch)); 733 734 if (emulate_insn_up) 735 return emulate_insn_up.release(); 736 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) { 737 std::unique_ptr<EmulateInstructionARM> emulate_insn_up( 738 new EmulateInstructionARM(arch)); 739 740 if (emulate_insn_up) 741 return emulate_insn_up.release(); 742 } 743 } 744 745 return nullptr; 746 } 747 748 bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) { 749 if (arch.GetTriple().getArch() == llvm::Triple::arm) 750 return true; 751 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 752 return true; 753 754 return false; 755 } 756 757 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for 758 // many ARM instructions. 759 bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) { 760 EmulateInstruction::Context context; 761 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 762 context.SetNoArgs(); 763 764 uint32_t random_data = rand(); 765 const uint32_t addr_byte_size = GetAddressByteSize(); 766 767 return MemAWrite(context, address, random_data, addr_byte_size); 768 } 769 770 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM 771 // instructions. 772 bool EmulateInstructionARM::WriteBits32Unknown(int n) { 773 EmulateInstruction::Context context; 774 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 775 context.SetNoArgs(); 776 777 bool success; 778 uint32_t data = 779 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 780 781 if (!success) 782 return false; 783 784 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data)) 785 return false; 786 787 return true; 788 } 789 790 bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind, 791 uint32_t reg_num, 792 RegisterInfo ®_info) { 793 if (reg_kind == eRegisterKindGeneric) { 794 switch (reg_num) { 795 case LLDB_REGNUM_GENERIC_PC: 796 reg_kind = eRegisterKindDWARF; 797 reg_num = dwarf_pc; 798 break; 799 case LLDB_REGNUM_GENERIC_SP: 800 reg_kind = eRegisterKindDWARF; 801 reg_num = dwarf_sp; 802 break; 803 case LLDB_REGNUM_GENERIC_FP: 804 reg_kind = eRegisterKindDWARF; 805 reg_num = dwarf_r7; 806 break; 807 case LLDB_REGNUM_GENERIC_RA: 808 reg_kind = eRegisterKindDWARF; 809 reg_num = dwarf_lr; 810 break; 811 case LLDB_REGNUM_GENERIC_FLAGS: 812 reg_kind = eRegisterKindDWARF; 813 reg_num = dwarf_cpsr; 814 break; 815 default: 816 return false; 817 } 818 } 819 820 if (reg_kind == eRegisterKindDWARF) 821 return GetARMDWARFRegisterInfo(reg_num, reg_info); 822 return false; 823 } 824 825 uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const { 826 if (m_arch.GetTriple().isAndroid()) 827 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android 828 bool is_apple = false; 829 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 830 is_apple = true; 831 switch (m_arch.GetTriple().getOS()) { 832 case llvm::Triple::Darwin: 833 case llvm::Triple::MacOSX: 834 case llvm::Triple::IOS: 835 case llvm::Triple::TvOS: 836 case llvm::Triple::WatchOS: 837 // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS: 838 is_apple = true; 839 break; 840 default: 841 break; 842 } 843 844 /* On Apple iOS et al, the frame pointer register is always r7. 845 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 846 * Windows on ARM, which is in thumb mode, uses r11 though. 847 */ 848 849 uint32_t fp_regnum = 11; 850 851 if (is_apple) 852 fp_regnum = 7; 853 854 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows()) 855 fp_regnum = 7; 856 857 return fp_regnum; 858 } 859 860 uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const { 861 bool is_apple = false; 862 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 863 is_apple = true; 864 switch (m_arch.GetTriple().getOS()) { 865 case llvm::Triple::Darwin: 866 case llvm::Triple::MacOSX: 867 case llvm::Triple::IOS: 868 is_apple = true; 869 break; 870 default: 871 break; 872 } 873 874 /* On Apple iOS et al, the frame pointer register is always r7. 875 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 876 * Windows on ARM, which is in thumb mode, uses r11 though. 877 */ 878 879 uint32_t fp_regnum = dwarf_r11; 880 881 if (is_apple) 882 fp_regnum = dwarf_r7; 883 884 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows()) 885 fp_regnum = dwarf_r7; 886 887 return fp_regnum; 888 } 889 890 // Push Multiple Registers stores multiple registers to the stack, storing to 891 // consecutive memory locations ending just below the address in SP, and 892 // updates 893 // SP to point to the start of the stored data. 894 bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode, 895 const ARMEncoding encoding) { 896 #if 0 897 // ARM pseudo code... 898 if (ConditionPassed()) 899 { 900 EncodingSpecificOperations(); 901 NullCheckIfThumbEE(13); 902 address = SP - 4*BitCount(registers); 903 904 for (i = 0 to 14) 905 { 906 if (registers<i> == '1') 907 { 908 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 909 MemA[address,4] = bits(32) UNKNOWN; 910 else 911 MemA[address,4] = R[i]; 912 address = address + 4; 913 } 914 } 915 916 if (registers<15> == '1') // Only possible for encoding A1 or A2 917 MemA[address,4] = PCStoreValue(); 918 919 SP = SP - 4*BitCount(registers); 920 } 921 #endif 922 923 bool success = false; 924 if (ConditionPassed(opcode)) { 925 const uint32_t addr_byte_size = GetAddressByteSize(); 926 const addr_t sp = ReadCoreReg(SP_REG, &success); 927 if (!success) 928 return false; 929 uint32_t registers = 0; 930 uint32_t Rt; // the source register 931 switch (encoding) { 932 case eEncodingT1: 933 registers = Bits32(opcode, 7, 0); 934 // The M bit represents LR. 935 if (Bit32(opcode, 8)) 936 registers |= (1u << 14); 937 // if BitCount(registers) < 1 then UNPREDICTABLE; 938 if (BitCount(registers) < 1) 939 return false; 940 break; 941 case eEncodingT2: 942 // Ignore bits 15 & 13. 943 registers = Bits32(opcode, 15, 0) & ~0xa000; 944 // if BitCount(registers) < 2 then UNPREDICTABLE; 945 if (BitCount(registers) < 2) 946 return false; 947 break; 948 case eEncodingT3: 949 Rt = Bits32(opcode, 15, 12); 950 // if BadReg(t) then UNPREDICTABLE; 951 if (BadReg(Rt)) 952 return false; 953 registers = (1u << Rt); 954 break; 955 case eEncodingA1: 956 registers = Bits32(opcode, 15, 0); 957 // Instead of return false, let's handle the following case as well, 958 // which amounts to pushing one reg onto the full descending stacks. 959 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 960 break; 961 case eEncodingA2: 962 Rt = Bits32(opcode, 15, 12); 963 // if t == 13 then UNPREDICTABLE; 964 if (Rt == dwarf_sp) 965 return false; 966 registers = (1u << Rt); 967 break; 968 default: 969 return false; 970 } 971 addr_t sp_offset = addr_byte_size * BitCount(registers); 972 addr_t addr = sp - sp_offset; 973 uint32_t i; 974 975 EmulateInstruction::Context context; 976 context.type = EmulateInstruction::eContextPushRegisterOnStack; 977 RegisterInfo reg_info; 978 RegisterInfo sp_reg; 979 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 980 for (i = 0; i < 15; ++i) { 981 if (BitIsSet(registers, i)) { 982 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info); 983 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 984 uint32_t reg_value = ReadCoreReg(i, &success); 985 if (!success) 986 return false; 987 if (!MemAWrite(context, addr, reg_value, addr_byte_size)) 988 return false; 989 addr += addr_byte_size; 990 } 991 } 992 993 if (BitIsSet(registers, 15)) { 994 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info); 995 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 996 const uint32_t pc = ReadCoreReg(PC_REG, &success); 997 if (!success) 998 return false; 999 if (!MemAWrite(context, addr, pc, addr_byte_size)) 1000 return false; 1001 } 1002 1003 context.type = EmulateInstruction::eContextAdjustStackPointer; 1004 context.SetImmediateSigned(-sp_offset); 1005 1006 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1007 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1008 return false; 1009 } 1010 return true; 1011 } 1012 1013 // Pop Multiple Registers loads multiple registers from the stack, loading from 1014 // consecutive memory locations staring at the address in SP, and updates 1015 // SP to point just above the loaded data. 1016 bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode, 1017 const ARMEncoding encoding) { 1018 #if 0 1019 // ARM pseudo code... 1020 if (ConditionPassed()) 1021 { 1022 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 1023 address = SP; 1024 for i = 0 to 14 1025 if registers<i> == '1' then 1026 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 1027 if registers<15> == '1' then 1028 if UnalignedAllowed then 1029 LoadWritePC(MemU[address,4]); 1030 else 1031 LoadWritePC(MemA[address,4]); 1032 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 1033 if registers<13> == '1' then SP = bits(32) UNKNOWN; 1034 } 1035 #endif 1036 1037 bool success = false; 1038 1039 if (ConditionPassed(opcode)) { 1040 const uint32_t addr_byte_size = GetAddressByteSize(); 1041 const addr_t sp = ReadCoreReg(SP_REG, &success); 1042 if (!success) 1043 return false; 1044 uint32_t registers = 0; 1045 uint32_t Rt; // the destination register 1046 switch (encoding) { 1047 case eEncodingT1: 1048 registers = Bits32(opcode, 7, 0); 1049 // The P bit represents PC. 1050 if (Bit32(opcode, 8)) 1051 registers |= (1u << 15); 1052 // if BitCount(registers) < 1 then UNPREDICTABLE; 1053 if (BitCount(registers) < 1) 1054 return false; 1055 break; 1056 case eEncodingT2: 1057 // Ignore bit 13. 1058 registers = Bits32(opcode, 15, 0) & ~0x2000; 1059 // if BitCount(registers) < 2 || (P == '1' && M == '1') then 1060 // UNPREDICTABLE; 1061 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 1062 return false; 1063 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 1064 // UNPREDICTABLE; 1065 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 1066 return false; 1067 break; 1068 case eEncodingT3: 1069 Rt = Bits32(opcode, 15, 12); 1070 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then 1071 // UNPREDICTABLE; 1072 if (Rt == 13) 1073 return false; 1074 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1075 return false; 1076 registers = (1u << Rt); 1077 break; 1078 case eEncodingA1: 1079 registers = Bits32(opcode, 15, 0); 1080 // Instead of return false, let's handle the following case as well, 1081 // which amounts to popping one reg from the full descending stacks. 1082 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 1083 1084 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 1085 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 1086 return false; 1087 break; 1088 case eEncodingA2: 1089 Rt = Bits32(opcode, 15, 12); 1090 // if t == 13 then UNPREDICTABLE; 1091 if (Rt == dwarf_sp) 1092 return false; 1093 registers = (1u << Rt); 1094 break; 1095 default: 1096 return false; 1097 } 1098 addr_t sp_offset = addr_byte_size * BitCount(registers); 1099 addr_t addr = sp; 1100 uint32_t i, data; 1101 1102 EmulateInstruction::Context context; 1103 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1104 1105 RegisterInfo sp_reg; 1106 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1107 1108 for (i = 0; i < 15; ++i) { 1109 if (BitIsSet(registers, i)) { 1110 context.SetAddress(addr); 1111 data = MemARead(context, addr, 4, 0, &success); 1112 if (!success) 1113 return false; 1114 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 1115 data)) 1116 return false; 1117 addr += addr_byte_size; 1118 } 1119 } 1120 1121 if (BitIsSet(registers, 15)) { 1122 context.SetRegisterPlusOffset(sp_reg, addr - sp); 1123 data = MemARead(context, addr, 4, 0, &success); 1124 if (!success) 1125 return false; 1126 // In ARMv5T and above, this is an interworking branch. 1127 if (!LoadWritePC(context, data)) 1128 return false; 1129 // addr += addr_byte_size; 1130 } 1131 1132 context.type = EmulateInstruction::eContextAdjustStackPointer; 1133 context.SetImmediateSigned(sp_offset); 1134 1135 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1136 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1137 return false; 1138 } 1139 return true; 1140 } 1141 1142 // Set r7 or ip to point to saved value residing within the stack. 1143 // ADD (SP plus immediate) 1144 bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode, 1145 const ARMEncoding encoding) { 1146 #if 0 1147 // ARM pseudo code... 1148 if (ConditionPassed()) 1149 { 1150 EncodingSpecificOperations(); 1151 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1152 if d == 15 then 1153 ALUWritePC(result); // setflags is always FALSE here 1154 else 1155 R[d] = result; 1156 if setflags then 1157 APSR.N = result<31>; 1158 APSR.Z = IsZeroBit(result); 1159 APSR.C = carry; 1160 APSR.V = overflow; 1161 } 1162 #endif 1163 1164 bool success = false; 1165 1166 if (ConditionPassed(opcode)) { 1167 const addr_t sp = ReadCoreReg(SP_REG, &success); 1168 if (!success) 1169 return false; 1170 uint32_t Rd; // the destination register 1171 uint32_t imm32; 1172 switch (encoding) { 1173 case eEncodingT1: 1174 Rd = 7; 1175 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 1176 break; 1177 case eEncodingA1: 1178 Rd = Bits32(opcode, 15, 12); 1179 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1180 break; 1181 default: 1182 return false; 1183 } 1184 addr_t sp_offset = imm32; 1185 addr_t addr = sp + sp_offset; // a pointer to the stack area 1186 1187 EmulateInstruction::Context context; 1188 if (Rd == GetFramePointerRegisterNumber()) 1189 context.type = eContextSetFramePointer; 1190 else 1191 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1192 RegisterInfo sp_reg; 1193 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1194 context.SetRegisterPlusOffset(sp_reg, sp_offset); 1195 1196 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, 1197 addr)) 1198 return false; 1199 } 1200 return true; 1201 } 1202 1203 // Set r7 or ip to the current stack pointer. 1204 // MOV (register) 1205 bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode, 1206 const ARMEncoding encoding) { 1207 #if 0 1208 // ARM pseudo code... 1209 if (ConditionPassed()) 1210 { 1211 EncodingSpecificOperations(); 1212 result = R[m]; 1213 if d == 15 then 1214 ALUWritePC(result); // setflags is always FALSE here 1215 else 1216 R[d] = result; 1217 if setflags then 1218 APSR.N = result<31>; 1219 APSR.Z = IsZeroBit(result); 1220 // APSR.C unchanged 1221 // APSR.V unchanged 1222 } 1223 #endif 1224 1225 bool success = false; 1226 1227 if (ConditionPassed(opcode)) { 1228 const addr_t sp = ReadCoreReg(SP_REG, &success); 1229 if (!success) 1230 return false; 1231 uint32_t Rd; // the destination register 1232 switch (encoding) { 1233 case eEncodingT1: 1234 Rd = 7; 1235 break; 1236 case eEncodingA1: 1237 Rd = 12; 1238 break; 1239 default: 1240 return false; 1241 } 1242 1243 EmulateInstruction::Context context; 1244 if (Rd == GetFramePointerRegisterNumber()) 1245 context.type = EmulateInstruction::eContextSetFramePointer; 1246 else 1247 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1248 RegisterInfo sp_reg; 1249 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1250 context.SetRegisterPlusOffset(sp_reg, 0); 1251 1252 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 1253 return false; 1254 } 1255 return true; 1256 } 1257 1258 // Move from high register (r8-r15) to low register (r0-r7). 1259 // MOV (register) 1260 bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode, 1261 const ARMEncoding encoding) { 1262 return EmulateMOVRdRm(opcode, encoding); 1263 } 1264 1265 // Move from register to register. 1266 // MOV (register) 1267 bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode, 1268 const ARMEncoding encoding) { 1269 #if 0 1270 // ARM pseudo code... 1271 if (ConditionPassed()) 1272 { 1273 EncodingSpecificOperations(); 1274 result = R[m]; 1275 if d == 15 then 1276 ALUWritePC(result); // setflags is always FALSE here 1277 else 1278 R[d] = result; 1279 if setflags then 1280 APSR.N = result<31>; 1281 APSR.Z = IsZeroBit(result); 1282 // APSR.C unchanged 1283 // APSR.V unchanged 1284 } 1285 #endif 1286 1287 bool success = false; 1288 1289 if (ConditionPassed(opcode)) { 1290 uint32_t Rm; // the source register 1291 uint32_t Rd; // the destination register 1292 bool setflags; 1293 switch (encoding) { 1294 case eEncodingT1: 1295 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1296 Rm = Bits32(opcode, 6, 3); 1297 setflags = false; 1298 if (Rd == 15 && InITBlock() && !LastInITBlock()) 1299 return false; 1300 break; 1301 case eEncodingT2: 1302 Rd = Bits32(opcode, 2, 0); 1303 Rm = Bits32(opcode, 5, 3); 1304 setflags = true; 1305 if (InITBlock()) 1306 return false; 1307 break; 1308 case eEncodingT3: 1309 Rd = Bits32(opcode, 11, 8); 1310 Rm = Bits32(opcode, 3, 0); 1311 setflags = BitIsSet(opcode, 20); 1312 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1313 if (setflags && (BadReg(Rd) || BadReg(Rm))) 1314 return false; 1315 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then 1316 // UNPREDICTABLE; 1317 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 1318 return false; 1319 break; 1320 case eEncodingA1: 1321 Rd = Bits32(opcode, 15, 12); 1322 Rm = Bits32(opcode, 3, 0); 1323 setflags = BitIsSet(opcode, 20); 1324 1325 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1326 // instructions; 1327 if (Rd == 15 && setflags) 1328 return EmulateSUBSPcLrEtc(opcode, encoding); 1329 break; 1330 default: 1331 return false; 1332 } 1333 uint32_t result = ReadCoreReg(Rm, &success); 1334 if (!success) 1335 return false; 1336 1337 // The context specifies that Rm is to be moved into Rd. 1338 EmulateInstruction::Context context; 1339 if (Rd == 13) 1340 context.type = EmulateInstruction::eContextAdjustStackPointer; 1341 else if (Rd == GetFramePointerRegisterNumber() && Rm == 13) 1342 context.type = EmulateInstruction::eContextSetFramePointer; 1343 else 1344 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1345 RegisterInfo dwarf_reg; 1346 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1347 context.SetRegisterPlusOffset(dwarf_reg, 0); 1348 1349 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 1350 return false; 1351 } 1352 return true; 1353 } 1354 1355 // Move (immediate) writes an immediate value to the destination register. It 1356 // can optionally update the condition flags based on the value. 1357 // MOV (immediate) 1358 bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode, 1359 const ARMEncoding encoding) { 1360 #if 0 1361 // ARM pseudo code... 1362 if (ConditionPassed()) 1363 { 1364 EncodingSpecificOperations(); 1365 result = imm32; 1366 if d == 15 then // Can only occur for ARM encoding 1367 ALUWritePC(result); // setflags is always FALSE here 1368 else 1369 R[d] = result; 1370 if setflags then 1371 APSR.N = result<31>; 1372 APSR.Z = IsZeroBit(result); 1373 APSR.C = carry; 1374 // APSR.V unchanged 1375 } 1376 #endif 1377 1378 if (ConditionPassed(opcode)) { 1379 uint32_t Rd; // the destination register 1380 uint32_t imm32; // the immediate value to be written to Rd 1381 uint32_t carry = 1382 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 1383 // for setflags == false, this value is a don't care initialized to 1384 // 0 to silence the static analyzer 1385 bool setflags; 1386 switch (encoding) { 1387 case eEncodingT1: 1388 Rd = Bits32(opcode, 10, 8); 1389 setflags = !InITBlock(); 1390 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 1391 carry = APSR_C; 1392 1393 break; 1394 1395 case eEncodingT2: 1396 Rd = Bits32(opcode, 11, 8); 1397 setflags = BitIsSet(opcode, 20); 1398 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1399 if (BadReg(Rd)) 1400 return false; 1401 1402 break; 1403 1404 case eEncodingT3: { 1405 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 1406 // 32); 1407 Rd = Bits32(opcode, 11, 8); 1408 setflags = false; 1409 uint32_t imm4 = Bits32(opcode, 19, 16); 1410 uint32_t imm3 = Bits32(opcode, 14, 12); 1411 uint32_t i = Bit32(opcode, 26); 1412 uint32_t imm8 = Bits32(opcode, 7, 0); 1413 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 1414 1415 // if BadReg(d) then UNPREDICTABLE; 1416 if (BadReg(Rd)) 1417 return false; 1418 } break; 1419 1420 case eEncodingA1: 1421 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = 1422 // ARMExpandImm_C(imm12, APSR.C); 1423 Rd = Bits32(opcode, 15, 12); 1424 setflags = BitIsSet(opcode, 20); 1425 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1426 1427 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1428 // instructions; 1429 if ((Rd == 15) && setflags) 1430 return EmulateSUBSPcLrEtc(opcode, encoding); 1431 1432 break; 1433 1434 case eEncodingA2: { 1435 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 1436 Rd = Bits32(opcode, 15, 12); 1437 setflags = false; 1438 uint32_t imm4 = Bits32(opcode, 19, 16); 1439 uint32_t imm12 = Bits32(opcode, 11, 0); 1440 imm32 = (imm4 << 12) | imm12; 1441 1442 // if d == 15 then UNPREDICTABLE; 1443 if (Rd == 15) 1444 return false; 1445 } break; 1446 1447 default: 1448 return false; 1449 } 1450 uint32_t result = imm32; 1451 1452 // The context specifies that an immediate is to be moved into Rd. 1453 EmulateInstruction::Context context; 1454 context.type = EmulateInstruction::eContextImmediate; 1455 context.SetNoArgs(); 1456 1457 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1458 return false; 1459 } 1460 return true; 1461 } 1462 1463 // MUL multiplies two register values. The least significant 32 bits of the 1464 // result are written to the destination 1465 // register. These 32 bits do not depend on whether the source register values 1466 // are considered to be signed values or unsigned values. 1467 // 1468 // Optionally, it can update the condition flags based on the result. In the 1469 // Thumb instruction set, this option is limited to only a few forms of the 1470 // instruction. 1471 bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode, 1472 const ARMEncoding encoding) { 1473 #if 0 1474 if ConditionPassed() then 1475 EncodingSpecificOperations(); 1476 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1477 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1478 result = operand1 * operand2; 1479 R[d] = result<31:0>; 1480 if setflags then 1481 APSR.N = result<31>; 1482 APSR.Z = IsZeroBit(result); 1483 if ArchVersion() == 4 then 1484 APSR.C = bit UNKNOWN; 1485 // else APSR.C unchanged 1486 // APSR.V always unchanged 1487 #endif 1488 1489 if (ConditionPassed(opcode)) { 1490 uint32_t d; 1491 uint32_t n; 1492 uint32_t m; 1493 bool setflags; 1494 1495 // EncodingSpecificOperations(); 1496 switch (encoding) { 1497 case eEncodingT1: 1498 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 1499 d = Bits32(opcode, 2, 0); 1500 n = Bits32(opcode, 5, 3); 1501 m = Bits32(opcode, 2, 0); 1502 setflags = !InITBlock(); 1503 1504 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1505 if ((ArchVersion() < ARMv6) && (d == n)) 1506 return false; 1507 1508 break; 1509 1510 case eEncodingT2: 1511 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 1512 d = Bits32(opcode, 11, 8); 1513 n = Bits32(opcode, 19, 16); 1514 m = Bits32(opcode, 3, 0); 1515 setflags = false; 1516 1517 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 1518 if (BadReg(d) || BadReg(n) || BadReg(m)) 1519 return false; 1520 1521 break; 1522 1523 case eEncodingA1: 1524 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 1525 d = Bits32(opcode, 19, 16); 1526 n = Bits32(opcode, 3, 0); 1527 m = Bits32(opcode, 11, 8); 1528 setflags = BitIsSet(opcode, 20); 1529 1530 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1531 if ((d == 15) || (n == 15) || (m == 15)) 1532 return false; 1533 1534 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1535 if ((ArchVersion() < ARMv6) && (d == n)) 1536 return false; 1537 1538 break; 1539 1540 default: 1541 return false; 1542 } 1543 1544 bool success = false; 1545 1546 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final 1547 // results 1548 uint64_t operand1 = 1549 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1550 if (!success) 1551 return false; 1552 1553 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final 1554 // results 1555 uint64_t operand2 = 1556 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1557 if (!success) 1558 return false; 1559 1560 // result = operand1 * operand2; 1561 uint64_t result = operand1 * operand2; 1562 1563 // R[d] = result<31:0>; 1564 RegisterInfo op1_reg; 1565 RegisterInfo op2_reg; 1566 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1567 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1568 1569 EmulateInstruction::Context context; 1570 context.type = eContextArithmetic; 1571 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 1572 1573 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 1574 (0x0000ffff & result))) 1575 return false; 1576 1577 // if setflags then 1578 if (setflags) { 1579 // APSR.N = result<31>; 1580 // APSR.Z = IsZeroBit(result); 1581 m_new_inst_cpsr = m_opcode_cpsr; 1582 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31)); 1583 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1584 if (m_new_inst_cpsr != m_opcode_cpsr) { 1585 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1586 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1587 return false; 1588 } 1589 1590 // if ArchVersion() == 4 then 1591 // APSR.C = bit UNKNOWN; 1592 } 1593 } 1594 return true; 1595 } 1596 1597 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to 1598 // the destination register. It can optionally update the condition flags based 1599 // on the value. 1600 bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode, 1601 const ARMEncoding encoding) { 1602 #if 0 1603 // ARM pseudo code... 1604 if (ConditionPassed()) 1605 { 1606 EncodingSpecificOperations(); 1607 result = NOT(imm32); 1608 if d == 15 then // Can only occur for ARM encoding 1609 ALUWritePC(result); // setflags is always FALSE here 1610 else 1611 R[d] = result; 1612 if setflags then 1613 APSR.N = result<31>; 1614 APSR.Z = IsZeroBit(result); 1615 APSR.C = carry; 1616 // APSR.V unchanged 1617 } 1618 #endif 1619 1620 if (ConditionPassed(opcode)) { 1621 uint32_t Rd; // the destination register 1622 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1623 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1624 bool setflags; 1625 switch (encoding) { 1626 case eEncodingT1: 1627 Rd = Bits32(opcode, 11, 8); 1628 setflags = BitIsSet(opcode, 20); 1629 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1630 break; 1631 case eEncodingA1: 1632 Rd = Bits32(opcode, 15, 12); 1633 setflags = BitIsSet(opcode, 20); 1634 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1635 1636 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1637 // instructions; 1638 if (Rd == 15 && setflags) 1639 return EmulateSUBSPcLrEtc(opcode, encoding); 1640 break; 1641 default: 1642 return false; 1643 } 1644 uint32_t result = ~imm32; 1645 1646 // The context specifies that an immediate is to be moved into Rd. 1647 EmulateInstruction::Context context; 1648 context.type = EmulateInstruction::eContextImmediate; 1649 context.SetNoArgs(); 1650 1651 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1652 return false; 1653 } 1654 return true; 1655 } 1656 1657 // Bitwise NOT (register) writes the bitwise inverse of a register value to the 1658 // destination register. It can optionally update the condition flags based on 1659 // the result. 1660 bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode, 1661 const ARMEncoding encoding) { 1662 #if 0 1663 // ARM pseudo code... 1664 if (ConditionPassed()) 1665 { 1666 EncodingSpecificOperations(); 1667 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1668 result = NOT(shifted); 1669 if d == 15 then // Can only occur for ARM encoding 1670 ALUWritePC(result); // setflags is always FALSE here 1671 else 1672 R[d] = result; 1673 if setflags then 1674 APSR.N = result<31>; 1675 APSR.Z = IsZeroBit(result); 1676 APSR.C = carry; 1677 // APSR.V unchanged 1678 } 1679 #endif 1680 1681 if (ConditionPassed(opcode)) { 1682 uint32_t Rm; // the source register 1683 uint32_t Rd; // the destination register 1684 ARM_ShifterType shift_t; 1685 uint32_t shift_n; // the shift applied to the value read from Rm 1686 bool setflags; 1687 uint32_t carry; // the carry bit after the shift operation 1688 switch (encoding) { 1689 case eEncodingT1: 1690 Rd = Bits32(opcode, 2, 0); 1691 Rm = Bits32(opcode, 5, 3); 1692 setflags = !InITBlock(); 1693 shift_t = SRType_LSL; 1694 shift_n = 0; 1695 if (InITBlock()) 1696 return false; 1697 break; 1698 case eEncodingT2: 1699 Rd = Bits32(opcode, 11, 8); 1700 Rm = Bits32(opcode, 3, 0); 1701 setflags = BitIsSet(opcode, 20); 1702 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1703 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1704 if (BadReg(Rd) || BadReg(Rm)) 1705 return false; 1706 break; 1707 case eEncodingA1: 1708 Rd = Bits32(opcode, 15, 12); 1709 Rm = Bits32(opcode, 3, 0); 1710 setflags = BitIsSet(opcode, 20); 1711 shift_n = DecodeImmShiftARM(opcode, shift_t); 1712 break; 1713 default: 1714 return false; 1715 } 1716 bool success = false; 1717 uint32_t value = ReadCoreReg(Rm, &success); 1718 if (!success) 1719 return false; 1720 1721 uint32_t shifted = 1722 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1723 if (!success) 1724 return false; 1725 uint32_t result = ~shifted; 1726 1727 // The context specifies that an immediate is to be moved into Rd. 1728 EmulateInstruction::Context context; 1729 context.type = EmulateInstruction::eContextImmediate; 1730 context.SetNoArgs(); 1731 1732 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1733 return false; 1734 } 1735 return true; 1736 } 1737 1738 // PC relative immediate load into register, possibly followed by ADD (SP plus 1739 // register). 1740 // LDR (literal) 1741 bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode, 1742 const ARMEncoding encoding) { 1743 #if 0 1744 // ARM pseudo code... 1745 if (ConditionPassed()) 1746 { 1747 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1748 base = Align(PC,4); 1749 address = if add then (base + imm32) else (base - imm32); 1750 data = MemU[address,4]; 1751 if t == 15 then 1752 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1753 elsif UnalignedSupport() || address<1:0> = '00' then 1754 R[t] = data; 1755 else // Can only apply before ARMv7 1756 if CurrentInstrSet() == InstrSet_ARM then 1757 R[t] = ROR(data, 8*UInt(address<1:0>)); 1758 else 1759 R[t] = bits(32) UNKNOWN; 1760 } 1761 #endif 1762 1763 if (ConditionPassed(opcode)) { 1764 bool success = false; 1765 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1766 if (!success) 1767 return false; 1768 1769 // PC relative immediate load context 1770 EmulateInstruction::Context context; 1771 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1772 RegisterInfo pc_reg; 1773 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 1774 context.SetRegisterPlusOffset(pc_reg, 0); 1775 1776 uint32_t Rt; // the destination register 1777 uint32_t imm32; // immediate offset from the PC 1778 bool add; // +imm32 or -imm32? 1779 addr_t base; // the base address 1780 addr_t address; // the PC relative address 1781 uint32_t data; // the literal data value from the PC relative load 1782 switch (encoding) { 1783 case eEncodingT1: 1784 Rt = Bits32(opcode, 10, 8); 1785 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1786 add = true; 1787 break; 1788 case eEncodingT2: 1789 Rt = Bits32(opcode, 15, 12); 1790 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1791 add = BitIsSet(opcode, 23); 1792 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1793 return false; 1794 break; 1795 default: 1796 return false; 1797 } 1798 1799 base = Align(pc, 4); 1800 if (add) 1801 address = base + imm32; 1802 else 1803 address = base - imm32; 1804 1805 context.SetRegisterPlusOffset(pc_reg, address - base); 1806 data = MemURead(context, address, 4, 0, &success); 1807 if (!success) 1808 return false; 1809 1810 if (Rt == 15) { 1811 if (Bits32(address, 1, 0) == 0) { 1812 // In ARMv5T and above, this is an interworking branch. 1813 if (!LoadWritePC(context, data)) 1814 return false; 1815 } else 1816 return false; 1817 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 1818 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 1819 data)) 1820 return false; 1821 } else // We don't handle ARM for now. 1822 return false; 1823 } 1824 return true; 1825 } 1826 1827 // An add operation to adjust the SP. 1828 // ADD (SP plus immediate) 1829 bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode, 1830 const ARMEncoding encoding) { 1831 #if 0 1832 // ARM pseudo code... 1833 if (ConditionPassed()) 1834 { 1835 EncodingSpecificOperations(); 1836 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1837 if d == 15 then // Can only occur for ARM encoding 1838 ALUWritePC(result); // setflags is always FALSE here 1839 else 1840 R[d] = result; 1841 if setflags then 1842 APSR.N = result<31>; 1843 APSR.Z = IsZeroBit(result); 1844 APSR.C = carry; 1845 APSR.V = overflow; 1846 } 1847 #endif 1848 1849 bool success = false; 1850 1851 if (ConditionPassed(opcode)) { 1852 const addr_t sp = ReadCoreReg(SP_REG, &success); 1853 if (!success) 1854 return false; 1855 uint32_t imm32; // the immediate operand 1856 uint32_t d; 1857 bool setflags; 1858 switch (encoding) { 1859 case eEncodingT1: 1860 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1861 d = Bits32(opcode, 10, 8); 1862 imm32 = (Bits32(opcode, 7, 0) << 2); 1863 setflags = false; 1864 break; 1865 1866 case eEncodingT2: 1867 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1868 d = 13; 1869 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1870 setflags = false; 1871 break; 1872 1873 case eEncodingT3: 1874 // d = UInt(Rd); setflags = (S == "1"); imm32 = 1875 // ThumbExpandImm(i:imm3:imm8); 1876 d = Bits32(opcode, 11, 8); 1877 imm32 = ThumbExpandImm(opcode); 1878 setflags = Bit32(opcode, 20); 1879 1880 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 1881 if (d == 15 && setflags == 1) 1882 return false; // CMN (immediate) not yet supported 1883 1884 // if d == 15 && S == "0" then UNPREDICTABLE; 1885 if (d == 15 && setflags == 0) 1886 return false; 1887 break; 1888 1889 case eEncodingT4: { 1890 // if Rn == '1111' then SEE ADR; 1891 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 1892 d = Bits32(opcode, 11, 8); 1893 setflags = false; 1894 uint32_t i = Bit32(opcode, 26); 1895 uint32_t imm3 = Bits32(opcode, 14, 12); 1896 uint32_t imm8 = Bits32(opcode, 7, 0); 1897 imm32 = (i << 11) | (imm3 << 8) | imm8; 1898 1899 // if d == 15 then UNPREDICTABLE; 1900 if (d == 15) 1901 return false; 1902 } break; 1903 1904 default: 1905 return false; 1906 } 1907 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 1908 AddWithCarryResult res = AddWithCarry(sp, imm32, 0); 1909 1910 EmulateInstruction::Context context; 1911 if (d == 13) 1912 context.type = EmulateInstruction::eContextAdjustStackPointer; 1913 else 1914 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1915 1916 RegisterInfo sp_reg; 1917 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1918 context.SetRegisterPlusOffset(sp_reg, res.result - sp); 1919 1920 if (d == 15) { 1921 if (!ALUWritePC(context, res.result)) 1922 return false; 1923 } else { 1924 // R[d] = result; 1925 // if setflags then 1926 // APSR.N = result<31>; 1927 // APSR.Z = IsZeroBit(result); 1928 // APSR.C = carry; 1929 // APSR.V = overflow; 1930 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 1931 res.carry_out, res.overflow)) 1932 return false; 1933 } 1934 } 1935 return true; 1936 } 1937 1938 // An add operation to adjust the SP. 1939 // ADD (SP plus register) 1940 bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode, 1941 const ARMEncoding encoding) { 1942 #if 0 1943 // ARM pseudo code... 1944 if (ConditionPassed()) 1945 { 1946 EncodingSpecificOperations(); 1947 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1948 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1949 if d == 15 then 1950 ALUWritePC(result); // setflags is always FALSE here 1951 else 1952 R[d] = result; 1953 if setflags then 1954 APSR.N = result<31>; 1955 APSR.Z = IsZeroBit(result); 1956 APSR.C = carry; 1957 APSR.V = overflow; 1958 } 1959 #endif 1960 1961 bool success = false; 1962 1963 if (ConditionPassed(opcode)) { 1964 const addr_t sp = ReadCoreReg(SP_REG, &success); 1965 if (!success) 1966 return false; 1967 uint32_t Rm; // the second operand 1968 switch (encoding) { 1969 case eEncodingT2: 1970 Rm = Bits32(opcode, 6, 3); 1971 break; 1972 default: 1973 return false; 1974 } 1975 int32_t reg_value = ReadCoreReg(Rm, &success); 1976 if (!success) 1977 return false; 1978 1979 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1980 1981 EmulateInstruction::Context context; 1982 context.type = eContextArithmetic; 1983 RegisterInfo sp_reg; 1984 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1985 1986 RegisterInfo other_reg; 1987 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1988 context.SetRegisterRegisterOperands(sp_reg, other_reg); 1989 1990 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1991 LLDB_REGNUM_GENERIC_SP, addr)) 1992 return false; 1993 } 1994 return true; 1995 } 1996 1997 // Branch with Link and Exchange Instruction Sets (immediate) calls a 1998 // subroutine at a PC-relative address, and changes instruction set from ARM to 1999 // Thumb, or from Thumb to ARM. 2000 // BLX (immediate) 2001 bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode, 2002 const ARMEncoding encoding) { 2003 #if 0 2004 // ARM pseudo code... 2005 if (ConditionPassed()) 2006 { 2007 EncodingSpecificOperations(); 2008 if CurrentInstrSet() == InstrSet_ARM then 2009 LR = PC - 4; 2010 else 2011 LR = PC<31:1> : '1'; 2012 if targetInstrSet == InstrSet_ARM then 2013 targetAddress = Align(PC,4) + imm32; 2014 else 2015 targetAddress = PC + imm32; 2016 SelectInstrSet(targetInstrSet); 2017 BranchWritePC(targetAddress); 2018 } 2019 #endif 2020 2021 bool success = true; 2022 2023 if (ConditionPassed(opcode)) { 2024 EmulateInstruction::Context context; 2025 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2026 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2027 if (!success) 2028 return false; 2029 addr_t lr; // next instruction address 2030 addr_t target; // target address 2031 int32_t imm32; // PC-relative offset 2032 switch (encoding) { 2033 case eEncodingT1: { 2034 lr = pc | 1u; // return address 2035 uint32_t S = Bit32(opcode, 26); 2036 uint32_t imm10 = Bits32(opcode, 25, 16); 2037 uint32_t J1 = Bit32(opcode, 13); 2038 uint32_t J2 = Bit32(opcode, 11); 2039 uint32_t imm11 = Bits32(opcode, 10, 0); 2040 uint32_t I1 = !(J1 ^ S); 2041 uint32_t I2 = !(J2 ^ S); 2042 uint32_t imm25 = 2043 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2044 imm32 = llvm::SignExtend32<25>(imm25); 2045 target = pc + imm32; 2046 SelectInstrSet(eModeThumb); 2047 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2048 if (InITBlock() && !LastInITBlock()) 2049 return false; 2050 break; 2051 } 2052 case eEncodingT2: { 2053 lr = pc | 1u; // return address 2054 uint32_t S = Bit32(opcode, 26); 2055 uint32_t imm10H = Bits32(opcode, 25, 16); 2056 uint32_t J1 = Bit32(opcode, 13); 2057 uint32_t J2 = Bit32(opcode, 11); 2058 uint32_t imm10L = Bits32(opcode, 10, 1); 2059 uint32_t I1 = !(J1 ^ S); 2060 uint32_t I2 = !(J2 ^ S); 2061 uint32_t imm25 = 2062 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 2063 imm32 = llvm::SignExtend32<25>(imm25); 2064 target = Align(pc, 4) + imm32; 2065 SelectInstrSet(eModeARM); 2066 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32); 2067 if (InITBlock() && !LastInITBlock()) 2068 return false; 2069 break; 2070 } 2071 case eEncodingA1: 2072 lr = pc - 4; // return address 2073 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2074 target = Align(pc, 4) + imm32; 2075 SelectInstrSet(eModeARM); 2076 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2077 break; 2078 case eEncodingA2: 2079 lr = pc - 4; // return address 2080 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | 2081 Bits32(opcode, 24, 24) << 1); 2082 target = pc + imm32; 2083 SelectInstrSet(eModeThumb); 2084 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32); 2085 break; 2086 default: 2087 return false; 2088 } 2089 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2090 LLDB_REGNUM_GENERIC_RA, lr)) 2091 return false; 2092 if (!BranchWritePC(context, target)) 2093 return false; 2094 if (m_opcode_cpsr != m_new_inst_cpsr) 2095 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2096 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2097 return false; 2098 } 2099 return true; 2100 } 2101 2102 // Branch with Link and Exchange (register) calls a subroutine at an address 2103 // and instruction set specified by a register. 2104 // BLX (register) 2105 bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode, 2106 const ARMEncoding encoding) { 2107 #if 0 2108 // ARM pseudo code... 2109 if (ConditionPassed()) 2110 { 2111 EncodingSpecificOperations(); 2112 target = R[m]; 2113 if CurrentInstrSet() == InstrSet_ARM then 2114 next_instr_addr = PC - 4; 2115 LR = next_instr_addr; 2116 else 2117 next_instr_addr = PC - 2; 2118 LR = next_instr_addr<31:1> : '1'; 2119 BXWritePC(target); 2120 } 2121 #endif 2122 2123 bool success = false; 2124 2125 if (ConditionPassed(opcode)) { 2126 EmulateInstruction::Context context; 2127 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2128 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2129 addr_t lr; // next instruction address 2130 if (!success) 2131 return false; 2132 uint32_t Rm; // the register with the target address 2133 switch (encoding) { 2134 case eEncodingT1: 2135 lr = (pc - 2) | 1u; // return address 2136 Rm = Bits32(opcode, 6, 3); 2137 // if m == 15 then UNPREDICTABLE; 2138 if (Rm == 15) 2139 return false; 2140 if (InITBlock() && !LastInITBlock()) 2141 return false; 2142 break; 2143 case eEncodingA1: 2144 lr = pc - 4; // return address 2145 Rm = Bits32(opcode, 3, 0); 2146 // if m == 15 then UNPREDICTABLE; 2147 if (Rm == 15) 2148 return false; 2149 break; 2150 default: 2151 return false; 2152 } 2153 addr_t target = ReadCoreReg(Rm, &success); 2154 if (!success) 2155 return false; 2156 RegisterInfo dwarf_reg; 2157 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2158 context.SetRegister(dwarf_reg); 2159 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2160 LLDB_REGNUM_GENERIC_RA, lr)) 2161 return false; 2162 if (!BXWritePC(context, target)) 2163 return false; 2164 } 2165 return true; 2166 } 2167 2168 // Branch and Exchange causes a branch to an address and instruction set 2169 // specified by a register. 2170 bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode, 2171 const ARMEncoding encoding) { 2172 #if 0 2173 // ARM pseudo code... 2174 if (ConditionPassed()) 2175 { 2176 EncodingSpecificOperations(); 2177 BXWritePC(R[m]); 2178 } 2179 #endif 2180 2181 if (ConditionPassed(opcode)) { 2182 EmulateInstruction::Context context; 2183 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2184 uint32_t Rm; // the register with the target address 2185 switch (encoding) { 2186 case eEncodingT1: 2187 Rm = Bits32(opcode, 6, 3); 2188 if (InITBlock() && !LastInITBlock()) 2189 return false; 2190 break; 2191 case eEncodingA1: 2192 Rm = Bits32(opcode, 3, 0); 2193 break; 2194 default: 2195 return false; 2196 } 2197 bool success = false; 2198 addr_t target = ReadCoreReg(Rm, &success); 2199 if (!success) 2200 return false; 2201 2202 RegisterInfo dwarf_reg; 2203 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2204 context.SetRegister(dwarf_reg); 2205 if (!BXWritePC(context, target)) 2206 return false; 2207 } 2208 return true; 2209 } 2210 2211 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the 2212 // attempt fails, it branches to an address and instruction set specified by a 2213 // register as though it were a BX instruction. 2214 // 2215 // TODO: Emulate Jazelle architecture? 2216 // We currently assume that switching to Jazelle state fails, thus 2217 // treating BXJ as a BX operation. 2218 bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode, 2219 const ARMEncoding encoding) { 2220 #if 0 2221 // ARM pseudo code... 2222 if (ConditionPassed()) 2223 { 2224 EncodingSpecificOperations(); 2225 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 2226 BXWritePC(R[m]); 2227 else 2228 if JazelleAcceptsExecution() then 2229 SwitchToJazelleExecution(); 2230 else 2231 SUBARCHITECTURE_DEFINED handler call; 2232 } 2233 #endif 2234 2235 if (ConditionPassed(opcode)) { 2236 EmulateInstruction::Context context; 2237 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2238 uint32_t Rm; // the register with the target address 2239 switch (encoding) { 2240 case eEncodingT1: 2241 Rm = Bits32(opcode, 19, 16); 2242 if (BadReg(Rm)) 2243 return false; 2244 if (InITBlock() && !LastInITBlock()) 2245 return false; 2246 break; 2247 case eEncodingA1: 2248 Rm = Bits32(opcode, 3, 0); 2249 if (Rm == 15) 2250 return false; 2251 break; 2252 default: 2253 return false; 2254 } 2255 bool success = false; 2256 addr_t target = ReadCoreReg(Rm, &success); 2257 if (!success) 2258 return false; 2259 2260 RegisterInfo dwarf_reg; 2261 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2262 context.SetRegister(dwarf_reg); 2263 if (!BXWritePC(context, target)) 2264 return false; 2265 } 2266 return true; 2267 } 2268 2269 // Set r7 to point to some ip offset. 2270 // SUB (immediate) 2271 bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode, 2272 const ARMEncoding encoding) { 2273 #if 0 2274 // ARM pseudo code... 2275 if (ConditionPassed()) 2276 { 2277 EncodingSpecificOperations(); 2278 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2279 if d == 15 then // Can only occur for ARM encoding 2280 ALUWritePC(result); // setflags is always FALSE here 2281 else 2282 R[d] = result; 2283 if setflags then 2284 APSR.N = result<31>; 2285 APSR.Z = IsZeroBit(result); 2286 APSR.C = carry; 2287 APSR.V = overflow; 2288 } 2289 #endif 2290 2291 if (ConditionPassed(opcode)) { 2292 bool success = false; 2293 const addr_t ip = ReadCoreReg(12, &success); 2294 if (!success) 2295 return false; 2296 uint32_t imm32; 2297 switch (encoding) { 2298 case eEncodingA1: 2299 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2300 break; 2301 default: 2302 return false; 2303 } 2304 addr_t ip_offset = imm32; 2305 addr_t addr = ip - ip_offset; // the adjusted ip value 2306 2307 EmulateInstruction::Context context; 2308 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2309 RegisterInfo dwarf_reg; 2310 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg); 2311 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset); 2312 2313 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr)) 2314 return false; 2315 } 2316 return true; 2317 } 2318 2319 // Set ip to point to some stack offset. 2320 // SUB (SP minus immediate) 2321 bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode, 2322 const ARMEncoding encoding) { 2323 #if 0 2324 // ARM pseudo code... 2325 if (ConditionPassed()) 2326 { 2327 EncodingSpecificOperations(); 2328 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2329 if d == 15 then // Can only occur for ARM encoding 2330 ALUWritePC(result); // setflags is always FALSE here 2331 else 2332 R[d] = result; 2333 if setflags then 2334 APSR.N = result<31>; 2335 APSR.Z = IsZeroBit(result); 2336 APSR.C = carry; 2337 APSR.V = overflow; 2338 } 2339 #endif 2340 2341 if (ConditionPassed(opcode)) { 2342 bool success = false; 2343 const addr_t sp = ReadCoreReg(SP_REG, &success); 2344 if (!success) 2345 return false; 2346 uint32_t imm32; 2347 switch (encoding) { 2348 case eEncodingA1: 2349 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2350 break; 2351 default: 2352 return false; 2353 } 2354 addr_t sp_offset = imm32; 2355 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 2356 2357 EmulateInstruction::Context context; 2358 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2359 RegisterInfo dwarf_reg; 2360 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 2361 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset); 2362 2363 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr)) 2364 return false; 2365 } 2366 return true; 2367 } 2368 2369 // This instruction subtracts an immediate value from the SP value, and writes 2370 // the result to the destination register. 2371 // 2372 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local 2373 // storage. 2374 bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode, 2375 const ARMEncoding encoding) { 2376 #if 0 2377 // ARM pseudo code... 2378 if (ConditionPassed()) 2379 { 2380 EncodingSpecificOperations(); 2381 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2382 if d == 15 then // Can only occur for ARM encoding 2383 ALUWritePC(result); // setflags is always FALSE here 2384 else 2385 R[d] = result; 2386 if setflags then 2387 APSR.N = result<31>; 2388 APSR.Z = IsZeroBit(result); 2389 APSR.C = carry; 2390 APSR.V = overflow; 2391 } 2392 #endif 2393 2394 bool success = false; 2395 if (ConditionPassed(opcode)) { 2396 const addr_t sp = ReadCoreReg(SP_REG, &success); 2397 if (!success) 2398 return false; 2399 2400 uint32_t Rd; 2401 bool setflags; 2402 uint32_t imm32; 2403 switch (encoding) { 2404 case eEncodingT1: 2405 Rd = 13; 2406 setflags = false; 2407 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 2408 break; 2409 case eEncodingT2: 2410 Rd = Bits32(opcode, 11, 8); 2411 setflags = BitIsSet(opcode, 20); 2412 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2413 if (Rd == 15 && setflags) 2414 return EmulateCMPImm(opcode, eEncodingT2); 2415 if (Rd == 15 && !setflags) 2416 return false; 2417 break; 2418 case eEncodingT3: 2419 Rd = Bits32(opcode, 11, 8); 2420 setflags = false; 2421 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 2422 if (Rd == 15) 2423 return false; 2424 break; 2425 case eEncodingA1: 2426 Rd = Bits32(opcode, 15, 12); 2427 setflags = BitIsSet(opcode, 20); 2428 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2429 2430 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 2431 // instructions; 2432 if (Rd == 15 && setflags) 2433 return EmulateSUBSPcLrEtc(opcode, encoding); 2434 break; 2435 default: 2436 return false; 2437 } 2438 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 2439 2440 EmulateInstruction::Context context; 2441 if (Rd == 13) { 2442 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting 2443 // to negate it, or the wrong 2444 // value gets passed down to context.SetImmediateSigned. 2445 context.type = EmulateInstruction::eContextAdjustStackPointer; 2446 context.SetImmediateSigned(-imm64); // the stack pointer offset 2447 } else { 2448 context.type = EmulateInstruction::eContextImmediate; 2449 context.SetNoArgs(); 2450 } 2451 2452 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 2453 res.carry_out, res.overflow)) 2454 return false; 2455 } 2456 return true; 2457 } 2458 2459 // A store operation to the stack that also updates the SP. 2460 bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode, 2461 const ARMEncoding encoding) { 2462 #if 0 2463 // ARM pseudo code... 2464 if (ConditionPassed()) 2465 { 2466 EncodingSpecificOperations(); 2467 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2468 address = if index then offset_addr else R[n]; 2469 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 2470 if wback then R[n] = offset_addr; 2471 } 2472 #endif 2473 2474 bool success = false; 2475 if (ConditionPassed(opcode)) { 2476 const uint32_t addr_byte_size = GetAddressByteSize(); 2477 const addr_t sp = ReadCoreReg(SP_REG, &success); 2478 if (!success) 2479 return false; 2480 uint32_t Rt; // the source register 2481 uint32_t imm12; 2482 uint32_t 2483 Rn; // This function assumes Rn is the SP, but we should verify that. 2484 2485 bool index; 2486 bool add; 2487 bool wback; 2488 switch (encoding) { 2489 case eEncodingA1: 2490 Rt = Bits32(opcode, 15, 12); 2491 imm12 = Bits32(opcode, 11, 0); 2492 Rn = Bits32(opcode, 19, 16); 2493 2494 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 2495 return false; 2496 2497 index = BitIsSet(opcode, 24); 2498 add = BitIsSet(opcode, 23); 2499 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 2500 2501 if (wback && ((Rn == 15) || (Rn == Rt))) 2502 return false; 2503 break; 2504 default: 2505 return false; 2506 } 2507 addr_t offset_addr; 2508 if (add) 2509 offset_addr = sp + imm12; 2510 else 2511 offset_addr = sp - imm12; 2512 2513 addr_t addr; 2514 if (index) 2515 addr = offset_addr; 2516 else 2517 addr = sp; 2518 2519 EmulateInstruction::Context context; 2520 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2521 RegisterInfo sp_reg; 2522 RegisterInfo dwarf_reg; 2523 2524 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2525 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2526 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2527 if (Rt != 15) { 2528 uint32_t reg_value = ReadCoreReg(Rt, &success); 2529 if (!success) 2530 return false; 2531 if (!MemUWrite(context, addr, reg_value, addr_byte_size)) 2532 return false; 2533 } else { 2534 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2535 if (!success) 2536 return false; 2537 if (!MemUWrite(context, addr, pc, addr_byte_size)) 2538 return false; 2539 } 2540 2541 if (wback) { 2542 context.type = EmulateInstruction::eContextAdjustStackPointer; 2543 context.SetImmediateSigned(addr - sp); 2544 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2545 LLDB_REGNUM_GENERIC_SP, offset_addr)) 2546 return false; 2547 } 2548 } 2549 return true; 2550 } 2551 2552 // Vector Push stores multiple extension registers to the stack. It also 2553 // updates SP to point to the start of the stored data. 2554 bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode, 2555 const ARMEncoding encoding) { 2556 #if 0 2557 // ARM pseudo code... 2558 if (ConditionPassed()) 2559 { 2560 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2561 address = SP - imm32; 2562 SP = SP - imm32; 2563 if single_regs then 2564 for r = 0 to regs-1 2565 MemA[address,4] = S[d+r]; address = address+4; 2566 else 2567 for r = 0 to regs-1 2568 // Store as two word-aligned words in the correct order for 2569 // current endianness. 2570 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2571 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2572 address = address+8; 2573 } 2574 #endif 2575 2576 bool success = false; 2577 if (ConditionPassed(opcode)) { 2578 const uint32_t addr_byte_size = GetAddressByteSize(); 2579 const addr_t sp = ReadCoreReg(SP_REG, &success); 2580 if (!success) 2581 return false; 2582 bool single_regs; 2583 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2584 uint32_t imm32; // stack offset 2585 uint32_t regs; // number of registers 2586 switch (encoding) { 2587 case eEncodingT1: 2588 case eEncodingA1: 2589 single_regs = false; 2590 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2591 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2592 // If UInt(imm8) is odd, see "FSTMX". 2593 regs = Bits32(opcode, 7, 0) / 2; 2594 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2595 if (regs == 0 || regs > 16 || (d + regs) > 32) 2596 return false; 2597 break; 2598 case eEncodingT2: 2599 case eEncodingA2: 2600 single_regs = true; 2601 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2602 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2603 regs = Bits32(opcode, 7, 0); 2604 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2605 if (regs == 0 || regs > 16 || (d + regs) > 32) 2606 return false; 2607 break; 2608 default: 2609 return false; 2610 } 2611 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2612 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2613 addr_t sp_offset = imm32; 2614 addr_t addr = sp - sp_offset; 2615 uint32_t i; 2616 2617 EmulateInstruction::Context context; 2618 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2619 2620 RegisterInfo dwarf_reg; 2621 RegisterInfo sp_reg; 2622 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2623 for (i = 0; i < regs; ++i) { 2624 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2625 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2626 // uint64_t to accommodate 64-bit registers. 2627 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success); 2628 if (!success) 2629 return false; 2630 if (!MemAWrite(context, addr, reg_value, reg_byte_size)) 2631 return false; 2632 addr += reg_byte_size; 2633 } 2634 2635 context.type = EmulateInstruction::eContextAdjustStackPointer; 2636 context.SetImmediateSigned(-sp_offset); 2637 2638 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2639 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2640 return false; 2641 } 2642 return true; 2643 } 2644 2645 // Vector Pop loads multiple extension registers from the stack. It also 2646 // updates SP to point just above the loaded data. 2647 bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode, 2648 const ARMEncoding encoding) { 2649 #if 0 2650 // ARM pseudo code... 2651 if (ConditionPassed()) 2652 { 2653 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2654 address = SP; 2655 SP = SP + imm32; 2656 if single_regs then 2657 for r = 0 to regs-1 2658 S[d+r] = MemA[address,4]; address = address+4; 2659 else 2660 for r = 0 to regs-1 2661 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2662 // Combine the word-aligned words in the correct order for 2663 // current endianness. 2664 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2665 } 2666 #endif 2667 2668 bool success = false; 2669 if (ConditionPassed(opcode)) { 2670 const uint32_t addr_byte_size = GetAddressByteSize(); 2671 const addr_t sp = ReadCoreReg(SP_REG, &success); 2672 if (!success) 2673 return false; 2674 bool single_regs; 2675 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2676 uint32_t imm32; // stack offset 2677 uint32_t regs; // number of registers 2678 switch (encoding) { 2679 case eEncodingT1: 2680 case eEncodingA1: 2681 single_regs = false; 2682 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2683 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2684 // If UInt(imm8) is odd, see "FLDMX". 2685 regs = Bits32(opcode, 7, 0) / 2; 2686 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2687 if (regs == 0 || regs > 16 || (d + regs) > 32) 2688 return false; 2689 break; 2690 case eEncodingT2: 2691 case eEncodingA2: 2692 single_regs = true; 2693 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2694 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2695 regs = Bits32(opcode, 7, 0); 2696 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2697 if (regs == 0 || regs > 16 || (d + regs) > 32) 2698 return false; 2699 break; 2700 default: 2701 return false; 2702 } 2703 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2704 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2705 addr_t sp_offset = imm32; 2706 addr_t addr = sp; 2707 uint32_t i; 2708 uint64_t data; // uint64_t to accommodate 64-bit registers. 2709 2710 EmulateInstruction::Context context; 2711 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2712 2713 RegisterInfo dwarf_reg; 2714 RegisterInfo sp_reg; 2715 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2716 for (i = 0; i < regs; ++i) { 2717 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2718 context.SetAddress(addr); 2719 data = MemARead(context, addr, reg_byte_size, 0, &success); 2720 if (!success) 2721 return false; 2722 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2723 return false; 2724 addr += reg_byte_size; 2725 } 2726 2727 context.type = EmulateInstruction::eContextAdjustStackPointer; 2728 context.SetImmediateSigned(sp_offset); 2729 2730 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2731 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2732 return false; 2733 } 2734 return true; 2735 } 2736 2737 // SVC (previously SWI) 2738 bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode, 2739 const ARMEncoding encoding) { 2740 #if 0 2741 // ARM pseudo code... 2742 if (ConditionPassed()) 2743 { 2744 EncodingSpecificOperations(); 2745 CallSupervisor(); 2746 } 2747 #endif 2748 2749 bool success = false; 2750 2751 if (ConditionPassed(opcode)) { 2752 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2753 addr_t lr; // next instruction address 2754 if (!success) 2755 return false; 2756 uint32_t imm32; // the immediate constant 2757 uint32_t mode; // ARM or Thumb mode 2758 switch (encoding) { 2759 case eEncodingT1: 2760 lr = (pc + 2) | 1u; // return address 2761 imm32 = Bits32(opcode, 7, 0); 2762 mode = eModeThumb; 2763 break; 2764 case eEncodingA1: 2765 lr = pc + 4; // return address 2766 imm32 = Bits32(opcode, 23, 0); 2767 mode = eModeARM; 2768 break; 2769 default: 2770 return false; 2771 } 2772 2773 EmulateInstruction::Context context; 2774 context.type = EmulateInstruction::eContextSupervisorCall; 2775 context.SetISAAndImmediate(mode, imm32); 2776 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2777 LLDB_REGNUM_GENERIC_RA, lr)) 2778 return false; 2779 } 2780 return true; 2781 } 2782 2783 // If Then makes up to four following instructions (the IT block) conditional. 2784 bool EmulateInstructionARM::EmulateIT(const uint32_t opcode, 2785 const ARMEncoding encoding) { 2786 #if 0 2787 // ARM pseudo code... 2788 EncodingSpecificOperations(); 2789 ITSTATE.IT<7:0> = firstcond:mask; 2790 #endif 2791 2792 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2793 return true; 2794 } 2795 2796 bool EmulateInstructionARM::EmulateNop(const uint32_t opcode, 2797 const ARMEncoding encoding) { 2798 // NOP, nothing to do... 2799 return true; 2800 } 2801 2802 // Branch causes a branch to a target address. 2803 bool EmulateInstructionARM::EmulateB(const uint32_t opcode, 2804 const ARMEncoding encoding) { 2805 #if 0 2806 // ARM pseudo code... 2807 if (ConditionPassed()) 2808 { 2809 EncodingSpecificOperations(); 2810 BranchWritePC(PC + imm32); 2811 } 2812 #endif 2813 2814 bool success = false; 2815 2816 if (ConditionPassed(opcode)) { 2817 EmulateInstruction::Context context; 2818 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2819 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2820 if (!success) 2821 return false; 2822 addr_t target; // target address 2823 int32_t imm32; // PC-relative offset 2824 switch (encoding) { 2825 case eEncodingT1: 2826 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2827 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2828 target = pc + imm32; 2829 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2830 break; 2831 case eEncodingT2: 2832 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2833 target = pc + imm32; 2834 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2835 break; 2836 case eEncodingT3: 2837 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2838 { 2839 if (Bits32(opcode, 25, 23) == 7) 2840 return false; // See Branches and miscellaneous control on page 2841 // A6-235. 2842 2843 uint32_t S = Bit32(opcode, 26); 2844 uint32_t imm6 = Bits32(opcode, 21, 16); 2845 uint32_t J1 = Bit32(opcode, 13); 2846 uint32_t J2 = Bit32(opcode, 11); 2847 uint32_t imm11 = Bits32(opcode, 10, 0); 2848 uint32_t imm21 = 2849 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2850 imm32 = llvm::SignExtend32<21>(imm21); 2851 target = pc + imm32; 2852 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2853 break; 2854 } 2855 case eEncodingT4: { 2856 uint32_t S = Bit32(opcode, 26); 2857 uint32_t imm10 = Bits32(opcode, 25, 16); 2858 uint32_t J1 = Bit32(opcode, 13); 2859 uint32_t J2 = Bit32(opcode, 11); 2860 uint32_t imm11 = Bits32(opcode, 10, 0); 2861 uint32_t I1 = !(J1 ^ S); 2862 uint32_t I2 = !(J2 ^ S); 2863 uint32_t imm25 = 2864 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2865 imm32 = llvm::SignExtend32<25>(imm25); 2866 target = pc + imm32; 2867 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2868 break; 2869 } 2870 case eEncodingA1: 2871 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2872 target = pc + imm32; 2873 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2874 break; 2875 default: 2876 return false; 2877 } 2878 if (!BranchWritePC(context, target)) 2879 return false; 2880 } 2881 return true; 2882 } 2883 2884 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the 2885 // value in a register with zero and conditionally branch forward a constant 2886 // value. They do not affect the condition flags. CBNZ, CBZ 2887 bool EmulateInstructionARM::EmulateCB(const uint32_t opcode, 2888 const ARMEncoding encoding) { 2889 #if 0 2890 // ARM pseudo code... 2891 EncodingSpecificOperations(); 2892 if nonzero ^ IsZero(R[n]) then 2893 BranchWritePC(PC + imm32); 2894 #endif 2895 2896 bool success = false; 2897 2898 // Read the register value from the operand register Rn. 2899 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2900 if (!success) 2901 return false; 2902 2903 EmulateInstruction::Context context; 2904 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2905 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2906 if (!success) 2907 return false; 2908 2909 addr_t target; // target address 2910 uint32_t imm32; // PC-relative offset to branch forward 2911 bool nonzero; 2912 switch (encoding) { 2913 case eEncodingT1: 2914 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2915 nonzero = BitIsSet(opcode, 11); 2916 target = pc + imm32; 2917 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2918 break; 2919 default: 2920 return false; 2921 } 2922 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2923 if (!BranchWritePC(context, target)) 2924 return false; 2925 2926 return true; 2927 } 2928 2929 // Table Branch Byte causes a PC-relative forward branch using a table of 2930 // single byte offsets. 2931 // A base register provides a pointer to the table, and a second register 2932 // supplies an index into the table. 2933 // The branch length is twice the value of the byte returned from the table. 2934 // 2935 // Table Branch Halfword causes a PC-relative forward branch using a table of 2936 // single halfword offsets. 2937 // A base register provides a pointer to the table, and a second register 2938 // supplies an index into the table. 2939 // The branch length is twice the value of the halfword returned from the 2940 // table. TBB, TBH 2941 bool EmulateInstructionARM::EmulateTB(const uint32_t opcode, 2942 const ARMEncoding encoding) { 2943 #if 0 2944 // ARM pseudo code... 2945 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2946 if is_tbh then 2947 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2948 else 2949 halfwords = UInt(MemU[R[n]+R[m], 1]); 2950 BranchWritePC(PC + 2*halfwords); 2951 #endif 2952 2953 bool success = false; 2954 2955 if (ConditionPassed(opcode)) { 2956 uint32_t Rn; // the base register which contains the address of the table of 2957 // branch lengths 2958 uint32_t Rm; // the index register which contains an integer pointing to a 2959 // byte/halfword in the table 2960 bool is_tbh; // true if table branch halfword 2961 switch (encoding) { 2962 case eEncodingT1: 2963 Rn = Bits32(opcode, 19, 16); 2964 Rm = Bits32(opcode, 3, 0); 2965 is_tbh = BitIsSet(opcode, 4); 2966 if (Rn == 13 || BadReg(Rm)) 2967 return false; 2968 if (InITBlock() && !LastInITBlock()) 2969 return false; 2970 break; 2971 default: 2972 return false; 2973 } 2974 2975 // Read the address of the table from the operand register Rn. The PC can 2976 // be used, in which case the table immediately follows this instruction. 2977 uint32_t base = ReadCoreReg(Rn, &success); 2978 if (!success) 2979 return false; 2980 2981 // the table index 2982 uint32_t index = ReadCoreReg(Rm, &success); 2983 if (!success) 2984 return false; 2985 2986 // the offsetted table address 2987 addr_t addr = base + (is_tbh ? index * 2 : index); 2988 2989 // PC-relative offset to branch forward 2990 EmulateInstruction::Context context; 2991 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2992 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2993 if (!success) 2994 return false; 2995 2996 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2997 if (!success) 2998 return false; 2999 3000 // target address 3001 addr_t target = pc + offset; 3002 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 3003 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset); 3004 3005 if (!BranchWritePC(context, target)) 3006 return false; 3007 } 3008 3009 return true; 3010 } 3011 3012 // This instruction adds an immediate value to a register value, and writes the 3013 // result to the destination register. It can optionally update the condition 3014 // flags based on the result. 3015 bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode, 3016 const ARMEncoding encoding) { 3017 #if 0 3018 if ConditionPassed() then 3019 EncodingSpecificOperations(); 3020 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3021 R[d] = result; 3022 if setflags then 3023 APSR.N = result<31>; 3024 APSR.Z = IsZeroBit(result); 3025 APSR.C = carry; 3026 APSR.V = overflow; 3027 #endif 3028 3029 bool success = false; 3030 3031 if (ConditionPassed(opcode)) { 3032 uint32_t d; 3033 uint32_t n; 3034 bool setflags; 3035 uint32_t imm32; 3036 uint32_t carry_out; 3037 3038 // EncodingSpecificOperations(); 3039 switch (encoding) { 3040 case eEncodingT1: 3041 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = 3042 // ZeroExtend(imm3, 32); 3043 d = Bits32(opcode, 2, 0); 3044 n = Bits32(opcode, 5, 3); 3045 setflags = !InITBlock(); 3046 imm32 = Bits32(opcode, 8, 6); 3047 3048 break; 3049 3050 case eEncodingT2: 3051 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = 3052 // ZeroExtend(imm8, 32); 3053 d = Bits32(opcode, 10, 8); 3054 n = Bits32(opcode, 10, 8); 3055 setflags = !InITBlock(); 3056 imm32 = Bits32(opcode, 7, 0); 3057 3058 break; 3059 3060 case eEncodingT3: 3061 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 3062 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = 3063 // ThumbExpandImm(i:imm3:imm8); 3064 d = Bits32(opcode, 11, 8); 3065 n = Bits32(opcode, 19, 16); 3066 setflags = BitIsSet(opcode, 20); 3067 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out); 3068 3069 // if Rn == '1101' then SEE ADD (SP plus immediate); 3070 if (n == 13) 3071 return EmulateADDSPImm(opcode, eEncodingT3); 3072 3073 // if BadReg(d) || n == 15 then UNPREDICTABLE; 3074 if (BadReg(d) || (n == 15)) 3075 return false; 3076 3077 break; 3078 3079 case eEncodingT4: { 3080 // if Rn == '1111' then SEE ADR; 3081 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = 3082 // ZeroExtend(i:imm3:imm8, 32); 3083 d = Bits32(opcode, 11, 8); 3084 n = Bits32(opcode, 19, 16); 3085 setflags = false; 3086 uint32_t i = Bit32(opcode, 26); 3087 uint32_t imm3 = Bits32(opcode, 14, 12); 3088 uint32_t imm8 = Bits32(opcode, 7, 0); 3089 imm32 = (i << 11) | (imm3 << 8) | imm8; 3090 3091 // if Rn == '1101' then SEE ADD (SP plus immediate); 3092 if (n == 13) 3093 return EmulateADDSPImm(opcode, eEncodingT4); 3094 3095 // if BadReg(d) then UNPREDICTABLE; 3096 if (BadReg(d)) 3097 return false; 3098 3099 break; 3100 } 3101 3102 default: 3103 return false; 3104 } 3105 3106 uint64_t Rn = 3107 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3108 if (!success) 3109 return false; 3110 3111 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3112 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0); 3113 3114 RegisterInfo reg_n; 3115 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 3116 3117 EmulateInstruction::Context context; 3118 context.type = eContextArithmetic; 3119 context.SetRegisterPlusOffset(reg_n, imm32); 3120 3121 // R[d] = result; 3122 // if setflags then 3123 // APSR.N = result<31>; 3124 // APSR.Z = IsZeroBit(result); 3125 // APSR.C = carry; 3126 // APSR.V = overflow; 3127 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 3128 res.carry_out, res.overflow)) 3129 return false; 3130 } 3131 return true; 3132 } 3133 3134 // This instruction adds an immediate value to a register value, and writes the 3135 // result to the destination register. It can optionally update the condition 3136 // flags based on the result. 3137 bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode, 3138 const ARMEncoding encoding) { 3139 #if 0 3140 // ARM pseudo code... 3141 if ConditionPassed() then 3142 EncodingSpecificOperations(); 3143 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3144 if d == 15 then 3145 ALUWritePC(result); // setflags is always FALSE here 3146 else 3147 R[d] = result; 3148 if setflags then 3149 APSR.N = result<31>; 3150 APSR.Z = IsZeroBit(result); 3151 APSR.C = carry; 3152 APSR.V = overflow; 3153 #endif 3154 3155 bool success = false; 3156 3157 if (ConditionPassed(opcode)) { 3158 uint32_t Rd, Rn; 3159 uint32_t 3160 imm32; // the immediate value to be added to the value obtained from Rn 3161 bool setflags; 3162 switch (encoding) { 3163 case eEncodingA1: 3164 Rd = Bits32(opcode, 15, 12); 3165 Rn = Bits32(opcode, 19, 16); 3166 setflags = BitIsSet(opcode, 20); 3167 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3168 break; 3169 default: 3170 return false; 3171 } 3172 3173 // Read the first operand. 3174 uint32_t val1 = ReadCoreReg(Rn, &success); 3175 if (!success) 3176 return false; 3177 3178 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 3179 3180 EmulateInstruction::Context context; 3181 if (Rd == 13) 3182 context.type = EmulateInstruction::eContextAdjustStackPointer; 3183 else if (Rd == GetFramePointerRegisterNumber()) 3184 context.type = EmulateInstruction::eContextSetFramePointer; 3185 else 3186 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3187 3188 RegisterInfo dwarf_reg; 3189 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 3190 context.SetRegisterPlusOffset(dwarf_reg, imm32); 3191 3192 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3193 res.carry_out, res.overflow)) 3194 return false; 3195 } 3196 return true; 3197 } 3198 3199 // This instruction adds a register value and an optionally-shifted register 3200 // value, and writes the result to the destination register. It can optionally 3201 // update the condition flags based on the result. 3202 bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode, 3203 const ARMEncoding encoding) { 3204 #if 0 3205 // ARM pseudo code... 3206 if ConditionPassed() then 3207 EncodingSpecificOperations(); 3208 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3209 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3210 if d == 15 then 3211 ALUWritePC(result); // setflags is always FALSE here 3212 else 3213 R[d] = result; 3214 if setflags then 3215 APSR.N = result<31>; 3216 APSR.Z = IsZeroBit(result); 3217 APSR.C = carry; 3218 APSR.V = overflow; 3219 #endif 3220 3221 bool success = false; 3222 3223 if (ConditionPassed(opcode)) { 3224 uint32_t Rd, Rn, Rm; 3225 ARM_ShifterType shift_t; 3226 uint32_t shift_n; // the shift applied to the value read from Rm 3227 bool setflags; 3228 switch (encoding) { 3229 case eEncodingT1: 3230 Rd = Bits32(opcode, 2, 0); 3231 Rn = Bits32(opcode, 5, 3); 3232 Rm = Bits32(opcode, 8, 6); 3233 setflags = !InITBlock(); 3234 shift_t = SRType_LSL; 3235 shift_n = 0; 3236 break; 3237 case eEncodingT2: 3238 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3239 Rm = Bits32(opcode, 6, 3); 3240 setflags = false; 3241 shift_t = SRType_LSL; 3242 shift_n = 0; 3243 if (Rn == 15 && Rm == 15) 3244 return false; 3245 if (Rd == 15 && InITBlock() && !LastInITBlock()) 3246 return false; 3247 break; 3248 case eEncodingA1: 3249 Rd = Bits32(opcode, 15, 12); 3250 Rn = Bits32(opcode, 19, 16); 3251 Rm = Bits32(opcode, 3, 0); 3252 setflags = BitIsSet(opcode, 20); 3253 shift_n = DecodeImmShiftARM(opcode, shift_t); 3254 break; 3255 default: 3256 return false; 3257 } 3258 3259 // Read the first operand. 3260 uint32_t val1 = ReadCoreReg(Rn, &success); 3261 if (!success) 3262 return false; 3263 3264 // Read the second operand. 3265 uint32_t val2 = ReadCoreReg(Rm, &success); 3266 if (!success) 3267 return false; 3268 3269 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3270 if (!success) 3271 return false; 3272 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3273 3274 EmulateInstruction::Context context; 3275 context.type = eContextArithmetic; 3276 RegisterInfo op1_reg; 3277 RegisterInfo op2_reg; 3278 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 3279 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 3280 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 3281 3282 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3283 res.carry_out, res.overflow)) 3284 return false; 3285 } 3286 return true; 3287 } 3288 3289 // Compare Negative (immediate) adds a register value and an immediate value. 3290 // It updates the condition flags based on the result, and discards the result. 3291 bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode, 3292 const ARMEncoding encoding) { 3293 #if 0 3294 // ARM pseudo code... 3295 if ConditionPassed() then 3296 EncodingSpecificOperations(); 3297 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3298 APSR.N = result<31>; 3299 APSR.Z = IsZeroBit(result); 3300 APSR.C = carry; 3301 APSR.V = overflow; 3302 #endif 3303 3304 bool success = false; 3305 3306 uint32_t Rn; // the first operand 3307 uint32_t imm32; // the immediate value to be compared with 3308 switch (encoding) { 3309 case eEncodingT1: 3310 Rn = Bits32(opcode, 19, 16); 3311 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3312 if (Rn == 15) 3313 return false; 3314 break; 3315 case eEncodingA1: 3316 Rn = Bits32(opcode, 19, 16); 3317 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3318 break; 3319 default: 3320 return false; 3321 } 3322 // Read the register value from the operand register Rn. 3323 uint32_t reg_val = ReadCoreReg(Rn, &success); 3324 if (!success) 3325 return false; 3326 3327 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 3328 3329 EmulateInstruction::Context context; 3330 context.type = EmulateInstruction::eContextImmediate; 3331 context.SetNoArgs(); 3332 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3333 } 3334 3335 // Compare Negative (register) adds a register value and an optionally-shifted 3336 // register value. It updates the condition flags based on the result, and 3337 // discards the result. 3338 bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode, 3339 const ARMEncoding encoding) { 3340 #if 0 3341 // ARM pseudo code... 3342 if ConditionPassed() then 3343 EncodingSpecificOperations(); 3344 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3345 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3346 APSR.N = result<31>; 3347 APSR.Z = IsZeroBit(result); 3348 APSR.C = carry; 3349 APSR.V = overflow; 3350 #endif 3351 3352 bool success = false; 3353 3354 uint32_t Rn; // the first operand 3355 uint32_t Rm; // the second operand 3356 ARM_ShifterType shift_t; 3357 uint32_t shift_n; // the shift applied to the value read from Rm 3358 switch (encoding) { 3359 case eEncodingT1: 3360 Rn = Bits32(opcode, 2, 0); 3361 Rm = Bits32(opcode, 5, 3); 3362 shift_t = SRType_LSL; 3363 shift_n = 0; 3364 break; 3365 case eEncodingT2: 3366 Rn = Bits32(opcode, 19, 16); 3367 Rm = Bits32(opcode, 3, 0); 3368 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3369 // if n == 15 || BadReg(m) then UNPREDICTABLE; 3370 if (Rn == 15 || BadReg(Rm)) 3371 return false; 3372 break; 3373 case eEncodingA1: 3374 Rn = Bits32(opcode, 19, 16); 3375 Rm = Bits32(opcode, 3, 0); 3376 shift_n = DecodeImmShiftARM(opcode, shift_t); 3377 break; 3378 default: 3379 return false; 3380 } 3381 // Read the register value from register Rn. 3382 uint32_t val1 = ReadCoreReg(Rn, &success); 3383 if (!success) 3384 return false; 3385 3386 // Read the register value from register Rm. 3387 uint32_t val2 = ReadCoreReg(Rm, &success); 3388 if (!success) 3389 return false; 3390 3391 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3392 if (!success) 3393 return false; 3394 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3395 3396 EmulateInstruction::Context context; 3397 context.type = EmulateInstruction::eContextImmediate; 3398 context.SetNoArgs(); 3399 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3400 } 3401 3402 // Compare (immediate) subtracts an immediate value from a register value. It 3403 // updates the condition flags based on the result, and discards the result. 3404 bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode, 3405 const ARMEncoding encoding) { 3406 #if 0 3407 // ARM pseudo code... 3408 if ConditionPassed() then 3409 EncodingSpecificOperations(); 3410 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 3411 APSR.N = result<31>; 3412 APSR.Z = IsZeroBit(result); 3413 APSR.C = carry; 3414 APSR.V = overflow; 3415 #endif 3416 3417 bool success = false; 3418 3419 uint32_t Rn; // the first operand 3420 uint32_t imm32; // the immediate value to be compared with 3421 switch (encoding) { 3422 case eEncodingT1: 3423 Rn = Bits32(opcode, 10, 8); 3424 imm32 = Bits32(opcode, 7, 0); 3425 break; 3426 case eEncodingT2: 3427 Rn = Bits32(opcode, 19, 16); 3428 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3429 if (Rn == 15) 3430 return false; 3431 break; 3432 case eEncodingA1: 3433 Rn = Bits32(opcode, 19, 16); 3434 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3435 break; 3436 default: 3437 return false; 3438 } 3439 // Read the register value from the operand register Rn. 3440 uint32_t reg_val = ReadCoreReg(Rn, &success); 3441 if (!success) 3442 return false; 3443 3444 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 3445 3446 EmulateInstruction::Context context; 3447 context.type = EmulateInstruction::eContextImmediate; 3448 context.SetNoArgs(); 3449 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3450 } 3451 3452 // Compare (register) subtracts an optionally-shifted register value from a 3453 // register value. It updates the condition flags based on the result, and 3454 // discards the result. 3455 bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode, 3456 const ARMEncoding encoding) { 3457 #if 0 3458 // ARM pseudo code... 3459 if ConditionPassed() then 3460 EncodingSpecificOperations(); 3461 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3462 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 3463 APSR.N = result<31>; 3464 APSR.Z = IsZeroBit(result); 3465 APSR.C = carry; 3466 APSR.V = overflow; 3467 #endif 3468 3469 bool success = false; 3470 3471 uint32_t Rn; // the first operand 3472 uint32_t Rm; // the second operand 3473 ARM_ShifterType shift_t; 3474 uint32_t shift_n; // the shift applied to the value read from Rm 3475 switch (encoding) { 3476 case eEncodingT1: 3477 Rn = Bits32(opcode, 2, 0); 3478 Rm = Bits32(opcode, 5, 3); 3479 shift_t = SRType_LSL; 3480 shift_n = 0; 3481 break; 3482 case eEncodingT2: 3483 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3484 Rm = Bits32(opcode, 6, 3); 3485 shift_t = SRType_LSL; 3486 shift_n = 0; 3487 if (Rn < 8 && Rm < 8) 3488 return false; 3489 if (Rn == 15 || Rm == 15) 3490 return false; 3491 break; 3492 case eEncodingT3: 3493 Rn = Bits32(opcode, 19, 16); 3494 Rm = Bits32(opcode, 3, 0); 3495 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3496 if (Rn == 15 || BadReg(Rm)) 3497 return false; 3498 break; 3499 case eEncodingA1: 3500 Rn = Bits32(opcode, 19, 16); 3501 Rm = Bits32(opcode, 3, 0); 3502 shift_n = DecodeImmShiftARM(opcode, shift_t); 3503 break; 3504 default: 3505 return false; 3506 } 3507 // Read the register value from register Rn. 3508 uint32_t val1 = ReadCoreReg(Rn, &success); 3509 if (!success) 3510 return false; 3511 3512 // Read the register value from register Rm. 3513 uint32_t val2 = ReadCoreReg(Rm, &success); 3514 if (!success) 3515 return false; 3516 3517 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3518 if (!success) 3519 return false; 3520 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3521 3522 EmulateInstruction::Context context; 3523 context.type = EmulateInstruction::eContextImmediate; 3524 context.SetNoArgs(); 3525 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3526 } 3527 3528 // Arithmetic Shift Right (immediate) shifts a register value right by an 3529 // immediate number of bits, shifting in copies of its sign bit, and writes the 3530 // result to the destination register. It can optionally update the condition 3531 // flags based on the result. 3532 bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode, 3533 const ARMEncoding encoding) { 3534 #if 0 3535 // ARM pseudo code... 3536 if ConditionPassed() then 3537 EncodingSpecificOperations(); 3538 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3539 if d == 15 then // Can only occur for ARM encoding 3540 ALUWritePC(result); // setflags is always FALSE here 3541 else 3542 R[d] = result; 3543 if setflags then 3544 APSR.N = result<31>; 3545 APSR.Z = IsZeroBit(result); 3546 APSR.C = carry; 3547 // APSR.V unchanged 3548 #endif 3549 3550 return EmulateShiftImm(opcode, encoding, SRType_ASR); 3551 } 3552 3553 // Arithmetic Shift Right (register) shifts a register value right by a 3554 // variable number of bits, shifting in copies of its sign bit, and writes the 3555 // result to the destination register. The variable number of bits is read from 3556 // the bottom byte of a register. It can optionally update the condition flags 3557 // based on the result. 3558 bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode, 3559 const ARMEncoding encoding) { 3560 #if 0 3561 // ARM pseudo code... 3562 if ConditionPassed() then 3563 EncodingSpecificOperations(); 3564 shift_n = UInt(R[m]<7:0>); 3565 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3566 R[d] = result; 3567 if setflags then 3568 APSR.N = result<31>; 3569 APSR.Z = IsZeroBit(result); 3570 APSR.C = carry; 3571 // APSR.V unchanged 3572 #endif 3573 3574 return EmulateShiftReg(opcode, encoding, SRType_ASR); 3575 } 3576 3577 // Logical Shift Left (immediate) shifts a register value left by an immediate 3578 // number of bits, shifting in zeros, and writes the result to the destination 3579 // register. It can optionally update the condition flags based on the result. 3580 bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode, 3581 const ARMEncoding encoding) { 3582 #if 0 3583 // ARM pseudo code... 3584 if ConditionPassed() then 3585 EncodingSpecificOperations(); 3586 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3587 if d == 15 then // Can only occur for ARM encoding 3588 ALUWritePC(result); // setflags is always FALSE here 3589 else 3590 R[d] = result; 3591 if setflags then 3592 APSR.N = result<31>; 3593 APSR.Z = IsZeroBit(result); 3594 APSR.C = carry; 3595 // APSR.V unchanged 3596 #endif 3597 3598 return EmulateShiftImm(opcode, encoding, SRType_LSL); 3599 } 3600 3601 // Logical Shift Left (register) shifts a register value left by a variable 3602 // number of bits, shifting in zeros, and writes the result to the destination 3603 // register. The variable number of bits is read from the bottom byte of a 3604 // register. It can optionally update the condition flags based on the result. 3605 bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode, 3606 const ARMEncoding encoding) { 3607 #if 0 3608 // ARM pseudo code... 3609 if ConditionPassed() then 3610 EncodingSpecificOperations(); 3611 shift_n = UInt(R[m]<7:0>); 3612 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3613 R[d] = result; 3614 if setflags then 3615 APSR.N = result<31>; 3616 APSR.Z = IsZeroBit(result); 3617 APSR.C = carry; 3618 // APSR.V unchanged 3619 #endif 3620 3621 return EmulateShiftReg(opcode, encoding, SRType_LSL); 3622 } 3623 3624 // Logical Shift Right (immediate) shifts a register value right by an 3625 // immediate number of bits, shifting in zeros, and writes the result to the 3626 // destination register. It can optionally update the condition flags based on 3627 // the result. 3628 bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode, 3629 const ARMEncoding encoding) { 3630 #if 0 3631 // ARM pseudo code... 3632 if ConditionPassed() then 3633 EncodingSpecificOperations(); 3634 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3635 if d == 15 then // Can only occur for ARM encoding 3636 ALUWritePC(result); // setflags is always FALSE here 3637 else 3638 R[d] = result; 3639 if setflags then 3640 APSR.N = result<31>; 3641 APSR.Z = IsZeroBit(result); 3642 APSR.C = carry; 3643 // APSR.V unchanged 3644 #endif 3645 3646 return EmulateShiftImm(opcode, encoding, SRType_LSR); 3647 } 3648 3649 // Logical Shift Right (register) shifts a register value right by a variable 3650 // number of bits, shifting in zeros, and writes the result to the destination 3651 // register. The variable number of bits is read from the bottom byte of a 3652 // register. It can optionally update the condition flags based on the result. 3653 bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode, 3654 const ARMEncoding encoding) { 3655 #if 0 3656 // ARM pseudo code... 3657 if ConditionPassed() then 3658 EncodingSpecificOperations(); 3659 shift_n = UInt(R[m]<7:0>); 3660 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3661 R[d] = result; 3662 if setflags then 3663 APSR.N = result<31>; 3664 APSR.Z = IsZeroBit(result); 3665 APSR.C = carry; 3666 // APSR.V unchanged 3667 #endif 3668 3669 return EmulateShiftReg(opcode, encoding, SRType_LSR); 3670 } 3671 3672 // Rotate Right (immediate) provides the value of the contents of a register 3673 // rotated by a constant value. The bits that are rotated off the right end are 3674 // inserted into the vacated bit positions on the left. It can optionally 3675 // update the condition flags based on the result. 3676 bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode, 3677 const ARMEncoding encoding) { 3678 #if 0 3679 // ARM pseudo code... 3680 if ConditionPassed() then 3681 EncodingSpecificOperations(); 3682 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3683 if d == 15 then // Can only occur for ARM encoding 3684 ALUWritePC(result); // setflags is always FALSE here 3685 else 3686 R[d] = result; 3687 if setflags then 3688 APSR.N = result<31>; 3689 APSR.Z = IsZeroBit(result); 3690 APSR.C = carry; 3691 // APSR.V unchanged 3692 #endif 3693 3694 return EmulateShiftImm(opcode, encoding, SRType_ROR); 3695 } 3696 3697 // Rotate Right (register) provides the value of the contents of a register 3698 // rotated by a variable number of bits. The bits that are rotated off the 3699 // right end are inserted into the vacated bit positions on the left. The 3700 // variable number of bits is read from the bottom byte of a register. It can 3701 // optionally update the condition flags based on the result. 3702 bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode, 3703 const ARMEncoding encoding) { 3704 #if 0 3705 // ARM pseudo code... 3706 if ConditionPassed() then 3707 EncodingSpecificOperations(); 3708 shift_n = UInt(R[m]<7:0>); 3709 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3710 R[d] = result; 3711 if setflags then 3712 APSR.N = result<31>; 3713 APSR.Z = IsZeroBit(result); 3714 APSR.C = carry; 3715 // APSR.V unchanged 3716 #endif 3717 3718 return EmulateShiftReg(opcode, encoding, SRType_ROR); 3719 } 3720 3721 // Rotate Right with Extend provides the value of the contents of a register 3722 // shifted right by one place, with the carry flag shifted into bit [31]. 3723 // 3724 // RRX can optionally update the condition flags based on the result. 3725 // In that case, bit [0] is shifted into the carry flag. 3726 bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode, 3727 const ARMEncoding encoding) { 3728 #if 0 3729 // ARM pseudo code... 3730 if ConditionPassed() then 3731 EncodingSpecificOperations(); 3732 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3733 if d == 15 then // Can only occur for ARM encoding 3734 ALUWritePC(result); // setflags is always FALSE here 3735 else 3736 R[d] = result; 3737 if setflags then 3738 APSR.N = result<31>; 3739 APSR.Z = IsZeroBit(result); 3740 APSR.C = carry; 3741 // APSR.V unchanged 3742 #endif 3743 3744 return EmulateShiftImm(opcode, encoding, SRType_RRX); 3745 } 3746 3747 bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode, 3748 const ARMEncoding encoding, 3749 ARM_ShifterType shift_type) { 3750 // assert(shift_type == SRType_ASR 3751 // || shift_type == SRType_LSL 3752 // || shift_type == SRType_LSR 3753 // || shift_type == SRType_ROR 3754 // || shift_type == SRType_RRX); 3755 3756 bool success = false; 3757 3758 if (ConditionPassed(opcode)) { 3759 uint32_t Rd; // the destination register 3760 uint32_t Rm; // the first operand register 3761 uint32_t imm5; // encoding for the shift amount 3762 uint32_t carry; // the carry bit after the shift operation 3763 bool setflags; 3764 3765 // Special case handling! 3766 // A8.6.139 ROR (immediate) -- Encoding T1 3767 ARMEncoding use_encoding = encoding; 3768 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) { 3769 // Morph the T1 encoding from the ARM Architecture Manual into T2 3770 // encoding to have the same decoding of bit fields as the other Thumb2 3771 // shift operations. 3772 use_encoding = eEncodingT2; 3773 } 3774 3775 switch (use_encoding) { 3776 case eEncodingT1: 3777 // Due to the above special case handling! 3778 if (shift_type == SRType_ROR) 3779 return false; 3780 3781 Rd = Bits32(opcode, 2, 0); 3782 Rm = Bits32(opcode, 5, 3); 3783 setflags = !InITBlock(); 3784 imm5 = Bits32(opcode, 10, 6); 3785 break; 3786 case eEncodingT2: 3787 // A8.6.141 RRX 3788 // There's no imm form of RRX instructions. 3789 if (shift_type == SRType_RRX) 3790 return false; 3791 3792 Rd = Bits32(opcode, 11, 8); 3793 Rm = Bits32(opcode, 3, 0); 3794 setflags = BitIsSet(opcode, 20); 3795 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3796 if (BadReg(Rd) || BadReg(Rm)) 3797 return false; 3798 break; 3799 case eEncodingA1: 3800 Rd = Bits32(opcode, 15, 12); 3801 Rm = Bits32(opcode, 3, 0); 3802 setflags = BitIsSet(opcode, 20); 3803 imm5 = Bits32(opcode, 11, 7); 3804 break; 3805 default: 3806 return false; 3807 } 3808 3809 // A8.6.139 ROR (immediate) 3810 if (shift_type == SRType_ROR && imm5 == 0) 3811 shift_type = SRType_RRX; 3812 3813 // Get the first operand. 3814 uint32_t value = ReadCoreReg(Rm, &success); 3815 if (!success) 3816 return false; 3817 3818 // Decode the shift amount if not RRX. 3819 uint32_t amt = 3820 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3821 3822 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3823 if (!success) 3824 return false; 3825 3826 // The context specifies that an immediate is to be moved into Rd. 3827 EmulateInstruction::Context context; 3828 context.type = EmulateInstruction::eContextImmediate; 3829 context.SetNoArgs(); 3830 3831 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3832 return false; 3833 } 3834 return true; 3835 } 3836 3837 bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode, 3838 const ARMEncoding encoding, 3839 ARM_ShifterType shift_type) { 3840 // assert(shift_type == SRType_ASR 3841 // || shift_type == SRType_LSL 3842 // || shift_type == SRType_LSR 3843 // || shift_type == SRType_ROR); 3844 3845 bool success = false; 3846 3847 if (ConditionPassed(opcode)) { 3848 uint32_t Rd; // the destination register 3849 uint32_t Rn; // the first operand register 3850 uint32_t 3851 Rm; // the register whose bottom byte contains the amount to shift by 3852 uint32_t carry; // the carry bit after the shift operation 3853 bool setflags; 3854 switch (encoding) { 3855 case eEncodingT1: 3856 Rd = Bits32(opcode, 2, 0); 3857 Rn = Rd; 3858 Rm = Bits32(opcode, 5, 3); 3859 setflags = !InITBlock(); 3860 break; 3861 case eEncodingT2: 3862 Rd = Bits32(opcode, 11, 8); 3863 Rn = Bits32(opcode, 19, 16); 3864 Rm = Bits32(opcode, 3, 0); 3865 setflags = BitIsSet(opcode, 20); 3866 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3867 return false; 3868 break; 3869 case eEncodingA1: 3870 Rd = Bits32(opcode, 15, 12); 3871 Rn = Bits32(opcode, 3, 0); 3872 Rm = Bits32(opcode, 11, 8); 3873 setflags = BitIsSet(opcode, 20); 3874 if (Rd == 15 || Rn == 15 || Rm == 15) 3875 return false; 3876 break; 3877 default: 3878 return false; 3879 } 3880 3881 // Get the first operand. 3882 uint32_t value = ReadCoreReg(Rn, &success); 3883 if (!success) 3884 return false; 3885 // Get the Rm register content. 3886 uint32_t val = ReadCoreReg(Rm, &success); 3887 if (!success) 3888 return false; 3889 3890 // Get the shift amount. 3891 uint32_t amt = Bits32(val, 7, 0); 3892 3893 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3894 if (!success) 3895 return false; 3896 3897 // The context specifies that an immediate is to be moved into Rd. 3898 EmulateInstruction::Context context; 3899 context.type = EmulateInstruction::eContextImmediate; 3900 context.SetNoArgs(); 3901 3902 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3903 return false; 3904 } 3905 return true; 3906 } 3907 3908 // LDM loads multiple registers from consecutive memory locations, using an 3909 // address from a base register. Optionally the address just above the highest 3910 // of those locations can be written back to the base register. 3911 bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode, 3912 const ARMEncoding encoding) { 3913 #if 0 3914 // ARM pseudo code... 3915 if ConditionPassed() 3916 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3917 address = R[n]; 3918 3919 for i = 0 to 14 3920 if registers<i> == '1' then 3921 R[i] = MemA[address, 4]; address = address + 4; 3922 if registers<15> == '1' then 3923 LoadWritePC (MemA[address, 4]); 3924 3925 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3926 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3927 3928 #endif 3929 3930 bool success = false; 3931 if (ConditionPassed(opcode)) { 3932 uint32_t n; 3933 uint32_t registers = 0; 3934 bool wback; 3935 const uint32_t addr_byte_size = GetAddressByteSize(); 3936 switch (encoding) { 3937 case eEncodingT1: 3938 // n = UInt(Rn); registers = '00000000':register_list; wback = 3939 // (registers<n> == '0'); 3940 n = Bits32(opcode, 10, 8); 3941 registers = Bits32(opcode, 7, 0); 3942 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3943 wback = BitIsClear(registers, n); 3944 // if BitCount(registers) < 1 then UNPREDICTABLE; 3945 if (BitCount(registers) < 1) 3946 return false; 3947 break; 3948 case eEncodingT2: 3949 // if W == '1' && Rn == '1101' then SEE POP; 3950 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3951 n = Bits32(opcode, 19, 16); 3952 registers = Bits32(opcode, 15, 0); 3953 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3954 wback = BitIsSet(opcode, 21); 3955 3956 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 3957 // UNPREDICTABLE; 3958 if ((n == 15) || (BitCount(registers) < 2) || 3959 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 3960 return false; 3961 3962 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 3963 // UNPREDICTABLE; 3964 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 3965 return false; 3966 3967 // if wback && registers<n> == '1' then UNPREDICTABLE; 3968 if (wback && BitIsSet(registers, n)) 3969 return false; 3970 break; 3971 3972 case eEncodingA1: 3973 n = Bits32(opcode, 19, 16); 3974 registers = Bits32(opcode, 15, 0); 3975 wback = BitIsSet(opcode, 21); 3976 if ((n == 15) || (BitCount(registers) < 1)) 3977 return false; 3978 break; 3979 default: 3980 return false; 3981 } 3982 3983 int32_t offset = 0; 3984 const addr_t base_address = 3985 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3986 if (!success) 3987 return false; 3988 3989 EmulateInstruction::Context context; 3990 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3991 RegisterInfo dwarf_reg; 3992 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3993 context.SetRegisterPlusOffset(dwarf_reg, offset); 3994 3995 for (int i = 0; i < 14; ++i) { 3996 if (BitIsSet(registers, i)) { 3997 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3998 context.SetRegisterPlusOffset(dwarf_reg, offset); 3999 if (wback && (n == 13)) // Pop Instruction 4000 { 4001 context.type = EmulateInstruction::eContextPopRegisterOffStack; 4002 context.SetAddress(base_address + offset); 4003 } 4004 4005 // R[i] = MemA [address, 4]; address = address + 4; 4006 uint32_t data = MemARead(context, base_address + offset, addr_byte_size, 4007 0, &success); 4008 if (!success) 4009 return false; 4010 4011 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4012 data)) 4013 return false; 4014 4015 offset += addr_byte_size; 4016 } 4017 } 4018 4019 if (BitIsSet(registers, 15)) { 4020 // LoadWritePC (MemA [address, 4]); 4021 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4022 context.SetRegisterPlusOffset(dwarf_reg, offset); 4023 uint32_t data = 4024 MemARead(context, base_address + offset, addr_byte_size, 0, &success); 4025 if (!success) 4026 return false; 4027 // In ARMv5T and above, this is an interworking branch. 4028 if (!LoadWritePC(context, data)) 4029 return false; 4030 } 4031 4032 if (wback && BitIsClear(registers, n)) { 4033 // R[n] = R[n] + 4 * BitCount (registers) 4034 int32_t offset = addr_byte_size * BitCount(registers); 4035 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4036 context.SetRegisterPlusOffset(dwarf_reg, offset); 4037 4038 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4039 base_address + offset)) 4040 return false; 4041 } 4042 if (wback && BitIsSet(registers, n)) 4043 // R[n] bits(32) UNKNOWN; 4044 return WriteBits32Unknown(n); 4045 } 4046 return true; 4047 } 4048 4049 // LDMDA loads multiple registers from consecutive memory locations using an 4050 // address from a base register. 4051 // The consecutive memory locations end at this address and the address just 4052 // below the lowest of those locations can optionally be written back to the 4053 // base register. 4054 bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode, 4055 const ARMEncoding encoding) { 4056 #if 0 4057 // ARM pseudo code... 4058 if ConditionPassed() then 4059 EncodingSpecificOperations(); 4060 address = R[n] - 4*BitCount(registers) + 4; 4061 4062 for i = 0 to 14 4063 if registers<i> == '1' then 4064 R[i] = MemA[address,4]; address = address + 4; 4065 4066 if registers<15> == '1' then 4067 LoadWritePC(MemA[address,4]); 4068 4069 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4070 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4071 #endif 4072 4073 bool success = false; 4074 4075 if (ConditionPassed(opcode)) { 4076 uint32_t n; 4077 uint32_t registers = 0; 4078 bool wback; 4079 const uint32_t addr_byte_size = GetAddressByteSize(); 4080 4081 // EncodingSpecificOperations(); 4082 switch (encoding) { 4083 case eEncodingA1: 4084 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4085 n = Bits32(opcode, 19, 16); 4086 registers = Bits32(opcode, 15, 0); 4087 wback = BitIsSet(opcode, 21); 4088 4089 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4090 if ((n == 15) || (BitCount(registers) < 1)) 4091 return false; 4092 4093 break; 4094 4095 default: 4096 return false; 4097 } 4098 // address = R[n] - 4*BitCount(registers) + 4; 4099 4100 int32_t offset = 0; 4101 addr_t Rn = ReadCoreReg(n, &success); 4102 4103 if (!success) 4104 return false; 4105 4106 addr_t address = 4107 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size; 4108 4109 EmulateInstruction::Context context; 4110 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4111 RegisterInfo dwarf_reg; 4112 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4113 context.SetRegisterPlusOffset(dwarf_reg, offset); 4114 4115 // for i = 0 to 14 4116 for (int i = 0; i < 14; ++i) { 4117 // if registers<i> == '1' then 4118 if (BitIsSet(registers, i)) { 4119 // R[i] = MemA[address,4]; address = address + 4; 4120 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4121 uint32_t data = 4122 MemARead(context, address + offset, addr_byte_size, 0, &success); 4123 if (!success) 4124 return false; 4125 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4126 data)) 4127 return false; 4128 offset += addr_byte_size; 4129 } 4130 } 4131 4132 // if registers<15> == '1' then 4133 // LoadWritePC(MemA[address,4]); 4134 if (BitIsSet(registers, 15)) { 4135 context.SetRegisterPlusOffset(dwarf_reg, offset); 4136 uint32_t data = 4137 MemARead(context, address + offset, addr_byte_size, 0, &success); 4138 if (!success) 4139 return false; 4140 // In ARMv5T and above, this is an interworking branch. 4141 if (!LoadWritePC(context, data)) 4142 return false; 4143 } 4144 4145 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4146 if (wback && BitIsClear(registers, n)) { 4147 if (!success) 4148 return false; 4149 4150 offset = (addr_byte_size * BitCount(registers)) * -1; 4151 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4152 context.SetImmediateSigned(offset); 4153 addr_t addr = Rn + offset; 4154 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4155 addr)) 4156 return false; 4157 } 4158 4159 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4160 if (wback && BitIsSet(registers, n)) 4161 return WriteBits32Unknown(n); 4162 } 4163 return true; 4164 } 4165 4166 // LDMDB loads multiple registers from consecutive memory locations using an 4167 // address from a base register. The 4168 // consecutive memory locations end just below this address, and the address of 4169 // the lowest of those locations can be optionally written back to the base 4170 // register. 4171 bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode, 4172 const ARMEncoding encoding) { 4173 #if 0 4174 // ARM pseudo code... 4175 if ConditionPassed() then 4176 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4177 address = R[n] - 4*BitCount(registers); 4178 4179 for i = 0 to 14 4180 if registers<i> == '1' then 4181 R[i] = MemA[address,4]; address = address + 4; 4182 if registers<15> == '1' then 4183 LoadWritePC(MemA[address,4]); 4184 4185 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4186 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 4187 #endif 4188 4189 bool success = false; 4190 4191 if (ConditionPassed(opcode)) { 4192 uint32_t n; 4193 uint32_t registers = 0; 4194 bool wback; 4195 const uint32_t addr_byte_size = GetAddressByteSize(); 4196 switch (encoding) { 4197 case eEncodingT1: 4198 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 4199 n = Bits32(opcode, 19, 16); 4200 registers = Bits32(opcode, 15, 0); 4201 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 4202 wback = BitIsSet(opcode, 21); 4203 4204 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 4205 // UNPREDICTABLE; 4206 if ((n == 15) || (BitCount(registers) < 2) || 4207 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 4208 return false; 4209 4210 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 4211 // UNPREDICTABLE; 4212 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 4213 return false; 4214 4215 // if wback && registers<n> == '1' then UNPREDICTABLE; 4216 if (wback && BitIsSet(registers, n)) 4217 return false; 4218 4219 break; 4220 4221 case eEncodingA1: 4222 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4223 n = Bits32(opcode, 19, 16); 4224 registers = Bits32(opcode, 15, 0); 4225 wback = BitIsSet(opcode, 21); 4226 4227 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4228 if ((n == 15) || (BitCount(registers) < 1)) 4229 return false; 4230 4231 break; 4232 4233 default: 4234 return false; 4235 } 4236 4237 // address = R[n] - 4*BitCount(registers); 4238 4239 int32_t offset = 0; 4240 addr_t Rn = 4241 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4242 4243 if (!success) 4244 return false; 4245 4246 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4247 EmulateInstruction::Context context; 4248 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4249 RegisterInfo dwarf_reg; 4250 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4251 context.SetRegisterPlusOffset(dwarf_reg, Rn - address); 4252 4253 for (int i = 0; i < 14; ++i) { 4254 if (BitIsSet(registers, i)) { 4255 // R[i] = MemA[address,4]; address = address + 4; 4256 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4257 uint32_t data = 4258 MemARead(context, address + offset, addr_byte_size, 0, &success); 4259 if (!success) 4260 return false; 4261 4262 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4263 data)) 4264 return false; 4265 4266 offset += addr_byte_size; 4267 } 4268 } 4269 4270 // if registers<15> == '1' then 4271 // LoadWritePC(MemA[address,4]); 4272 if (BitIsSet(registers, 15)) { 4273 context.SetRegisterPlusOffset(dwarf_reg, offset); 4274 uint32_t data = 4275 MemARead(context, address + offset, addr_byte_size, 0, &success); 4276 if (!success) 4277 return false; 4278 // In ARMv5T and above, this is an interworking branch. 4279 if (!LoadWritePC(context, data)) 4280 return false; 4281 } 4282 4283 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4284 if (wback && BitIsClear(registers, n)) { 4285 if (!success) 4286 return false; 4287 4288 offset = (addr_byte_size * BitCount(registers)) * -1; 4289 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4290 context.SetImmediateSigned(offset); 4291 addr_t addr = Rn + offset; 4292 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4293 addr)) 4294 return false; 4295 } 4296 4297 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4298 // possible for encoding A1 4299 if (wback && BitIsSet(registers, n)) 4300 return WriteBits32Unknown(n); 4301 } 4302 return true; 4303 } 4304 4305 // LDMIB loads multiple registers from consecutive memory locations using an 4306 // address from a base register. The 4307 // consecutive memory locations start just above this address, and thea ddress 4308 // of the last of those locations can optinoally be written back to the base 4309 // register. 4310 bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode, 4311 const ARMEncoding encoding) { 4312 #if 0 4313 if ConditionPassed() then 4314 EncodingSpecificOperations(); 4315 address = R[n] + 4; 4316 4317 for i = 0 to 14 4318 if registers<i> == '1' then 4319 R[i] = MemA[address,4]; address = address + 4; 4320 if registers<15> == '1' then 4321 LoadWritePC(MemA[address,4]); 4322 4323 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4324 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4325 #endif 4326 4327 bool success = false; 4328 4329 if (ConditionPassed(opcode)) { 4330 uint32_t n; 4331 uint32_t registers = 0; 4332 bool wback; 4333 const uint32_t addr_byte_size = GetAddressByteSize(); 4334 switch (encoding) { 4335 case eEncodingA1: 4336 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4337 n = Bits32(opcode, 19, 16); 4338 registers = Bits32(opcode, 15, 0); 4339 wback = BitIsSet(opcode, 21); 4340 4341 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4342 if ((n == 15) || (BitCount(registers) < 1)) 4343 return false; 4344 4345 break; 4346 default: 4347 return false; 4348 } 4349 // address = R[n] + 4; 4350 4351 int32_t offset = 0; 4352 addr_t Rn = 4353 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4354 4355 if (!success) 4356 return false; 4357 4358 addr_t address = Rn + addr_byte_size; 4359 4360 EmulateInstruction::Context context; 4361 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4362 RegisterInfo dwarf_reg; 4363 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4364 context.SetRegisterPlusOffset(dwarf_reg, offset); 4365 4366 for (int i = 0; i < 14; ++i) { 4367 if (BitIsSet(registers, i)) { 4368 // R[i] = MemA[address,4]; address = address + 4; 4369 4370 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size); 4371 uint32_t data = 4372 MemARead(context, address + offset, addr_byte_size, 0, &success); 4373 if (!success) 4374 return false; 4375 4376 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4377 data)) 4378 return false; 4379 4380 offset += addr_byte_size; 4381 } 4382 } 4383 4384 // if registers<15> == '1' then 4385 // LoadWritePC(MemA[address,4]); 4386 if (BitIsSet(registers, 15)) { 4387 context.SetRegisterPlusOffset(dwarf_reg, offset); 4388 uint32_t data = 4389 MemARead(context, address + offset, addr_byte_size, 0, &success); 4390 if (!success) 4391 return false; 4392 // In ARMv5T and above, this is an interworking branch. 4393 if (!LoadWritePC(context, data)) 4394 return false; 4395 } 4396 4397 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4398 if (wback && BitIsClear(registers, n)) { 4399 if (!success) 4400 return false; 4401 4402 offset = addr_byte_size * BitCount(registers); 4403 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4404 context.SetImmediateSigned(offset); 4405 addr_t addr = Rn + offset; 4406 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4407 addr)) 4408 return false; 4409 } 4410 4411 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4412 // possible for encoding A1 4413 if (wback && BitIsSet(registers, n)) 4414 return WriteBits32Unknown(n); 4415 } 4416 return true; 4417 } 4418 4419 // Load Register (immediate) calculates an address from a base register value 4420 // and an immediate offset, loads a word from memory, and writes to a register. 4421 // LDR (immediate, Thumb) 4422 bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode, 4423 const ARMEncoding encoding) { 4424 #if 0 4425 // ARM pseudo code... 4426 if (ConditionPassed()) 4427 { 4428 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 4429 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4430 address = if index then offset_addr else R[n]; 4431 data = MemU[address,4]; 4432 if wback then R[n] = offset_addr; 4433 if t == 15 then 4434 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 4435 elsif UnalignedSupport() || address<1:0> = '00' then 4436 R[t] = data; 4437 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 4438 } 4439 #endif 4440 4441 bool success = false; 4442 4443 if (ConditionPassed(opcode)) { 4444 uint32_t Rt; // the destination register 4445 uint32_t Rn; // the base register 4446 uint32_t imm32; // the immediate offset used to form the address 4447 addr_t offset_addr; // the offset address 4448 addr_t address; // the calculated address 4449 uint32_t data; // the literal data value from memory load 4450 bool add, index, wback; 4451 switch (encoding) { 4452 case eEncodingT1: 4453 Rt = Bits32(opcode, 2, 0); 4454 Rn = Bits32(opcode, 5, 3); 4455 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 4456 // index = TRUE; add = TRUE; wback = FALSE 4457 add = true; 4458 index = true; 4459 wback = false; 4460 4461 break; 4462 4463 case eEncodingT2: 4464 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4465 Rt = Bits32(opcode, 10, 8); 4466 Rn = 13; 4467 imm32 = Bits32(opcode, 7, 0) << 2; 4468 4469 // index = TRUE; add = TRUE; wback = FALSE; 4470 index = true; 4471 add = true; 4472 wback = false; 4473 4474 break; 4475 4476 case eEncodingT3: 4477 // if Rn == '1111' then SEE LDR (literal); 4478 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4479 Rt = Bits32(opcode, 15, 12); 4480 Rn = Bits32(opcode, 19, 16); 4481 imm32 = Bits32(opcode, 11, 0); 4482 4483 // index = TRUE; add = TRUE; wback = FALSE; 4484 index = true; 4485 add = true; 4486 wback = false; 4487 4488 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4489 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4490 return false; 4491 4492 break; 4493 4494 case eEncodingT4: 4495 // if Rn == '1111' then SEE LDR (literal); 4496 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4497 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == 4498 // '00000100' then SEE POP; 4499 // if P == '0' && W == '0' then UNDEFINED; 4500 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 4501 return false; 4502 4503 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4504 Rt = Bits32(opcode, 15, 12); 4505 Rn = Bits32(opcode, 19, 16); 4506 imm32 = Bits32(opcode, 7, 0); 4507 4508 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4509 index = BitIsSet(opcode, 10); 4510 add = BitIsSet(opcode, 9); 4511 wback = BitIsSet(opcode, 8); 4512 4513 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) 4514 // then UNPREDICTABLE; 4515 if ((wback && (Rn == Rt)) || 4516 ((Rt == 15) && InITBlock() && !LastInITBlock())) 4517 return false; 4518 4519 break; 4520 4521 default: 4522 return false; 4523 } 4524 uint32_t base = ReadCoreReg(Rn, &success); 4525 if (!success) 4526 return false; 4527 if (add) 4528 offset_addr = base + imm32; 4529 else 4530 offset_addr = base - imm32; 4531 4532 address = (index ? offset_addr : base); 4533 4534 RegisterInfo base_reg; 4535 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4536 if (wback) { 4537 EmulateInstruction::Context ctx; 4538 if (Rn == 13) { 4539 ctx.type = eContextAdjustStackPointer; 4540 ctx.SetImmediateSigned((int32_t)(offset_addr - base)); 4541 } else if (Rn == GetFramePointerRegisterNumber()) { 4542 ctx.type = eContextSetFramePointer; 4543 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4544 } else { 4545 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4546 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4547 } 4548 4549 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn, 4550 offset_addr)) 4551 return false; 4552 } 4553 4554 // Prepare to write to the Rt register. 4555 EmulateInstruction::Context context; 4556 context.type = EmulateInstruction::eContextRegisterLoad; 4557 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4558 4559 // Read memory from the address. 4560 data = MemURead(context, address, 4, 0, &success); 4561 if (!success) 4562 return false; 4563 4564 if (Rt == 15) { 4565 if (Bits32(address, 1, 0) == 0) { 4566 if (!LoadWritePC(context, data)) 4567 return false; 4568 } else 4569 return false; 4570 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 4571 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 4572 data)) 4573 return false; 4574 } else 4575 WriteBits32Unknown(Rt); 4576 } 4577 return true; 4578 } 4579 4580 // STM (Store Multiple Increment After) stores multiple registers to consecutive 4581 // memory locations using an address 4582 // from a base register. The consecutive memory locations start at this 4583 // address, and the address just above the last of those locations can 4584 // optionally be written back to the base register. 4585 bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode, 4586 const ARMEncoding encoding) { 4587 #if 0 4588 if ConditionPassed() then 4589 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4590 address = R[n]; 4591 4592 for i = 0 to 14 4593 if registers<i> == '1' then 4594 if i == n && wback && i != LowestSetBit(registers) then 4595 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4596 else 4597 MemA[address,4] = R[i]; 4598 address = address + 4; 4599 4600 if registers<15> == '1' then // Only possible for encoding A1 4601 MemA[address,4] = PCStoreValue(); 4602 if wback then R[n] = R[n] + 4*BitCount(registers); 4603 #endif 4604 4605 bool success = false; 4606 4607 if (ConditionPassed(opcode)) { 4608 uint32_t n; 4609 uint32_t registers = 0; 4610 bool wback; 4611 const uint32_t addr_byte_size = GetAddressByteSize(); 4612 4613 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4614 switch (encoding) { 4615 case eEncodingT1: 4616 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4617 n = Bits32(opcode, 10, 8); 4618 registers = Bits32(opcode, 7, 0); 4619 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4620 wback = true; 4621 4622 // if BitCount(registers) < 1 then UNPREDICTABLE; 4623 if (BitCount(registers) < 1) 4624 return false; 4625 4626 break; 4627 4628 case eEncodingT2: 4629 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4630 n = Bits32(opcode, 19, 16); 4631 registers = Bits32(opcode, 15, 0); 4632 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4633 wback = BitIsSet(opcode, 21); 4634 4635 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4636 if ((n == 15) || (BitCount(registers) < 2)) 4637 return false; 4638 4639 // if wback && registers<n> == '1' then UNPREDICTABLE; 4640 if (wback && BitIsSet(registers, n)) 4641 return false; 4642 4643 break; 4644 4645 case eEncodingA1: 4646 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4647 n = Bits32(opcode, 19, 16); 4648 registers = Bits32(opcode, 15, 0); 4649 wback = BitIsSet(opcode, 21); 4650 4651 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4652 if ((n == 15) || (BitCount(registers) < 1)) 4653 return false; 4654 4655 break; 4656 4657 default: 4658 return false; 4659 } 4660 4661 // address = R[n]; 4662 int32_t offset = 0; 4663 const addr_t address = 4664 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4665 if (!success) 4666 return false; 4667 4668 EmulateInstruction::Context context; 4669 context.type = EmulateInstruction::eContextRegisterStore; 4670 RegisterInfo base_reg; 4671 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4672 4673 // for i = 0 to 14 4674 uint32_t lowest_set_bit = 14; 4675 for (uint32_t i = 0; i < 14; ++i) { 4676 // if registers<i> == '1' then 4677 if (BitIsSet(registers, i)) { 4678 if (i < lowest_set_bit) 4679 lowest_set_bit = i; 4680 // if i == n && wback && i != LowestSetBit(registers) then 4681 if ((i == n) && wback && (i != lowest_set_bit)) 4682 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings 4683 // T1 and A1 4684 WriteBits32UnknownToMemory(address + offset); 4685 else { 4686 // MemA[address,4] = R[i]; 4687 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4688 0, &success); 4689 if (!success) 4690 return false; 4691 4692 RegisterInfo data_reg; 4693 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4694 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 4695 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4696 return false; 4697 } 4698 4699 // address = address + 4; 4700 offset += addr_byte_size; 4701 } 4702 } 4703 4704 // if registers<15> == '1' then // Only possible for encoding A1 4705 // MemA[address,4] = PCStoreValue(); 4706 if (BitIsSet(registers, 15)) { 4707 RegisterInfo pc_reg; 4708 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4709 context.SetRegisterPlusOffset(pc_reg, 8); 4710 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4711 if (!success) 4712 return false; 4713 4714 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4715 return false; 4716 } 4717 4718 // if wback then R[n] = R[n] + 4*BitCount(registers); 4719 if (wback) { 4720 offset = addr_byte_size * BitCount(registers); 4721 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4722 context.SetImmediateSigned(offset); 4723 addr_t data = address + offset; 4724 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4725 data)) 4726 return false; 4727 } 4728 } 4729 return true; 4730 } 4731 4732 // STMDA (Store Multiple Decrement After) stores multiple registers to 4733 // consecutive memory locations using an address from a base register. The 4734 // consecutive memory locations end at this address, and the address just below 4735 // the lowest of those locations can optionally be written back to the base 4736 // register. 4737 bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode, 4738 const ARMEncoding encoding) { 4739 #if 0 4740 if ConditionPassed() then 4741 EncodingSpecificOperations(); 4742 address = R[n] - 4*BitCount(registers) + 4; 4743 4744 for i = 0 to 14 4745 if registers<i> == '1' then 4746 if i == n && wback && i != LowestSetBit(registers) then 4747 MemA[address,4] = bits(32) UNKNOWN; 4748 else 4749 MemA[address,4] = R[i]; 4750 address = address + 4; 4751 4752 if registers<15> == '1' then 4753 MemA[address,4] = PCStoreValue(); 4754 4755 if wback then R[n] = R[n] - 4*BitCount(registers); 4756 #endif 4757 4758 bool success = false; 4759 4760 if (ConditionPassed(opcode)) { 4761 uint32_t n; 4762 uint32_t registers = 0; 4763 bool wback; 4764 const uint32_t addr_byte_size = GetAddressByteSize(); 4765 4766 // EncodingSpecificOperations(); 4767 switch (encoding) { 4768 case eEncodingA1: 4769 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4770 n = Bits32(opcode, 19, 16); 4771 registers = Bits32(opcode, 15, 0); 4772 wback = BitIsSet(opcode, 21); 4773 4774 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4775 if ((n == 15) || (BitCount(registers) < 1)) 4776 return false; 4777 break; 4778 default: 4779 return false; 4780 } 4781 4782 // address = R[n] - 4*BitCount(registers) + 4; 4783 int32_t offset = 0; 4784 addr_t Rn = ReadCoreReg(n, &success); 4785 if (!success) 4786 return false; 4787 4788 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4; 4789 4790 EmulateInstruction::Context context; 4791 context.type = EmulateInstruction::eContextRegisterStore; 4792 RegisterInfo base_reg; 4793 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4794 4795 // for i = 0 to 14 4796 uint32_t lowest_bit_set = 14; 4797 for (uint32_t i = 0; i < 14; ++i) { 4798 // if registers<i> == '1' then 4799 if (BitIsSet(registers, i)) { 4800 if (i < lowest_bit_set) 4801 lowest_bit_set = i; 4802 // if i == n && wback && i != LowestSetBit(registers) then 4803 if ((i == n) && wback && (i != lowest_bit_set)) 4804 // MemA[address,4] = bits(32) UNKNOWN; 4805 WriteBits32UnknownToMemory(address + offset); 4806 else { 4807 // MemA[address,4] = R[i]; 4808 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4809 0, &success); 4810 if (!success) 4811 return false; 4812 4813 RegisterInfo data_reg; 4814 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4815 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4816 Rn - (address + offset)); 4817 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4818 return false; 4819 } 4820 4821 // address = address + 4; 4822 offset += addr_byte_size; 4823 } 4824 } 4825 4826 // if registers<15> == '1' then 4827 // MemA[address,4] = PCStoreValue(); 4828 if (BitIsSet(registers, 15)) { 4829 RegisterInfo pc_reg; 4830 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4831 context.SetRegisterPlusOffset(pc_reg, 8); 4832 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4833 if (!success) 4834 return false; 4835 4836 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4837 return false; 4838 } 4839 4840 // if wback then R[n] = R[n] - 4*BitCount(registers); 4841 if (wback) { 4842 offset = (addr_byte_size * BitCount(registers)) * -1; 4843 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4844 context.SetImmediateSigned(offset); 4845 addr_t data = Rn + offset; 4846 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4847 data)) 4848 return false; 4849 } 4850 } 4851 return true; 4852 } 4853 4854 // STMDB (Store Multiple Decrement Before) stores multiple registers to 4855 // consecutive memory locations using an address from a base register. The 4856 // consecutive memory locations end just below this address, and the address of 4857 // the first of those locations can optionally be written back to the base 4858 // register. 4859 bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode, 4860 const ARMEncoding encoding) { 4861 #if 0 4862 if ConditionPassed() then 4863 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4864 address = R[n] - 4*BitCount(registers); 4865 4866 for i = 0 to 14 4867 if registers<i> == '1' then 4868 if i == n && wback && i != LowestSetBit(registers) then 4869 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4870 else 4871 MemA[address,4] = R[i]; 4872 address = address + 4; 4873 4874 if registers<15> == '1' then // Only possible for encoding A1 4875 MemA[address,4] = PCStoreValue(); 4876 4877 if wback then R[n] = R[n] - 4*BitCount(registers); 4878 #endif 4879 4880 bool success = false; 4881 4882 if (ConditionPassed(opcode)) { 4883 uint32_t n; 4884 uint32_t registers = 0; 4885 bool wback; 4886 const uint32_t addr_byte_size = GetAddressByteSize(); 4887 4888 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4889 switch (encoding) { 4890 case eEncodingT1: 4891 // if W == '1' && Rn == '1101' then SEE PUSH; 4892 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) { 4893 // See PUSH 4894 } 4895 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4896 n = Bits32(opcode, 19, 16); 4897 registers = Bits32(opcode, 15, 0); 4898 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4899 wback = BitIsSet(opcode, 21); 4900 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4901 if ((n == 15) || BitCount(registers) < 2) 4902 return false; 4903 // if wback && registers<n> == '1' then UNPREDICTABLE; 4904 if (wback && BitIsSet(registers, n)) 4905 return false; 4906 break; 4907 4908 case eEncodingA1: 4909 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE 4910 // PUSH; 4911 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) && 4912 BitCount(Bits32(opcode, 15, 0)) >= 2) { 4913 // See Push 4914 } 4915 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4916 n = Bits32(opcode, 19, 16); 4917 registers = Bits32(opcode, 15, 0); 4918 wback = BitIsSet(opcode, 21); 4919 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4920 if ((n == 15) || BitCount(registers) < 1) 4921 return false; 4922 break; 4923 4924 default: 4925 return false; 4926 } 4927 4928 // address = R[n] - 4*BitCount(registers); 4929 4930 int32_t offset = 0; 4931 addr_t Rn = 4932 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4933 if (!success) 4934 return false; 4935 4936 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4937 4938 EmulateInstruction::Context context; 4939 context.type = EmulateInstruction::eContextRegisterStore; 4940 RegisterInfo base_reg; 4941 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4942 4943 // for i = 0 to 14 4944 uint32_t lowest_set_bit = 14; 4945 for (uint32_t i = 0; i < 14; ++i) { 4946 // if registers<i> == '1' then 4947 if (BitIsSet(registers, i)) { 4948 if (i < lowest_set_bit) 4949 lowest_set_bit = i; 4950 // if i == n && wback && i != LowestSetBit(registers) then 4951 if ((i == n) && wback && (i != lowest_set_bit)) 4952 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding 4953 // A1 4954 WriteBits32UnknownToMemory(address + offset); 4955 else { 4956 // MemA[address,4] = R[i]; 4957 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4958 0, &success); 4959 if (!success) 4960 return false; 4961 4962 RegisterInfo data_reg; 4963 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4964 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4965 Rn - (address + offset)); 4966 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4967 return false; 4968 } 4969 4970 // address = address + 4; 4971 offset += addr_byte_size; 4972 } 4973 } 4974 4975 // if registers<15> == '1' then // Only possible for encoding A1 4976 // MemA[address,4] = PCStoreValue(); 4977 if (BitIsSet(registers, 15)) { 4978 RegisterInfo pc_reg; 4979 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4980 context.SetRegisterPlusOffset(pc_reg, 8); 4981 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4982 if (!success) 4983 return false; 4984 4985 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4986 return false; 4987 } 4988 4989 // if wback then R[n] = R[n] - 4*BitCount(registers); 4990 if (wback) { 4991 offset = (addr_byte_size * BitCount(registers)) * -1; 4992 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4993 context.SetImmediateSigned(offset); 4994 addr_t data = Rn + offset; 4995 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4996 data)) 4997 return false; 4998 } 4999 } 5000 return true; 5001 } 5002 5003 // STMIB (Store Multiple Increment Before) stores multiple registers to 5004 // consecutive memory locations using an address from a base register. The 5005 // consecutive memory locations start just above this address, and the address 5006 // of the last of those locations can optionally be written back to the base 5007 // register. 5008 bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode, 5009 const ARMEncoding encoding) { 5010 #if 0 5011 if ConditionPassed() then 5012 EncodingSpecificOperations(); 5013 address = R[n] + 4; 5014 5015 for i = 0 to 14 5016 if registers<i> == '1' then 5017 if i == n && wback && i != LowestSetBit(registers) then 5018 MemA[address,4] = bits(32) UNKNOWN; 5019 else 5020 MemA[address,4] = R[i]; 5021 address = address + 4; 5022 5023 if registers<15> == '1' then 5024 MemA[address,4] = PCStoreValue(); 5025 5026 if wback then R[n] = R[n] + 4*BitCount(registers); 5027 #endif 5028 5029 bool success = false; 5030 5031 if (ConditionPassed(opcode)) { 5032 uint32_t n; 5033 uint32_t registers = 0; 5034 bool wback; 5035 const uint32_t addr_byte_size = GetAddressByteSize(); 5036 5037 // EncodingSpecificOperations(); 5038 switch (encoding) { 5039 case eEncodingA1: 5040 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 5041 n = Bits32(opcode, 19, 16); 5042 registers = Bits32(opcode, 15, 0); 5043 wback = BitIsSet(opcode, 21); 5044 5045 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 5046 if ((n == 15) && (BitCount(registers) < 1)) 5047 return false; 5048 break; 5049 default: 5050 return false; 5051 } 5052 // address = R[n] + 4; 5053 5054 int32_t offset = 0; 5055 addr_t Rn = ReadCoreReg(n, &success); 5056 if (!success) 5057 return false; 5058 5059 addr_t address = Rn + addr_byte_size; 5060 5061 EmulateInstruction::Context context; 5062 context.type = EmulateInstruction::eContextRegisterStore; 5063 RegisterInfo base_reg; 5064 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5065 5066 uint32_t lowest_set_bit = 14; 5067 // for i = 0 to 14 5068 for (uint32_t i = 0; i < 14; ++i) { 5069 // if registers<i> == '1' then 5070 if (BitIsSet(registers, i)) { 5071 if (i < lowest_set_bit) 5072 lowest_set_bit = i; 5073 // if i == n && wback && i != LowestSetBit(registers) then 5074 if ((i == n) && wback && (i != lowest_set_bit)) 5075 // MemA[address,4] = bits(32) UNKNOWN; 5076 WriteBits32UnknownToMemory(address + offset); 5077 // else 5078 else { 5079 // MemA[address,4] = R[i]; 5080 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5081 0, &success); 5082 if (!success) 5083 return false; 5084 5085 RegisterInfo data_reg; 5086 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5087 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5088 offset + addr_byte_size); 5089 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5090 return false; 5091 } 5092 5093 // address = address + 4; 5094 offset += addr_byte_size; 5095 } 5096 } 5097 5098 // if registers<15> == '1' then 5099 // MemA[address,4] = PCStoreValue(); 5100 if (BitIsSet(registers, 15)) { 5101 RegisterInfo pc_reg; 5102 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5103 context.SetRegisterPlusOffset(pc_reg, 8); 5104 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5105 if (!success) 5106 return false; 5107 5108 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5109 return false; 5110 } 5111 5112 // if wback then R[n] = R[n] + 4*BitCount(registers); 5113 if (wback) { 5114 offset = addr_byte_size * BitCount(registers); 5115 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5116 context.SetImmediateSigned(offset); 5117 addr_t data = Rn + offset; 5118 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5119 data)) 5120 return false; 5121 } 5122 } 5123 return true; 5124 } 5125 5126 // STR (store immediate) calculates an address from a base register value and an 5127 // immediate offset, and stores a word 5128 // from a register to memory. It can use offset, post-indexed, or pre-indexed 5129 // addressing. 5130 bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode, 5131 const ARMEncoding encoding) { 5132 #if 0 5133 if ConditionPassed() then 5134 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5135 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5136 address = if index then offset_addr else R[n]; 5137 if UnalignedSupport() || address<1:0> == '00' then 5138 MemU[address,4] = R[t]; 5139 else // Can only occur before ARMv7 5140 MemU[address,4] = bits(32) UNKNOWN; 5141 if wback then R[n] = offset_addr; 5142 #endif 5143 5144 bool success = false; 5145 5146 if (ConditionPassed(opcode)) { 5147 const uint32_t addr_byte_size = GetAddressByteSize(); 5148 5149 uint32_t t; 5150 uint32_t n; 5151 uint32_t imm32; 5152 bool index; 5153 bool add; 5154 bool wback; 5155 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5156 switch (encoding) { 5157 case eEncodingT1: 5158 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 5159 t = Bits32(opcode, 2, 0); 5160 n = Bits32(opcode, 5, 3); 5161 imm32 = Bits32(opcode, 10, 6) << 2; 5162 5163 // index = TRUE; add = TRUE; wback = FALSE; 5164 index = true; 5165 add = false; 5166 wback = false; 5167 break; 5168 5169 case eEncodingT2: 5170 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 5171 t = Bits32(opcode, 10, 8); 5172 n = 13; 5173 imm32 = Bits32(opcode, 7, 0) << 2; 5174 5175 // index = TRUE; add = TRUE; wback = FALSE; 5176 index = true; 5177 add = true; 5178 wback = false; 5179 break; 5180 5181 case eEncodingT3: 5182 // if Rn == '1111' then UNDEFINED; 5183 if (Bits32(opcode, 19, 16) == 15) 5184 return false; 5185 5186 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5187 t = Bits32(opcode, 15, 12); 5188 n = Bits32(opcode, 19, 16); 5189 imm32 = Bits32(opcode, 11, 0); 5190 5191 // index = TRUE; add = TRUE; wback = FALSE; 5192 index = true; 5193 add = true; 5194 wback = false; 5195 5196 // if t == 15 then UNPREDICTABLE; 5197 if (t == 15) 5198 return false; 5199 break; 5200 5201 case eEncodingT4: 5202 // if P == '1' && U == '1' && W == '0' then SEE STRT; 5203 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == 5204 // '00000100' then SEE PUSH; 5205 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5206 if ((Bits32(opcode, 19, 16) == 15) || 5207 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))) 5208 return false; 5209 5210 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5211 t = Bits32(opcode, 15, 12); 5212 n = Bits32(opcode, 19, 16); 5213 imm32 = Bits32(opcode, 7, 0); 5214 5215 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5216 index = BitIsSet(opcode, 10); 5217 add = BitIsSet(opcode, 9); 5218 wback = BitIsSet(opcode, 8); 5219 5220 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 5221 if ((t == 15) || (wback && (n == t))) 5222 return false; 5223 break; 5224 5225 default: 5226 return false; 5227 } 5228 5229 addr_t offset_addr; 5230 addr_t address; 5231 5232 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5233 uint32_t base_address = ReadCoreReg(n, &success); 5234 if (!success) 5235 return false; 5236 5237 if (add) 5238 offset_addr = base_address + imm32; 5239 else 5240 offset_addr = base_address - imm32; 5241 5242 // address = if index then offset_addr else R[n]; 5243 if (index) 5244 address = offset_addr; 5245 else 5246 address = base_address; 5247 5248 EmulateInstruction::Context context; 5249 if (n == 13) 5250 context.type = eContextPushRegisterOnStack; 5251 else 5252 context.type = eContextRegisterStore; 5253 5254 RegisterInfo base_reg; 5255 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5256 5257 // if UnalignedSupport() || address<1:0> == '00' then 5258 if (UnalignedSupport() || 5259 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 5260 // MemU[address,4] = R[t]; 5261 uint32_t data = 5262 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5263 if (!success) 5264 return false; 5265 5266 RegisterInfo data_reg; 5267 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5268 int32_t offset = address - base_address; 5269 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 5270 if (!MemUWrite(context, address, data, addr_byte_size)) 5271 return false; 5272 } else { 5273 // MemU[address,4] = bits(32) UNKNOWN; 5274 WriteBits32UnknownToMemory(address); 5275 } 5276 5277 // if wback then R[n] = offset_addr; 5278 if (wback) { 5279 if (n == 13) 5280 context.type = eContextAdjustStackPointer; 5281 else 5282 context.type = eContextAdjustBaseRegister; 5283 context.SetAddress(offset_addr); 5284 5285 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5286 offset_addr)) 5287 return false; 5288 } 5289 } 5290 return true; 5291 } 5292 5293 // STR (Store Register) calculates an address from a base register value and an 5294 // offset register value, stores a 5295 // word from a register to memory. The offset register value can optionally 5296 // be shifted. 5297 bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode, 5298 const ARMEncoding encoding) { 5299 #if 0 5300 if ConditionPassed() then 5301 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5302 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5303 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5304 address = if index then offset_addr else R[n]; 5305 if t == 15 then // Only possible for encoding A1 5306 data = PCStoreValue(); 5307 else 5308 data = R[t]; 5309 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 5310 MemU[address,4] = data; 5311 else // Can only occur before ARMv7 5312 MemU[address,4] = bits(32) UNKNOWN; 5313 if wback then R[n] = offset_addr; 5314 #endif 5315 5316 bool success = false; 5317 5318 if (ConditionPassed(opcode)) { 5319 const uint32_t addr_byte_size = GetAddressByteSize(); 5320 5321 uint32_t t; 5322 uint32_t n; 5323 uint32_t m; 5324 ARM_ShifterType shift_t; 5325 uint32_t shift_n; 5326 bool index; 5327 bool add; 5328 bool wback; 5329 5330 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5331 switch (encoding) { 5332 case eEncodingT1: 5333 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5334 // in ThumbEE"; 5335 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5336 t = Bits32(opcode, 2, 0); 5337 n = Bits32(opcode, 5, 3); 5338 m = Bits32(opcode, 8, 6); 5339 5340 // index = TRUE; add = TRUE; wback = FALSE; 5341 index = true; 5342 add = true; 5343 wback = false; 5344 5345 // (shift_t, shift_n) = (SRType_LSL, 0); 5346 shift_t = SRType_LSL; 5347 shift_n = 0; 5348 break; 5349 5350 case eEncodingT2: 5351 // if Rn == '1111' then UNDEFINED; 5352 if (Bits32(opcode, 19, 16) == 15) 5353 return false; 5354 5355 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5356 t = Bits32(opcode, 15, 12); 5357 n = Bits32(opcode, 19, 16); 5358 m = Bits32(opcode, 3, 0); 5359 5360 // index = TRUE; add = TRUE; wback = FALSE; 5361 index = true; 5362 add = true; 5363 wback = false; 5364 5365 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5366 shift_t = SRType_LSL; 5367 shift_n = Bits32(opcode, 5, 4); 5368 5369 // if t == 15 || BadReg(m) then UNPREDICTABLE; 5370 if ((t == 15) || (BadReg(m))) 5371 return false; 5372 break; 5373 5374 case eEncodingA1: { 5375 // if P == '0' && W == '1' then SEE STRT; 5376 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5377 t = Bits32(opcode, 15, 12); 5378 n = Bits32(opcode, 19, 16); 5379 m = Bits32(opcode, 3, 0); 5380 5381 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5382 // (W == '1'); 5383 index = BitIsSet(opcode, 24); 5384 add = BitIsSet(opcode, 23); 5385 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5386 5387 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5388 uint32_t typ = Bits32(opcode, 6, 5); 5389 uint32_t imm5 = Bits32(opcode, 11, 7); 5390 shift_n = DecodeImmShift(typ, imm5, shift_t); 5391 5392 // if m == 15 then UNPREDICTABLE; 5393 if (m == 15) 5394 return false; 5395 5396 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5397 if (wback && ((n == 15) || (n == t))) 5398 return false; 5399 5400 break; 5401 } 5402 default: 5403 return false; 5404 } 5405 5406 addr_t offset_addr; 5407 addr_t address; 5408 int32_t offset = 0; 5409 5410 addr_t base_address = 5411 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5412 if (!success) 5413 return false; 5414 5415 uint32_t Rm_data = 5416 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5417 if (!success) 5418 return false; 5419 5420 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5421 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success); 5422 if (!success) 5423 return false; 5424 5425 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5426 if (add) 5427 offset_addr = base_address + offset; 5428 else 5429 offset_addr = base_address - offset; 5430 5431 // address = if index then offset_addr else R[n]; 5432 if (index) 5433 address = offset_addr; 5434 else 5435 address = base_address; 5436 5437 uint32_t data; 5438 // if t == 15 then // Only possible for encoding A1 5439 if (t == 15) 5440 // data = PCStoreValue(); 5441 data = ReadCoreReg(PC_REG, &success); 5442 else 5443 // data = R[t]; 5444 data = 5445 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5446 5447 if (!success) 5448 return false; 5449 5450 EmulateInstruction::Context context; 5451 context.type = eContextRegisterStore; 5452 5453 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == 5454 // InstrSet_ARM then 5455 if (UnalignedSupport() || 5456 (BitIsClear(address, 1) && BitIsClear(address, 0)) || 5457 CurrentInstrSet() == eModeARM) { 5458 // MemU[address,4] = data; 5459 5460 RegisterInfo base_reg; 5461 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5462 5463 RegisterInfo data_reg; 5464 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5465 5466 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5467 address - base_address); 5468 if (!MemUWrite(context, address, data, addr_byte_size)) 5469 return false; 5470 5471 } else 5472 // MemU[address,4] = bits(32) UNKNOWN; 5473 WriteBits32UnknownToMemory(address); 5474 5475 // if wback then R[n] = offset_addr; 5476 if (wback) { 5477 context.type = eContextRegisterLoad; 5478 context.SetAddress(offset_addr); 5479 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5480 offset_addr)) 5481 return false; 5482 } 5483 } 5484 return true; 5485 } 5486 5487 bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode, 5488 const ARMEncoding encoding) { 5489 #if 0 5490 if ConditionPassed() then 5491 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5492 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5493 address = if index then offset_addr else R[n]; 5494 MemU[address,1] = R[t]<7:0>; 5495 if wback then R[n] = offset_addr; 5496 #endif 5497 5498 bool success = false; 5499 5500 if (ConditionPassed(opcode)) { 5501 uint32_t t; 5502 uint32_t n; 5503 uint32_t imm32; 5504 bool index; 5505 bool add; 5506 bool wback; 5507 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5508 switch (encoding) { 5509 case eEncodingT1: 5510 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5511 t = Bits32(opcode, 2, 0); 5512 n = Bits32(opcode, 5, 3); 5513 imm32 = Bits32(opcode, 10, 6); 5514 5515 // index = TRUE; add = TRUE; wback = FALSE; 5516 index = true; 5517 add = true; 5518 wback = false; 5519 break; 5520 5521 case eEncodingT2: 5522 // if Rn == '1111' then UNDEFINED; 5523 if (Bits32(opcode, 19, 16) == 15) 5524 return false; 5525 5526 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5527 t = Bits32(opcode, 15, 12); 5528 n = Bits32(opcode, 19, 16); 5529 imm32 = Bits32(opcode, 11, 0); 5530 5531 // index = TRUE; add = TRUE; wback = FALSE; 5532 index = true; 5533 add = true; 5534 wback = false; 5535 5536 // if BadReg(t) then UNPREDICTABLE; 5537 if (BadReg(t)) 5538 return false; 5539 break; 5540 5541 case eEncodingT3: 5542 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5543 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5544 if (Bits32(opcode, 19, 16) == 15) 5545 return false; 5546 5547 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5548 t = Bits32(opcode, 15, 12); 5549 n = Bits32(opcode, 19, 16); 5550 imm32 = Bits32(opcode, 7, 0); 5551 5552 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5553 index = BitIsSet(opcode, 10); 5554 add = BitIsSet(opcode, 9); 5555 wback = BitIsSet(opcode, 8); 5556 5557 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5558 if ((BadReg(t)) || (wback && (n == t))) 5559 return false; 5560 break; 5561 5562 default: 5563 return false; 5564 } 5565 5566 addr_t offset_addr; 5567 addr_t address; 5568 addr_t base_address = 5569 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5570 if (!success) 5571 return false; 5572 5573 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5574 if (add) 5575 offset_addr = base_address + imm32; 5576 else 5577 offset_addr = base_address - imm32; 5578 5579 // address = if index then offset_addr else R[n]; 5580 if (index) 5581 address = offset_addr; 5582 else 5583 address = base_address; 5584 5585 // MemU[address,1] = R[t]<7:0> 5586 RegisterInfo base_reg; 5587 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5588 5589 RegisterInfo data_reg; 5590 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5591 5592 EmulateInstruction::Context context; 5593 context.type = eContextRegisterStore; 5594 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5595 address - base_address); 5596 5597 uint32_t data = 5598 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5599 if (!success) 5600 return false; 5601 5602 data = Bits32(data, 7, 0); 5603 5604 if (!MemUWrite(context, address, data, 1)) 5605 return false; 5606 5607 // if wback then R[n] = offset_addr; 5608 if (wback) { 5609 context.type = eContextRegisterLoad; 5610 context.SetAddress(offset_addr); 5611 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5612 offset_addr)) 5613 return false; 5614 } 5615 } 5616 5617 return true; 5618 } 5619 5620 // STRH (register) calculates an address from a base register value and an 5621 // offset register value, and stores a 5622 // halfword from a register to memory. The offset register value can be 5623 // shifted left by 0, 1, 2, or 3 bits. 5624 bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode, 5625 const ARMEncoding encoding) { 5626 #if 0 5627 if ConditionPassed() then 5628 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5629 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5630 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5631 address = if index then offset_addr else R[n]; 5632 if UnalignedSupport() || address<0> == '0' then 5633 MemU[address,2] = R[t]<15:0>; 5634 else // Can only occur before ARMv7 5635 MemU[address,2] = bits(16) UNKNOWN; 5636 if wback then R[n] = offset_addr; 5637 #endif 5638 5639 bool success = false; 5640 5641 if (ConditionPassed(opcode)) { 5642 uint32_t t; 5643 uint32_t n; 5644 uint32_t m; 5645 bool index; 5646 bool add; 5647 bool wback; 5648 ARM_ShifterType shift_t; 5649 uint32_t shift_n; 5650 5651 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5652 switch (encoding) { 5653 case eEncodingT1: 5654 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5655 // in ThumbEE"; 5656 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5657 t = Bits32(opcode, 2, 0); 5658 n = Bits32(opcode, 5, 3); 5659 m = Bits32(opcode, 8, 6); 5660 5661 // index = TRUE; add = TRUE; wback = FALSE; 5662 index = true; 5663 add = true; 5664 wback = false; 5665 5666 // (shift_t, shift_n) = (SRType_LSL, 0); 5667 shift_t = SRType_LSL; 5668 shift_n = 0; 5669 5670 break; 5671 5672 case eEncodingT2: 5673 // if Rn == '1111' then UNDEFINED; 5674 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5675 t = Bits32(opcode, 15, 12); 5676 n = Bits32(opcode, 19, 16); 5677 m = Bits32(opcode, 3, 0); 5678 if (n == 15) 5679 return false; 5680 5681 // index = TRUE; add = TRUE; wback = FALSE; 5682 index = true; 5683 add = true; 5684 wback = false; 5685 5686 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5687 shift_t = SRType_LSL; 5688 shift_n = Bits32(opcode, 5, 4); 5689 5690 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5691 if (BadReg(t) || BadReg(m)) 5692 return false; 5693 5694 break; 5695 5696 case eEncodingA1: 5697 // if P == '0' && W == '1' then SEE STRHT; 5698 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5699 t = Bits32(opcode, 15, 12); 5700 n = Bits32(opcode, 19, 16); 5701 m = Bits32(opcode, 3, 0); 5702 5703 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5704 // (W == '1'); 5705 index = BitIsSet(opcode, 24); 5706 add = BitIsSet(opcode, 23); 5707 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5708 5709 // (shift_t, shift_n) = (SRType_LSL, 0); 5710 shift_t = SRType_LSL; 5711 shift_n = 0; 5712 5713 // if t == 15 || m == 15 then UNPREDICTABLE; 5714 if ((t == 15) || (m == 15)) 5715 return false; 5716 5717 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5718 if (wback && ((n == 15) || (n == t))) 5719 return false; 5720 5721 break; 5722 5723 default: 5724 return false; 5725 } 5726 5727 uint32_t Rm = ReadCoreReg(m, &success); 5728 if (!success) 5729 return false; 5730 5731 uint32_t Rn = ReadCoreReg(n, &success); 5732 if (!success) 5733 return false; 5734 5735 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5736 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 5737 if (!success) 5738 return false; 5739 5740 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5741 addr_t offset_addr; 5742 if (add) 5743 offset_addr = Rn + offset; 5744 else 5745 offset_addr = Rn - offset; 5746 5747 // address = if index then offset_addr else R[n]; 5748 addr_t address; 5749 if (index) 5750 address = offset_addr; 5751 else 5752 address = Rn; 5753 5754 EmulateInstruction::Context context; 5755 context.type = eContextRegisterStore; 5756 RegisterInfo base_reg; 5757 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5758 RegisterInfo offset_reg; 5759 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5760 5761 // if UnalignedSupport() || address<0> == '0' then 5762 if (UnalignedSupport() || BitIsClear(address, 0)) { 5763 // MemU[address,2] = R[t]<15:0>; 5764 uint32_t Rt = ReadCoreReg(t, &success); 5765 if (!success) 5766 return false; 5767 5768 EmulateInstruction::Context context; 5769 context.type = eContextRegisterStore; 5770 RegisterInfo base_reg; 5771 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5772 RegisterInfo offset_reg; 5773 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5774 RegisterInfo data_reg; 5775 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5776 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 5777 data_reg); 5778 5779 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2)) 5780 return false; 5781 } else // Can only occur before ARMv7 5782 { 5783 // MemU[address,2] = bits(16) UNKNOWN; 5784 } 5785 5786 // if wback then R[n] = offset_addr; 5787 if (wback) { 5788 context.type = eContextAdjustBaseRegister; 5789 context.SetAddress(offset_addr); 5790 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5791 offset_addr)) 5792 return false; 5793 } 5794 } 5795 5796 return true; 5797 } 5798 5799 // Add with Carry (immediate) adds an immediate value and the carry flag value 5800 // to a register value, and writes the result to the destination register. It 5801 // can optionally update the condition flags based on the result. 5802 bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode, 5803 const ARMEncoding encoding) { 5804 #if 0 5805 // ARM pseudo code... 5806 if ConditionPassed() then 5807 EncodingSpecificOperations(); 5808 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5809 if d == 15 then // Can only occur for ARM encoding 5810 ALUWritePC(result); // setflags is always FALSE here 5811 else 5812 R[d] = result; 5813 if setflags then 5814 APSR.N = result<31>; 5815 APSR.Z = IsZeroBit(result); 5816 APSR.C = carry; 5817 APSR.V = overflow; 5818 #endif 5819 5820 bool success = false; 5821 5822 if (ConditionPassed(opcode)) { 5823 uint32_t Rd, Rn; 5824 uint32_t 5825 imm32; // the immediate value to be added to the value obtained from Rn 5826 bool setflags; 5827 switch (encoding) { 5828 case eEncodingT1: 5829 Rd = Bits32(opcode, 11, 8); 5830 Rn = Bits32(opcode, 19, 16); 5831 setflags = BitIsSet(opcode, 20); 5832 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5833 if (BadReg(Rd) || BadReg(Rn)) 5834 return false; 5835 break; 5836 case eEncodingA1: 5837 Rd = Bits32(opcode, 15, 12); 5838 Rn = Bits32(opcode, 19, 16); 5839 setflags = BitIsSet(opcode, 20); 5840 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5841 5842 if (Rd == 15 && setflags) 5843 return EmulateSUBSPcLrEtc(opcode, encoding); 5844 break; 5845 default: 5846 return false; 5847 } 5848 5849 // Read the first operand. 5850 int32_t val1 = ReadCoreReg(Rn, &success); 5851 if (!success) 5852 return false; 5853 5854 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5855 5856 EmulateInstruction::Context context; 5857 context.type = EmulateInstruction::eContextImmediate; 5858 context.SetNoArgs(); 5859 5860 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5861 res.carry_out, res.overflow)) 5862 return false; 5863 } 5864 return true; 5865 } 5866 5867 // Add with Carry (register) adds a register value, the carry flag value, and 5868 // an optionally-shifted register value, and writes the result to the 5869 // destination register. It can optionally update the condition flags based on 5870 // the result. 5871 bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode, 5872 const ARMEncoding encoding) { 5873 #if 0 5874 // ARM pseudo code... 5875 if ConditionPassed() then 5876 EncodingSpecificOperations(); 5877 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5878 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5879 if d == 15 then // Can only occur for ARM encoding 5880 ALUWritePC(result); // setflags is always FALSE here 5881 else 5882 R[d] = result; 5883 if setflags then 5884 APSR.N = result<31>; 5885 APSR.Z = IsZeroBit(result); 5886 APSR.C = carry; 5887 APSR.V = overflow; 5888 #endif 5889 5890 bool success = false; 5891 5892 if (ConditionPassed(opcode)) { 5893 uint32_t Rd, Rn, Rm; 5894 ARM_ShifterType shift_t; 5895 uint32_t shift_n; // the shift applied to the value read from Rm 5896 bool setflags; 5897 switch (encoding) { 5898 case eEncodingT1: 5899 Rd = Rn = Bits32(opcode, 2, 0); 5900 Rm = Bits32(opcode, 5, 3); 5901 setflags = !InITBlock(); 5902 shift_t = SRType_LSL; 5903 shift_n = 0; 5904 break; 5905 case eEncodingT2: 5906 Rd = Bits32(opcode, 11, 8); 5907 Rn = Bits32(opcode, 19, 16); 5908 Rm = Bits32(opcode, 3, 0); 5909 setflags = BitIsSet(opcode, 20); 5910 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5911 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5912 return false; 5913 break; 5914 case eEncodingA1: 5915 Rd = Bits32(opcode, 15, 12); 5916 Rn = Bits32(opcode, 19, 16); 5917 Rm = Bits32(opcode, 3, 0); 5918 setflags = BitIsSet(opcode, 20); 5919 shift_n = DecodeImmShiftARM(opcode, shift_t); 5920 5921 if (Rd == 15 && setflags) 5922 return EmulateSUBSPcLrEtc(opcode, encoding); 5923 break; 5924 default: 5925 return false; 5926 } 5927 5928 // Read the first operand. 5929 int32_t val1 = ReadCoreReg(Rn, &success); 5930 if (!success) 5931 return false; 5932 5933 // Read the second operand. 5934 int32_t val2 = ReadCoreReg(Rm, &success); 5935 if (!success) 5936 return false; 5937 5938 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5939 if (!success) 5940 return false; 5941 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5942 5943 EmulateInstruction::Context context; 5944 context.type = EmulateInstruction::eContextImmediate; 5945 context.SetNoArgs(); 5946 5947 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5948 res.carry_out, res.overflow)) 5949 return false; 5950 } 5951 return true; 5952 } 5953 5954 // This instruction adds an immediate value to the PC value to form a PC- 5955 // relative address, and writes the result to the destination register. 5956 bool EmulateInstructionARM::EmulateADR(const uint32_t opcode, 5957 const ARMEncoding encoding) { 5958 #if 0 5959 // ARM pseudo code... 5960 if ConditionPassed() then 5961 EncodingSpecificOperations(); 5962 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5963 if d == 15 then // Can only occur for ARM encodings 5964 ALUWritePC(result); 5965 else 5966 R[d] = result; 5967 #endif 5968 5969 bool success = false; 5970 5971 if (ConditionPassed(opcode)) { 5972 uint32_t Rd; 5973 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5974 bool add; 5975 switch (encoding) { 5976 case eEncodingT1: 5977 Rd = Bits32(opcode, 10, 8); 5978 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5979 add = true; 5980 break; 5981 case eEncodingT2: 5982 case eEncodingT3: 5983 Rd = Bits32(opcode, 11, 8); 5984 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5985 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5986 if (BadReg(Rd)) 5987 return false; 5988 break; 5989 case eEncodingA1: 5990 case eEncodingA2: 5991 Rd = Bits32(opcode, 15, 12); 5992 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5993 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5994 break; 5995 default: 5996 return false; 5997 } 5998 5999 // Read the PC value. 6000 uint32_t pc = ReadCoreReg(PC_REG, &success); 6001 if (!success) 6002 return false; 6003 6004 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 6005 6006 EmulateInstruction::Context context; 6007 context.type = EmulateInstruction::eContextImmediate; 6008 context.SetNoArgs(); 6009 6010 if (!WriteCoreReg(context, result, Rd)) 6011 return false; 6012 } 6013 return true; 6014 } 6015 6016 // This instruction performs a bitwise AND of a register value and an immediate 6017 // value, and writes the result to the destination register. It can optionally 6018 // update the condition flags based on the result. 6019 bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode, 6020 const ARMEncoding encoding) { 6021 #if 0 6022 // ARM pseudo code... 6023 if ConditionPassed() then 6024 EncodingSpecificOperations(); 6025 result = R[n] AND imm32; 6026 if d == 15 then // Can only occur for ARM encoding 6027 ALUWritePC(result); // setflags is always FALSE here 6028 else 6029 R[d] = result; 6030 if setflags then 6031 APSR.N = result<31>; 6032 APSR.Z = IsZeroBit(result); 6033 APSR.C = carry; 6034 // APSR.V unchanged 6035 #endif 6036 6037 bool success = false; 6038 6039 if (ConditionPassed(opcode)) { 6040 uint32_t Rd, Rn; 6041 uint32_t 6042 imm32; // the immediate value to be ANDed to the value obtained from Rn 6043 bool setflags; 6044 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6045 switch (encoding) { 6046 case eEncodingT1: 6047 Rd = Bits32(opcode, 11, 8); 6048 Rn = Bits32(opcode, 19, 16); 6049 setflags = BitIsSet(opcode, 20); 6050 imm32 = ThumbExpandImm_C( 6051 opcode, APSR_C, 6052 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6053 // if Rd == '1111' && S == '1' then SEE TST (immediate); 6054 if (Rd == 15 && setflags) 6055 return EmulateTSTImm(opcode, eEncodingT1); 6056 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 6057 return false; 6058 break; 6059 case eEncodingA1: 6060 Rd = Bits32(opcode, 15, 12); 6061 Rn = Bits32(opcode, 19, 16); 6062 setflags = BitIsSet(opcode, 20); 6063 imm32 = 6064 ARMExpandImm_C(opcode, APSR_C, 6065 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6066 6067 if (Rd == 15 && setflags) 6068 return EmulateSUBSPcLrEtc(opcode, encoding); 6069 break; 6070 default: 6071 return false; 6072 } 6073 6074 // Read the first operand. 6075 uint32_t val1 = ReadCoreReg(Rn, &success); 6076 if (!success) 6077 return false; 6078 6079 uint32_t result = val1 & imm32; 6080 6081 EmulateInstruction::Context context; 6082 context.type = EmulateInstruction::eContextImmediate; 6083 context.SetNoArgs(); 6084 6085 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6086 return false; 6087 } 6088 return true; 6089 } 6090 6091 // This instruction performs a bitwise AND of a register value and an 6092 // optionally-shifted register value, and writes the result to the destination 6093 // register. It can optionally update the condition flags based on the result. 6094 bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode, 6095 const ARMEncoding encoding) { 6096 #if 0 6097 // ARM pseudo code... 6098 if ConditionPassed() then 6099 EncodingSpecificOperations(); 6100 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6101 result = R[n] AND shifted; 6102 if d == 15 then // Can only occur for ARM encoding 6103 ALUWritePC(result); // setflags is always FALSE here 6104 else 6105 R[d] = result; 6106 if setflags then 6107 APSR.N = result<31>; 6108 APSR.Z = IsZeroBit(result); 6109 APSR.C = carry; 6110 // APSR.V unchanged 6111 #endif 6112 6113 bool success = false; 6114 6115 if (ConditionPassed(opcode)) { 6116 uint32_t Rd, Rn, Rm; 6117 ARM_ShifterType shift_t; 6118 uint32_t shift_n; // the shift applied to the value read from Rm 6119 bool setflags; 6120 uint32_t carry; 6121 switch (encoding) { 6122 case eEncodingT1: 6123 Rd = Rn = Bits32(opcode, 2, 0); 6124 Rm = Bits32(opcode, 5, 3); 6125 setflags = !InITBlock(); 6126 shift_t = SRType_LSL; 6127 shift_n = 0; 6128 break; 6129 case eEncodingT2: 6130 Rd = Bits32(opcode, 11, 8); 6131 Rn = Bits32(opcode, 19, 16); 6132 Rm = Bits32(opcode, 3, 0); 6133 setflags = BitIsSet(opcode, 20); 6134 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6135 // if Rd == '1111' && S == '1' then SEE TST (register); 6136 if (Rd == 15 && setflags) 6137 return EmulateTSTReg(opcode, eEncodingT2); 6138 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 6139 return false; 6140 break; 6141 case eEncodingA1: 6142 Rd = Bits32(opcode, 15, 12); 6143 Rn = Bits32(opcode, 19, 16); 6144 Rm = Bits32(opcode, 3, 0); 6145 setflags = BitIsSet(opcode, 20); 6146 shift_n = DecodeImmShiftARM(opcode, shift_t); 6147 6148 if (Rd == 15 && setflags) 6149 return EmulateSUBSPcLrEtc(opcode, encoding); 6150 break; 6151 default: 6152 return false; 6153 } 6154 6155 // Read the first operand. 6156 uint32_t val1 = ReadCoreReg(Rn, &success); 6157 if (!success) 6158 return false; 6159 6160 // Read the second operand. 6161 uint32_t val2 = ReadCoreReg(Rm, &success); 6162 if (!success) 6163 return false; 6164 6165 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6166 if (!success) 6167 return false; 6168 uint32_t result = val1 & shifted; 6169 6170 EmulateInstruction::Context context; 6171 context.type = EmulateInstruction::eContextImmediate; 6172 context.SetNoArgs(); 6173 6174 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6175 return false; 6176 } 6177 return true; 6178 } 6179 6180 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and 6181 // the complement of an immediate value, and writes the result to the 6182 // destination register. It can optionally update the condition flags based on 6183 // the result. 6184 bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode, 6185 const ARMEncoding encoding) { 6186 #if 0 6187 // ARM pseudo code... 6188 if ConditionPassed() then 6189 EncodingSpecificOperations(); 6190 result = R[n] AND NOT(imm32); 6191 if d == 15 then // Can only occur for ARM encoding 6192 ALUWritePC(result); // setflags is always FALSE here 6193 else 6194 R[d] = result; 6195 if setflags then 6196 APSR.N = result<31>; 6197 APSR.Z = IsZeroBit(result); 6198 APSR.C = carry; 6199 // APSR.V unchanged 6200 #endif 6201 6202 bool success = false; 6203 6204 if (ConditionPassed(opcode)) { 6205 uint32_t Rd, Rn; 6206 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to 6207 // the value obtained from Rn 6208 bool setflags; 6209 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6210 switch (encoding) { 6211 case eEncodingT1: 6212 Rd = Bits32(opcode, 11, 8); 6213 Rn = Bits32(opcode, 19, 16); 6214 setflags = BitIsSet(opcode, 20); 6215 imm32 = ThumbExpandImm_C( 6216 opcode, APSR_C, 6217 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6218 if (BadReg(Rd) || BadReg(Rn)) 6219 return false; 6220 break; 6221 case eEncodingA1: 6222 Rd = Bits32(opcode, 15, 12); 6223 Rn = Bits32(opcode, 19, 16); 6224 setflags = BitIsSet(opcode, 20); 6225 imm32 = 6226 ARMExpandImm_C(opcode, APSR_C, 6227 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6228 6229 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6230 // instructions; 6231 if (Rd == 15 && setflags) 6232 return EmulateSUBSPcLrEtc(opcode, encoding); 6233 break; 6234 default: 6235 return false; 6236 } 6237 6238 // Read the first operand. 6239 uint32_t val1 = ReadCoreReg(Rn, &success); 6240 if (!success) 6241 return false; 6242 6243 uint32_t result = val1 & ~imm32; 6244 6245 EmulateInstruction::Context context; 6246 context.type = EmulateInstruction::eContextImmediate; 6247 context.SetNoArgs(); 6248 6249 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6250 return false; 6251 } 6252 return true; 6253 } 6254 6255 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and 6256 // the complement of an optionally-shifted register value, and writes the 6257 // result to the destination register. It can optionally update the condition 6258 // flags based on the result. 6259 bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode, 6260 const ARMEncoding encoding) { 6261 #if 0 6262 // ARM pseudo code... 6263 if ConditionPassed() then 6264 EncodingSpecificOperations(); 6265 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6266 result = R[n] AND NOT(shifted); 6267 if d == 15 then // Can only occur for ARM encoding 6268 ALUWritePC(result); // setflags is always FALSE here 6269 else 6270 R[d] = result; 6271 if setflags then 6272 APSR.N = result<31>; 6273 APSR.Z = IsZeroBit(result); 6274 APSR.C = carry; 6275 // APSR.V unchanged 6276 #endif 6277 6278 bool success = false; 6279 6280 if (ConditionPassed(opcode)) { 6281 uint32_t Rd, Rn, Rm; 6282 ARM_ShifterType shift_t; 6283 uint32_t shift_n; // the shift applied to the value read from Rm 6284 bool setflags; 6285 uint32_t carry; 6286 switch (encoding) { 6287 case eEncodingT1: 6288 Rd = Rn = Bits32(opcode, 2, 0); 6289 Rm = Bits32(opcode, 5, 3); 6290 setflags = !InITBlock(); 6291 shift_t = SRType_LSL; 6292 shift_n = 0; 6293 break; 6294 case eEncodingT2: 6295 Rd = Bits32(opcode, 11, 8); 6296 Rn = Bits32(opcode, 19, 16); 6297 Rm = Bits32(opcode, 3, 0); 6298 setflags = BitIsSet(opcode, 20); 6299 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6300 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 6301 return false; 6302 break; 6303 case eEncodingA1: 6304 Rd = Bits32(opcode, 15, 12); 6305 Rn = Bits32(opcode, 19, 16); 6306 Rm = Bits32(opcode, 3, 0); 6307 setflags = BitIsSet(opcode, 20); 6308 shift_n = DecodeImmShiftARM(opcode, shift_t); 6309 6310 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6311 // instructions; 6312 if (Rd == 15 && setflags) 6313 return EmulateSUBSPcLrEtc(opcode, encoding); 6314 break; 6315 default: 6316 return false; 6317 } 6318 6319 // Read the first operand. 6320 uint32_t val1 = ReadCoreReg(Rn, &success); 6321 if (!success) 6322 return false; 6323 6324 // Read the second operand. 6325 uint32_t val2 = ReadCoreReg(Rm, &success); 6326 if (!success) 6327 return false; 6328 6329 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6330 if (!success) 6331 return false; 6332 uint32_t result = val1 & ~shifted; 6333 6334 EmulateInstruction::Context context; 6335 context.type = EmulateInstruction::eContextImmediate; 6336 context.SetNoArgs(); 6337 6338 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6339 return false; 6340 } 6341 return true; 6342 } 6343 6344 // LDR (immediate, ARM) calculates an address from a base register value and an 6345 // immediate offset, loads a word 6346 // from memory, and writes it to a register. It can use offset, post-indexed, 6347 // or pre-indexed addressing. 6348 bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode, 6349 const ARMEncoding encoding) { 6350 #if 0 6351 if ConditionPassed() then 6352 EncodingSpecificOperations(); 6353 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6354 address = if index then offset_addr else R[n]; 6355 data = MemU[address,4]; 6356 if wback then R[n] = offset_addr; 6357 if t == 15 then 6358 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6359 elsif UnalignedSupport() || address<1:0> = '00' then 6360 R[t] = data; 6361 else // Can only apply before ARMv7 6362 R[t] = ROR(data, 8*UInt(address<1:0>)); 6363 #endif 6364 6365 bool success = false; 6366 6367 if (ConditionPassed(opcode)) { 6368 const uint32_t addr_byte_size = GetAddressByteSize(); 6369 6370 uint32_t t; 6371 uint32_t n; 6372 uint32_t imm32; 6373 bool index; 6374 bool add; 6375 bool wback; 6376 6377 switch (encoding) { 6378 case eEncodingA1: 6379 // if Rn == '1111' then SEE LDR (literal); 6380 // if P == '0' && W == '1' then SEE LDRT; 6381 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == 6382 // '000000000100' then SEE POP; 6383 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6384 t = Bits32(opcode, 15, 12); 6385 n = Bits32(opcode, 19, 16); 6386 imm32 = Bits32(opcode, 11, 0); 6387 6388 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6389 // (W == '1'); 6390 index = BitIsSet(opcode, 24); 6391 add = BitIsSet(opcode, 23); 6392 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6393 6394 // if wback && n == t then UNPREDICTABLE; 6395 if (wback && (n == t)) 6396 return false; 6397 6398 break; 6399 6400 default: 6401 return false; 6402 } 6403 6404 addr_t address; 6405 addr_t offset_addr; 6406 addr_t base_address = ReadCoreReg(n, &success); 6407 if (!success) 6408 return false; 6409 6410 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6411 if (add) 6412 offset_addr = base_address + imm32; 6413 else 6414 offset_addr = base_address - imm32; 6415 6416 // address = if index then offset_addr else R[n]; 6417 if (index) 6418 address = offset_addr; 6419 else 6420 address = base_address; 6421 6422 // data = MemU[address,4]; 6423 6424 RegisterInfo base_reg; 6425 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6426 6427 EmulateInstruction::Context context; 6428 context.type = eContextRegisterLoad; 6429 context.SetRegisterPlusOffset(base_reg, address - base_address); 6430 6431 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6432 if (!success) 6433 return false; 6434 6435 // if wback then R[n] = offset_addr; 6436 if (wback) { 6437 context.type = eContextAdjustBaseRegister; 6438 context.SetAddress(offset_addr); 6439 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6440 offset_addr)) 6441 return false; 6442 } 6443 6444 // if t == 15 then 6445 if (t == 15) { 6446 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6447 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6448 // LoadWritePC (data); 6449 context.type = eContextRegisterLoad; 6450 context.SetRegisterPlusOffset(base_reg, address - base_address); 6451 LoadWritePC(context, data); 6452 } else 6453 return false; 6454 } 6455 // elsif UnalignedSupport() || address<1:0> = '00' then 6456 else if (UnalignedSupport() || 6457 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6458 // R[t] = data; 6459 context.type = eContextRegisterLoad; 6460 context.SetRegisterPlusOffset(base_reg, address - base_address); 6461 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6462 data)) 6463 return false; 6464 } 6465 // else // Can only apply before ARMv7 6466 else { 6467 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6468 data = ROR(data, Bits32(address, 1, 0), &success); 6469 if (!success) 6470 return false; 6471 context.type = eContextRegisterLoad; 6472 context.SetImmediate(data); 6473 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6474 data)) 6475 return false; 6476 } 6477 } 6478 return true; 6479 } 6480 6481 // LDR (register) calculates an address from a base register value and an offset 6482 // register value, loads a word 6483 // from memory, and writes it to a register. The offset register value can 6484 // optionally be shifted. 6485 bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode, 6486 const ARMEncoding encoding) { 6487 #if 0 6488 if ConditionPassed() then 6489 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6490 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6491 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6492 address = if index then offset_addr else R[n]; 6493 data = MemU[address,4]; 6494 if wback then R[n] = offset_addr; 6495 if t == 15 then 6496 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6497 elsif UnalignedSupport() || address<1:0> = '00' then 6498 R[t] = data; 6499 else // Can only apply before ARMv7 6500 if CurrentInstrSet() == InstrSet_ARM then 6501 R[t] = ROR(data, 8*UInt(address<1:0>)); 6502 else 6503 R[t] = bits(32) UNKNOWN; 6504 #endif 6505 6506 bool success = false; 6507 6508 if (ConditionPassed(opcode)) { 6509 const uint32_t addr_byte_size = GetAddressByteSize(); 6510 6511 uint32_t t; 6512 uint32_t n; 6513 uint32_t m; 6514 bool index; 6515 bool add; 6516 bool wback; 6517 ARM_ShifterType shift_t; 6518 uint32_t shift_n; 6519 6520 switch (encoding) { 6521 case eEncodingT1: 6522 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 6523 // in ThumbEE"; 6524 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6525 t = Bits32(opcode, 2, 0); 6526 n = Bits32(opcode, 5, 3); 6527 m = Bits32(opcode, 8, 6); 6528 6529 // index = TRUE; add = TRUE; wback = FALSE; 6530 index = true; 6531 add = true; 6532 wback = false; 6533 6534 // (shift_t, shift_n) = (SRType_LSL, 0); 6535 shift_t = SRType_LSL; 6536 shift_n = 0; 6537 6538 break; 6539 6540 case eEncodingT2: 6541 // if Rn == '1111' then SEE LDR (literal); 6542 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6543 t = Bits32(opcode, 15, 12); 6544 n = Bits32(opcode, 19, 16); 6545 m = Bits32(opcode, 3, 0); 6546 6547 // index = TRUE; add = TRUE; wback = FALSE; 6548 index = true; 6549 add = true; 6550 wback = false; 6551 6552 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6553 shift_t = SRType_LSL; 6554 shift_n = Bits32(opcode, 5, 4); 6555 6556 // if BadReg(m) then UNPREDICTABLE; 6557 if (BadReg(m)) 6558 return false; 6559 6560 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6561 if ((t == 15) && InITBlock() && !LastInITBlock()) 6562 return false; 6563 6564 break; 6565 6566 case eEncodingA1: { 6567 // if P == '0' && W == '1' then SEE LDRT; 6568 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6569 t = Bits32(opcode, 15, 12); 6570 n = Bits32(opcode, 19, 16); 6571 m = Bits32(opcode, 3, 0); 6572 6573 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6574 // (W == '1'); 6575 index = BitIsSet(opcode, 24); 6576 add = BitIsSet(opcode, 23); 6577 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6578 6579 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6580 uint32_t type = Bits32(opcode, 6, 5); 6581 uint32_t imm5 = Bits32(opcode, 11, 7); 6582 shift_n = DecodeImmShift(type, imm5, shift_t); 6583 6584 // if m == 15 then UNPREDICTABLE; 6585 if (m == 15) 6586 return false; 6587 6588 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6589 if (wback && ((n == 15) || (n == t))) 6590 return false; 6591 } break; 6592 6593 default: 6594 return false; 6595 } 6596 6597 uint32_t Rm = 6598 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6599 if (!success) 6600 return false; 6601 6602 uint32_t Rn = 6603 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6604 if (!success) 6605 return false; 6606 6607 addr_t offset_addr; 6608 addr_t address; 6609 6610 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is 6611 // an application level alias for the CPSR". 6612 addr_t offset = 6613 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success); 6614 if (!success) 6615 return false; 6616 6617 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6618 if (add) 6619 offset_addr = Rn + offset; 6620 else 6621 offset_addr = Rn - offset; 6622 6623 // address = if index then offset_addr else R[n]; 6624 if (index) 6625 address = offset_addr; 6626 else 6627 address = Rn; 6628 6629 // data = MemU[address,4]; 6630 RegisterInfo base_reg; 6631 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6632 6633 EmulateInstruction::Context context; 6634 context.type = eContextRegisterLoad; 6635 context.SetRegisterPlusOffset(base_reg, address - Rn); 6636 6637 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6638 if (!success) 6639 return false; 6640 6641 // if wback then R[n] = offset_addr; 6642 if (wback) { 6643 context.type = eContextAdjustBaseRegister; 6644 context.SetAddress(offset_addr); 6645 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6646 offset_addr)) 6647 return false; 6648 } 6649 6650 // if t == 15 then 6651 if (t == 15) { 6652 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6653 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6654 context.type = eContextRegisterLoad; 6655 context.SetRegisterPlusOffset(base_reg, address - Rn); 6656 LoadWritePC(context, data); 6657 } else 6658 return false; 6659 } 6660 // elsif UnalignedSupport() || address<1:0> = '00' then 6661 else if (UnalignedSupport() || 6662 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6663 // R[t] = data; 6664 context.type = eContextRegisterLoad; 6665 context.SetRegisterPlusOffset(base_reg, address - Rn); 6666 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6667 data)) 6668 return false; 6669 } else // Can only apply before ARMv7 6670 { 6671 // if CurrentInstrSet() == InstrSet_ARM then 6672 if (CurrentInstrSet() == eModeARM) { 6673 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6674 data = ROR(data, Bits32(address, 1, 0), &success); 6675 if (!success) 6676 return false; 6677 context.type = eContextRegisterLoad; 6678 context.SetImmediate(data); 6679 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6680 data)) 6681 return false; 6682 } else { 6683 // R[t] = bits(32) UNKNOWN; 6684 WriteBits32Unknown(t); 6685 } 6686 } 6687 } 6688 return true; 6689 } 6690 6691 // LDRB (immediate, Thumb) 6692 bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode, 6693 const ARMEncoding encoding) { 6694 #if 0 6695 if ConditionPassed() then 6696 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6697 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6698 address = if index then offset_addr else R[n]; 6699 R[t] = ZeroExtend(MemU[address,1], 32); 6700 if wback then R[n] = offset_addr; 6701 #endif 6702 6703 bool success = false; 6704 6705 if (ConditionPassed(opcode)) { 6706 uint32_t t; 6707 uint32_t n; 6708 uint32_t imm32; 6709 bool index; 6710 bool add; 6711 bool wback; 6712 6713 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6714 switch (encoding) { 6715 case eEncodingT1: 6716 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6717 t = Bits32(opcode, 2, 0); 6718 n = Bits32(opcode, 5, 3); 6719 imm32 = Bits32(opcode, 10, 6); 6720 6721 // index = TRUE; add = TRUE; wback = FALSE; 6722 index = true; 6723 add = true; 6724 wback = false; 6725 6726 break; 6727 6728 case eEncodingT2: 6729 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6730 t = Bits32(opcode, 15, 12); 6731 n = Bits32(opcode, 19, 16); 6732 imm32 = Bits32(opcode, 11, 0); 6733 6734 // index = TRUE; add = TRUE; wback = FALSE; 6735 index = true; 6736 add = true; 6737 wback = false; 6738 6739 // if Rt == '1111' then SEE PLD; 6740 if (t == 15) 6741 return false; // PLD is not implemented yet 6742 6743 // if Rn == '1111' then SEE LDRB (literal); 6744 if (n == 15) 6745 return EmulateLDRBLiteral(opcode, eEncodingT1); 6746 6747 // if t == 13 then UNPREDICTABLE; 6748 if (t == 13) 6749 return false; 6750 6751 break; 6752 6753 case eEncodingT3: 6754 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6755 // if P == '0' && W == '0' then UNDEFINED; 6756 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 6757 return false; 6758 6759 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6760 t = Bits32(opcode, 15, 12); 6761 n = Bits32(opcode, 19, 16); 6762 imm32 = Bits32(opcode, 7, 0); 6763 6764 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6765 index = BitIsSet(opcode, 10); 6766 add = BitIsSet(opcode, 9); 6767 wback = BitIsSet(opcode, 8); 6768 6769 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6770 if (t == 15) 6771 return false; // PLD is not implemented yet 6772 6773 // if Rn == '1111' then SEE LDRB (literal); 6774 if (n == 15) 6775 return EmulateLDRBLiteral(opcode, eEncodingT1); 6776 6777 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6778 if (BadReg(t) || (wback && (n == t))) 6779 return false; 6780 6781 break; 6782 6783 default: 6784 return false; 6785 } 6786 6787 uint32_t Rn = 6788 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6789 if (!success) 6790 return false; 6791 6792 addr_t address; 6793 addr_t offset_addr; 6794 6795 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6796 if (add) 6797 offset_addr = Rn + imm32; 6798 else 6799 offset_addr = Rn - imm32; 6800 6801 // address = if index then offset_addr else R[n]; 6802 if (index) 6803 address = offset_addr; 6804 else 6805 address = Rn; 6806 6807 // R[t] = ZeroExtend(MemU[address,1], 32); 6808 RegisterInfo base_reg; 6809 RegisterInfo data_reg; 6810 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6811 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6812 6813 EmulateInstruction::Context context; 6814 context.type = eContextRegisterLoad; 6815 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 6816 6817 uint64_t data = MemURead(context, address, 1, 0, &success); 6818 if (!success) 6819 return false; 6820 6821 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6822 return false; 6823 6824 // if wback then R[n] = offset_addr; 6825 if (wback) { 6826 context.type = eContextAdjustBaseRegister; 6827 context.SetAddress(offset_addr); 6828 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6829 offset_addr)) 6830 return false; 6831 } 6832 } 6833 return true; 6834 } 6835 6836 // LDRB (literal) calculates an address from the PC value and an immediate 6837 // offset, loads a byte from memory, 6838 // zero-extends it to form a 32-bit word and writes it to a register. 6839 bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode, 6840 const ARMEncoding encoding) { 6841 #if 0 6842 if ConditionPassed() then 6843 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6844 base = Align(PC,4); 6845 address = if add then (base + imm32) else (base - imm32); 6846 R[t] = ZeroExtend(MemU[address,1], 32); 6847 #endif 6848 6849 bool success = false; 6850 6851 if (ConditionPassed(opcode)) { 6852 uint32_t t; 6853 uint32_t imm32; 6854 bool add; 6855 switch (encoding) { 6856 case eEncodingT1: 6857 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6858 t = Bits32(opcode, 15, 12); 6859 imm32 = Bits32(opcode, 11, 0); 6860 add = BitIsSet(opcode, 23); 6861 6862 // if Rt == '1111' then SEE PLD; 6863 if (t == 15) 6864 return false; // PLD is not implemented yet 6865 6866 // if t == 13 then UNPREDICTABLE; 6867 if (t == 13) 6868 return false; 6869 6870 break; 6871 6872 case eEncodingA1: 6873 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6874 t = Bits32(opcode, 15, 12); 6875 imm32 = Bits32(opcode, 11, 0); 6876 add = BitIsSet(opcode, 23); 6877 6878 // if t == 15 then UNPREDICTABLE; 6879 if (t == 15) 6880 return false; 6881 break; 6882 6883 default: 6884 return false; 6885 } 6886 6887 // base = Align(PC,4); 6888 uint32_t pc_val = ReadCoreReg(PC_REG, &success); 6889 if (!success) 6890 return false; 6891 6892 uint32_t base = AlignPC(pc_val); 6893 6894 addr_t address; 6895 // address = if add then (base + imm32) else (base - imm32); 6896 if (add) 6897 address = base + imm32; 6898 else 6899 address = base - imm32; 6900 6901 // R[t] = ZeroExtend(MemU[address,1], 32); 6902 EmulateInstruction::Context context; 6903 context.type = eContextRelativeBranchImmediate; 6904 context.SetImmediate(address - base); 6905 6906 uint64_t data = MemURead(context, address, 1, 0, &success); 6907 if (!success) 6908 return false; 6909 6910 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6911 return false; 6912 } 6913 return true; 6914 } 6915 6916 // LDRB (register) calculates an address from a base register value and an 6917 // offset rigister value, loads a byte from memory, zero-extends it to form a 6918 // 32-bit word, and writes it to a register. The offset register value can 6919 // optionally be shifted. 6920 bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode, 6921 const ARMEncoding encoding) { 6922 #if 0 6923 if ConditionPassed() then 6924 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6925 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6926 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6927 address = if index then offset_addr else R[n]; 6928 R[t] = ZeroExtend(MemU[address,1],32); 6929 if wback then R[n] = offset_addr; 6930 #endif 6931 6932 bool success = false; 6933 6934 if (ConditionPassed(opcode)) { 6935 uint32_t t; 6936 uint32_t n; 6937 uint32_t m; 6938 bool index; 6939 bool add; 6940 bool wback; 6941 ARM_ShifterType shift_t; 6942 uint32_t shift_n; 6943 6944 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6945 switch (encoding) { 6946 case eEncodingT1: 6947 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6948 t = Bits32(opcode, 2, 0); 6949 n = Bits32(opcode, 5, 3); 6950 m = Bits32(opcode, 8, 6); 6951 6952 // index = TRUE; add = TRUE; wback = FALSE; 6953 index = true; 6954 add = true; 6955 wback = false; 6956 6957 // (shift_t, shift_n) = (SRType_LSL, 0); 6958 shift_t = SRType_LSL; 6959 shift_n = 0; 6960 break; 6961 6962 case eEncodingT2: 6963 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6964 t = Bits32(opcode, 15, 12); 6965 n = Bits32(opcode, 19, 16); 6966 m = Bits32(opcode, 3, 0); 6967 6968 // index = TRUE; add = TRUE; wback = FALSE; 6969 index = true; 6970 add = true; 6971 wback = false; 6972 6973 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6974 shift_t = SRType_LSL; 6975 shift_n = Bits32(opcode, 5, 4); 6976 6977 // if Rt == '1111' then SEE PLD; 6978 if (t == 15) 6979 return false; // PLD is not implemented yet 6980 6981 // if Rn == '1111' then SEE LDRB (literal); 6982 if (n == 15) 6983 return EmulateLDRBLiteral(opcode, eEncodingT1); 6984 6985 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6986 if ((t == 13) || BadReg(m)) 6987 return false; 6988 break; 6989 6990 case eEncodingA1: { 6991 // if P == '0' && W == '1' then SEE LDRBT; 6992 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6993 t = Bits32(opcode, 15, 12); 6994 n = Bits32(opcode, 19, 16); 6995 m = Bits32(opcode, 3, 0); 6996 6997 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6998 // (W == '1'); 6999 index = BitIsSet(opcode, 24); 7000 add = BitIsSet(opcode, 23); 7001 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7002 7003 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 7004 uint32_t type = Bits32(opcode, 6, 5); 7005 uint32_t imm5 = Bits32(opcode, 11, 7); 7006 shift_n = DecodeImmShift(type, imm5, shift_t); 7007 7008 // if t == 15 || m == 15 then UNPREDICTABLE; 7009 if ((t == 15) || (m == 15)) 7010 return false; 7011 7012 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7013 if (wback && ((n == 15) || (n == t))) 7014 return false; 7015 } break; 7016 7017 default: 7018 return false; 7019 } 7020 7021 addr_t offset_addr; 7022 addr_t address; 7023 7024 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7025 uint32_t Rm = 7026 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7027 if (!success) 7028 return false; 7029 7030 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7031 if (!success) 7032 return false; 7033 7034 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7035 uint32_t Rn = 7036 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7037 if (!success) 7038 return false; 7039 7040 if (add) 7041 offset_addr = Rn + offset; 7042 else 7043 offset_addr = Rn - offset; 7044 7045 // address = if index then offset_addr else R[n]; 7046 if (index) 7047 address = offset_addr; 7048 else 7049 address = Rn; 7050 7051 // R[t] = ZeroExtend(MemU[address,1],32); 7052 RegisterInfo base_reg; 7053 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7054 7055 EmulateInstruction::Context context; 7056 context.type = eContextRegisterLoad; 7057 context.SetRegisterPlusOffset(base_reg, address - Rn); 7058 7059 uint64_t data = MemURead(context, address, 1, 0, &success); 7060 if (!success) 7061 return false; 7062 7063 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7064 return false; 7065 7066 // if wback then R[n] = offset_addr; 7067 if (wback) { 7068 context.type = eContextAdjustBaseRegister; 7069 context.SetAddress(offset_addr); 7070 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7071 offset_addr)) 7072 return false; 7073 } 7074 } 7075 return true; 7076 } 7077 7078 // LDRH (immediate, Thumb) calculates an address from a base register value and 7079 // an immediate offset, loads a 7080 // halfword from memory, zero-extends it to form a 32-bit word, and writes it 7081 // to a register. It can use offset, post-indexed, or pre-indexed addressing. 7082 bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode, 7083 const ARMEncoding encoding) { 7084 #if 0 7085 if ConditionPassed() then 7086 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7087 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7088 address = if index then offset_addr else R[n]; 7089 data = MemU[address,2]; 7090 if wback then R[n] = offset_addr; 7091 if UnalignedSupport() || address<0> = '0' then 7092 R[t] = ZeroExtend(data, 32); 7093 else // Can only apply before ARMv7 7094 R[t] = bits(32) UNKNOWN; 7095 #endif 7096 7097 bool success = false; 7098 7099 if (ConditionPassed(opcode)) { 7100 uint32_t t; 7101 uint32_t n; 7102 uint32_t imm32; 7103 bool index; 7104 bool add; 7105 bool wback; 7106 7107 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7108 switch (encoding) { 7109 case eEncodingT1: 7110 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 7111 t = Bits32(opcode, 2, 0); 7112 n = Bits32(opcode, 5, 3); 7113 imm32 = Bits32(opcode, 10, 6) << 1; 7114 7115 // index = TRUE; add = TRUE; wback = FALSE; 7116 index = true; 7117 add = true; 7118 wback = false; 7119 7120 break; 7121 7122 case eEncodingT2: 7123 // if Rt == '1111' then SEE "Unallocated memory hints"; 7124 // if Rn == '1111' then SEE LDRH (literal); 7125 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7126 t = Bits32(opcode, 15, 12); 7127 n = Bits32(opcode, 19, 16); 7128 imm32 = Bits32(opcode, 11, 0); 7129 7130 // index = TRUE; add = TRUE; wback = FALSE; 7131 index = true; 7132 add = true; 7133 wback = false; 7134 7135 // if t == 13 then UNPREDICTABLE; 7136 if (t == 13) 7137 return false; 7138 break; 7139 7140 case eEncodingT3: 7141 // if Rn == '1111' then SEE LDRH (literal); 7142 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7143 // "Unallocated memory hints"; 7144 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 7145 // if P == '0' && W == '0' then UNDEFINED; 7146 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7147 return false; 7148 7149 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7150 t = Bits32(opcode, 15, 12); 7151 n = Bits32(opcode, 19, 16); 7152 imm32 = Bits32(opcode, 7, 0); 7153 7154 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7155 index = BitIsSet(opcode, 10); 7156 add = BitIsSet(opcode, 9); 7157 wback = BitIsSet(opcode, 8); 7158 7159 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7160 if (BadReg(t) || (wback && (n == t))) 7161 return false; 7162 break; 7163 7164 default: 7165 return false; 7166 } 7167 7168 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7169 uint32_t Rn = 7170 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7171 if (!success) 7172 return false; 7173 7174 addr_t offset_addr; 7175 addr_t address; 7176 7177 if (add) 7178 offset_addr = Rn + imm32; 7179 else 7180 offset_addr = Rn - imm32; 7181 7182 // address = if index then offset_addr else R[n]; 7183 if (index) 7184 address = offset_addr; 7185 else 7186 address = Rn; 7187 7188 // data = MemU[address,2]; 7189 RegisterInfo base_reg; 7190 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7191 7192 EmulateInstruction::Context context; 7193 context.type = eContextRegisterLoad; 7194 context.SetRegisterPlusOffset(base_reg, address - Rn); 7195 7196 uint64_t data = MemURead(context, address, 2, 0, &success); 7197 if (!success) 7198 return false; 7199 7200 // if wback then R[n] = offset_addr; 7201 if (wback) { 7202 context.type = eContextAdjustBaseRegister; 7203 context.SetAddress(offset_addr); 7204 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7205 offset_addr)) 7206 return false; 7207 } 7208 7209 // if UnalignedSupport() || address<0> = '0' then 7210 if (UnalignedSupport() || BitIsClear(address, 0)) { 7211 // R[t] = ZeroExtend(data, 32); 7212 context.type = eContextRegisterLoad; 7213 context.SetRegisterPlusOffset(base_reg, address - Rn); 7214 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7215 data)) 7216 return false; 7217 } else // Can only apply before ARMv7 7218 { 7219 // R[t] = bits(32) UNKNOWN; 7220 WriteBits32Unknown(t); 7221 } 7222 } 7223 return true; 7224 } 7225 7226 // LDRH (literal) calculates an address from the PC value and an immediate 7227 // offset, loads a halfword from memory, 7228 // zero-extends it to form a 32-bit word, and writes it to a register. 7229 bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode, 7230 const ARMEncoding encoding) { 7231 #if 0 7232 if ConditionPassed() then 7233 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7234 base = Align(PC,4); 7235 address = if add then (base + imm32) else (base - imm32); 7236 data = MemU[address,2]; 7237 if UnalignedSupport() || address<0> = '0' then 7238 R[t] = ZeroExtend(data, 32); 7239 else // Can only apply before ARMv7 7240 R[t] = bits(32) UNKNOWN; 7241 #endif 7242 7243 bool success = false; 7244 7245 if (ConditionPassed(opcode)) { 7246 uint32_t t; 7247 uint32_t imm32; 7248 bool add; 7249 7250 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7251 switch (encoding) { 7252 case eEncodingT1: 7253 // if Rt == '1111' then SEE "Unallocated memory hints"; 7254 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7255 t = Bits32(opcode, 15, 12); 7256 imm32 = Bits32(opcode, 11, 0); 7257 add = BitIsSet(opcode, 23); 7258 7259 // if t == 13 then UNPREDICTABLE; 7260 if (t == 13) 7261 return false; 7262 7263 break; 7264 7265 case eEncodingA1: { 7266 uint32_t imm4H = Bits32(opcode, 11, 8); 7267 uint32_t imm4L = Bits32(opcode, 3, 0); 7268 7269 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7270 t = Bits32(opcode, 15, 12); 7271 imm32 = (imm4H << 4) | imm4L; 7272 add = BitIsSet(opcode, 23); 7273 7274 // if t == 15 then UNPREDICTABLE; 7275 if (t == 15) 7276 return false; 7277 break; 7278 } 7279 7280 default: 7281 return false; 7282 } 7283 7284 // base = Align(PC,4); 7285 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7286 if (!success) 7287 return false; 7288 7289 addr_t base = AlignPC(pc_value); 7290 addr_t address; 7291 7292 // address = if add then (base + imm32) else (base - imm32); 7293 if (add) 7294 address = base + imm32; 7295 else 7296 address = base - imm32; 7297 7298 // data = MemU[address,2]; 7299 RegisterInfo base_reg; 7300 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7301 7302 EmulateInstruction::Context context; 7303 context.type = eContextRegisterLoad; 7304 context.SetRegisterPlusOffset(base_reg, address - base); 7305 7306 uint64_t data = MemURead(context, address, 2, 0, &success); 7307 if (!success) 7308 return false; 7309 7310 // if UnalignedSupport() || address<0> = '0' then 7311 if (UnalignedSupport() || BitIsClear(address, 0)) { 7312 // R[t] = ZeroExtend(data, 32); 7313 context.type = eContextRegisterLoad; 7314 context.SetRegisterPlusOffset(base_reg, address - base); 7315 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7316 data)) 7317 return false; 7318 7319 } else // Can only apply before ARMv7 7320 { 7321 // R[t] = bits(32) UNKNOWN; 7322 WriteBits32Unknown(t); 7323 } 7324 } 7325 return true; 7326 } 7327 7328 // LDRH (literal) calculates an address from a base register value and an offset 7329 // register value, loads a halfword 7330 // from memory, zero-extends it to form a 32-bit word, and writes it to a 7331 // register. The offset register value can be shifted left by 0, 1, 2, or 3 7332 // bits. 7333 bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode, 7334 const ARMEncoding encoding) { 7335 #if 0 7336 if ConditionPassed() then 7337 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7338 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7339 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7340 address = if index then offset_addr else R[n]; 7341 data = MemU[address,2]; 7342 if wback then R[n] = offset_addr; 7343 if UnalignedSupport() || address<0> = '0' then 7344 R[t] = ZeroExtend(data, 32); 7345 else // Can only apply before ARMv7 7346 R[t] = bits(32) UNKNOWN; 7347 #endif 7348 7349 bool success = false; 7350 7351 if (ConditionPassed(opcode)) { 7352 uint32_t t; 7353 uint32_t n; 7354 uint32_t m; 7355 bool index; 7356 bool add; 7357 bool wback; 7358 ARM_ShifterType shift_t; 7359 uint32_t shift_n; 7360 7361 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7362 switch (encoding) { 7363 case eEncodingT1: 7364 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 7365 // in ThumbEE"; 7366 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7367 t = Bits32(opcode, 2, 0); 7368 n = Bits32(opcode, 5, 3); 7369 m = Bits32(opcode, 8, 6); 7370 7371 // index = TRUE; add = TRUE; wback = FALSE; 7372 index = true; 7373 add = true; 7374 wback = false; 7375 7376 // (shift_t, shift_n) = (SRType_LSL, 0); 7377 shift_t = SRType_LSL; 7378 shift_n = 0; 7379 7380 break; 7381 7382 case eEncodingT2: 7383 // if Rn == '1111' then SEE LDRH (literal); 7384 // if Rt == '1111' then SEE "Unallocated memory hints"; 7385 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7386 t = Bits32(opcode, 15, 12); 7387 n = Bits32(opcode, 19, 16); 7388 m = Bits32(opcode, 3, 0); 7389 7390 // index = TRUE; add = TRUE; wback = FALSE; 7391 index = true; 7392 add = true; 7393 wback = false; 7394 7395 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7396 shift_t = SRType_LSL; 7397 shift_n = Bits32(opcode, 5, 4); 7398 7399 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7400 if ((t == 13) || BadReg(m)) 7401 return false; 7402 break; 7403 7404 case eEncodingA1: 7405 // if P == '0' && W == '1' then SEE LDRHT; 7406 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7407 t = Bits32(opcode, 15, 12); 7408 n = Bits32(opcode, 19, 16); 7409 m = Bits32(opcode, 3, 0); 7410 7411 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7412 // (W == '1'); 7413 index = BitIsSet(opcode, 24); 7414 add = BitIsSet(opcode, 23); 7415 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7416 7417 // (shift_t, shift_n) = (SRType_LSL, 0); 7418 shift_t = SRType_LSL; 7419 shift_n = 0; 7420 7421 // if t == 15 || m == 15 then UNPREDICTABLE; 7422 if ((t == 15) || (m == 15)) 7423 return false; 7424 7425 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7426 if (wback && ((n == 15) || (n == t))) 7427 return false; 7428 7429 break; 7430 7431 default: 7432 return false; 7433 } 7434 7435 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7436 7437 uint64_t Rm = 7438 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7439 if (!success) 7440 return false; 7441 7442 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7443 if (!success) 7444 return false; 7445 7446 addr_t offset_addr; 7447 addr_t address; 7448 7449 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7450 uint64_t Rn = 7451 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7452 if (!success) 7453 return false; 7454 7455 if (add) 7456 offset_addr = Rn + offset; 7457 else 7458 offset_addr = Rn - offset; 7459 7460 // address = if index then offset_addr else R[n]; 7461 if (index) 7462 address = offset_addr; 7463 else 7464 address = Rn; 7465 7466 // data = MemU[address,2]; 7467 RegisterInfo base_reg; 7468 RegisterInfo offset_reg; 7469 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7470 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7471 7472 EmulateInstruction::Context context; 7473 context.type = eContextRegisterLoad; 7474 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7475 uint64_t data = MemURead(context, address, 2, 0, &success); 7476 if (!success) 7477 return false; 7478 7479 // if wback then R[n] = offset_addr; 7480 if (wback) { 7481 context.type = eContextAdjustBaseRegister; 7482 context.SetAddress(offset_addr); 7483 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7484 offset_addr)) 7485 return false; 7486 } 7487 7488 // if UnalignedSupport() || address<0> = '0' then 7489 if (UnalignedSupport() || BitIsClear(address, 0)) { 7490 // R[t] = ZeroExtend(data, 32); 7491 context.type = eContextRegisterLoad; 7492 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7493 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7494 data)) 7495 return false; 7496 } else // Can only apply before ARMv7 7497 { 7498 // R[t] = bits(32) UNKNOWN; 7499 WriteBits32Unknown(t); 7500 } 7501 } 7502 return true; 7503 } 7504 7505 // LDRSB (immediate) calculates an address from a base register value and an 7506 // immediate offset, loads a byte from 7507 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7508 // It can use offset, post-indexed, or pre-indexed addressing. 7509 bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode, 7510 const ARMEncoding encoding) { 7511 #if 0 7512 if ConditionPassed() then 7513 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7514 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7515 address = if index then offset_addr else R[n]; 7516 R[t] = SignExtend(MemU[address,1], 32); 7517 if wback then R[n] = offset_addr; 7518 #endif 7519 7520 bool success = false; 7521 7522 if (ConditionPassed(opcode)) { 7523 uint32_t t; 7524 uint32_t n; 7525 uint32_t imm32; 7526 bool index; 7527 bool add; 7528 bool wback; 7529 7530 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7531 switch (encoding) { 7532 case eEncodingT1: 7533 // if Rt == '1111' then SEE PLI; 7534 // if Rn == '1111' then SEE LDRSB (literal); 7535 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7536 t = Bits32(opcode, 15, 12); 7537 n = Bits32(opcode, 19, 16); 7538 imm32 = Bits32(opcode, 11, 0); 7539 7540 // index = TRUE; add = TRUE; wback = FALSE; 7541 index = true; 7542 add = true; 7543 wback = false; 7544 7545 // if t == 13 then UNPREDICTABLE; 7546 if (t == 13) 7547 return false; 7548 7549 break; 7550 7551 case eEncodingT2: 7552 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7553 // if Rn == '1111' then SEE LDRSB (literal); 7554 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7555 // if P == '0' && W == '0' then UNDEFINED; 7556 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7557 return false; 7558 7559 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7560 t = Bits32(opcode, 15, 12); 7561 n = Bits32(opcode, 19, 16); 7562 imm32 = Bits32(opcode, 7, 0); 7563 7564 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7565 index = BitIsSet(opcode, 10); 7566 add = BitIsSet(opcode, 9); 7567 wback = BitIsSet(opcode, 8); 7568 7569 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7570 if (((t == 13) || 7571 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) || 7572 BitIsSet(opcode, 8)))) || 7573 (wback && (n == t))) 7574 return false; 7575 7576 break; 7577 7578 case eEncodingA1: { 7579 // if Rn == '1111' then SEE LDRSB (literal); 7580 // if P == '0' && W == '1' then SEE LDRSBT; 7581 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7582 t = Bits32(opcode, 15, 12); 7583 n = Bits32(opcode, 19, 16); 7584 7585 uint32_t imm4H = Bits32(opcode, 11, 8); 7586 uint32_t imm4L = Bits32(opcode, 3, 0); 7587 imm32 = (imm4H << 4) | imm4L; 7588 7589 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7590 // (W == '1'); 7591 index = BitIsSet(opcode, 24); 7592 add = BitIsSet(opcode, 23); 7593 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7594 7595 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7596 if ((t == 15) || (wback && (n == t))) 7597 return false; 7598 7599 break; 7600 } 7601 7602 default: 7603 return false; 7604 } 7605 7606 uint64_t Rn = ReadCoreReg(n, &success); 7607 if (!success) 7608 return false; 7609 7610 addr_t offset_addr; 7611 addr_t address; 7612 7613 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7614 if (add) 7615 offset_addr = Rn + imm32; 7616 else 7617 offset_addr = Rn - imm32; 7618 7619 // address = if index then offset_addr else R[n]; 7620 if (index) 7621 address = offset_addr; 7622 else 7623 address = Rn; 7624 7625 // R[t] = SignExtend(MemU[address,1], 32); 7626 RegisterInfo base_reg; 7627 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7628 7629 EmulateInstruction::Context context; 7630 context.type = eContextRegisterLoad; 7631 context.SetRegisterPlusOffset(base_reg, address - Rn); 7632 7633 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7634 if (!success) 7635 return false; 7636 7637 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7638 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7639 (uint64_t)signed_data)) 7640 return false; 7641 7642 // if wback then R[n] = offset_addr; 7643 if (wback) { 7644 context.type = eContextAdjustBaseRegister; 7645 context.SetAddress(offset_addr); 7646 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7647 offset_addr)) 7648 return false; 7649 } 7650 } 7651 7652 return true; 7653 } 7654 7655 // LDRSB (literal) calculates an address from the PC value and an immediate 7656 // offset, loads a byte from memory, 7657 // sign-extends it to form a 32-bit word, and writes tit to a register. 7658 bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode, 7659 const ARMEncoding encoding) { 7660 #if 0 7661 if ConditionPassed() then 7662 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7663 base = Align(PC,4); 7664 address = if add then (base + imm32) else (base - imm32); 7665 R[t] = SignExtend(MemU[address,1], 32); 7666 #endif 7667 7668 bool success = false; 7669 7670 if (ConditionPassed(opcode)) { 7671 uint32_t t; 7672 uint32_t imm32; 7673 bool add; 7674 7675 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7676 switch (encoding) { 7677 case eEncodingT1: 7678 // if Rt == '1111' then SEE PLI; 7679 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7680 t = Bits32(opcode, 15, 12); 7681 imm32 = Bits32(opcode, 11, 0); 7682 add = BitIsSet(opcode, 23); 7683 7684 // if t == 13 then UNPREDICTABLE; 7685 if (t == 13) 7686 return false; 7687 7688 break; 7689 7690 case eEncodingA1: { 7691 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7692 t = Bits32(opcode, 15, 12); 7693 uint32_t imm4H = Bits32(opcode, 11, 8); 7694 uint32_t imm4L = Bits32(opcode, 3, 0); 7695 imm32 = (imm4H << 4) | imm4L; 7696 add = BitIsSet(opcode, 23); 7697 7698 // if t == 15 then UNPREDICTABLE; 7699 if (t == 15) 7700 return false; 7701 7702 break; 7703 } 7704 7705 default: 7706 return false; 7707 } 7708 7709 // base = Align(PC,4); 7710 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7711 if (!success) 7712 return false; 7713 uint64_t base = AlignPC(pc_value); 7714 7715 // address = if add then (base + imm32) else (base - imm32); 7716 addr_t address; 7717 if (add) 7718 address = base + imm32; 7719 else 7720 address = base - imm32; 7721 7722 // R[t] = SignExtend(MemU[address,1], 32); 7723 RegisterInfo base_reg; 7724 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7725 7726 EmulateInstruction::Context context; 7727 context.type = eContextRegisterLoad; 7728 context.SetRegisterPlusOffset(base_reg, address - base); 7729 7730 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7731 if (!success) 7732 return false; 7733 7734 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7735 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7736 (uint64_t)signed_data)) 7737 return false; 7738 } 7739 return true; 7740 } 7741 7742 // LDRSB (register) calculates an address from a base register value and an 7743 // offset register value, loadsa byte from 7744 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7745 // The offset register value can be shifted left by 0, 1, 2, or 3 bits. 7746 bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode, 7747 const ARMEncoding encoding) { 7748 #if 0 7749 if ConditionPassed() then 7750 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7751 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7752 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7753 address = if index then offset_addr else R[n]; 7754 R[t] = SignExtend(MemU[address,1], 32); 7755 if wback then R[n] = offset_addr; 7756 #endif 7757 7758 bool success = false; 7759 7760 if (ConditionPassed(opcode)) { 7761 uint32_t t; 7762 uint32_t n; 7763 uint32_t m; 7764 bool index; 7765 bool add; 7766 bool wback; 7767 ARM_ShifterType shift_t; 7768 uint32_t shift_n; 7769 7770 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7771 switch (encoding) { 7772 case eEncodingT1: 7773 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7774 t = Bits32(opcode, 2, 0); 7775 n = Bits32(opcode, 5, 3); 7776 m = Bits32(opcode, 8, 6); 7777 7778 // index = TRUE; add = TRUE; wback = FALSE; 7779 index = true; 7780 add = true; 7781 wback = false; 7782 7783 // (shift_t, shift_n) = (SRType_LSL, 0); 7784 shift_t = SRType_LSL; 7785 shift_n = 0; 7786 7787 break; 7788 7789 case eEncodingT2: 7790 // if Rt == '1111' then SEE PLI; 7791 // if Rn == '1111' then SEE LDRSB (literal); 7792 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7793 t = Bits32(opcode, 15, 12); 7794 n = Bits32(opcode, 19, 16); 7795 m = Bits32(opcode, 3, 0); 7796 7797 // index = TRUE; add = TRUE; wback = FALSE; 7798 index = true; 7799 add = true; 7800 wback = false; 7801 7802 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7803 shift_t = SRType_LSL; 7804 shift_n = Bits32(opcode, 5, 4); 7805 7806 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7807 if ((t == 13) || BadReg(m)) 7808 return false; 7809 break; 7810 7811 case eEncodingA1: 7812 // if P == '0' && W == '1' then SEE LDRSBT; 7813 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7814 t = Bits32(opcode, 15, 12); 7815 n = Bits32(opcode, 19, 16); 7816 m = Bits32(opcode, 3, 0); 7817 7818 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7819 // (W == '1'); 7820 index = BitIsSet(opcode, 24); 7821 add = BitIsSet(opcode, 23); 7822 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7823 7824 // (shift_t, shift_n) = (SRType_LSL, 0); 7825 shift_t = SRType_LSL; 7826 shift_n = 0; 7827 7828 // if t == 15 || m == 15 then UNPREDICTABLE; 7829 if ((t == 15) || (m == 15)) 7830 return false; 7831 7832 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7833 if (wback && ((n == 15) || (n == t))) 7834 return false; 7835 break; 7836 7837 default: 7838 return false; 7839 } 7840 7841 uint64_t Rm = 7842 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7843 if (!success) 7844 return false; 7845 7846 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7847 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7848 if (!success) 7849 return false; 7850 7851 addr_t offset_addr; 7852 addr_t address; 7853 7854 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7855 uint64_t Rn = 7856 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7857 if (!success) 7858 return false; 7859 7860 if (add) 7861 offset_addr = Rn + offset; 7862 else 7863 offset_addr = Rn - offset; 7864 7865 // address = if index then offset_addr else R[n]; 7866 if (index) 7867 address = offset_addr; 7868 else 7869 address = Rn; 7870 7871 // R[t] = SignExtend(MemU[address,1], 32); 7872 RegisterInfo base_reg; 7873 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7874 RegisterInfo offset_reg; 7875 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7876 7877 EmulateInstruction::Context context; 7878 context.type = eContextRegisterLoad; 7879 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7880 7881 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7882 if (!success) 7883 return false; 7884 7885 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7886 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7887 (uint64_t)signed_data)) 7888 return false; 7889 7890 // if wback then R[n] = offset_addr; 7891 if (wback) { 7892 context.type = eContextAdjustBaseRegister; 7893 context.SetAddress(offset_addr); 7894 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7895 offset_addr)) 7896 return false; 7897 } 7898 } 7899 return true; 7900 } 7901 7902 // LDRSH (immediate) calculates an address from a base register value and an 7903 // immediate offset, loads a halfword from 7904 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7905 // It can use offset, post-indexed, or pre-indexed addressing. 7906 bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode, 7907 const ARMEncoding encoding) { 7908 #if 0 7909 if ConditionPassed() then 7910 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7911 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7912 address = if index then offset_addr else R[n]; 7913 data = MemU[address,2]; 7914 if wback then R[n] = offset_addr; 7915 if UnalignedSupport() || address<0> = '0' then 7916 R[t] = SignExtend(data, 32); 7917 else // Can only apply before ARMv7 7918 R[t] = bits(32) UNKNOWN; 7919 #endif 7920 7921 bool success = false; 7922 7923 if (ConditionPassed(opcode)) { 7924 uint32_t t; 7925 uint32_t n; 7926 uint32_t imm32; 7927 bool index; 7928 bool add; 7929 bool wback; 7930 7931 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7932 switch (encoding) { 7933 case eEncodingT1: 7934 // if Rn == '1111' then SEE LDRSH (literal); 7935 // if Rt == '1111' then SEE "Unallocated memory hints"; 7936 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7937 t = Bits32(opcode, 15, 12); 7938 n = Bits32(opcode, 19, 16); 7939 imm32 = Bits32(opcode, 11, 0); 7940 7941 // index = TRUE; add = TRUE; wback = FALSE; 7942 index = true; 7943 add = true; 7944 wback = false; 7945 7946 // if t == 13 then UNPREDICTABLE; 7947 if (t == 13) 7948 return false; 7949 7950 break; 7951 7952 case eEncodingT2: 7953 // if Rn == '1111' then SEE LDRSH (literal); 7954 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7955 // "Unallocated memory hints"; 7956 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7957 // if P == '0' && W == '0' then UNDEFINED; 7958 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7959 return false; 7960 7961 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7962 t = Bits32(opcode, 15, 12); 7963 n = Bits32(opcode, 19, 16); 7964 imm32 = Bits32(opcode, 7, 0); 7965 7966 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7967 index = BitIsSet(opcode, 10); 7968 add = BitIsSet(opcode, 9); 7969 wback = BitIsSet(opcode, 8); 7970 7971 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7972 if (BadReg(t) || (wback && (n == t))) 7973 return false; 7974 7975 break; 7976 7977 case eEncodingA1: { 7978 // if Rn == '1111' then SEE LDRSH (literal); 7979 // if P == '0' && W == '1' then SEE LDRSHT; 7980 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7981 t = Bits32(opcode, 15, 12); 7982 n = Bits32(opcode, 19, 16); 7983 uint32_t imm4H = Bits32(opcode, 11, 8); 7984 uint32_t imm4L = Bits32(opcode, 3, 0); 7985 imm32 = (imm4H << 4) | imm4L; 7986 7987 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7988 // (W == '1'); 7989 index = BitIsSet(opcode, 24); 7990 add = BitIsSet(opcode, 23); 7991 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7992 7993 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7994 if ((t == 15) || (wback && (n == t))) 7995 return false; 7996 7997 break; 7998 } 7999 8000 default: 8001 return false; 8002 } 8003 8004 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 8005 uint64_t Rn = 8006 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8007 if (!success) 8008 return false; 8009 8010 addr_t offset_addr; 8011 if (add) 8012 offset_addr = Rn + imm32; 8013 else 8014 offset_addr = Rn - imm32; 8015 8016 // address = if index then offset_addr else R[n]; 8017 addr_t address; 8018 if (index) 8019 address = offset_addr; 8020 else 8021 address = Rn; 8022 8023 // data = MemU[address,2]; 8024 RegisterInfo base_reg; 8025 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8026 8027 EmulateInstruction::Context context; 8028 context.type = eContextRegisterLoad; 8029 context.SetRegisterPlusOffset(base_reg, address - Rn); 8030 8031 uint64_t data = MemURead(context, address, 2, 0, &success); 8032 if (!success) 8033 return false; 8034 8035 // if wback then R[n] = offset_addr; 8036 if (wback) { 8037 context.type = eContextAdjustBaseRegister; 8038 context.SetAddress(offset_addr); 8039 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8040 offset_addr)) 8041 return false; 8042 } 8043 8044 // if UnalignedSupport() || address<0> = '0' then 8045 if (UnalignedSupport() || BitIsClear(address, 0)) { 8046 // R[t] = SignExtend(data, 32); 8047 int64_t signed_data = llvm::SignExtend64<16>(data); 8048 context.type = eContextRegisterLoad; 8049 context.SetRegisterPlusOffset(base_reg, address - Rn); 8050 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8051 (uint64_t)signed_data)) 8052 return false; 8053 } else // Can only apply before ARMv7 8054 { 8055 // R[t] = bits(32) UNKNOWN; 8056 WriteBits32Unknown(t); 8057 } 8058 } 8059 return true; 8060 } 8061 8062 // LDRSH (literal) calculates an address from the PC value and an immediate 8063 // offset, loads a halfword from memory, 8064 // sign-extends it to from a 32-bit word, and writes it to a register. 8065 bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode, 8066 const ARMEncoding encoding) { 8067 #if 0 8068 if ConditionPassed() then 8069 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8070 base = Align(PC,4); 8071 address = if add then (base + imm32) else (base - imm32); 8072 data = MemU[address,2]; 8073 if UnalignedSupport() || address<0> = '0' then 8074 R[t] = SignExtend(data, 32); 8075 else // Can only apply before ARMv7 8076 R[t] = bits(32) UNKNOWN; 8077 #endif 8078 8079 bool success = false; 8080 8081 if (ConditionPassed(opcode)) { 8082 uint32_t t; 8083 uint32_t imm32; 8084 bool add; 8085 8086 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8087 switch (encoding) { 8088 case eEncodingT1: 8089 // if Rt == '1111' then SEE "Unallocated memory hints"; 8090 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 8091 t = Bits32(opcode, 15, 12); 8092 imm32 = Bits32(opcode, 11, 0); 8093 add = BitIsSet(opcode, 23); 8094 8095 // if t == 13 then UNPREDICTABLE; 8096 if (t == 13) 8097 return false; 8098 8099 break; 8100 8101 case eEncodingA1: { 8102 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 8103 t = Bits32(opcode, 15, 12); 8104 uint32_t imm4H = Bits32(opcode, 11, 8); 8105 uint32_t imm4L = Bits32(opcode, 3, 0); 8106 imm32 = (imm4H << 4) | imm4L; 8107 add = BitIsSet(opcode, 23); 8108 8109 // if t == 15 then UNPREDICTABLE; 8110 if (t == 15) 8111 return false; 8112 8113 break; 8114 } 8115 default: 8116 return false; 8117 } 8118 8119 // base = Align(PC,4); 8120 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 8121 if (!success) 8122 return false; 8123 8124 uint64_t base = AlignPC(pc_value); 8125 8126 addr_t address; 8127 // address = if add then (base + imm32) else (base - imm32); 8128 if (add) 8129 address = base + imm32; 8130 else 8131 address = base - imm32; 8132 8133 // data = MemU[address,2]; 8134 RegisterInfo base_reg; 8135 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 8136 8137 EmulateInstruction::Context context; 8138 context.type = eContextRegisterLoad; 8139 context.SetRegisterPlusOffset(base_reg, imm32); 8140 8141 uint64_t data = MemURead(context, address, 2, 0, &success); 8142 if (!success) 8143 return false; 8144 8145 // if UnalignedSupport() || address<0> = '0' then 8146 if (UnalignedSupport() || BitIsClear(address, 0)) { 8147 // R[t] = SignExtend(data, 32); 8148 int64_t signed_data = llvm::SignExtend64<16>(data); 8149 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8150 (uint64_t)signed_data)) 8151 return false; 8152 } else // Can only apply before ARMv7 8153 { 8154 // R[t] = bits(32) UNKNOWN; 8155 WriteBits32Unknown(t); 8156 } 8157 } 8158 return true; 8159 } 8160 8161 // LDRSH (register) calculates an address from a base register value and an 8162 // offset register value, loads a halfword 8163 // from memory, sign-extends it to form a 32-bit word, and writes it to a 8164 // register. The offset register value can be shifted left by 0, 1, 2, or 3 8165 // bits. 8166 bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode, 8167 const ARMEncoding encoding) { 8168 #if 0 8169 if ConditionPassed() then 8170 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8171 offset = Shift(R[m], shift_t, shift_n, APSR.C); 8172 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8173 address = if index then offset_addr else R[n]; 8174 data = MemU[address,2]; 8175 if wback then R[n] = offset_addr; 8176 if UnalignedSupport() || address<0> = '0' then 8177 R[t] = SignExtend(data, 32); 8178 else // Can only apply before ARMv7 8179 R[t] = bits(32) UNKNOWN; 8180 #endif 8181 8182 bool success = false; 8183 8184 if (ConditionPassed(opcode)) { 8185 uint32_t t; 8186 uint32_t n; 8187 uint32_t m; 8188 bool index; 8189 bool add; 8190 bool wback; 8191 ARM_ShifterType shift_t; 8192 uint32_t shift_n; 8193 8194 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8195 switch (encoding) { 8196 case eEncodingT1: 8197 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 8198 // in ThumbEE"; 8199 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8200 t = Bits32(opcode, 2, 0); 8201 n = Bits32(opcode, 5, 3); 8202 m = Bits32(opcode, 8, 6); 8203 8204 // index = TRUE; add = TRUE; wback = FALSE; 8205 index = true; 8206 add = true; 8207 wback = false; 8208 8209 // (shift_t, shift_n) = (SRType_LSL, 0); 8210 shift_t = SRType_LSL; 8211 shift_n = 0; 8212 8213 break; 8214 8215 case eEncodingT2: 8216 // if Rn == '1111' then SEE LDRSH (literal); 8217 // if Rt == '1111' then SEE "Unallocated memory hints"; 8218 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8219 t = Bits32(opcode, 15, 12); 8220 n = Bits32(opcode, 19, 16); 8221 m = Bits32(opcode, 3, 0); 8222 8223 // index = TRUE; add = TRUE; wback = FALSE; 8224 index = true; 8225 add = true; 8226 wback = false; 8227 8228 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 8229 shift_t = SRType_LSL; 8230 shift_n = Bits32(opcode, 5, 4); 8231 8232 // if t == 13 || BadReg(m) then UNPREDICTABLE; 8233 if ((t == 13) || BadReg(m)) 8234 return false; 8235 8236 break; 8237 8238 case eEncodingA1: 8239 // if P == '0' && W == '1' then SEE LDRSHT; 8240 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8241 t = Bits32(opcode, 15, 12); 8242 n = Bits32(opcode, 19, 16); 8243 m = Bits32(opcode, 3, 0); 8244 8245 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8246 // (W == '1'); 8247 index = BitIsSet(opcode, 24); 8248 add = BitIsSet(opcode, 23); 8249 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8250 8251 // (shift_t, shift_n) = (SRType_LSL, 0); 8252 shift_t = SRType_LSL; 8253 shift_n = 0; 8254 8255 // if t == 15 || m == 15 then UNPREDICTABLE; 8256 if ((t == 15) || (m == 15)) 8257 return false; 8258 8259 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 8260 if (wback && ((n == 15) || (n == t))) 8261 return false; 8262 8263 break; 8264 8265 default: 8266 return false; 8267 } 8268 8269 uint64_t Rm = 8270 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8271 if (!success) 8272 return false; 8273 8274 uint64_t Rn = 8275 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8276 if (!success) 8277 return false; 8278 8279 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 8280 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 8281 if (!success) 8282 return false; 8283 8284 addr_t offset_addr; 8285 addr_t address; 8286 8287 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8288 if (add) 8289 offset_addr = Rn + offset; 8290 else 8291 offset_addr = Rn - offset; 8292 8293 // address = if index then offset_addr else R[n]; 8294 if (index) 8295 address = offset_addr; 8296 else 8297 address = Rn; 8298 8299 // data = MemU[address,2]; 8300 RegisterInfo base_reg; 8301 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8302 8303 RegisterInfo offset_reg; 8304 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 8305 8306 EmulateInstruction::Context context; 8307 context.type = eContextRegisterLoad; 8308 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8309 8310 uint64_t data = MemURead(context, address, 2, 0, &success); 8311 if (!success) 8312 return false; 8313 8314 // if wback then R[n] = offset_addr; 8315 if (wback) { 8316 context.type = eContextAdjustBaseRegister; 8317 context.SetAddress(offset_addr); 8318 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8319 offset_addr)) 8320 return false; 8321 } 8322 8323 // if UnalignedSupport() || address<0> = '0' then 8324 if (UnalignedSupport() || BitIsClear(address, 0)) { 8325 // R[t] = SignExtend(data, 32); 8326 context.type = eContextRegisterLoad; 8327 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8328 8329 int64_t signed_data = llvm::SignExtend64<16>(data); 8330 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8331 (uint64_t)signed_data)) 8332 return false; 8333 } else // Can only apply before ARMv7 8334 { 8335 // R[t] = bits(32) UNKNOWN; 8336 WriteBits32Unknown(t); 8337 } 8338 } 8339 return true; 8340 } 8341 8342 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and 8343 // writes the result to the destination 8344 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before 8345 // extracting the 8-bit value. 8346 bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode, 8347 const ARMEncoding encoding) { 8348 #if 0 8349 if ConditionPassed() then 8350 EncodingSpecificOperations(); 8351 rotated = ROR(R[m], rotation); 8352 R[d] = SignExtend(rotated<7:0>, 32); 8353 #endif 8354 8355 bool success = false; 8356 8357 if (ConditionPassed(opcode)) { 8358 uint32_t d; 8359 uint32_t m; 8360 uint32_t rotation; 8361 8362 // EncodingSpecificOperations(); 8363 switch (encoding) { 8364 case eEncodingT1: 8365 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8366 d = Bits32(opcode, 2, 0); 8367 m = Bits32(opcode, 5, 3); 8368 rotation = 0; 8369 8370 break; 8371 8372 case eEncodingT2: 8373 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8374 d = Bits32(opcode, 11, 8); 8375 m = Bits32(opcode, 3, 0); 8376 rotation = Bits32(opcode, 5, 4) << 3; 8377 8378 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8379 if (BadReg(d) || BadReg(m)) 8380 return false; 8381 8382 break; 8383 8384 case eEncodingA1: 8385 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8386 d = Bits32(opcode, 15, 12); 8387 m = Bits32(opcode, 3, 0); 8388 rotation = Bits32(opcode, 11, 10) << 3; 8389 8390 // if d == 15 || m == 15 then UNPREDICTABLE; 8391 if ((d == 15) || (m == 15)) 8392 return false; 8393 8394 break; 8395 8396 default: 8397 return false; 8398 } 8399 8400 uint64_t Rm = 8401 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8402 if (!success) 8403 return false; 8404 8405 // rotated = ROR(R[m], rotation); 8406 uint64_t rotated = ROR(Rm, rotation, &success); 8407 if (!success) 8408 return false; 8409 8410 // R[d] = SignExtend(rotated<7:0>, 32); 8411 int64_t data = llvm::SignExtend64<8>(rotated); 8412 8413 RegisterInfo source_reg; 8414 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8415 8416 EmulateInstruction::Context context; 8417 context.type = eContextRegisterLoad; 8418 context.SetRegister(source_reg); 8419 8420 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8421 (uint64_t)data)) 8422 return false; 8423 } 8424 return true; 8425 } 8426 8427 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and 8428 // writes the result to the destination 8429 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8430 // extracting the 16-bit value. 8431 bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode, 8432 const ARMEncoding encoding) { 8433 #if 0 8434 if ConditionPassed() then 8435 EncodingSpecificOperations(); 8436 rotated = ROR(R[m], rotation); 8437 R[d] = SignExtend(rotated<15:0>, 32); 8438 #endif 8439 8440 bool success = false; 8441 8442 if (ConditionPassed(opcode)) { 8443 uint32_t d; 8444 uint32_t m; 8445 uint32_t rotation; 8446 8447 // EncodingSpecificOperations(); 8448 switch (encoding) { 8449 case eEncodingT1: 8450 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8451 d = Bits32(opcode, 2, 0); 8452 m = Bits32(opcode, 5, 3); 8453 rotation = 0; 8454 8455 break; 8456 8457 case eEncodingT2: 8458 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8459 d = Bits32(opcode, 11, 8); 8460 m = Bits32(opcode, 3, 0); 8461 rotation = Bits32(opcode, 5, 4) << 3; 8462 8463 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8464 if (BadReg(d) || BadReg(m)) 8465 return false; 8466 8467 break; 8468 8469 case eEncodingA1: 8470 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8471 d = Bits32(opcode, 15, 12); 8472 m = Bits32(opcode, 3, 0); 8473 rotation = Bits32(opcode, 11, 10) << 3; 8474 8475 // if d == 15 || m == 15 then UNPREDICTABLE; 8476 if ((d == 15) || (m == 15)) 8477 return false; 8478 8479 break; 8480 8481 default: 8482 return false; 8483 } 8484 8485 uint64_t Rm = 8486 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8487 if (!success) 8488 return false; 8489 8490 // rotated = ROR(R[m], rotation); 8491 uint64_t rotated = ROR(Rm, rotation, &success); 8492 if (!success) 8493 return false; 8494 8495 // R[d] = SignExtend(rotated<15:0>, 32); 8496 RegisterInfo source_reg; 8497 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8498 8499 EmulateInstruction::Context context; 8500 context.type = eContextRegisterLoad; 8501 context.SetRegister(source_reg); 8502 8503 int64_t data = llvm::SignExtend64<16>(rotated); 8504 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8505 (uint64_t)data)) 8506 return false; 8507 } 8508 8509 return true; 8510 } 8511 8512 // UXTB extracts an 8-bit value from a register, zero-extends it to 32 bits, and 8513 // writes the result to the destination 8514 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8515 // extracting the 8-bit value. 8516 bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode, 8517 const ARMEncoding encoding) { 8518 #if 0 8519 if ConditionPassed() then 8520 EncodingSpecificOperations(); 8521 rotated = ROR(R[m], rotation); 8522 R[d] = ZeroExtend(rotated<7:0>, 32); 8523 #endif 8524 8525 bool success = false; 8526 8527 if (ConditionPassed(opcode)) { 8528 uint32_t d; 8529 uint32_t m; 8530 uint32_t rotation; 8531 8532 // EncodingSpecificOperations(); 8533 switch (encoding) { 8534 case eEncodingT1: 8535 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8536 d = Bits32(opcode, 2, 0); 8537 m = Bits32(opcode, 5, 3); 8538 rotation = 0; 8539 8540 break; 8541 8542 case eEncodingT2: 8543 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8544 d = Bits32(opcode, 11, 8); 8545 m = Bits32(opcode, 3, 0); 8546 rotation = Bits32(opcode, 5, 4) << 3; 8547 8548 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8549 if (BadReg(d) || BadReg(m)) 8550 return false; 8551 8552 break; 8553 8554 case eEncodingA1: 8555 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8556 d = Bits32(opcode, 15, 12); 8557 m = Bits32(opcode, 3, 0); 8558 rotation = Bits32(opcode, 11, 10) << 3; 8559 8560 // if d == 15 || m == 15 then UNPREDICTABLE; 8561 if ((d == 15) || (m == 15)) 8562 return false; 8563 8564 break; 8565 8566 default: 8567 return false; 8568 } 8569 8570 uint64_t Rm = 8571 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8572 if (!success) 8573 return false; 8574 8575 // rotated = ROR(R[m], rotation); 8576 uint64_t rotated = ROR(Rm, rotation, &success); 8577 if (!success) 8578 return false; 8579 8580 // R[d] = ZeroExtend(rotated<7:0>, 32); 8581 RegisterInfo source_reg; 8582 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8583 8584 EmulateInstruction::Context context; 8585 context.type = eContextRegisterLoad; 8586 context.SetRegister(source_reg); 8587 8588 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8589 Bits32(rotated, 7, 0))) 8590 return false; 8591 } 8592 return true; 8593 } 8594 8595 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and 8596 // writes the result to the destination 8597 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8598 // extracting the 16-bit value. 8599 bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode, 8600 const ARMEncoding encoding) { 8601 #if 0 8602 if ConditionPassed() then 8603 EncodingSpecificOperations(); 8604 rotated = ROR(R[m], rotation); 8605 R[d] = ZeroExtend(rotated<15:0>, 32); 8606 #endif 8607 8608 bool success = false; 8609 8610 if (ConditionPassed(opcode)) { 8611 uint32_t d; 8612 uint32_t m; 8613 uint32_t rotation; 8614 8615 switch (encoding) { 8616 case eEncodingT1: 8617 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8618 d = Bits32(opcode, 2, 0); 8619 m = Bits32(opcode, 5, 3); 8620 rotation = 0; 8621 8622 break; 8623 8624 case eEncodingT2: 8625 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8626 d = Bits32(opcode, 11, 8); 8627 m = Bits32(opcode, 3, 0); 8628 rotation = Bits32(opcode, 5, 4) << 3; 8629 8630 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8631 if (BadReg(d) || BadReg(m)) 8632 return false; 8633 8634 break; 8635 8636 case eEncodingA1: 8637 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8638 d = Bits32(opcode, 15, 12); 8639 m = Bits32(opcode, 3, 0); 8640 rotation = Bits32(opcode, 11, 10) << 3; 8641 8642 // if d == 15 || m == 15 then UNPREDICTABLE; 8643 if ((d == 15) || (m == 15)) 8644 return false; 8645 8646 break; 8647 8648 default: 8649 return false; 8650 } 8651 8652 uint64_t Rm = 8653 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8654 if (!success) 8655 return false; 8656 8657 // rotated = ROR(R[m], rotation); 8658 uint64_t rotated = ROR(Rm, rotation, &success); 8659 if (!success) 8660 return false; 8661 8662 // R[d] = ZeroExtend(rotated<15:0>, 32); 8663 RegisterInfo source_reg; 8664 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8665 8666 EmulateInstruction::Context context; 8667 context.type = eContextRegisterLoad; 8668 context.SetRegister(source_reg); 8669 8670 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8671 Bits32(rotated, 15, 0))) 8672 return false; 8673 } 8674 return true; 8675 } 8676 8677 // RFE (Return From Exception) loads the PC and the CPSR from the word at the 8678 // specified address and the following 8679 // word respectively. 8680 bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode, 8681 const ARMEncoding encoding) { 8682 #if 0 8683 if ConditionPassed() then 8684 EncodingSpecificOperations(); 8685 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8686 UNPREDICTABLE; 8687 else 8688 address = if increment then R[n] else R[n]-8; 8689 if wordhigher then address = address+4; 8690 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8691 BranchWritePC(MemA[address,4]); 8692 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8693 #endif 8694 8695 bool success = false; 8696 8697 if (ConditionPassed(opcode)) { 8698 uint32_t n; 8699 bool wback; 8700 bool increment; 8701 bool wordhigher; 8702 8703 // EncodingSpecificOperations(); 8704 switch (encoding) { 8705 case eEncodingT1: 8706 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = 8707 // FALSE; 8708 n = Bits32(opcode, 19, 16); 8709 wback = BitIsSet(opcode, 21); 8710 increment = false; 8711 wordhigher = false; 8712 8713 // if n == 15 then UNPREDICTABLE; 8714 if (n == 15) 8715 return false; 8716 8717 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8718 if (InITBlock() && !LastInITBlock()) 8719 return false; 8720 8721 break; 8722 8723 case eEncodingT2: 8724 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8725 n = Bits32(opcode, 19, 16); 8726 wback = BitIsSet(opcode, 21); 8727 increment = true; 8728 wordhigher = false; 8729 8730 // if n == 15 then UNPREDICTABLE; 8731 if (n == 15) 8732 return false; 8733 8734 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8735 if (InITBlock() && !LastInITBlock()) 8736 return false; 8737 8738 break; 8739 8740 case eEncodingA1: 8741 // n = UInt(Rn); 8742 n = Bits32(opcode, 19, 16); 8743 8744 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8745 wback = BitIsSet(opcode, 21); 8746 increment = BitIsSet(opcode, 23); 8747 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23)); 8748 8749 // if n == 15 then UNPREDICTABLE; 8750 if (n == 15) 8751 return false; 8752 8753 break; 8754 8755 default: 8756 return false; 8757 } 8758 8759 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE 8760 // then 8761 if (!CurrentModeIsPrivileged()) 8762 // UNPREDICTABLE; 8763 return false; 8764 else { 8765 uint64_t Rn = 8766 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8767 if (!success) 8768 return false; 8769 8770 addr_t address; 8771 // address = if increment then R[n] else R[n]-8; 8772 if (increment) 8773 address = Rn; 8774 else 8775 address = Rn - 8; 8776 8777 // if wordhigher then address = address+4; 8778 if (wordhigher) 8779 address = address + 4; 8780 8781 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8782 RegisterInfo base_reg; 8783 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8784 8785 EmulateInstruction::Context context; 8786 context.type = eContextReturnFromException; 8787 context.SetRegisterPlusOffset(base_reg, address - Rn); 8788 8789 uint64_t data = MemARead(context, address + 4, 4, 0, &success); 8790 if (!success) 8791 return false; 8792 8793 CPSRWriteByInstr(data, 15, true); 8794 8795 // BranchWritePC(MemA[address,4]); 8796 uint64_t data2 = MemARead(context, address, 4, 0, &success); 8797 if (!success) 8798 return false; 8799 8800 BranchWritePC(context, data2); 8801 8802 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8803 if (wback) { 8804 context.type = eContextAdjustBaseRegister; 8805 if (increment) { 8806 context.SetOffset(8); 8807 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8808 Rn + 8)) 8809 return false; 8810 } else { 8811 context.SetOffset(-8); 8812 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8813 Rn - 8)) 8814 return false; 8815 } 8816 } // if wback 8817 } 8818 } // if ConditionPassed() 8819 return true; 8820 } 8821 8822 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a 8823 // register value and an immediate value, and writes the result to the 8824 // destination register. It can optionally update the condition flags based on 8825 // the result. 8826 bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode, 8827 const ARMEncoding encoding) { 8828 #if 0 8829 // ARM pseudo code... 8830 if ConditionPassed() then 8831 EncodingSpecificOperations(); 8832 result = R[n] EOR imm32; 8833 if d == 15 then // Can only occur for ARM encoding 8834 ALUWritePC(result); // setflags is always FALSE here 8835 else 8836 R[d] = result; 8837 if setflags then 8838 APSR.N = result<31>; 8839 APSR.Z = IsZeroBit(result); 8840 APSR.C = carry; 8841 // APSR.V unchanged 8842 #endif 8843 8844 bool success = false; 8845 8846 if (ConditionPassed(opcode)) { 8847 uint32_t Rd, Rn; 8848 uint32_t 8849 imm32; // the immediate value to be ORed to the value obtained from Rn 8850 bool setflags; 8851 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8852 switch (encoding) { 8853 case eEncodingT1: 8854 Rd = Bits32(opcode, 11, 8); 8855 Rn = Bits32(opcode, 19, 16); 8856 setflags = BitIsSet(opcode, 20); 8857 imm32 = ThumbExpandImm_C( 8858 opcode, APSR_C, 8859 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8860 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8861 if (Rd == 15 && setflags) 8862 return EmulateTEQImm(opcode, eEncodingT1); 8863 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8864 return false; 8865 break; 8866 case eEncodingA1: 8867 Rd = Bits32(opcode, 15, 12); 8868 Rn = Bits32(opcode, 19, 16); 8869 setflags = BitIsSet(opcode, 20); 8870 imm32 = 8871 ARMExpandImm_C(opcode, APSR_C, 8872 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8873 8874 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8875 // instructions; 8876 if (Rd == 15 && setflags) 8877 return EmulateSUBSPcLrEtc(opcode, encoding); 8878 break; 8879 default: 8880 return false; 8881 } 8882 8883 // Read the first operand. 8884 uint32_t val1 = ReadCoreReg(Rn, &success); 8885 if (!success) 8886 return false; 8887 8888 uint32_t result = val1 ^ imm32; 8889 8890 EmulateInstruction::Context context; 8891 context.type = EmulateInstruction::eContextImmediate; 8892 context.SetNoArgs(); 8893 8894 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8895 return false; 8896 } 8897 return true; 8898 } 8899 8900 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a 8901 // register value and an optionally-shifted register value, and writes the 8902 // result to the destination register. It can optionally update the condition 8903 // flags based on the result. 8904 bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode, 8905 const ARMEncoding encoding) { 8906 #if 0 8907 // ARM pseudo code... 8908 if ConditionPassed() then 8909 EncodingSpecificOperations(); 8910 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8911 result = R[n] EOR shifted; 8912 if d == 15 then // Can only occur for ARM encoding 8913 ALUWritePC(result); // setflags is always FALSE here 8914 else 8915 R[d] = result; 8916 if setflags then 8917 APSR.N = result<31>; 8918 APSR.Z = IsZeroBit(result); 8919 APSR.C = carry; 8920 // APSR.V unchanged 8921 #endif 8922 8923 bool success = false; 8924 8925 if (ConditionPassed(opcode)) { 8926 uint32_t Rd, Rn, Rm; 8927 ARM_ShifterType shift_t; 8928 uint32_t shift_n; // the shift applied to the value read from Rm 8929 bool setflags; 8930 uint32_t carry; 8931 switch (encoding) { 8932 case eEncodingT1: 8933 Rd = Rn = Bits32(opcode, 2, 0); 8934 Rm = Bits32(opcode, 5, 3); 8935 setflags = !InITBlock(); 8936 shift_t = SRType_LSL; 8937 shift_n = 0; 8938 break; 8939 case eEncodingT2: 8940 Rd = Bits32(opcode, 11, 8); 8941 Rn = Bits32(opcode, 19, 16); 8942 Rm = Bits32(opcode, 3, 0); 8943 setflags = BitIsSet(opcode, 20); 8944 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8945 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8946 if (Rd == 15 && setflags) 8947 return EmulateTEQReg(opcode, eEncodingT1); 8948 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8949 return false; 8950 break; 8951 case eEncodingA1: 8952 Rd = Bits32(opcode, 15, 12); 8953 Rn = Bits32(opcode, 19, 16); 8954 Rm = Bits32(opcode, 3, 0); 8955 setflags = BitIsSet(opcode, 20); 8956 shift_n = DecodeImmShiftARM(opcode, shift_t); 8957 8958 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8959 // instructions; 8960 if (Rd == 15 && setflags) 8961 return EmulateSUBSPcLrEtc(opcode, encoding); 8962 break; 8963 default: 8964 return false; 8965 } 8966 8967 // Read the first operand. 8968 uint32_t val1 = ReadCoreReg(Rn, &success); 8969 if (!success) 8970 return false; 8971 8972 // Read the second operand. 8973 uint32_t val2 = ReadCoreReg(Rm, &success); 8974 if (!success) 8975 return false; 8976 8977 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8978 if (!success) 8979 return false; 8980 uint32_t result = val1 ^ shifted; 8981 8982 EmulateInstruction::Context context; 8983 context.type = EmulateInstruction::eContextImmediate; 8984 context.SetNoArgs(); 8985 8986 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8987 return false; 8988 } 8989 return true; 8990 } 8991 8992 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value 8993 // and an immediate value, and writes the result to the destination register. 8994 // It can optionally update the condition flags based on the result. 8995 bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode, 8996 const ARMEncoding encoding) { 8997 #if 0 8998 // ARM pseudo code... 8999 if ConditionPassed() then 9000 EncodingSpecificOperations(); 9001 result = R[n] OR imm32; 9002 if d == 15 then // Can only occur for ARM encoding 9003 ALUWritePC(result); // setflags is always FALSE here 9004 else 9005 R[d] = result; 9006 if setflags then 9007 APSR.N = result<31>; 9008 APSR.Z = IsZeroBit(result); 9009 APSR.C = carry; 9010 // APSR.V unchanged 9011 #endif 9012 9013 bool success = false; 9014 9015 if (ConditionPassed(opcode)) { 9016 uint32_t Rd, Rn; 9017 uint32_t 9018 imm32; // the immediate value to be ORed to the value obtained from Rn 9019 bool setflags; 9020 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9021 switch (encoding) { 9022 case eEncodingT1: 9023 Rd = Bits32(opcode, 11, 8); 9024 Rn = Bits32(opcode, 19, 16); 9025 setflags = BitIsSet(opcode, 20); 9026 imm32 = ThumbExpandImm_C( 9027 opcode, APSR_C, 9028 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9029 // if Rn == '1111' then SEE MOV (immediate); 9030 if (Rn == 15) 9031 return EmulateMOVRdImm(opcode, eEncodingT2); 9032 if (BadReg(Rd) || Rn == 13) 9033 return false; 9034 break; 9035 case eEncodingA1: 9036 Rd = Bits32(opcode, 15, 12); 9037 Rn = Bits32(opcode, 19, 16); 9038 setflags = BitIsSet(opcode, 20); 9039 imm32 = 9040 ARMExpandImm_C(opcode, APSR_C, 9041 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9042 9043 if (Rd == 15 && setflags) 9044 return EmulateSUBSPcLrEtc(opcode, encoding); 9045 break; 9046 default: 9047 return false; 9048 } 9049 9050 // Read the first operand. 9051 uint32_t val1 = ReadCoreReg(Rn, &success); 9052 if (!success) 9053 return false; 9054 9055 uint32_t result = val1 | imm32; 9056 9057 EmulateInstruction::Context context; 9058 context.type = EmulateInstruction::eContextImmediate; 9059 context.SetNoArgs(); 9060 9061 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9062 return false; 9063 } 9064 return true; 9065 } 9066 9067 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value 9068 // and an optionally-shifted register value, and writes the result to the 9069 // destination register. It can optionally update the condition flags based on 9070 // the result. 9071 bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode, 9072 const ARMEncoding encoding) { 9073 #if 0 9074 // ARM pseudo code... 9075 if ConditionPassed() then 9076 EncodingSpecificOperations(); 9077 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9078 result = R[n] OR shifted; 9079 if d == 15 then // Can only occur for ARM encoding 9080 ALUWritePC(result); // setflags is always FALSE here 9081 else 9082 R[d] = result; 9083 if setflags then 9084 APSR.N = result<31>; 9085 APSR.Z = IsZeroBit(result); 9086 APSR.C = carry; 9087 // APSR.V unchanged 9088 #endif 9089 9090 bool success = false; 9091 9092 if (ConditionPassed(opcode)) { 9093 uint32_t Rd, Rn, Rm; 9094 ARM_ShifterType shift_t; 9095 uint32_t shift_n; // the shift applied to the value read from Rm 9096 bool setflags; 9097 uint32_t carry; 9098 switch (encoding) { 9099 case eEncodingT1: 9100 Rd = Rn = Bits32(opcode, 2, 0); 9101 Rm = Bits32(opcode, 5, 3); 9102 setflags = !InITBlock(); 9103 shift_t = SRType_LSL; 9104 shift_n = 0; 9105 break; 9106 case eEncodingT2: 9107 Rd = Bits32(opcode, 11, 8); 9108 Rn = Bits32(opcode, 19, 16); 9109 Rm = Bits32(opcode, 3, 0); 9110 setflags = BitIsSet(opcode, 20); 9111 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9112 // if Rn == '1111' then SEE MOV (register); 9113 if (Rn == 15) 9114 return EmulateMOVRdRm(opcode, eEncodingT3); 9115 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 9116 return false; 9117 break; 9118 case eEncodingA1: 9119 Rd = Bits32(opcode, 15, 12); 9120 Rn = Bits32(opcode, 19, 16); 9121 Rm = Bits32(opcode, 3, 0); 9122 setflags = BitIsSet(opcode, 20); 9123 shift_n = DecodeImmShiftARM(opcode, shift_t); 9124 9125 if (Rd == 15 && setflags) 9126 return EmulateSUBSPcLrEtc(opcode, encoding); 9127 break; 9128 default: 9129 return false; 9130 } 9131 9132 // Read the first operand. 9133 uint32_t val1 = ReadCoreReg(Rn, &success); 9134 if (!success) 9135 return false; 9136 9137 // Read the second operand. 9138 uint32_t val2 = ReadCoreReg(Rm, &success); 9139 if (!success) 9140 return false; 9141 9142 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9143 if (!success) 9144 return false; 9145 uint32_t result = val1 | shifted; 9146 9147 EmulateInstruction::Context context; 9148 context.type = EmulateInstruction::eContextImmediate; 9149 context.SetNoArgs(); 9150 9151 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9152 return false; 9153 } 9154 return true; 9155 } 9156 9157 // Reverse Subtract (immediate) subtracts a register value from an immediate 9158 // value, and writes the result to the destination register. It can optionally 9159 // update the condition flags based on the result. 9160 bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode, 9161 const ARMEncoding encoding) { 9162 #if 0 9163 // ARM pseudo code... 9164 if ConditionPassed() then 9165 EncodingSpecificOperations(); 9166 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 9167 if d == 15 then // Can only occur for ARM encoding 9168 ALUWritePC(result); // setflags is always FALSE here 9169 else 9170 R[d] = result; 9171 if setflags then 9172 APSR.N = result<31>; 9173 APSR.Z = IsZeroBit(result); 9174 APSR.C = carry; 9175 APSR.V = overflow; 9176 #endif 9177 9178 bool success = false; 9179 9180 uint32_t Rd; // the destination register 9181 uint32_t Rn; // the first operand 9182 bool setflags; 9183 uint32_t 9184 imm32; // the immediate value to be added to the value obtained from Rn 9185 switch (encoding) { 9186 case eEncodingT1: 9187 Rd = Bits32(opcode, 2, 0); 9188 Rn = Bits32(opcode, 5, 3); 9189 setflags = !InITBlock(); 9190 imm32 = 0; 9191 break; 9192 case eEncodingT2: 9193 Rd = Bits32(opcode, 11, 8); 9194 Rn = Bits32(opcode, 19, 16); 9195 setflags = BitIsSet(opcode, 20); 9196 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9197 if (BadReg(Rd) || BadReg(Rn)) 9198 return false; 9199 break; 9200 case eEncodingA1: 9201 Rd = Bits32(opcode, 15, 12); 9202 Rn = Bits32(opcode, 19, 16); 9203 setflags = BitIsSet(opcode, 20); 9204 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9205 9206 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9207 // instructions; 9208 if (Rd == 15 && setflags) 9209 return EmulateSUBSPcLrEtc(opcode, encoding); 9210 break; 9211 default: 9212 return false; 9213 } 9214 // Read the register value from the operand register Rn. 9215 uint32_t reg_val = ReadCoreReg(Rn, &success); 9216 if (!success) 9217 return false; 9218 9219 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 9220 9221 EmulateInstruction::Context context; 9222 context.type = EmulateInstruction::eContextImmediate; 9223 context.SetNoArgs(); 9224 9225 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9226 res.carry_out, res.overflow); 9227 } 9228 9229 // Reverse Subtract (register) subtracts a register value from an optionally- 9230 // shifted register value, and writes the result to the destination register. 9231 // It can optionally update the condition flags based on the result. 9232 bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode, 9233 const ARMEncoding encoding) { 9234 #if 0 9235 // ARM pseudo code... 9236 if ConditionPassed() then 9237 EncodingSpecificOperations(); 9238 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9239 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 9240 if d == 15 then // Can only occur for ARM encoding 9241 ALUWritePC(result); // setflags is always FALSE here 9242 else 9243 R[d] = result; 9244 if setflags then 9245 APSR.N = result<31>; 9246 APSR.Z = IsZeroBit(result); 9247 APSR.C = carry; 9248 APSR.V = overflow; 9249 #endif 9250 9251 bool success = false; 9252 9253 uint32_t Rd; // the destination register 9254 uint32_t Rn; // the first operand 9255 uint32_t Rm; // the second operand 9256 bool setflags; 9257 ARM_ShifterType shift_t; 9258 uint32_t shift_n; // the shift applied to the value read from Rm 9259 switch (encoding) { 9260 case eEncodingT1: 9261 Rd = Bits32(opcode, 11, 8); 9262 Rn = Bits32(opcode, 19, 16); 9263 Rm = Bits32(opcode, 3, 0); 9264 setflags = BitIsSet(opcode, 20); 9265 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9266 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 9267 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9268 return false; 9269 break; 9270 case eEncodingA1: 9271 Rd = Bits32(opcode, 15, 12); 9272 Rn = Bits32(opcode, 19, 16); 9273 Rm = Bits32(opcode, 3, 0); 9274 setflags = BitIsSet(opcode, 20); 9275 shift_n = DecodeImmShiftARM(opcode, shift_t); 9276 9277 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9278 // instructions; 9279 if (Rd == 15 && setflags) 9280 return EmulateSUBSPcLrEtc(opcode, encoding); 9281 break; 9282 default: 9283 return false; 9284 } 9285 // Read the register value from register Rn. 9286 uint32_t val1 = ReadCoreReg(Rn, &success); 9287 if (!success) 9288 return false; 9289 9290 // Read the register value from register Rm. 9291 uint32_t val2 = ReadCoreReg(Rm, &success); 9292 if (!success) 9293 return false; 9294 9295 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9296 if (!success) 9297 return false; 9298 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 9299 9300 EmulateInstruction::Context context; 9301 context.type = EmulateInstruction::eContextImmediate; 9302 context.SetNoArgs(); 9303 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9304 res.carry_out, res.overflow); 9305 } 9306 9307 // Reverse Subtract with Carry (immediate) subtracts a register value and the 9308 // value of NOT (Carry flag) from an immediate value, and writes the result to 9309 // the destination register. It can optionally update the condition flags based 9310 // on the result. 9311 bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode, 9312 const ARMEncoding encoding) { 9313 #if 0 9314 // ARM pseudo code... 9315 if ConditionPassed() then 9316 EncodingSpecificOperations(); 9317 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 9318 if d == 15 then 9319 ALUWritePC(result); // setflags is always FALSE here 9320 else 9321 R[d] = result; 9322 if setflags then 9323 APSR.N = result<31>; 9324 APSR.Z = IsZeroBit(result); 9325 APSR.C = carry; 9326 APSR.V = overflow; 9327 #endif 9328 9329 bool success = false; 9330 9331 uint32_t Rd; // the destination register 9332 uint32_t Rn; // the first operand 9333 bool setflags; 9334 uint32_t 9335 imm32; // the immediate value to be added to the value obtained from Rn 9336 switch (encoding) { 9337 case eEncodingA1: 9338 Rd = Bits32(opcode, 15, 12); 9339 Rn = Bits32(opcode, 19, 16); 9340 setflags = BitIsSet(opcode, 20); 9341 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9342 9343 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9344 // instructions; 9345 if (Rd == 15 && setflags) 9346 return EmulateSUBSPcLrEtc(opcode, encoding); 9347 break; 9348 default: 9349 return false; 9350 } 9351 // Read the register value from the operand register Rn. 9352 uint32_t reg_val = ReadCoreReg(Rn, &success); 9353 if (!success) 9354 return false; 9355 9356 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 9357 9358 EmulateInstruction::Context context; 9359 context.type = EmulateInstruction::eContextImmediate; 9360 context.SetNoArgs(); 9361 9362 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9363 res.carry_out, res.overflow); 9364 } 9365 9366 // Reverse Subtract with Carry (register) subtracts a register value and the 9367 // value of NOT (Carry flag) from an optionally-shifted register value, and 9368 // writes the result to the destination register. It can optionally update the 9369 // condition flags based on the result. 9370 bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode, 9371 const ARMEncoding encoding) { 9372 #if 0 9373 // ARM pseudo code... 9374 if ConditionPassed() then 9375 EncodingSpecificOperations(); 9376 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9377 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 9378 if d == 15 then 9379 ALUWritePC(result); // setflags is always FALSE here 9380 else 9381 R[d] = result; 9382 if setflags then 9383 APSR.N = result<31>; 9384 APSR.Z = IsZeroBit(result); 9385 APSR.C = carry; 9386 APSR.V = overflow; 9387 #endif 9388 9389 bool success = false; 9390 9391 uint32_t Rd; // the destination register 9392 uint32_t Rn; // the first operand 9393 uint32_t Rm; // the second operand 9394 bool setflags; 9395 ARM_ShifterType shift_t; 9396 uint32_t shift_n; // the shift applied to the value read from Rm 9397 switch (encoding) { 9398 case eEncodingA1: 9399 Rd = Bits32(opcode, 15, 12); 9400 Rn = Bits32(opcode, 19, 16); 9401 Rm = Bits32(opcode, 3, 0); 9402 setflags = BitIsSet(opcode, 20); 9403 shift_n = DecodeImmShiftARM(opcode, shift_t); 9404 9405 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9406 // instructions; 9407 if (Rd == 15 && setflags) 9408 return EmulateSUBSPcLrEtc(opcode, encoding); 9409 break; 9410 default: 9411 return false; 9412 } 9413 // Read the register value from register Rn. 9414 uint32_t val1 = ReadCoreReg(Rn, &success); 9415 if (!success) 9416 return false; 9417 9418 // Read the register value from register Rm. 9419 uint32_t val2 = ReadCoreReg(Rm, &success); 9420 if (!success) 9421 return false; 9422 9423 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9424 if (!success) 9425 return false; 9426 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 9427 9428 EmulateInstruction::Context context; 9429 context.type = EmulateInstruction::eContextImmediate; 9430 context.SetNoArgs(); 9431 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9432 res.carry_out, res.overflow); 9433 } 9434 9435 // Subtract with Carry (immediate) subtracts an immediate value and the value 9436 // of 9437 // NOT (Carry flag) from a register value, and writes the result to the 9438 // destination register. 9439 // It can optionally update the condition flags based on the result. 9440 bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode, 9441 const ARMEncoding encoding) { 9442 #if 0 9443 // ARM pseudo code... 9444 if ConditionPassed() then 9445 EncodingSpecificOperations(); 9446 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 9447 if d == 15 then // Can only occur for ARM encoding 9448 ALUWritePC(result); // setflags is always FALSE here 9449 else 9450 R[d] = result; 9451 if setflags then 9452 APSR.N = result<31>; 9453 APSR.Z = IsZeroBit(result); 9454 APSR.C = carry; 9455 APSR.V = overflow; 9456 #endif 9457 9458 bool success = false; 9459 9460 uint32_t Rd; // the destination register 9461 uint32_t Rn; // the first operand 9462 bool setflags; 9463 uint32_t 9464 imm32; // the immediate value to be added to the value obtained from Rn 9465 switch (encoding) { 9466 case eEncodingT1: 9467 Rd = Bits32(opcode, 11, 8); 9468 Rn = Bits32(opcode, 19, 16); 9469 setflags = BitIsSet(opcode, 20); 9470 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9471 if (BadReg(Rd) || BadReg(Rn)) 9472 return false; 9473 break; 9474 case eEncodingA1: 9475 Rd = Bits32(opcode, 15, 12); 9476 Rn = Bits32(opcode, 19, 16); 9477 setflags = BitIsSet(opcode, 20); 9478 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9479 9480 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9481 // instructions; 9482 if (Rd == 15 && setflags) 9483 return EmulateSUBSPcLrEtc(opcode, encoding); 9484 break; 9485 default: 9486 return false; 9487 } 9488 // Read the register value from the operand register Rn. 9489 uint32_t reg_val = ReadCoreReg(Rn, &success); 9490 if (!success) 9491 return false; 9492 9493 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9494 9495 EmulateInstruction::Context context; 9496 context.type = EmulateInstruction::eContextImmediate; 9497 context.SetNoArgs(); 9498 9499 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9500 res.carry_out, res.overflow); 9501 } 9502 9503 // Subtract with Carry (register) subtracts an optionally-shifted register 9504 // value and the value of 9505 // NOT (Carry flag) from a register value, and writes the result to the 9506 // destination register. 9507 // It can optionally update the condition flags based on the result. 9508 bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode, 9509 const ARMEncoding encoding) { 9510 #if 0 9511 // ARM pseudo code... 9512 if ConditionPassed() then 9513 EncodingSpecificOperations(); 9514 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9515 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9516 if d == 15 then // Can only occur for ARM encoding 9517 ALUWritePC(result); // setflags is always FALSE here 9518 else 9519 R[d] = result; 9520 if setflags then 9521 APSR.N = result<31>; 9522 APSR.Z = IsZeroBit(result); 9523 APSR.C = carry; 9524 APSR.V = overflow; 9525 #endif 9526 9527 bool success = false; 9528 9529 uint32_t Rd; // the destination register 9530 uint32_t Rn; // the first operand 9531 uint32_t Rm; // the second operand 9532 bool setflags; 9533 ARM_ShifterType shift_t; 9534 uint32_t shift_n; // the shift applied to the value read from Rm 9535 switch (encoding) { 9536 case eEncodingT1: 9537 Rd = Rn = Bits32(opcode, 2, 0); 9538 Rm = Bits32(opcode, 5, 3); 9539 setflags = !InITBlock(); 9540 shift_t = SRType_LSL; 9541 shift_n = 0; 9542 break; 9543 case eEncodingT2: 9544 Rd = Bits32(opcode, 11, 8); 9545 Rn = Bits32(opcode, 19, 16); 9546 Rm = Bits32(opcode, 3, 0); 9547 setflags = BitIsSet(opcode, 20); 9548 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9549 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9550 return false; 9551 break; 9552 case eEncodingA1: 9553 Rd = Bits32(opcode, 15, 12); 9554 Rn = Bits32(opcode, 19, 16); 9555 Rm = Bits32(opcode, 3, 0); 9556 setflags = BitIsSet(opcode, 20); 9557 shift_n = DecodeImmShiftARM(opcode, shift_t); 9558 9559 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9560 // instructions; 9561 if (Rd == 15 && setflags) 9562 return EmulateSUBSPcLrEtc(opcode, encoding); 9563 break; 9564 default: 9565 return false; 9566 } 9567 // Read the register value from register Rn. 9568 uint32_t val1 = ReadCoreReg(Rn, &success); 9569 if (!success) 9570 return false; 9571 9572 // Read the register value from register Rm. 9573 uint32_t val2 = ReadCoreReg(Rm, &success); 9574 if (!success) 9575 return false; 9576 9577 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9578 if (!success) 9579 return false; 9580 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9581 9582 EmulateInstruction::Context context; 9583 context.type = EmulateInstruction::eContextImmediate; 9584 context.SetNoArgs(); 9585 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9586 res.carry_out, res.overflow); 9587 } 9588 9589 // This instruction subtracts an immediate value from a register value, and 9590 // writes the result to the destination register. It can optionally update the 9591 // condition flags based on the result. 9592 bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode, 9593 const ARMEncoding encoding) { 9594 #if 0 9595 // ARM pseudo code... 9596 if ConditionPassed() then 9597 EncodingSpecificOperations(); 9598 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9599 R[d] = result; 9600 if setflags then 9601 APSR.N = result<31>; 9602 APSR.Z = IsZeroBit(result); 9603 APSR.C = carry; 9604 APSR.V = overflow; 9605 #endif 9606 9607 bool success = false; 9608 9609 uint32_t Rd; // the destination register 9610 uint32_t Rn; // the first operand 9611 bool setflags; 9612 uint32_t imm32; // the immediate value to be subtracted from the value 9613 // obtained from Rn 9614 switch (encoding) { 9615 case eEncodingT1: 9616 Rd = Bits32(opcode, 2, 0); 9617 Rn = Bits32(opcode, 5, 3); 9618 setflags = !InITBlock(); 9619 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9620 break; 9621 case eEncodingT2: 9622 Rd = Rn = Bits32(opcode, 10, 8); 9623 setflags = !InITBlock(); 9624 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9625 break; 9626 case eEncodingT3: 9627 Rd = Bits32(opcode, 11, 8); 9628 Rn = Bits32(opcode, 19, 16); 9629 setflags = BitIsSet(opcode, 20); 9630 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9631 9632 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9633 if (Rd == 15 && setflags) 9634 return EmulateCMPImm(opcode, eEncodingT2); 9635 9636 // if Rn == '1101' then SEE SUB (SP minus immediate); 9637 if (Rn == 13) 9638 return EmulateSUBSPImm(opcode, eEncodingT2); 9639 9640 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9641 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9642 return false; 9643 break; 9644 case eEncodingT4: 9645 Rd = Bits32(opcode, 11, 8); 9646 Rn = Bits32(opcode, 19, 16); 9647 setflags = BitIsSet(opcode, 20); 9648 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9649 9650 // if Rn == '1111' then SEE ADR; 9651 if (Rn == 15) 9652 return EmulateADR(opcode, eEncodingT2); 9653 9654 // if Rn == '1101' then SEE SUB (SP minus immediate); 9655 if (Rn == 13) 9656 return EmulateSUBSPImm(opcode, eEncodingT3); 9657 9658 if (BadReg(Rd)) 9659 return false; 9660 break; 9661 default: 9662 return false; 9663 } 9664 // Read the register value from the operand register Rn. 9665 uint32_t reg_val = ReadCoreReg(Rn, &success); 9666 if (!success) 9667 return false; 9668 9669 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9670 9671 EmulateInstruction::Context context; 9672 context.type = EmulateInstruction::eContextImmediate; 9673 context.SetNoArgs(); 9674 9675 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9676 res.carry_out, res.overflow); 9677 } 9678 9679 // This instruction subtracts an immediate value from a register value, and 9680 // writes the result to the destination register. It can optionally update the 9681 // condition flags based on the result. 9682 bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode, 9683 const ARMEncoding encoding) { 9684 #if 0 9685 // ARM pseudo code... 9686 if ConditionPassed() then 9687 EncodingSpecificOperations(); 9688 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9689 if d == 15 then 9690 ALUWritePC(result); // setflags is always FALSE here 9691 else 9692 R[d] = result; 9693 if setflags then 9694 APSR.N = result<31>; 9695 APSR.Z = IsZeroBit(result); 9696 APSR.C = carry; 9697 APSR.V = overflow; 9698 #endif 9699 9700 bool success = false; 9701 9702 if (ConditionPassed(opcode)) { 9703 uint32_t Rd; // the destination register 9704 uint32_t Rn; // the first operand 9705 bool setflags; 9706 uint32_t imm32; // the immediate value to be subtracted from the value 9707 // obtained from Rn 9708 switch (encoding) { 9709 case eEncodingA1: 9710 Rd = Bits32(opcode, 15, 12); 9711 Rn = Bits32(opcode, 19, 16); 9712 setflags = BitIsSet(opcode, 20); 9713 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9714 9715 // if Rn == '1111' && S == '0' then SEE ADR; 9716 if (Rn == 15 && !setflags) 9717 return EmulateADR(opcode, eEncodingA2); 9718 9719 // if Rn == '1101' then SEE SUB (SP minus immediate); 9720 if (Rn == 13) 9721 return EmulateSUBSPImm(opcode, eEncodingA1); 9722 9723 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9724 // instructions; 9725 if (Rd == 15 && setflags) 9726 return EmulateSUBSPcLrEtc(opcode, encoding); 9727 break; 9728 default: 9729 return false; 9730 } 9731 // Read the register value from the operand register Rn. 9732 uint32_t reg_val = ReadCoreReg(Rn, &success); 9733 if (!success) 9734 return false; 9735 9736 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9737 9738 EmulateInstruction::Context context; 9739 if (Rd == 13) 9740 context.type = EmulateInstruction::eContextAdjustStackPointer; 9741 else 9742 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9743 9744 RegisterInfo dwarf_reg; 9745 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 9746 int64_t imm32_signed = imm32; 9747 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed); 9748 9749 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9750 res.carry_out, res.overflow)) 9751 return false; 9752 } 9753 return true; 9754 } 9755 9756 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a 9757 // register value and an immediate value. It updates the condition flags based 9758 // on the result, and discards the result. 9759 bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode, 9760 const ARMEncoding encoding) { 9761 #if 0 9762 // ARM pseudo code... 9763 if ConditionPassed() then 9764 EncodingSpecificOperations(); 9765 result = R[n] EOR imm32; 9766 APSR.N = result<31>; 9767 APSR.Z = IsZeroBit(result); 9768 APSR.C = carry; 9769 // APSR.V unchanged 9770 #endif 9771 9772 bool success = false; 9773 9774 if (ConditionPassed(opcode)) { 9775 uint32_t Rn; 9776 uint32_t 9777 imm32; // the immediate value to be ANDed to the value obtained from Rn 9778 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9779 switch (encoding) { 9780 case eEncodingT1: 9781 Rn = Bits32(opcode, 19, 16); 9782 imm32 = ThumbExpandImm_C( 9783 opcode, APSR_C, 9784 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9785 if (BadReg(Rn)) 9786 return false; 9787 break; 9788 case eEncodingA1: 9789 Rn = Bits32(opcode, 19, 16); 9790 imm32 = 9791 ARMExpandImm_C(opcode, APSR_C, 9792 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9793 break; 9794 default: 9795 return false; 9796 } 9797 9798 // Read the first operand. 9799 uint32_t val1 = ReadCoreReg(Rn, &success); 9800 if (!success) 9801 return false; 9802 9803 uint32_t result = val1 ^ imm32; 9804 9805 EmulateInstruction::Context context; 9806 context.type = EmulateInstruction::eContextImmediate; 9807 context.SetNoArgs(); 9808 9809 if (!WriteFlags(context, result, carry)) 9810 return false; 9811 } 9812 return true; 9813 } 9814 9815 // Test Equivalence (register) performs a bitwise exclusive OR operation on a 9816 // register value and an optionally-shifted register value. It updates the 9817 // condition flags based on the result, and discards the result. 9818 bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode, 9819 const ARMEncoding encoding) { 9820 #if 0 9821 // ARM pseudo code... 9822 if ConditionPassed() then 9823 EncodingSpecificOperations(); 9824 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9825 result = R[n] EOR shifted; 9826 APSR.N = result<31>; 9827 APSR.Z = IsZeroBit(result); 9828 APSR.C = carry; 9829 // APSR.V unchanged 9830 #endif 9831 9832 bool success = false; 9833 9834 if (ConditionPassed(opcode)) { 9835 uint32_t Rn, Rm; 9836 ARM_ShifterType shift_t; 9837 uint32_t shift_n; // the shift applied to the value read from Rm 9838 uint32_t carry; 9839 switch (encoding) { 9840 case eEncodingT1: 9841 Rn = Bits32(opcode, 19, 16); 9842 Rm = Bits32(opcode, 3, 0); 9843 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9844 if (BadReg(Rn) || BadReg(Rm)) 9845 return false; 9846 break; 9847 case eEncodingA1: 9848 Rn = Bits32(opcode, 19, 16); 9849 Rm = Bits32(opcode, 3, 0); 9850 shift_n = DecodeImmShiftARM(opcode, shift_t); 9851 break; 9852 default: 9853 return false; 9854 } 9855 9856 // Read the first operand. 9857 uint32_t val1 = ReadCoreReg(Rn, &success); 9858 if (!success) 9859 return false; 9860 9861 // Read the second operand. 9862 uint32_t val2 = ReadCoreReg(Rm, &success); 9863 if (!success) 9864 return false; 9865 9866 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9867 if (!success) 9868 return false; 9869 uint32_t result = val1 ^ shifted; 9870 9871 EmulateInstruction::Context context; 9872 context.type = EmulateInstruction::eContextImmediate; 9873 context.SetNoArgs(); 9874 9875 if (!WriteFlags(context, result, carry)) 9876 return false; 9877 } 9878 return true; 9879 } 9880 9881 // Test (immediate) performs a bitwise AND operation on a register value and an 9882 // immediate value. It updates the condition flags based on the result, and 9883 // discards the result. 9884 bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode, 9885 const ARMEncoding encoding) { 9886 #if 0 9887 // ARM pseudo code... 9888 if ConditionPassed() then 9889 EncodingSpecificOperations(); 9890 result = R[n] AND imm32; 9891 APSR.N = result<31>; 9892 APSR.Z = IsZeroBit(result); 9893 APSR.C = carry; 9894 // APSR.V unchanged 9895 #endif 9896 9897 bool success = false; 9898 9899 if (ConditionPassed(opcode)) { 9900 uint32_t Rn; 9901 uint32_t 9902 imm32; // the immediate value to be ANDed to the value obtained from Rn 9903 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9904 switch (encoding) { 9905 case eEncodingT1: 9906 Rn = Bits32(opcode, 19, 16); 9907 imm32 = ThumbExpandImm_C( 9908 opcode, APSR_C, 9909 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9910 if (BadReg(Rn)) 9911 return false; 9912 break; 9913 case eEncodingA1: 9914 Rn = Bits32(opcode, 19, 16); 9915 imm32 = 9916 ARMExpandImm_C(opcode, APSR_C, 9917 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9918 break; 9919 default: 9920 return false; 9921 } 9922 9923 // Read the first operand. 9924 uint32_t val1 = ReadCoreReg(Rn, &success); 9925 if (!success) 9926 return false; 9927 9928 uint32_t result = val1 & imm32; 9929 9930 EmulateInstruction::Context context; 9931 context.type = EmulateInstruction::eContextImmediate; 9932 context.SetNoArgs(); 9933 9934 if (!WriteFlags(context, result, carry)) 9935 return false; 9936 } 9937 return true; 9938 } 9939 9940 // Test (register) performs a bitwise AND operation on a register value and an 9941 // optionally-shifted register value. It updates the condition flags based on 9942 // the result, and discards the result. 9943 bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode, 9944 const ARMEncoding encoding) { 9945 #if 0 9946 // ARM pseudo code... 9947 if ConditionPassed() then 9948 EncodingSpecificOperations(); 9949 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9950 result = R[n] AND shifted; 9951 APSR.N = result<31>; 9952 APSR.Z = IsZeroBit(result); 9953 APSR.C = carry; 9954 // APSR.V unchanged 9955 #endif 9956 9957 bool success = false; 9958 9959 if (ConditionPassed(opcode)) { 9960 uint32_t Rn, Rm; 9961 ARM_ShifterType shift_t; 9962 uint32_t shift_n; // the shift applied to the value read from Rm 9963 uint32_t carry; 9964 switch (encoding) { 9965 case eEncodingT1: 9966 Rn = Bits32(opcode, 2, 0); 9967 Rm = Bits32(opcode, 5, 3); 9968 shift_t = SRType_LSL; 9969 shift_n = 0; 9970 break; 9971 case eEncodingT2: 9972 Rn = Bits32(opcode, 19, 16); 9973 Rm = Bits32(opcode, 3, 0); 9974 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9975 if (BadReg(Rn) || BadReg(Rm)) 9976 return false; 9977 break; 9978 case eEncodingA1: 9979 Rn = Bits32(opcode, 19, 16); 9980 Rm = Bits32(opcode, 3, 0); 9981 shift_n = DecodeImmShiftARM(opcode, shift_t); 9982 break; 9983 default: 9984 return false; 9985 } 9986 9987 // Read the first operand. 9988 uint32_t val1 = ReadCoreReg(Rn, &success); 9989 if (!success) 9990 return false; 9991 9992 // Read the second operand. 9993 uint32_t val2 = ReadCoreReg(Rm, &success); 9994 if (!success) 9995 return false; 9996 9997 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9998 if (!success) 9999 return false; 10000 uint32_t result = val1 & shifted; 10001 10002 EmulateInstruction::Context context; 10003 context.type = EmulateInstruction::eContextImmediate; 10004 context.SetNoArgs(); 10005 10006 if (!WriteFlags(context, result, carry)) 10007 return false; 10008 } 10009 return true; 10010 } 10011 10012 // A8.6.216 SUB (SP minus register) 10013 bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode, 10014 const ARMEncoding encoding) { 10015 #if 0 10016 if ConditionPassed() then 10017 EncodingSpecificOperations(); 10018 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10019 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10020 if d == 15 then // Can only occur for ARM encoding 10021 ALUWritePC(result); // setflags is always FALSE here 10022 else 10023 R[d] = result; 10024 if setflags then 10025 APSR.N = result<31>; 10026 APSR.Z = IsZeroBit(result); 10027 APSR.C = carry; 10028 APSR.V = overflow; 10029 #endif 10030 10031 bool success = false; 10032 10033 if (ConditionPassed(opcode)) { 10034 uint32_t d; 10035 uint32_t m; 10036 bool setflags; 10037 ARM_ShifterType shift_t; 10038 uint32_t shift_n; 10039 10040 switch (encoding) { 10041 case eEncodingT1: 10042 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10043 d = Bits32(opcode, 11, 8); 10044 m = Bits32(opcode, 3, 0); 10045 setflags = BitIsSet(opcode, 20); 10046 10047 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10048 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10049 10050 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then 10051 // UNPREDICTABLE; 10052 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 10053 return false; 10054 10055 // if d == 15 || BadReg(m) then UNPREDICTABLE; 10056 if ((d == 15) || BadReg(m)) 10057 return false; 10058 break; 10059 10060 case eEncodingA1: 10061 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10062 d = Bits32(opcode, 15, 12); 10063 m = Bits32(opcode, 3, 0); 10064 setflags = BitIsSet(opcode, 20); 10065 10066 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10067 // instructions; 10068 if (d == 15 && setflags) 10069 EmulateSUBSPcLrEtc(opcode, encoding); 10070 10071 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10072 shift_n = DecodeImmShiftARM(opcode, shift_t); 10073 break; 10074 10075 default: 10076 return false; 10077 } 10078 10079 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10080 uint32_t Rm = ReadCoreReg(m, &success); 10081 if (!success) 10082 return false; 10083 10084 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10085 if (!success) 10086 return false; 10087 10088 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10089 uint32_t sp_val = ReadCoreReg(SP_REG, &success); 10090 if (!success) 10091 return false; 10092 10093 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1); 10094 10095 EmulateInstruction::Context context; 10096 context.type = eContextArithmetic; 10097 RegisterInfo sp_reg; 10098 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 10099 RegisterInfo dwarf_reg; 10100 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 10101 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg); 10102 10103 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10104 res.carry_out, res.overflow)) 10105 return false; 10106 } 10107 return true; 10108 } 10109 10110 // A8.6.7 ADD (register-shifted register) 10111 bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode, 10112 const ARMEncoding encoding) { 10113 #if 0 10114 if ConditionPassed() then 10115 EncodingSpecificOperations(); 10116 shift_n = UInt(R[s]<7:0>); 10117 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10118 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10119 R[d] = result; 10120 if setflags then 10121 APSR.N = result<31>; 10122 APSR.Z = IsZeroBit(result); 10123 APSR.C = carry; 10124 APSR.V = overflow; 10125 #endif 10126 10127 bool success = false; 10128 10129 if (ConditionPassed(opcode)) { 10130 uint32_t d; 10131 uint32_t n; 10132 uint32_t m; 10133 uint32_t s; 10134 bool setflags; 10135 ARM_ShifterType shift_t; 10136 10137 switch (encoding) { 10138 case eEncodingA1: 10139 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 10140 d = Bits32(opcode, 15, 12); 10141 n = Bits32(opcode, 19, 16); 10142 m = Bits32(opcode, 3, 0); 10143 s = Bits32(opcode, 11, 8); 10144 10145 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 10146 setflags = BitIsSet(opcode, 20); 10147 shift_t = DecodeRegShift(Bits32(opcode, 6, 5)); 10148 10149 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 10150 if ((d == 15) || (n == 15) || (m == 15) || (s == 15)) 10151 return false; 10152 break; 10153 10154 default: 10155 return false; 10156 } 10157 10158 // shift_n = UInt(R[s]<7:0>); 10159 uint32_t Rs = ReadCoreReg(s, &success); 10160 if (!success) 10161 return false; 10162 10163 uint32_t shift_n = Bits32(Rs, 7, 0); 10164 10165 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10166 uint32_t Rm = ReadCoreReg(m, &success); 10167 if (!success) 10168 return false; 10169 10170 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10171 if (!success) 10172 return false; 10173 10174 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10175 uint32_t Rn = ReadCoreReg(n, &success); 10176 if (!success) 10177 return false; 10178 10179 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0); 10180 10181 // R[d] = result; 10182 EmulateInstruction::Context context; 10183 context.type = eContextArithmetic; 10184 RegisterInfo reg_n; 10185 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10186 RegisterInfo reg_m; 10187 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10188 10189 context.SetRegisterRegisterOperands(reg_n, reg_m); 10190 10191 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 10192 res.result)) 10193 return false; 10194 10195 // if setflags then 10196 // APSR.N = result<31>; 10197 // APSR.Z = IsZeroBit(result); 10198 // APSR.C = carry; 10199 // APSR.V = overflow; 10200 if (setflags) 10201 return WriteFlags(context, res.result, res.carry_out, res.overflow); 10202 } 10203 return true; 10204 } 10205 10206 // A8.6.213 SUB (register) 10207 bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode, 10208 const ARMEncoding encoding) { 10209 #if 0 10210 if ConditionPassed() then 10211 EncodingSpecificOperations(); 10212 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10213 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10214 if d == 15 then // Can only occur for ARM encoding 10215 ALUWritePC(result); // setflags is always FALSE here 10216 else 10217 R[d] = result; 10218 if setflags then 10219 APSR.N = result<31>; 10220 APSR.Z = IsZeroBit(result); 10221 APSR.C = carry; 10222 APSR.V = overflow; 10223 #endif 10224 10225 bool success = false; 10226 10227 if (ConditionPassed(opcode)) { 10228 uint32_t d; 10229 uint32_t n; 10230 uint32_t m; 10231 bool setflags; 10232 ARM_ShifterType shift_t; 10233 uint32_t shift_n; 10234 10235 switch (encoding) { 10236 case eEncodingT1: 10237 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 10238 d = Bits32(opcode, 2, 0); 10239 n = Bits32(opcode, 5, 3); 10240 m = Bits32(opcode, 8, 6); 10241 setflags = !InITBlock(); 10242 10243 // (shift_t, shift_n) = (SRType_LSL, 0); 10244 shift_t = SRType_LSL; 10245 shift_n = 0; 10246 10247 break; 10248 10249 case eEncodingT2: 10250 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 10251 d = Bits32(opcode, 11, 8); 10252 n = Bits32(opcode, 19, 16); 10253 m = Bits32(opcode, 3, 0); 10254 setflags = BitIsSet(opcode, 20); 10255 10256 // if Rd == "1111" && S == "1" then SEE CMP (register); 10257 if (d == 15 && setflags == 1) 10258 return EmulateCMPImm(opcode, eEncodingT3); 10259 10260 // if Rn == "1101" then SEE SUB (SP minus register); 10261 if (n == 13) 10262 return EmulateSUBSPReg(opcode, eEncodingT1); 10263 10264 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10265 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10266 10267 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then 10268 // UNPREDICTABLE; 10269 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) || 10270 BadReg(m)) 10271 return false; 10272 10273 break; 10274 10275 case eEncodingA1: 10276 // if Rn == '1101' then SEE SUB (SP minus register); 10277 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 10278 d = Bits32(opcode, 15, 12); 10279 n = Bits32(opcode, 19, 16); 10280 m = Bits32(opcode, 3, 0); 10281 setflags = BitIsSet(opcode, 20); 10282 10283 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10284 // instructions; 10285 if ((d == 15) && setflags) 10286 EmulateSUBSPcLrEtc(opcode, encoding); 10287 10288 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10289 shift_n = DecodeImmShiftARM(opcode, shift_t); 10290 10291 break; 10292 10293 default: 10294 return false; 10295 } 10296 10297 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10298 uint32_t Rm = ReadCoreReg(m, &success); 10299 if (!success) 10300 return false; 10301 10302 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10303 if (!success) 10304 return false; 10305 10306 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10307 uint32_t Rn = ReadCoreReg(n, &success); 10308 if (!success) 10309 return false; 10310 10311 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1); 10312 10313 // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result); 10314 // // setflags is always FALSE here else 10315 // R[d] = result; 10316 // if setflags then 10317 // APSR.N = result<31>; 10318 // APSR.Z = IsZeroBit(result); 10319 // APSR.C = carry; 10320 // APSR.V = overflow; 10321 10322 EmulateInstruction::Context context; 10323 context.type = eContextArithmetic; 10324 RegisterInfo reg_n; 10325 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10326 RegisterInfo reg_m; 10327 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10328 context.SetRegisterRegisterOperands(reg_n, reg_m); 10329 10330 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10331 res.carry_out, res.overflow)) 10332 return false; 10333 } 10334 return true; 10335 } 10336 10337 // A8.6.202 STREX 10338 // Store Register Exclusive calculates an address from a base register value 10339 // and an immediate offset, and stores a word from a register to memory if the 10340 // executing processor has exclusive access to the memory addressed. 10341 bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode, 10342 const ARMEncoding encoding) { 10343 #if 0 10344 if ConditionPassed() then 10345 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10346 address = R[n] + imm32; 10347 if ExclusiveMonitorsPass(address,4) then 10348 MemA[address,4] = R[t]; 10349 R[d] = 0; 10350 else 10351 R[d] = 1; 10352 #endif 10353 10354 bool success = false; 10355 10356 if (ConditionPassed(opcode)) { 10357 uint32_t d; 10358 uint32_t t; 10359 uint32_t n; 10360 uint32_t imm32; 10361 const uint32_t addr_byte_size = GetAddressByteSize(); 10362 10363 switch (encoding) { 10364 case eEncodingT1: 10365 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = 10366 // ZeroExtend(imm8:'00', 10367 // 32); 10368 d = Bits32(opcode, 11, 8); 10369 t = Bits32(opcode, 15, 12); 10370 n = Bits32(opcode, 19, 16); 10371 imm32 = Bits32(opcode, 7, 0) << 2; 10372 10373 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 10374 if (BadReg(d) || BadReg(t) || (n == 15)) 10375 return false; 10376 10377 // if d == n || d == t then UNPREDICTABLE; 10378 if ((d == n) || (d == t)) 10379 return false; 10380 10381 break; 10382 10383 case eEncodingA1: 10384 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero 10385 // offset 10386 d = Bits32(opcode, 15, 12); 10387 t = Bits32(opcode, 3, 0); 10388 n = Bits32(opcode, 19, 16); 10389 imm32 = 0; 10390 10391 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 10392 if ((d == 15) || (t == 15) || (n == 15)) 10393 return false; 10394 10395 // if d == n || d == t then UNPREDICTABLE; 10396 if ((d == n) || (d == t)) 10397 return false; 10398 10399 break; 10400 10401 default: 10402 return false; 10403 } 10404 10405 // address = R[n] + imm32; 10406 uint32_t Rn = ReadCoreReg(n, &success); 10407 if (!success) 10408 return false; 10409 10410 addr_t address = Rn + imm32; 10411 10412 RegisterInfo base_reg; 10413 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10414 RegisterInfo data_reg; 10415 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10416 EmulateInstruction::Context context; 10417 context.type = eContextRegisterStore; 10418 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32); 10419 10420 // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass 10421 // (address, addr_byte_size)) -- For now, for the sake of emulation, we 10422 // will say this 10423 // always return 10424 // true. 10425 if (true) { 10426 // MemA[address,4] = R[t]; 10427 uint32_t Rt = 10428 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 10429 if (!success) 10430 return false; 10431 10432 if (!MemAWrite(context, address, Rt, addr_byte_size)) 10433 return false; 10434 10435 // R[d] = 0; 10436 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 10437 return false; 10438 } 10439 #if 0 // unreachable because if true 10440 else 10441 { 10442 // R[d] = 1; 10443 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 10444 return false; 10445 } 10446 #endif // unreachable because if true 10447 } 10448 return true; 10449 } 10450 10451 // A8.6.197 STRB (immediate, ARM) 10452 bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode, 10453 const ARMEncoding encoding) { 10454 #if 0 10455 if ConditionPassed() then 10456 EncodingSpecificOperations(); 10457 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10458 address = if index then offset_addr else R[n]; 10459 MemU[address,1] = R[t]<7:0>; 10460 if wback then R[n] = offset_addr; 10461 #endif 10462 10463 bool success = false; 10464 10465 if (ConditionPassed(opcode)) { 10466 uint32_t t; 10467 uint32_t n; 10468 uint32_t imm32; 10469 bool index; 10470 bool add; 10471 bool wback; 10472 10473 switch (encoding) { 10474 case eEncodingA1: 10475 // if P == '0' && W == '1' then SEE STRBT; 10476 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10477 t = Bits32(opcode, 15, 12); 10478 n = Bits32(opcode, 19, 16); 10479 imm32 = Bits32(opcode, 11, 0); 10480 10481 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10482 index = BitIsSet(opcode, 24); 10483 add = BitIsSet(opcode, 23); 10484 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10485 10486 // if t == 15 then UNPREDICTABLE; 10487 if (t == 15) 10488 return false; 10489 10490 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10491 if (wback && ((n == 15) || (n == t))) 10492 return false; 10493 10494 break; 10495 10496 default: 10497 return false; 10498 } 10499 10500 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10501 uint32_t Rn = ReadCoreReg(n, &success); 10502 if (!success) 10503 return false; 10504 10505 addr_t offset_addr; 10506 if (add) 10507 offset_addr = Rn + imm32; 10508 else 10509 offset_addr = Rn - imm32; 10510 10511 // address = if index then offset_addr else R[n]; 10512 addr_t address; 10513 if (index) 10514 address = offset_addr; 10515 else 10516 address = Rn; 10517 10518 // MemU[address,1] = R[t]<7:0>; 10519 uint32_t Rt = ReadCoreReg(t, &success); 10520 if (!success) 10521 return false; 10522 10523 RegisterInfo base_reg; 10524 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10525 RegisterInfo data_reg; 10526 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10527 EmulateInstruction::Context context; 10528 context.type = eContextRegisterStore; 10529 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10530 10531 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1)) 10532 return false; 10533 10534 // if wback then R[n] = offset_addr; 10535 if (wback) { 10536 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10537 offset_addr)) 10538 return false; 10539 } 10540 } 10541 return true; 10542 } 10543 10544 // A8.6.194 STR (immediate, ARM) 10545 bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode, 10546 const ARMEncoding encoding) { 10547 #if 0 10548 if ConditionPassed() then 10549 EncodingSpecificOperations(); 10550 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10551 address = if index then offset_addr else R[n]; 10552 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10553 if wback then R[n] = offset_addr; 10554 #endif 10555 10556 bool success = false; 10557 10558 if (ConditionPassed(opcode)) { 10559 uint32_t t; 10560 uint32_t n; 10561 uint32_t imm32; 10562 bool index; 10563 bool add; 10564 bool wback; 10565 10566 const uint32_t addr_byte_size = GetAddressByteSize(); 10567 10568 switch (encoding) { 10569 case eEncodingA1: 10570 // if P == '0' && W == '1' then SEE STRT; 10571 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == 10572 // '000000000100' then SEE PUSH; 10573 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10574 t = Bits32(opcode, 15, 12); 10575 n = Bits32(opcode, 19, 16); 10576 imm32 = Bits32(opcode, 11, 0); 10577 10578 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10579 index = BitIsSet(opcode, 24); 10580 add = BitIsSet(opcode, 23); 10581 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10582 10583 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10584 if (wback && ((n == 15) || (n == t))) 10585 return false; 10586 10587 break; 10588 10589 default: 10590 return false; 10591 } 10592 10593 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10594 uint32_t Rn = ReadCoreReg(n, &success); 10595 if (!success) 10596 return false; 10597 10598 addr_t offset_addr; 10599 if (add) 10600 offset_addr = Rn + imm32; 10601 else 10602 offset_addr = Rn - imm32; 10603 10604 // address = if index then offset_addr else R[n]; 10605 addr_t address; 10606 if (index) 10607 address = offset_addr; 10608 else 10609 address = Rn; 10610 10611 RegisterInfo base_reg; 10612 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10613 RegisterInfo data_reg; 10614 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10615 EmulateInstruction::Context context; 10616 context.type = eContextRegisterStore; 10617 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10618 10619 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10620 uint32_t Rt = ReadCoreReg(t, &success); 10621 if (!success) 10622 return false; 10623 10624 if (t == 15) { 10625 uint32_t pc_value = ReadCoreReg(PC_REG, &success); 10626 if (!success) 10627 return false; 10628 10629 if (!MemUWrite(context, address, pc_value, addr_byte_size)) 10630 return false; 10631 } else { 10632 if (!MemUWrite(context, address, Rt, addr_byte_size)) 10633 return false; 10634 } 10635 10636 // if wback then R[n] = offset_addr; 10637 if (wback) { 10638 context.type = eContextAdjustBaseRegister; 10639 context.SetImmediate(offset_addr); 10640 10641 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10642 offset_addr)) 10643 return false; 10644 } 10645 } 10646 return true; 10647 } 10648 10649 // A8.6.66 LDRD (immediate) 10650 // Load Register Dual (immediate) calculates an address from a base register 10651 // value and an immediate offset, loads two words from memory, and writes them 10652 // to two registers. It can use offset, post-indexed, or pre-indexed 10653 // addressing. 10654 bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode, 10655 const ARMEncoding encoding) { 10656 #if 0 10657 if ConditionPassed() then 10658 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10659 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10660 address = if index then offset_addr else R[n]; 10661 R[t] = MemA[address,4]; 10662 R[t2] = MemA[address+4,4]; 10663 if wback then R[n] = offset_addr; 10664 #endif 10665 10666 bool success = false; 10667 10668 if (ConditionPassed(opcode)) { 10669 uint32_t t; 10670 uint32_t t2; 10671 uint32_t n; 10672 uint32_t imm32; 10673 bool index; 10674 bool add; 10675 bool wback; 10676 10677 switch (encoding) { 10678 case eEncodingT1: 10679 // if P == '0' && W == '0' then SEE 'Related encodings'; 10680 // if Rn == '1111' then SEE LDRD (literal); 10681 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10682 // ZeroExtend(imm8:'00', 32); 10683 t = Bits32(opcode, 15, 12); 10684 t2 = Bits32(opcode, 11, 8); 10685 n = Bits32(opcode, 19, 16); 10686 imm32 = Bits32(opcode, 7, 0) << 2; 10687 10688 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10689 index = BitIsSet(opcode, 24); 10690 add = BitIsSet(opcode, 23); 10691 wback = BitIsSet(opcode, 21); 10692 10693 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10694 if (wback && ((n == t) || (n == t2))) 10695 return false; 10696 10697 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10698 if (BadReg(t) || BadReg(t2) || (t == t2)) 10699 return false; 10700 10701 break; 10702 10703 case eEncodingA1: 10704 // if Rn == '1111' then SEE LDRD (literal); 10705 // if Rt<0> == '1' then UNPREDICTABLE; 10706 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10707 // 32); 10708 t = Bits32(opcode, 15, 12); 10709 if (BitIsSet(t, 0)) 10710 return false; 10711 t2 = t + 1; 10712 n = Bits32(opcode, 19, 16); 10713 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10714 10715 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10716 index = BitIsSet(opcode, 24); 10717 add = BitIsSet(opcode, 23); 10718 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10719 10720 // if P == '0' && W == '1' then UNPREDICTABLE; 10721 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10722 return false; 10723 10724 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10725 if (wback && ((n == t) || (n == t2))) 10726 return false; 10727 10728 // if t2 == 15 then UNPREDICTABLE; 10729 if (t2 == 15) 10730 return false; 10731 10732 break; 10733 10734 default: 10735 return false; 10736 } 10737 10738 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10739 uint32_t Rn = ReadCoreReg(n, &success); 10740 if (!success) 10741 return false; 10742 10743 addr_t offset_addr; 10744 if (add) 10745 offset_addr = Rn + imm32; 10746 else 10747 offset_addr = Rn - imm32; 10748 10749 // address = if index then offset_addr else R[n]; 10750 addr_t address; 10751 if (index) 10752 address = offset_addr; 10753 else 10754 address = Rn; 10755 10756 // R[t] = MemA[address,4]; 10757 RegisterInfo base_reg; 10758 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10759 10760 EmulateInstruction::Context context; 10761 if (n == 13) 10762 context.type = eContextPopRegisterOffStack; 10763 else 10764 context.type = eContextRegisterLoad; 10765 context.SetAddress(address); 10766 10767 const uint32_t addr_byte_size = GetAddressByteSize(); 10768 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10769 if (!success) 10770 return false; 10771 10772 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10773 return false; 10774 10775 // R[t2] = MemA[address+4,4]; 10776 context.SetAddress(address + 4); 10777 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10778 if (!success) 10779 return false; 10780 10781 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10782 data)) 10783 return false; 10784 10785 // if wback then R[n] = offset_addr; 10786 if (wback) { 10787 context.type = eContextAdjustBaseRegister; 10788 context.SetAddress(offset_addr); 10789 10790 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10791 offset_addr)) 10792 return false; 10793 } 10794 } 10795 return true; 10796 } 10797 10798 // A8.6.68 LDRD (register) 10799 // Load Register Dual (register) calculates an address from a base register 10800 // value and a register offset, loads two words from memory, and writes them to 10801 // two registers. It can use offset, post-indexed or pre-indexed addressing. 10802 bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode, 10803 const ARMEncoding encoding) { 10804 #if 0 10805 if ConditionPassed() then 10806 EncodingSpecificOperations(); 10807 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10808 address = if index then offset_addr else R[n]; 10809 R[t] = MemA[address,4]; 10810 R[t2] = MemA[address+4,4]; 10811 if wback then R[n] = offset_addr; 10812 #endif 10813 10814 bool success = false; 10815 10816 if (ConditionPassed(opcode)) { 10817 uint32_t t; 10818 uint32_t t2; 10819 uint32_t n; 10820 uint32_t m; 10821 bool index; 10822 bool add; 10823 bool wback; 10824 10825 switch (encoding) { 10826 case eEncodingA1: 10827 // if Rt<0> == '1' then UNPREDICTABLE; 10828 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10829 t = Bits32(opcode, 15, 12); 10830 if (BitIsSet(t, 0)) 10831 return false; 10832 t2 = t + 1; 10833 n = Bits32(opcode, 19, 16); 10834 m = Bits32(opcode, 3, 0); 10835 10836 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10837 index = BitIsSet(opcode, 24); 10838 add = BitIsSet(opcode, 23); 10839 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10840 10841 // if P == '0' && W == '1' then UNPREDICTABLE; 10842 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10843 return false; 10844 10845 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10846 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10847 return false; 10848 10849 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10850 if (wback && ((n == 15) || (n == t) || (n == t2))) 10851 return false; 10852 10853 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10854 if ((ArchVersion() < 6) && wback && (m == n)) 10855 return false; 10856 break; 10857 10858 default: 10859 return false; 10860 } 10861 10862 uint32_t Rn = ReadCoreReg(n, &success); 10863 if (!success) 10864 return false; 10865 RegisterInfo base_reg; 10866 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10867 10868 uint32_t Rm = ReadCoreReg(m, &success); 10869 if (!success) 10870 return false; 10871 RegisterInfo offset_reg; 10872 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10873 10874 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10875 addr_t offset_addr; 10876 if (add) 10877 offset_addr = Rn + Rm; 10878 else 10879 offset_addr = Rn - Rm; 10880 10881 // address = if index then offset_addr else R[n]; 10882 addr_t address; 10883 if (index) 10884 address = offset_addr; 10885 else 10886 address = Rn; 10887 10888 EmulateInstruction::Context context; 10889 if (n == 13) 10890 context.type = eContextPopRegisterOffStack; 10891 else 10892 context.type = eContextRegisterLoad; 10893 context.SetAddress(address); 10894 10895 // R[t] = MemA[address,4]; 10896 const uint32_t addr_byte_size = GetAddressByteSize(); 10897 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10898 if (!success) 10899 return false; 10900 10901 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10902 return false; 10903 10904 // R[t2] = MemA[address+4,4]; 10905 10906 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10907 if (!success) 10908 return false; 10909 10910 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10911 data)) 10912 return false; 10913 10914 // if wback then R[n] = offset_addr; 10915 if (wback) { 10916 context.type = eContextAdjustBaseRegister; 10917 context.SetAddress(offset_addr); 10918 10919 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10920 offset_addr)) 10921 return false; 10922 } 10923 } 10924 return true; 10925 } 10926 10927 // A8.6.200 STRD (immediate) 10928 // Store Register Dual (immediate) calculates an address from a base register 10929 // value and an immediate offset, and stores two words from two registers to 10930 // memory. It can use offset, post-indexed, or pre-indexed addressing. 10931 bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode, 10932 const ARMEncoding encoding) { 10933 #if 0 10934 if ConditionPassed() then 10935 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10936 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10937 address = if index then offset_addr else R[n]; 10938 MemA[address,4] = R[t]; 10939 MemA[address+4,4] = R[t2]; 10940 if wback then R[n] = offset_addr; 10941 #endif 10942 10943 bool success = false; 10944 10945 if (ConditionPassed(opcode)) { 10946 uint32_t t; 10947 uint32_t t2; 10948 uint32_t n; 10949 uint32_t imm32; 10950 bool index; 10951 bool add; 10952 bool wback; 10953 10954 switch (encoding) { 10955 case eEncodingT1: 10956 // if P == '0' && W == '0' then SEE 'Related encodings'; 10957 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10958 // ZeroExtend(imm8:'00', 32); 10959 t = Bits32(opcode, 15, 12); 10960 t2 = Bits32(opcode, 11, 8); 10961 n = Bits32(opcode, 19, 16); 10962 imm32 = Bits32(opcode, 7, 0) << 2; 10963 10964 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10965 index = BitIsSet(opcode, 24); 10966 add = BitIsSet(opcode, 23); 10967 wback = BitIsSet(opcode, 21); 10968 10969 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10970 if (wback && ((n == t) || (n == t2))) 10971 return false; 10972 10973 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10974 if ((n == 15) || BadReg(t) || BadReg(t2)) 10975 return false; 10976 10977 break; 10978 10979 case eEncodingA1: 10980 // if Rt<0> == '1' then UNPREDICTABLE; 10981 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10982 // 32); 10983 t = Bits32(opcode, 15, 12); 10984 if (BitIsSet(t, 0)) 10985 return false; 10986 10987 t2 = t + 1; 10988 n = Bits32(opcode, 19, 16); 10989 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10990 10991 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10992 index = BitIsSet(opcode, 24); 10993 add = BitIsSet(opcode, 23); 10994 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10995 10996 // if P == '0' && W == '1' then UNPREDICTABLE; 10997 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10998 return false; 10999 11000 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11001 if (wback && ((n == 15) || (n == t) || (n == t2))) 11002 return false; 11003 11004 // if t2 == 15 then UNPREDICTABLE; 11005 if (t2 == 15) 11006 return false; 11007 11008 break; 11009 11010 default: 11011 return false; 11012 } 11013 11014 RegisterInfo base_reg; 11015 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11016 11017 uint32_t Rn = ReadCoreReg(n, &success); 11018 if (!success) 11019 return false; 11020 11021 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11022 addr_t offset_addr; 11023 if (add) 11024 offset_addr = Rn + imm32; 11025 else 11026 offset_addr = Rn - imm32; 11027 11028 // address = if index then offset_addr else R[n]; 11029 addr_t address; 11030 if (index) 11031 address = offset_addr; 11032 else 11033 address = Rn; 11034 11035 // MemA[address,4] = R[t]; 11036 RegisterInfo data_reg; 11037 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11038 11039 uint32_t data = ReadCoreReg(t, &success); 11040 if (!success) 11041 return false; 11042 11043 EmulateInstruction::Context context; 11044 if (n == 13) 11045 context.type = eContextPushRegisterOnStack; 11046 else 11047 context.type = eContextRegisterStore; 11048 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11049 11050 const uint32_t addr_byte_size = GetAddressByteSize(); 11051 11052 if (!MemAWrite(context, address, data, addr_byte_size)) 11053 return false; 11054 11055 // MemA[address+4,4] = R[t2]; 11056 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11057 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11058 (address + 4) - Rn); 11059 11060 data = ReadCoreReg(t2, &success); 11061 if (!success) 11062 return false; 11063 11064 if (!MemAWrite(context, address + 4, data, addr_byte_size)) 11065 return false; 11066 11067 // if wback then R[n] = offset_addr; 11068 if (wback) { 11069 if (n == 13) 11070 context.type = eContextAdjustStackPointer; 11071 else 11072 context.type = eContextAdjustBaseRegister; 11073 context.SetAddress(offset_addr); 11074 11075 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11076 offset_addr)) 11077 return false; 11078 } 11079 } 11080 return true; 11081 } 11082 11083 // A8.6.201 STRD (register) 11084 bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode, 11085 const ARMEncoding encoding) { 11086 #if 0 11087 if ConditionPassed() then 11088 EncodingSpecificOperations(); 11089 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11090 address = if index then offset_addr else R[n]; 11091 MemA[address,4] = R[t]; 11092 MemA[address+4,4] = R[t2]; 11093 if wback then R[n] = offset_addr; 11094 #endif 11095 11096 bool success = false; 11097 11098 if (ConditionPassed(opcode)) { 11099 uint32_t t; 11100 uint32_t t2; 11101 uint32_t n; 11102 uint32_t m; 11103 bool index; 11104 bool add; 11105 bool wback; 11106 11107 switch (encoding) { 11108 case eEncodingA1: 11109 // if Rt<0> == '1' then UNPREDICTABLE; 11110 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 11111 t = Bits32(opcode, 15, 12); 11112 if (BitIsSet(t, 0)) 11113 return false; 11114 11115 t2 = t + 1; 11116 n = Bits32(opcode, 19, 16); 11117 m = Bits32(opcode, 3, 0); 11118 11119 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11120 index = BitIsSet(opcode, 24); 11121 add = BitIsSet(opcode, 23); 11122 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11123 11124 // if P == '0' && W == '1' then UNPREDICTABLE; 11125 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11126 return false; 11127 11128 // if t2 == 15 || m == 15 then UNPREDICTABLE; 11129 if ((t2 == 15) || (m == 15)) 11130 return false; 11131 11132 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11133 if (wback && ((n == 15) || (n == t) || (n == t2))) 11134 return false; 11135 11136 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 11137 if ((ArchVersion() < 6) && wback && (m == n)) 11138 return false; 11139 11140 break; 11141 11142 default: 11143 return false; 11144 } 11145 11146 RegisterInfo base_reg; 11147 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11148 RegisterInfo offset_reg; 11149 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 11150 RegisterInfo data_reg; 11151 11152 uint32_t Rn = ReadCoreReg(n, &success); 11153 if (!success) 11154 return false; 11155 11156 uint32_t Rm = ReadCoreReg(m, &success); 11157 if (!success) 11158 return false; 11159 11160 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11161 addr_t offset_addr; 11162 if (add) 11163 offset_addr = Rn + Rm; 11164 else 11165 offset_addr = Rn - Rm; 11166 11167 // address = if index then offset_addr else R[n]; 11168 addr_t address; 11169 if (index) 11170 address = offset_addr; 11171 else 11172 address = Rn; 11173 // MemA[address,4] = R[t]; 11174 uint32_t Rt = ReadCoreReg(t, &success); 11175 if (!success) 11176 return false; 11177 11178 EmulateInstruction::Context context; 11179 if (t == 13) 11180 context.type = eContextPushRegisterOnStack; 11181 else 11182 context.type = eContextRegisterStore; 11183 11184 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11185 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11186 data_reg); 11187 11188 const uint32_t addr_byte_size = GetAddressByteSize(); 11189 11190 if (!MemAWrite(context, address, Rt, addr_byte_size)) 11191 return false; 11192 11193 // MemA[address+4,4] = R[t2]; 11194 uint32_t Rt2 = ReadCoreReg(t2, &success); 11195 if (!success) 11196 return false; 11197 11198 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11199 11200 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11201 data_reg); 11202 11203 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size)) 11204 return false; 11205 11206 // if wback then R[n] = offset_addr; 11207 if (wback) { 11208 context.type = eContextAdjustBaseRegister; 11209 context.SetAddress(offset_addr); 11210 11211 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11212 offset_addr)) 11213 return false; 11214 } 11215 } 11216 return true; 11217 } 11218 11219 // A8.6.319 VLDM 11220 // Vector Load Multiple loads multiple extension registers from consecutive 11221 // memory locations using an address from an ARM core register. 11222 bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode, 11223 const ARMEncoding encoding) { 11224 #if 0 11225 if ConditionPassed() then 11226 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11227 address = if add then R[n] else R[n]-imm32; 11228 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11229 for r = 0 to regs-1 11230 if single_regs then 11231 S[d+r] = MemA[address,4]; address = address+4; 11232 else 11233 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 11234 // Combine the word-aligned words in the correct order for 11235 // current endianness. 11236 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11237 #endif 11238 11239 bool success = false; 11240 11241 if (ConditionPassed(opcode)) { 11242 bool single_regs; 11243 bool add; 11244 bool wback; 11245 uint32_t d; 11246 uint32_t n; 11247 uint32_t imm32; 11248 uint32_t regs; 11249 11250 switch (encoding) { 11251 case eEncodingT1: 11252 case eEncodingA1: 11253 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11254 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11255 // if P == '1' && W == '0' then SEE VLDR; 11256 // if P == U && W == '1' then UNDEFINED; 11257 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11258 return false; 11259 11260 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11261 // !), 101 (DB with !) 11262 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11263 single_regs = false; 11264 add = BitIsSet(opcode, 23); 11265 wback = BitIsSet(opcode, 21); 11266 11267 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11268 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11269 n = Bits32(opcode, 19, 16); 11270 imm32 = Bits32(opcode, 7, 0) << 2; 11271 11272 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 11273 regs = Bits32(opcode, 7, 0) / 2; 11274 11275 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11276 // UNPREDICTABLE; 11277 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 11278 return false; 11279 11280 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11281 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11282 return false; 11283 11284 break; 11285 11286 case eEncodingT2: 11287 case eEncodingA2: 11288 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11289 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11290 // if P == '1' && W == '0' then SEE VLDR; 11291 // if P == U && W == '1' then UNDEFINED; 11292 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11293 return false; 11294 11295 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11296 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11297 // == '1'); d = 11298 // UInt(Vd:D); n = UInt(Rn); 11299 single_regs = true; 11300 add = BitIsSet(opcode, 23); 11301 wback = BitIsSet(opcode, 21); 11302 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11303 n = Bits32(opcode, 19, 16); 11304 11305 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11306 imm32 = Bits32(opcode, 7, 0) << 2; 11307 regs = Bits32(opcode, 7, 0); 11308 11309 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11310 // UNPREDICTABLE; 11311 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11312 return false; 11313 11314 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11315 if ((regs == 0) || ((d + regs) > 32)) 11316 return false; 11317 break; 11318 11319 default: 11320 return false; 11321 } 11322 11323 RegisterInfo base_reg; 11324 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11325 11326 uint32_t Rn = ReadCoreReg(n, &success); 11327 if (!success) 11328 return false; 11329 11330 // address = if add then R[n] else R[n]-imm32; 11331 addr_t address; 11332 if (add) 11333 address = Rn; 11334 else 11335 address = Rn - imm32; 11336 11337 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11338 EmulateInstruction::Context context; 11339 11340 if (wback) { 11341 uint32_t value; 11342 if (add) 11343 value = Rn + imm32; 11344 else 11345 value = Rn - imm32; 11346 11347 context.type = eContextAdjustBaseRegister; 11348 context.SetImmediateSigned(value - Rn); 11349 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11350 value)) 11351 return false; 11352 } 11353 11354 const uint32_t addr_byte_size = GetAddressByteSize(); 11355 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11356 11357 context.type = eContextRegisterLoad; 11358 11359 // for r = 0 to regs-1 11360 for (uint32_t r = 0; r < regs; ++r) { 11361 if (single_regs) { 11362 // S[d+r] = MemA[address,4]; address = address+4; 11363 context.SetRegisterPlusOffset(base_reg, address - Rn); 11364 11365 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11366 if (!success) 11367 return false; 11368 11369 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11370 start_reg + d + r, data)) 11371 return false; 11372 11373 address = address + 4; 11374 } else { 11375 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = 11376 // address+8; 11377 context.SetRegisterPlusOffset(base_reg, address - Rn); 11378 uint32_t word1 = 11379 MemARead(context, address, addr_byte_size, 0, &success); 11380 if (!success) 11381 return false; 11382 11383 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn); 11384 uint32_t word2 = 11385 MemARead(context, address + 4, addr_byte_size, 0, &success); 11386 if (!success) 11387 return false; 11388 11389 address = address + 8; 11390 // // Combine the word-aligned words in the correct order for current 11391 // endianness. 11392 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11393 uint64_t data; 11394 if (GetByteOrder() == eByteOrderBig) { 11395 data = word1; 11396 data = (data << 32) | word2; 11397 } else { 11398 data = word2; 11399 data = (data << 32) | word1; 11400 } 11401 11402 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11403 start_reg + d + r, data)) 11404 return false; 11405 } 11406 } 11407 } 11408 return true; 11409 } 11410 11411 // A8.6.399 VSTM 11412 // Vector Store Multiple stores multiple extension registers to consecutive 11413 // memory locations using an address from an 11414 // ARM core register. 11415 bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode, 11416 const ARMEncoding encoding) { 11417 #if 0 11418 if ConditionPassed() then 11419 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11420 address = if add then R[n] else R[n]-imm32; 11421 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11422 for r = 0 to regs-1 11423 if single_regs then 11424 MemA[address,4] = S[d+r]; address = address+4; 11425 else 11426 // Store as two word-aligned words in the correct order for 11427 // current endianness. 11428 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11429 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11430 address = address+8; 11431 #endif 11432 11433 bool success = false; 11434 11435 if (ConditionPassed(opcode)) { 11436 bool single_regs; 11437 bool add; 11438 bool wback; 11439 uint32_t d; 11440 uint32_t n; 11441 uint32_t imm32; 11442 uint32_t regs; 11443 11444 switch (encoding) { 11445 case eEncodingT1: 11446 case eEncodingA1: 11447 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11448 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11449 // if P == '1' && W == '0' then SEE VSTR; 11450 // if P == U && W == '1' then UNDEFINED; 11451 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11452 return false; 11453 11454 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11455 // !), 101 (DB with !) 11456 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11457 single_regs = false; 11458 add = BitIsSet(opcode, 23); 11459 wback = BitIsSet(opcode, 21); 11460 11461 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11462 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11463 n = Bits32(opcode, 19, 16); 11464 imm32 = Bits32(opcode, 7, 0) << 2; 11465 11466 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11467 regs = Bits32(opcode, 7, 0) / 2; 11468 11469 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11470 // UNPREDICTABLE; 11471 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11472 return false; 11473 11474 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11475 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11476 return false; 11477 11478 break; 11479 11480 case eEncodingT2: 11481 case eEncodingA2: 11482 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11483 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11484 // if P == '1' && W == '0' then SEE VSTR; 11485 // if P == U && W == '1' then UNDEFINED; 11486 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11487 return false; 11488 11489 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11490 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11491 // == '1'); d = 11492 // UInt(Vd:D); n = UInt(Rn); 11493 single_regs = true; 11494 add = BitIsSet(opcode, 23); 11495 wback = BitIsSet(opcode, 21); 11496 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11497 n = Bits32(opcode, 19, 16); 11498 11499 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11500 imm32 = Bits32(opcode, 7, 0) << 2; 11501 regs = Bits32(opcode, 7, 0); 11502 11503 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11504 // UNPREDICTABLE; 11505 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11506 return false; 11507 11508 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11509 if ((regs == 0) || ((d + regs) > 32)) 11510 return false; 11511 11512 break; 11513 11514 default: 11515 return false; 11516 } 11517 11518 RegisterInfo base_reg; 11519 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11520 11521 uint32_t Rn = ReadCoreReg(n, &success); 11522 if (!success) 11523 return false; 11524 11525 // address = if add then R[n] else R[n]-imm32; 11526 addr_t address; 11527 if (add) 11528 address = Rn; 11529 else 11530 address = Rn - imm32; 11531 11532 EmulateInstruction::Context context; 11533 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11534 if (wback) { 11535 uint32_t value; 11536 if (add) 11537 value = Rn + imm32; 11538 else 11539 value = Rn - imm32; 11540 11541 context.type = eContextAdjustBaseRegister; 11542 context.SetRegisterPlusOffset(base_reg, value - Rn); 11543 11544 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11545 value)) 11546 return false; 11547 } 11548 11549 const uint32_t addr_byte_size = GetAddressByteSize(); 11550 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11551 11552 context.type = eContextRegisterStore; 11553 // for r = 0 to regs-1 11554 for (uint32_t r = 0; r < regs; ++r) { 11555 11556 if (single_regs) { 11557 // MemA[address,4] = S[d+r]; address = address+4; 11558 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11559 start_reg + d + r, 0, &success); 11560 if (!success) 11561 return false; 11562 11563 RegisterInfo data_reg; 11564 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11565 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11566 address - Rn); 11567 if (!MemAWrite(context, address, data, addr_byte_size)) 11568 return false; 11569 11570 address = address + 4; 11571 } else { 11572 // // Store as two word-aligned words in the correct order for current 11573 // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else 11574 // D[d+r]<31:0>; 11575 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else 11576 // D[d+r]<63:32>; 11577 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11578 start_reg + d + r, 0, &success); 11579 if (!success) 11580 return false; 11581 11582 RegisterInfo data_reg; 11583 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11584 11585 if (GetByteOrder() == eByteOrderBig) { 11586 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11587 address - Rn); 11588 if (!MemAWrite(context, address, Bits64(data, 63, 32), 11589 addr_byte_size)) 11590 return false; 11591 11592 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11593 (address + 4) - Rn); 11594 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11595 addr_byte_size)) 11596 return false; 11597 } else { 11598 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11599 address - Rn); 11600 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11601 return false; 11602 11603 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11604 (address + 4) - Rn); 11605 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11606 addr_byte_size)) 11607 return false; 11608 } 11609 // address = address+8; 11610 address = address + 8; 11611 } 11612 } 11613 } 11614 return true; 11615 } 11616 11617 // A8.6.320 11618 // This instruction loads a single extension register from memory, using an 11619 // address from an ARM core register, with an optional offset. 11620 bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode, 11621 ARMEncoding encoding) { 11622 #if 0 11623 if ConditionPassed() then 11624 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11625 base = if n == 15 then Align(PC,4) else R[n]; 11626 address = if add then (base + imm32) else (base - imm32); 11627 if single_reg then 11628 S[d] = MemA[address,4]; 11629 else 11630 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11631 // Combine the word-aligned words in the correct order for current 11632 // endianness. 11633 D[d] = if BigEndian() then word1:word2 else word2:word1; 11634 #endif 11635 11636 bool success = false; 11637 11638 if (ConditionPassed(opcode)) { 11639 bool single_reg; 11640 bool add; 11641 uint32_t imm32; 11642 uint32_t d; 11643 uint32_t n; 11644 11645 switch (encoding) { 11646 case eEncodingT1: 11647 case eEncodingA1: 11648 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11649 // 32); 11650 single_reg = false; 11651 add = BitIsSet(opcode, 23); 11652 imm32 = Bits32(opcode, 7, 0) << 2; 11653 11654 // d = UInt(D:Vd); n = UInt(Rn); 11655 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11656 n = Bits32(opcode, 19, 16); 11657 11658 break; 11659 11660 case eEncodingT2: 11661 case eEncodingA2: 11662 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11663 single_reg = true; 11664 add = BitIsSet(opcode, 23); 11665 imm32 = Bits32(opcode, 7, 0) << 2; 11666 11667 // d = UInt(Vd:D); n = UInt(Rn); 11668 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11669 n = Bits32(opcode, 19, 16); 11670 11671 break; 11672 11673 default: 11674 return false; 11675 } 11676 RegisterInfo base_reg; 11677 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11678 11679 uint32_t Rn = ReadCoreReg(n, &success); 11680 if (!success) 11681 return false; 11682 11683 // base = if n == 15 then Align(PC,4) else R[n]; 11684 uint32_t base; 11685 if (n == 15) 11686 base = AlignPC(Rn); 11687 else 11688 base = Rn; 11689 11690 // address = if add then (base + imm32) else (base - imm32); 11691 addr_t address; 11692 if (add) 11693 address = base + imm32; 11694 else 11695 address = base - imm32; 11696 11697 const uint32_t addr_byte_size = GetAddressByteSize(); 11698 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11699 11700 EmulateInstruction::Context context; 11701 context.type = eContextRegisterLoad; 11702 context.SetRegisterPlusOffset(base_reg, address - base); 11703 11704 if (single_reg) { 11705 // S[d] = MemA[address,4]; 11706 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11707 if (!success) 11708 return false; 11709 11710 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11711 data)) 11712 return false; 11713 } else { 11714 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11715 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success); 11716 if (!success) 11717 return false; 11718 11719 context.SetRegisterPlusOffset(base_reg, (address + 4) - base); 11720 uint32_t word2 = 11721 MemARead(context, address + 4, addr_byte_size, 0, &success); 11722 if (!success) 11723 return false; 11724 // // Combine the word-aligned words in the correct order for current 11725 // endianness. 11726 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11727 uint64_t data64; 11728 if (GetByteOrder() == eByteOrderBig) { 11729 data64 = word1; 11730 data64 = (data64 << 32) | word2; 11731 } else { 11732 data64 = word2; 11733 data64 = (data64 << 32) | word1; 11734 } 11735 11736 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11737 data64)) 11738 return false; 11739 } 11740 } 11741 return true; 11742 } 11743 11744 // A8.6.400 VSTR 11745 // This instruction stores a signle extension register to memory, using an 11746 // address from an ARM core register, with an optional offset. 11747 bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode, 11748 ARMEncoding encoding) { 11749 #if 0 11750 if ConditionPassed() then 11751 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11752 address = if add then (R[n] + imm32) else (R[n] - imm32); 11753 if single_reg then 11754 MemA[address,4] = S[d]; 11755 else 11756 // Store as two word-aligned words in the correct order for current 11757 // endianness. 11758 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11759 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11760 #endif 11761 11762 bool success = false; 11763 11764 if (ConditionPassed(opcode)) { 11765 bool single_reg; 11766 bool add; 11767 uint32_t imm32; 11768 uint32_t d; 11769 uint32_t n; 11770 11771 switch (encoding) { 11772 case eEncodingT1: 11773 case eEncodingA1: 11774 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11775 // 32); 11776 single_reg = false; 11777 add = BitIsSet(opcode, 23); 11778 imm32 = Bits32(opcode, 7, 0) << 2; 11779 11780 // d = UInt(D:Vd); n = UInt(Rn); 11781 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11782 n = Bits32(opcode, 19, 16); 11783 11784 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11785 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11786 return false; 11787 11788 break; 11789 11790 case eEncodingT2: 11791 case eEncodingA2: 11792 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11793 single_reg = true; 11794 add = BitIsSet(opcode, 23); 11795 imm32 = Bits32(opcode, 7, 0) << 2; 11796 11797 // d = UInt(Vd:D); n = UInt(Rn); 11798 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11799 n = Bits32(opcode, 19, 16); 11800 11801 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11802 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11803 return false; 11804 11805 break; 11806 11807 default: 11808 return false; 11809 } 11810 11811 RegisterInfo base_reg; 11812 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11813 11814 uint32_t Rn = ReadCoreReg(n, &success); 11815 if (!success) 11816 return false; 11817 11818 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11819 addr_t address; 11820 if (add) 11821 address = Rn + imm32; 11822 else 11823 address = Rn - imm32; 11824 11825 const uint32_t addr_byte_size = GetAddressByteSize(); 11826 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11827 11828 RegisterInfo data_reg; 11829 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg); 11830 EmulateInstruction::Context context; 11831 context.type = eContextRegisterStore; 11832 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11833 11834 if (single_reg) { 11835 // MemA[address,4] = S[d]; 11836 uint32_t data = 11837 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11838 if (!success) 11839 return false; 11840 11841 if (!MemAWrite(context, address, data, addr_byte_size)) 11842 return false; 11843 } else { 11844 // // Store as two word-aligned words in the correct order for current 11845 // endianness. 11846 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11847 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11848 uint64_t data = 11849 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11850 if (!success) 11851 return false; 11852 11853 if (GetByteOrder() == eByteOrderBig) { 11854 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size)) 11855 return false; 11856 11857 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11858 (address + 4) - Rn); 11859 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11860 addr_byte_size)) 11861 return false; 11862 } else { 11863 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11864 return false; 11865 11866 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11867 (address + 4) - Rn); 11868 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11869 addr_byte_size)) 11870 return false; 11871 } 11872 } 11873 } 11874 return true; 11875 } 11876 11877 // A8.6.307 VLDI1 (multiple single elements) This instruction loads elements 11878 // from memory into one, two, three or four registers, without de-interleaving. 11879 // Every element of each register is loaded. 11880 bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode, 11881 ARMEncoding encoding) { 11882 #if 0 11883 if ConditionPassed() then 11884 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11885 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11886 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11887 for r = 0 to regs-1 11888 for e = 0 to elements-1 11889 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11890 address = address + ebytes; 11891 #endif 11892 11893 bool success = false; 11894 11895 if (ConditionPassed(opcode)) { 11896 uint32_t regs; 11897 uint32_t alignment; 11898 uint32_t ebytes; 11899 uint32_t esize; 11900 uint32_t elements; 11901 uint32_t d; 11902 uint32_t n; 11903 uint32_t m; 11904 bool wback; 11905 bool register_index; 11906 11907 switch (encoding) { 11908 case eEncodingT1: 11909 case eEncodingA1: { 11910 // case type of 11911 // when '0111' 11912 // regs = 1; if align<1> == '1' then UNDEFINED; 11913 // when '1010' 11914 // regs = 2; if align == '11' then UNDEFINED; 11915 // when '0110' 11916 // regs = 3; if align<1> == '1' then UNDEFINED; 11917 // when '0010' 11918 // regs = 4; 11919 // otherwise 11920 // SEE 'Related encodings'; 11921 uint32_t type = Bits32(opcode, 11, 8); 11922 uint32_t align = Bits32(opcode, 5, 4); 11923 if (type == 7) // '0111' 11924 { 11925 regs = 1; 11926 if (BitIsSet(align, 1)) 11927 return false; 11928 } else if (type == 10) // '1010' 11929 { 11930 regs = 2; 11931 if (align == 3) 11932 return false; 11933 11934 } else if (type == 6) // '0110' 11935 { 11936 regs = 3; 11937 if (BitIsSet(align, 1)) 11938 return false; 11939 } else if (type == 2) // '0010' 11940 { 11941 regs = 4; 11942 } else 11943 return false; 11944 11945 // alignment = if align == '00' then 1 else 4 << UInt(align); 11946 if (align == 0) 11947 alignment = 1; 11948 else 11949 alignment = 4 << align; 11950 11951 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11952 ebytes = 1 << Bits32(opcode, 7, 6); 11953 esize = 8 * ebytes; 11954 elements = 8 / ebytes; 11955 11956 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11957 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11958 n = Bits32(opcode, 19, 15); 11959 m = Bits32(opcode, 3, 0); 11960 11961 // wback = (m != 15); register_index = (m != 15 && m != 13); 11962 wback = (m != 15); 11963 register_index = ((m != 15) && (m != 13)); 11964 11965 // if d+regs > 32 then UNPREDICTABLE; 11966 if ((d + regs) > 32) 11967 return false; 11968 } break; 11969 11970 default: 11971 return false; 11972 } 11973 11974 RegisterInfo base_reg; 11975 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11976 11977 uint32_t Rn = ReadCoreReg(n, &success); 11978 if (!success) 11979 return false; 11980 11981 // address = R[n]; if (address MOD alignment) != 0 then 11982 // GenerateAlignmentException(); 11983 addr_t address = Rn; 11984 if ((address % alignment) != 0) 11985 return false; 11986 11987 EmulateInstruction::Context context; 11988 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11989 if (wback) { 11990 uint32_t Rm = ReadCoreReg(m, &success); 11991 if (!success) 11992 return false; 11993 11994 uint32_t offset; 11995 if (register_index) 11996 offset = Rm; 11997 else 11998 offset = 8 * regs; 11999 12000 uint32_t value = Rn + offset; 12001 context.type = eContextAdjustBaseRegister; 12002 context.SetRegisterPlusOffset(base_reg, offset); 12003 12004 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12005 value)) 12006 return false; 12007 } 12008 12009 // for r = 0 to regs-1 12010 for (uint32_t r = 0; r < regs; ++r) { 12011 // for e = 0 to elements-1 12012 uint64_t assembled_data = 0; 12013 for (uint32_t e = 0; e < elements; ++e) { 12014 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 12015 context.type = eContextRegisterLoad; 12016 context.SetRegisterPlusOffset(base_reg, address - Rn); 12017 uint64_t data = MemURead(context, address, ebytes, 0, &success); 12018 if (!success) 12019 return false; 12020 12021 assembled_data = 12022 (data << (e * esize)) | 12023 assembled_data; // New data goes to the left of existing data 12024 12025 // address = address + ebytes; 12026 address = address + ebytes; 12027 } 12028 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12029 assembled_data)) 12030 return false; 12031 } 12032 } 12033 return true; 12034 } 12035 12036 // A8.6.308 VLD1 (single element to one lane) 12037 // 12038 bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode, 12039 const ARMEncoding encoding) { 12040 #if 0 12041 if ConditionPassed() then 12042 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12043 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12044 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12045 Elem[D[d],index,esize] = MemU[address,ebytes]; 12046 #endif 12047 12048 bool success = false; 12049 12050 if (ConditionPassed(opcode)) { 12051 uint32_t ebytes; 12052 uint32_t esize; 12053 uint32_t index; 12054 uint32_t alignment; 12055 uint32_t d; 12056 uint32_t n; 12057 uint32_t m; 12058 bool wback; 12059 bool register_index; 12060 12061 switch (encoding) { 12062 case eEncodingT1: 12063 case eEncodingA1: { 12064 uint32_t size = Bits32(opcode, 11, 10); 12065 uint32_t index_align = Bits32(opcode, 7, 4); 12066 // if size == '11' then SEE VLD1 (single element to all lanes); 12067 if (size == 3) 12068 return EmulateVLD1SingleAll(opcode, encoding); 12069 // case size of 12070 if (size == 0) // when '00' 12071 { 12072 // if index_align<0> != '0' then UNDEFINED; 12073 if (BitIsClear(index_align, 0)) 12074 return false; 12075 12076 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12077 ebytes = 1; 12078 esize = 8; 12079 index = Bits32(index_align, 3, 1); 12080 alignment = 1; 12081 } else if (size == 1) // when '01' 12082 { 12083 // if index_align<1> != '0' then UNDEFINED; 12084 if (BitIsClear(index_align, 1)) 12085 return false; 12086 12087 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12088 ebytes = 2; 12089 esize = 16; 12090 index = Bits32(index_align, 3, 2); 12091 12092 // alignment = if index_align<0> == '0' then 1 else 2; 12093 if (BitIsClear(index_align, 0)) 12094 alignment = 1; 12095 else 12096 alignment = 2; 12097 } else if (size == 2) // when '10' 12098 { 12099 // if index_align<2> != '0' then UNDEFINED; 12100 if (BitIsClear(index_align, 2)) 12101 return false; 12102 12103 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12104 // UNDEFINED; 12105 if ((Bits32(index_align, 1, 0) != 0) && 12106 (Bits32(index_align, 1, 0) != 3)) 12107 return false; 12108 12109 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12110 ebytes = 4; 12111 esize = 32; 12112 index = Bit32(index_align, 3); 12113 12114 // alignment = if index_align<1:0> == '00' then 1 else 4; 12115 if (Bits32(index_align, 1, 0) == 0) 12116 alignment = 1; 12117 else 12118 alignment = 4; 12119 } else { 12120 return false; 12121 } 12122 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12123 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12124 n = Bits32(opcode, 19, 16); 12125 m = Bits32(opcode, 3, 0); 12126 12127 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12128 // then UNPREDICTABLE; 12129 wback = (m != 15); 12130 register_index = ((m != 15) && (m != 13)); 12131 12132 if (n == 15) 12133 return false; 12134 12135 } break; 12136 12137 default: 12138 return false; 12139 } 12140 12141 RegisterInfo base_reg; 12142 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12143 12144 uint32_t Rn = ReadCoreReg(n, &success); 12145 if (!success) 12146 return false; 12147 12148 // address = R[n]; if (address MOD alignment) != 0 then 12149 // GenerateAlignmentException(); 12150 addr_t address = Rn; 12151 if ((address % alignment) != 0) 12152 return false; 12153 12154 EmulateInstruction::Context context; 12155 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12156 if (wback) { 12157 uint32_t Rm = ReadCoreReg(m, &success); 12158 if (!success) 12159 return false; 12160 12161 uint32_t offset; 12162 if (register_index) 12163 offset = Rm; 12164 else 12165 offset = ebytes; 12166 12167 uint32_t value = Rn + offset; 12168 12169 context.type = eContextAdjustBaseRegister; 12170 context.SetRegisterPlusOffset(base_reg, offset); 12171 12172 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12173 value)) 12174 return false; 12175 } 12176 12177 // Elem[D[d],index,esize] = MemU[address,ebytes]; 12178 uint32_t element = MemURead(context, address, esize, 0, &success); 12179 if (!success) 12180 return false; 12181 12182 element = element << (index * esize); 12183 12184 uint64_t reg_data = 12185 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12186 if (!success) 12187 return false; 12188 12189 uint64_t all_ones = -1; 12190 uint64_t mask = all_ones 12191 << ((index + 1) * esize); // mask is all 1's to left of 12192 // where 'element' goes, & all 0's 12193 // at element & to the right of element. 12194 if (index > 0) 12195 mask = mask | Bits64(all_ones, (index * esize) - 1, 12196 0); // add 1's to the right of where 'element' goes. 12197 // now mask should be 0's where element goes & 1's everywhere else. 12198 12199 uint64_t masked_reg = 12200 reg_data & mask; // Take original reg value & zero out 'element' bits 12201 reg_data = 12202 masked_reg & element; // Put 'element' into those bits in reg_data. 12203 12204 context.type = eContextRegisterLoad; 12205 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 12206 reg_data)) 12207 return false; 12208 } 12209 return true; 12210 } 12211 12212 // A8.6.391 VST1 (multiple single elements) Vector Store (multiple single 12213 // elements) stores elements to memory from one, two, three, or four registers, 12214 // without interleaving. Every element of each register is stored. 12215 bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode, 12216 ARMEncoding encoding) { 12217 #if 0 12218 if ConditionPassed() then 12219 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12220 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12221 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12222 for r = 0 to regs-1 12223 for e = 0 to elements-1 12224 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12225 address = address + ebytes; 12226 #endif 12227 12228 bool success = false; 12229 12230 if (ConditionPassed(opcode)) { 12231 uint32_t regs; 12232 uint32_t alignment; 12233 uint32_t ebytes; 12234 uint32_t esize; 12235 uint32_t elements; 12236 uint32_t d; 12237 uint32_t n; 12238 uint32_t m; 12239 bool wback; 12240 bool register_index; 12241 12242 switch (encoding) { 12243 case eEncodingT1: 12244 case eEncodingA1: { 12245 uint32_t type = Bits32(opcode, 11, 8); 12246 uint32_t align = Bits32(opcode, 5, 4); 12247 12248 // case type of 12249 if (type == 7) // when '0111' 12250 { 12251 // regs = 1; if align<1> == '1' then UNDEFINED; 12252 regs = 1; 12253 if (BitIsSet(align, 1)) 12254 return false; 12255 } else if (type == 10) // when '1010' 12256 { 12257 // regs = 2; if align == '11' then UNDEFINED; 12258 regs = 2; 12259 if (align == 3) 12260 return false; 12261 } else if (type == 6) // when '0110' 12262 { 12263 // regs = 3; if align<1> == '1' then UNDEFINED; 12264 regs = 3; 12265 if (BitIsSet(align, 1)) 12266 return false; 12267 } else if (type == 2) // when '0010' 12268 // regs = 4; 12269 regs = 4; 12270 else // otherwise 12271 // SEE 'Related encodings'; 12272 return false; 12273 12274 // alignment = if align == '00' then 1 else 4 << UInt(align); 12275 if (align == 0) 12276 alignment = 1; 12277 else 12278 alignment = 4 << align; 12279 12280 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 12281 ebytes = 1 << Bits32(opcode, 7, 6); 12282 esize = 8 * ebytes; 12283 elements = 8 / ebytes; 12284 12285 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12286 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12287 n = Bits32(opcode, 19, 16); 12288 m = Bits32(opcode, 3, 0); 12289 12290 // wback = (m != 15); register_index = (m != 15 && m != 13); 12291 wback = (m != 15); 12292 register_index = ((m != 15) && (m != 13)); 12293 12294 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12295 if ((d + regs) > 32) 12296 return false; 12297 12298 if (n == 15) 12299 return false; 12300 12301 } break; 12302 12303 default: 12304 return false; 12305 } 12306 12307 RegisterInfo base_reg; 12308 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12309 12310 uint32_t Rn = ReadCoreReg(n, &success); 12311 if (!success) 12312 return false; 12313 12314 // address = R[n]; if (address MOD alignment) != 0 then 12315 // GenerateAlignmentException(); 12316 addr_t address = Rn; 12317 if ((address % alignment) != 0) 12318 return false; 12319 12320 EmulateInstruction::Context context; 12321 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12322 if (wback) { 12323 uint32_t Rm = ReadCoreReg(m, &success); 12324 if (!success) 12325 return false; 12326 12327 uint32_t offset; 12328 if (register_index) 12329 offset = Rm; 12330 else 12331 offset = 8 * regs; 12332 12333 context.type = eContextAdjustBaseRegister; 12334 context.SetRegisterPlusOffset(base_reg, offset); 12335 12336 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12337 Rn + offset)) 12338 return false; 12339 } 12340 12341 RegisterInfo data_reg; 12342 context.type = eContextRegisterStore; 12343 // for r = 0 to regs-1 12344 for (uint32_t r = 0; r < regs; ++r) { 12345 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 12346 uint64_t register_data = ReadRegisterUnsigned( 12347 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 12348 if (!success) 12349 return false; 12350 12351 // for e = 0 to elements-1 12352 for (uint32_t e = 0; e < elements; ++e) { 12353 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12354 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize); 12355 12356 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12357 address - Rn); 12358 if (!MemUWrite(context, address, word, ebytes)) 12359 return false; 12360 12361 // address = address + ebytes; 12362 address = address + ebytes; 12363 } 12364 } 12365 } 12366 return true; 12367 } 12368 12369 // A8.6.392 VST1 (single element from one lane) This instruction stores one 12370 // element to memory from one element of a register. 12371 bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode, 12372 ARMEncoding encoding) { 12373 #if 0 12374 if ConditionPassed() then 12375 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12376 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12377 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12378 MemU[address,ebytes] = Elem[D[d],index,esize]; 12379 #endif 12380 12381 bool success = false; 12382 12383 if (ConditionPassed(opcode)) { 12384 uint32_t ebytes; 12385 uint32_t esize; 12386 uint32_t index; 12387 uint32_t alignment; 12388 uint32_t d; 12389 uint32_t n; 12390 uint32_t m; 12391 bool wback; 12392 bool register_index; 12393 12394 switch (encoding) { 12395 case eEncodingT1: 12396 case eEncodingA1: { 12397 uint32_t size = Bits32(opcode, 11, 10); 12398 uint32_t index_align = Bits32(opcode, 7, 4); 12399 12400 // if size == '11' then UNDEFINED; 12401 if (size == 3) 12402 return false; 12403 12404 // case size of 12405 if (size == 0) // when '00' 12406 { 12407 // if index_align<0> != '0' then UNDEFINED; 12408 if (BitIsClear(index_align, 0)) 12409 return false; 12410 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12411 ebytes = 1; 12412 esize = 8; 12413 index = Bits32(index_align, 3, 1); 12414 alignment = 1; 12415 } else if (size == 1) // when '01' 12416 { 12417 // if index_align<1> != '0' then UNDEFINED; 12418 if (BitIsClear(index_align, 1)) 12419 return false; 12420 12421 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12422 ebytes = 2; 12423 esize = 16; 12424 index = Bits32(index_align, 3, 2); 12425 12426 // alignment = if index_align<0> == '0' then 1 else 2; 12427 if (BitIsClear(index_align, 0)) 12428 alignment = 1; 12429 else 12430 alignment = 2; 12431 } else if (size == 2) // when '10' 12432 { 12433 // if index_align<2> != '0' then UNDEFINED; 12434 if (BitIsClear(index_align, 2)) 12435 return false; 12436 12437 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12438 // UNDEFINED; 12439 if ((Bits32(index_align, 1, 0) != 0) && 12440 (Bits32(index_align, 1, 0) != 3)) 12441 return false; 12442 12443 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12444 ebytes = 4; 12445 esize = 32; 12446 index = Bit32(index_align, 3); 12447 12448 // alignment = if index_align<1:0> == '00' then 1 else 4; 12449 if (Bits32(index_align, 1, 0) == 0) 12450 alignment = 1; 12451 else 12452 alignment = 4; 12453 } else { 12454 return false; 12455 } 12456 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12457 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12458 n = Bits32(opcode, 19, 16); 12459 m = Bits32(opcode, 3, 0); 12460 12461 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12462 // then UNPREDICTABLE; 12463 wback = (m != 15); 12464 register_index = ((m != 15) && (m != 13)); 12465 12466 if (n == 15) 12467 return false; 12468 } break; 12469 12470 default: 12471 return false; 12472 } 12473 12474 RegisterInfo base_reg; 12475 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12476 12477 uint32_t Rn = ReadCoreReg(n, &success); 12478 if (!success) 12479 return false; 12480 12481 // address = R[n]; if (address MOD alignment) != 0 then 12482 // GenerateAlignmentException(); 12483 addr_t address = Rn; 12484 if ((address % alignment) != 0) 12485 return false; 12486 12487 EmulateInstruction::Context context; 12488 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12489 if (wback) { 12490 uint32_t Rm = ReadCoreReg(m, &success); 12491 if (!success) 12492 return false; 12493 12494 uint32_t offset; 12495 if (register_index) 12496 offset = Rm; 12497 else 12498 offset = ebytes; 12499 12500 context.type = eContextAdjustBaseRegister; 12501 context.SetRegisterPlusOffset(base_reg, offset); 12502 12503 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12504 Rn + offset)) 12505 return false; 12506 } 12507 12508 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12509 uint64_t register_data = 12510 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12511 if (!success) 12512 return false; 12513 12514 uint64_t word = 12515 Bits64(register_data, ((index + 1) * esize) - 1, index * esize); 12516 12517 RegisterInfo data_reg; 12518 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12519 context.type = eContextRegisterStore; 12520 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 12521 12522 if (!MemUWrite(context, address, word, ebytes)) 12523 return false; 12524 } 12525 return true; 12526 } 12527 12528 // A8.6.309 VLD1 (single element to all lanes) This instruction loads one 12529 // element from memory into every element of one or two vectors. 12530 bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode, 12531 const ARMEncoding encoding) { 12532 #if 0 12533 if ConditionPassed() then 12534 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12535 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12536 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12537 replicated_element = Replicate(MemU[address,ebytes], elements); 12538 for r = 0 to regs-1 12539 D[d+r] = replicated_element; 12540 #endif 12541 12542 bool success = false; 12543 12544 if (ConditionPassed(opcode)) { 12545 uint32_t ebytes; 12546 uint32_t elements; 12547 uint32_t regs; 12548 uint32_t alignment; 12549 uint32_t d; 12550 uint32_t n; 12551 uint32_t m; 12552 bool wback; 12553 bool register_index; 12554 12555 switch (encoding) { 12556 case eEncodingT1: 12557 case eEncodingA1: { 12558 // if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12559 uint32_t size = Bits32(opcode, 7, 6); 12560 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4))) 12561 return false; 12562 12563 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' 12564 // then 1 else 2; 12565 ebytes = 1 << size; 12566 elements = 8 / ebytes; 12567 if (BitIsClear(opcode, 5)) 12568 regs = 1; 12569 else 12570 regs = 2; 12571 12572 // alignment = if a == '0' then 1 else ebytes; 12573 if (BitIsClear(opcode, 4)) 12574 alignment = 1; 12575 else 12576 alignment = ebytes; 12577 12578 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12579 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12580 n = Bits32(opcode, 19, 16); 12581 m = Bits32(opcode, 3, 0); 12582 12583 // wback = (m != 15); register_index = (m != 15 && m != 13); 12584 wback = (m != 15); 12585 register_index = ((m != 15) && (m != 13)); 12586 12587 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12588 if ((d + regs) > 32) 12589 return false; 12590 12591 if (n == 15) 12592 return false; 12593 } break; 12594 12595 default: 12596 return false; 12597 } 12598 12599 RegisterInfo base_reg; 12600 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12601 12602 uint32_t Rn = ReadCoreReg(n, &success); 12603 if (!success) 12604 return false; 12605 12606 // address = R[n]; if (address MOD alignment) != 0 then 12607 // GenerateAlignmentException(); 12608 addr_t address = Rn; 12609 if ((address % alignment) != 0) 12610 return false; 12611 12612 EmulateInstruction::Context context; 12613 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12614 if (wback) { 12615 uint32_t Rm = ReadCoreReg(m, &success); 12616 if (!success) 12617 return false; 12618 12619 uint32_t offset; 12620 if (register_index) 12621 offset = Rm; 12622 else 12623 offset = ebytes; 12624 12625 context.type = eContextAdjustBaseRegister; 12626 context.SetRegisterPlusOffset(base_reg, offset); 12627 12628 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12629 Rn + offset)) 12630 return false; 12631 } 12632 12633 // replicated_element = Replicate(MemU[address,ebytes], elements); 12634 12635 context.type = eContextRegisterLoad; 12636 uint64_t word = MemURead(context, address, ebytes, 0, &success); 12637 if (!success) 12638 return false; 12639 12640 uint64_t replicated_element = 0; 12641 uint32_t esize = ebytes * 8; 12642 for (uint32_t e = 0; e < elements; ++e) 12643 replicated_element = 12644 (replicated_element << esize) | Bits64(word, esize - 1, 0); 12645 12646 // for r = 0 to regs-1 12647 for (uint32_t r = 0; r < regs; ++r) { 12648 // D[d+r] = replicated_element; 12649 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12650 replicated_element)) 12651 return false; 12652 } 12653 } 12654 return true; 12655 } 12656 12657 // B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const? 12658 // instruction provides an exception return without the use of the stack. It 12659 // subtracts the immediate constant from the LR, branches to the resulting 12660 // address, and also copies the SPSR to the CPSR. 12661 bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode, 12662 const ARMEncoding encoding) { 12663 #if 0 12664 if ConditionPassed() then 12665 EncodingSpecificOperations(); 12666 if CurrentInstrSet() == InstrSet_ThumbEE then 12667 UNPREDICTABLE; 12668 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12669 case opcode of 12670 when '0000' result = R[n] AND operand2; // AND 12671 when '0001' result = R[n] EOR operand2; // EOR 12672 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12673 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12674 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12675 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12676 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12677 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12678 when '1100' result = R[n] OR operand2; // ORR 12679 when '1101' result = operand2; // MOV 12680 when '1110' result = R[n] AND NOT(operand2); // BIC 12681 when '1111' result = NOT(operand2); // MVN 12682 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12683 BranchWritePC(result); 12684 #endif 12685 12686 bool success = false; 12687 12688 if (ConditionPassed(opcode)) { 12689 uint32_t n; 12690 uint32_t m; 12691 uint32_t imm32; 12692 bool register_form; 12693 ARM_ShifterType shift_t; 12694 uint32_t shift_n; 12695 uint32_t code; 12696 12697 switch (encoding) { 12698 case eEncodingT1: 12699 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14; 12700 // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; 12701 // // = SUB 12702 n = 14; 12703 imm32 = Bits32(opcode, 7, 0); 12704 register_form = false; 12705 code = 2; 12706 12707 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12708 if (InITBlock() && !LastInITBlock()) 12709 return false; 12710 12711 break; 12712 12713 case eEncodingA1: 12714 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12715 n = Bits32(opcode, 19, 16); 12716 imm32 = ARMExpandImm(opcode); 12717 register_form = false; 12718 code = Bits32(opcode, 24, 21); 12719 12720 break; 12721 12722 case eEncodingA2: 12723 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12724 n = Bits32(opcode, 19, 16); 12725 m = Bits32(opcode, 3, 0); 12726 register_form = true; 12727 12728 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12729 shift_n = DecodeImmShiftARM(opcode, shift_t); 12730 12731 break; 12732 12733 default: 12734 return false; 12735 } 12736 12737 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) 12738 // else imm32; 12739 uint32_t operand2; 12740 if (register_form) { 12741 uint32_t Rm = ReadCoreReg(m, &success); 12742 if (!success) 12743 return false; 12744 12745 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success); 12746 if (!success) 12747 return false; 12748 } else { 12749 operand2 = imm32; 12750 } 12751 12752 uint32_t Rn = ReadCoreReg(n, &success); 12753 if (!success) 12754 return false; 12755 12756 AddWithCarryResult result; 12757 12758 // case opcode of 12759 switch (code) { 12760 case 0: // when '0000' 12761 // result = R[n] AND operand2; // AND 12762 result.result = Rn & operand2; 12763 break; 12764 12765 case 1: // when '0001' 12766 // result = R[n] EOR operand2; // EOR 12767 result.result = Rn ^ operand2; 12768 break; 12769 12770 case 2: // when '0010' 12771 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12772 result = AddWithCarry(Rn, ~(operand2), 1); 12773 break; 12774 12775 case 3: // when '0011' 12776 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12777 result = AddWithCarry(~(Rn), operand2, 1); 12778 break; 12779 12780 case 4: // when '0100' 12781 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12782 result = AddWithCarry(Rn, operand2, 0); 12783 break; 12784 12785 case 5: // when '0101' 12786 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12787 result = AddWithCarry(Rn, operand2, APSR_C); 12788 break; 12789 12790 case 6: // when '0110' 12791 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12792 result = AddWithCarry(Rn, ~(operand2), APSR_C); 12793 break; 12794 12795 case 7: // when '0111' 12796 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12797 result = AddWithCarry(~(Rn), operand2, APSR_C); 12798 break; 12799 12800 case 10: // when '1100' 12801 // result = R[n] OR operand2; // ORR 12802 result.result = Rn | operand2; 12803 break; 12804 12805 case 11: // when '1101' 12806 // result = operand2; // MOV 12807 result.result = operand2; 12808 break; 12809 12810 case 12: // when '1110' 12811 // result = R[n] AND NOT(operand2); // BIC 12812 result.result = Rn & ~(operand2); 12813 break; 12814 12815 case 15: // when '1111' 12816 // result = NOT(operand2); // MVN 12817 result.result = ~(operand2); 12818 break; 12819 12820 default: 12821 return false; 12822 } 12823 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12824 12825 // For now, in emulation mode, we don't have access to the SPSR, so we will 12826 // use the CPSR instead, and hope for the best. 12827 uint32_t spsr = 12828 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12829 if (!success) 12830 return false; 12831 12832 CPSRWriteByInstr(spsr, 15, true); 12833 12834 // BranchWritePC(result); 12835 EmulateInstruction::Context context; 12836 context.type = eContextAdjustPC; 12837 context.SetImmediate(result.result); 12838 12839 BranchWritePC(context, result.result); 12840 } 12841 return true; 12842 } 12843 12844 EmulateInstructionARM::ARMOpcode * 12845 EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode, 12846 uint32_t arm_isa) { 12847 static ARMOpcode g_arm_opcodes[] = { 12848 // Prologue instructions 12849 12850 // push register(s) 12851 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12852 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 12853 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12854 &EmulateInstructionARM::EmulatePUSH, "push <register>"}, 12855 12856 // set r7 to point to a stack offset 12857 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12858 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"}, 12859 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12860 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12861 // copy the stack pointer to ip 12862 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, 12863 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"}, 12864 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12865 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"}, 12866 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12867 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12868 12869 // adjust the stack pointer 12870 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12871 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12872 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12873 &EmulateInstructionARM::EmulateSUBSPReg, 12874 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 12875 12876 // push one register 12877 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12878 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12879 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"}, 12880 12881 // vector push consecutive extension register(s) 12882 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12883 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12884 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12885 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12886 12887 // Epilogue instructions 12888 12889 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12890 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12891 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12892 &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12893 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12894 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12895 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12896 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12897 12898 // Supervisor Call (previously Software Interrupt) 12899 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12900 &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12901 12902 // Branch instructions 12903 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and 12904 // "bl <label>". 12905 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, 12906 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12907 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12908 &EmulateInstructionARM::EmulateB, "b #imm24"}, 12909 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12910 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12911 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, 12912 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12913 // for example, "bx lr" 12914 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, 12915 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12916 // bxj 12917 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, 12918 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12919 12920 // Data-processing instructions 12921 // adc (immediate) 12922 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12923 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12924 // adc (register) 12925 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12926 &EmulateInstructionARM::EmulateADCReg, 12927 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12928 // add (immediate) 12929 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12930 &EmulateInstructionARM::EmulateADDImmARM, 12931 "add{s}<c> <Rd>, <Rn>, #const"}, 12932 // add (register) 12933 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12934 &EmulateInstructionARM::EmulateADDReg, 12935 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12936 // add (register-shifted register) 12937 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, 12938 &EmulateInstructionARM::EmulateADDRegShift, 12939 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12940 // adr 12941 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12942 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12943 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, 12944 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12945 // and (immediate) 12946 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12947 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12948 // and (register) 12949 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12950 &EmulateInstructionARM::EmulateANDReg, 12951 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12952 // bic (immediate) 12953 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12954 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12955 // bic (register) 12956 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12957 &EmulateInstructionARM::EmulateBICReg, 12958 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12959 // eor (immediate) 12960 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12961 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12962 // eor (register) 12963 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12964 &EmulateInstructionARM::EmulateEORReg, 12965 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12966 // orr (immediate) 12967 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12968 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12969 // orr (register) 12970 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12971 &EmulateInstructionARM::EmulateORRReg, 12972 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12973 // rsb (immediate) 12974 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12975 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12976 // rsb (register) 12977 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12978 &EmulateInstructionARM::EmulateRSBReg, 12979 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12980 // rsc (immediate) 12981 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12982 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12983 // rsc (register) 12984 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12985 &EmulateInstructionARM::EmulateRSCReg, 12986 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12987 // sbc (immediate) 12988 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12989 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12990 // sbc (register) 12991 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12992 &EmulateInstructionARM::EmulateSBCReg, 12993 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12994 // sub (immediate, ARM) 12995 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12996 &EmulateInstructionARM::EmulateSUBImmARM, 12997 "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12998 // sub (sp minus immediate) 12999 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13000 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 13001 // sub (register) 13002 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13003 &EmulateInstructionARM::EmulateSUBReg, 13004 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 13005 // teq (immediate) 13006 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13007 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 13008 // teq (register) 13009 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13010 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13011 // tst (immediate) 13012 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13013 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 13014 // tst (register) 13015 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13016 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 13017 13018 // mov (immediate) 13019 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13020 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 13021 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 13022 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"}, 13023 // mov (register) 13024 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13025 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 13026 // mvn (immediate) 13027 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13028 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 13029 // mvn (register) 13030 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13031 &EmulateInstructionARM::EmulateMVNReg, 13032 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 13033 // cmn (immediate) 13034 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13035 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13036 // cmn (register) 13037 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13038 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13039 // cmp (immediate) 13040 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13041 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 13042 // cmp (register) 13043 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13044 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 13045 // asr (immediate) 13046 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, 13047 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 13048 // asr (register) 13049 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13050 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 13051 // lsl (immediate) 13052 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13053 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 13054 // lsl (register) 13055 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, 13056 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 13057 // lsr (immediate) 13058 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, 13059 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 13060 // lsr (register) 13061 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13062 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 13063 // rrx is a special case encoding of ror (immediate) 13064 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13065 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 13066 // ror (immediate) 13067 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13068 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 13069 // ror (register) 13070 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, 13071 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 13072 // mul 13073 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, 13074 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"}, 13075 13076 // subs pc, lr and related instructions 13077 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13078 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13079 "<opc>S<c> PC,#<const> | <Rn>,#<const>"}, 13080 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, 13081 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13082 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"}, 13083 13084 // Load instructions 13085 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13086 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13087 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13088 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"}, 13089 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13090 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13091 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13092 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"}, 13093 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13094 &EmulateInstructionARM::EmulateLDRImmediateARM, 13095 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"}, 13096 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13097 &EmulateInstructionARM::EmulateLDRRegister, 13098 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"}, 13099 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13100 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 13101 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13102 &EmulateInstructionARM::EmulateLDRBRegister, 13103 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"}, 13104 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13105 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13106 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13107 &EmulateInstructionARM::EmulateLDRHRegister, 13108 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13109 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13110 &EmulateInstructionARM::EmulateLDRSBImmediate, 13111 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"}, 13112 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13113 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"}, 13114 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13115 &EmulateInstructionARM::EmulateLDRSBRegister, 13116 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13117 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13118 &EmulateInstructionARM::EmulateLDRSHImmediate, 13119 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 13120 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13121 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13122 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13123 &EmulateInstructionARM::EmulateLDRSHRegister, 13124 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13125 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13126 &EmulateInstructionARM::EmulateLDRDImmediate, 13127 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 13128 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13129 &EmulateInstructionARM::EmulateLDRDRegister, 13130 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13131 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13132 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13133 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13134 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13135 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13136 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13137 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13138 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13139 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13140 &EmulateInstructionARM::EmulateVLD1Multiple, 13141 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13142 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13143 &EmulateInstructionARM::EmulateVLD1Single, 13144 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13145 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13146 &EmulateInstructionARM::EmulateVLD1SingleAll, 13147 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13148 13149 // Store instructions 13150 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13151 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13152 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13153 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"}, 13154 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13155 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13156 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13157 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"}, 13158 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13159 &EmulateInstructionARM::EmulateSTRRegister, 13160 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"}, 13161 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13162 &EmulateInstructionARM::EmulateSTRHRegister, 13163 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"}, 13164 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13165 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 13166 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13167 &EmulateInstructionARM::EmulateSTRBImmARM, 13168 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13169 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13170 &EmulateInstructionARM::EmulateSTRImmARM, 13171 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13172 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13173 &EmulateInstructionARM::EmulateSTRDImm, 13174 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 13175 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13176 &EmulateInstructionARM::EmulateSTRDReg, 13177 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13178 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13179 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13180 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13181 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13182 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13183 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 13184 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13185 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 13186 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13187 &EmulateInstructionARM::EmulateVST1Multiple, 13188 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13189 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13190 &EmulateInstructionARM::EmulateVST1Single, 13191 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13192 13193 // Other instructions 13194 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13195 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13196 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13197 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"}, 13198 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13199 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13200 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13201 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"}, 13202 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13203 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"} 13204 13205 }; 13206 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 13207 13208 for (size_t i = 0; i < k_num_arm_opcodes; ++i) { 13209 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 13210 (g_arm_opcodes[i].variants & arm_isa) != 0) 13211 return &g_arm_opcodes[i]; 13212 } 13213 return nullptr; 13214 } 13215 13216 EmulateInstructionARM::ARMOpcode * 13217 EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode, 13218 uint32_t arm_isa) { 13219 13220 static ARMOpcode g_thumb_opcodes[] = { 13221 // Prologue instructions 13222 13223 // push register(s) 13224 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, 13225 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 13226 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13227 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"}, 13228 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13229 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"}, 13230 13231 // set r7 to point to a stack offset 13232 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13233 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"}, 13234 // copy the stack pointer to r7 13235 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, 13236 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"}, 13237 // move from high register to low register (comes after "mov r7, sp" to 13238 // resolve ambiguity) 13239 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, 13240 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"}, 13241 13242 // PC-relative load into register (see also EmulateADDSPRm) 13243 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13244 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 13245 13246 // adjust the stack pointer 13247 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, 13248 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 13249 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13250 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 13251 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13252 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 13253 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13254 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 13255 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13256 &EmulateInstructionARM::EmulateSUBSPReg, 13257 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 13258 13259 // vector push consecutive extension register(s) 13260 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13261 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 13262 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13263 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 13264 13265 // Epilogue instructions 13266 13267 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13268 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 13269 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13270 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 13271 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13272 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 13273 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13274 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"}, 13275 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13276 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"}, 13277 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13278 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 13279 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13280 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 13281 13282 // Supervisor Call (previously Software Interrupt) 13283 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13284 &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 13285 13286 // If Then makes up to four following instructions conditional. 13287 // The next 5 opcode _must_ come before the if then instruction 13288 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13289 &EmulateInstructionARM::EmulateNop, "nop"}, 13290 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13291 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 13292 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13293 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 13294 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13295 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 13296 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13297 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 13298 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13299 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 13300 13301 // Branch instructions 13302 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 13303 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13304 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 13305 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13306 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 13307 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13308 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 13309 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13310 &EmulateInstructionARM::EmulateB, 13311 "b<c>.w #imm8 (outside or last in IT)"}, 13312 // J1 == J2 == 1 13313 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, 13314 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 13315 // J1 == J2 == 1 13316 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, 13317 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 13318 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, 13319 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 13320 // for example, "bx lr" 13321 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, 13322 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 13323 // bxj 13324 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, 13325 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 13326 // compare and branch 13327 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13328 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 13329 // table branch byte 13330 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13331 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 13332 // table branch halfword 13333 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13334 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 13335 13336 // Data-processing instructions 13337 // adc (immediate) 13338 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13339 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 13340 // adc (register) 13341 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, 13342 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 13343 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13344 &EmulateInstructionARM::EmulateADCReg, 13345 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13346 // add (register) 13347 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13348 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 13349 // Make sure "add sp, <Rm>" comes before this instruction, so there's no 13350 // ambiguity decoding the two. 13351 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, 13352 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 13353 // adr 13354 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13355 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13356 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13357 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 13358 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13359 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13360 // and (immediate) 13361 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13362 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 13363 // and (register) 13364 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13365 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 13366 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13367 &EmulateInstructionARM::EmulateANDReg, 13368 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13369 // bic (immediate) 13370 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13371 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 13372 // bic (register) 13373 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, 13374 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 13375 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13376 &EmulateInstructionARM::EmulateBICReg, 13377 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13378 // eor (immediate) 13379 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13380 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 13381 // eor (register) 13382 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, 13383 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 13384 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13385 &EmulateInstructionARM::EmulateEORReg, 13386 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13387 // orr (immediate) 13388 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13389 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 13390 // orr (register) 13391 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, 13392 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 13393 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13394 &EmulateInstructionARM::EmulateORRReg, 13395 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13396 // rsb (immediate) 13397 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, 13398 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 13399 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13400 &EmulateInstructionARM::EmulateRSBImm, 13401 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 13402 // rsb (register) 13403 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13404 &EmulateInstructionARM::EmulateRSBReg, 13405 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13406 // sbc (immediate) 13407 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13408 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13409 // sbc (register) 13410 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, 13411 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 13412 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13413 &EmulateInstructionARM::EmulateSBCReg, 13414 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13415 // add (immediate, Thumb) 13416 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13417 &EmulateInstructionARM::EmulateADDImmThumb, 13418 "adds|add<c> <Rd>,<Rn>,#<imm3>"}, 13419 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13420 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"}, 13421 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13422 &EmulateInstructionARM::EmulateADDImmThumb, 13423 "add{s}<c>.w <Rd>,<Rn>,#<const>"}, 13424 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13425 &EmulateInstructionARM::EmulateADDImmThumb, 13426 "addw<c> <Rd>,<Rn>,#<imm12>"}, 13427 // sub (immediate, Thumb) 13428 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13429 &EmulateInstructionARM::EmulateSUBImmThumb, 13430 "subs|sub<c> <Rd>, <Rn> #imm3"}, 13431 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, 13432 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 13433 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13434 &EmulateInstructionARM::EmulateSUBImmThumb, 13435 "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 13436 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13437 &EmulateInstructionARM::EmulateSUBImmThumb, 13438 "subw<c> <Rd>, <Rn>, #imm12"}, 13439 // sub (sp minus immediate) 13440 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13441 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 13442 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13443 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 13444 // sub (register) 13445 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13446 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 13447 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13448 &EmulateInstructionARM::EmulateSUBReg, 13449 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 13450 // teq (immediate) 13451 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13452 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 13453 // teq (register) 13454 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13455 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13456 // tst (immediate) 13457 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13458 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 13459 // tst (register) 13460 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, 13461 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 13462 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13463 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 13464 13465 // move from high register to high register 13466 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, 13467 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 13468 // move from low register to low register 13469 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13470 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 13471 // mov{s}<c>.w <Rd>, <Rm> 13472 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13473 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 13474 // move immediate 13475 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13476 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 13477 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13478 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 13479 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13480 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 13481 // mvn (immediate) 13482 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13483 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 13484 // mvn (register) 13485 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13486 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 13487 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13488 &EmulateInstructionARM::EmulateMVNReg, 13489 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 13490 // cmn (immediate) 13491 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13492 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13493 // cmn (register) 13494 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13495 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 13496 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13497 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13498 // cmp (immediate) 13499 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13500 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 13501 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13502 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 13503 // cmp (register) (Rn and Rm both from r0-r7) 13504 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, 13505 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13506 // cmp (register) (Rn and Rm not both from r0-r7) 13507 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, 13508 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13509 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, 13510 &EmulateInstructionARM::EmulateCMPReg, 13511 "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 13512 // asr (immediate) 13513 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13514 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 13515 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13516 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 13517 // asr (register) 13518 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, 13519 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 13520 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13521 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13522 // lsl (immediate) 13523 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13524 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 13525 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13526 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 13527 // lsl (register) 13528 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13529 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 13530 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13531 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13532 // lsr (immediate) 13533 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13534 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 13535 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13536 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 13537 // lsr (register) 13538 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13539 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 13540 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13541 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13542 // rrx is a special case encoding of ror (immediate) 13543 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13544 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 13545 // ror (immediate) 13546 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13547 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 13548 // ror (register) 13549 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13550 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 13551 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13552 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13553 // mul 13554 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13555 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"}, 13556 // mul 13557 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13558 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"}, 13559 13560 // subs pc, lr and related instructions 13561 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13562 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"}, 13563 13564 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE 13565 // LDM.. Instructions in this table; 13566 // otherwise the wrong instructions will be selected. 13567 13568 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13569 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"}, 13570 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13571 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"}, 13572 13573 // Load instructions 13574 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13575 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13576 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13577 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"}, 13578 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13579 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13580 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13581 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 13582 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13583 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 13584 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13585 &EmulateInstructionARM::EmulateLDRRtRnImm, 13586 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 13587 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13588 &EmulateInstructionARM::EmulateLDRRtRnImm, 13589 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 13590 // Thumb2 PC-relative load into register 13591 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13592 &EmulateInstructionARM::EmulateLDRRtPCRelative, 13593 "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 13594 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13595 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"}, 13596 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13597 &EmulateInstructionARM::EmulateLDRRegister, 13598 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"}, 13599 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13600 &EmulateInstructionARM::EmulateLDRBImmediate, 13601 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"}, 13602 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13603 &EmulateInstructionARM::EmulateLDRBImmediate, 13604 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13605 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13606 &EmulateInstructionARM::EmulateLDRBImmediate, 13607 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"}, 13608 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13609 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"}, 13610 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13611 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"}, 13612 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13613 &EmulateInstructionARM::EmulateLDRBRegister, 13614 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13615 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13616 &EmulateInstructionARM::EmulateLDRHImmediate, 13617 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"}, 13618 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13619 &EmulateInstructionARM::EmulateLDRHImmediate, 13620 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13621 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13622 &EmulateInstructionARM::EmulateLDRHImmediate, 13623 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"}, 13624 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13625 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13626 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13627 &EmulateInstructionARM::EmulateLDRHRegister, 13628 "ldrh<c> <Rt>, [<Rn>,<Rm>]"}, 13629 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13630 &EmulateInstructionARM::EmulateLDRHRegister, 13631 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13632 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13633 &EmulateInstructionARM::EmulateLDRSBImmediate, 13634 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"}, 13635 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13636 &EmulateInstructionARM::EmulateLDRSBImmediate, 13637 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13638 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13639 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"}, 13640 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13641 &EmulateInstructionARM::EmulateLDRSBRegister, 13642 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"}, 13643 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13644 &EmulateInstructionARM::EmulateLDRSBRegister, 13645 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13646 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13647 &EmulateInstructionARM::EmulateLDRSHImmediate, 13648 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"}, 13649 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13650 &EmulateInstructionARM::EmulateLDRSHImmediate, 13651 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13652 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13653 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13654 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13655 &EmulateInstructionARM::EmulateLDRSHRegister, 13656 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"}, 13657 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13658 &EmulateInstructionARM::EmulateLDRSHRegister, 13659 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13660 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13661 &EmulateInstructionARM::EmulateLDRDImmediate, 13662 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 13663 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13664 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13665 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13666 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13667 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13668 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13669 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13670 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 13671 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13672 &EmulateInstructionARM::EmulateVLD1Multiple, 13673 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13674 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13675 &EmulateInstructionARM::EmulateVLD1Single, 13676 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13677 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13678 &EmulateInstructionARM::EmulateVLD1SingleAll, 13679 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13680 13681 // Store instructions 13682 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13683 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13684 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13685 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"}, 13686 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13687 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13688 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13689 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"}, 13690 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13691 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"}, 13692 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13693 &EmulateInstructionARM::EmulateSTRThumb, 13694 "str<c>.w <Rt>, [<Rn>,#<imm12>]"}, 13695 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13696 &EmulateInstructionARM::EmulateSTRThumb, 13697 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"}, 13698 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13699 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"}, 13700 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13701 &EmulateInstructionARM::EmulateSTRRegister, 13702 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"}, 13703 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13704 &EmulateInstructionARM::EmulateSTRBThumb, 13705 "strb<c> <Rt>, [<Rn>, #<imm5>]"}, 13706 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13707 &EmulateInstructionARM::EmulateSTRBThumb, 13708 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"}, 13709 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13710 &EmulateInstructionARM::EmulateSTRBThumb, 13711 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"}, 13712 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13713 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"}, 13714 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13715 &EmulateInstructionARM::EmulateSTRHRegister, 13716 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13717 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13718 &EmulateInstructionARM::EmulateSTREX, 13719 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"}, 13720 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13721 &EmulateInstructionARM::EmulateSTRDImm, 13722 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 13723 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13724 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13725 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13726 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13727 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13728 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13729 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13730 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13731 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13732 &EmulateInstructionARM::EmulateVST1Multiple, 13733 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13734 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13735 &EmulateInstructionARM::EmulateVST1Single, 13736 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13737 13738 // Other instructions 13739 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13740 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"}, 13741 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, 13742 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13743 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13744 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"}, 13745 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13746 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13747 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13748 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"}, 13749 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13750 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13751 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13752 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"}, 13753 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13754 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13755 }; 13756 13757 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 13758 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) { 13759 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 13760 (g_thumb_opcodes[i].variants & arm_isa) != 0) 13761 return &g_thumb_opcodes[i]; 13762 } 13763 return nullptr; 13764 } 13765 13766 bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) { 13767 m_arch = arch; 13768 m_arm_isa = 0; 13769 const char *arch_cstr = arch.GetArchitectureName(); 13770 if (arch_cstr) { 13771 if (0 == ::strcasecmp(arch_cstr, "armv4t")) 13772 m_arm_isa = ARMv4T; 13773 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) 13774 m_arm_isa = ARMv5TEJ; 13775 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) 13776 m_arm_isa = ARMv5TE; 13777 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) 13778 m_arm_isa = ARMv5T; 13779 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) 13780 m_arm_isa = ARMv6K; 13781 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) 13782 m_arm_isa = ARMv6T2; 13783 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) 13784 m_arm_isa = ARMv7S; 13785 else if (0 == ::strcasecmp(arch_cstr, "arm")) 13786 m_arm_isa = ARMvAll; 13787 else if (0 == ::strcasecmp(arch_cstr, "thumb")) 13788 m_arm_isa = ARMvAll; 13789 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5)) 13790 m_arm_isa = ARMv4; 13791 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5)) 13792 m_arm_isa = ARMv6; 13793 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5)) 13794 m_arm_isa = ARMv7; 13795 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5)) 13796 m_arm_isa = ARMv8; 13797 } 13798 return m_arm_isa != 0; 13799 } 13800 13801 bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode, 13802 const Address &inst_addr, 13803 Target *target) { 13804 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { 13805 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || 13806 m_arch.IsAlwaysThumbInstructions()) 13807 m_opcode_mode = eModeThumb; 13808 else { 13809 AddressClass addr_class = inst_addr.GetAddressClass(); 13810 13811 if ((addr_class == AddressClass::eCode) || 13812 (addr_class == AddressClass::eUnknown)) 13813 m_opcode_mode = eModeARM; 13814 else if (addr_class == AddressClass::eCodeAlternateISA) 13815 m_opcode_mode = eModeThumb; 13816 else 13817 return false; 13818 } 13819 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions()) 13820 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13821 else 13822 m_opcode_cpsr = CPSR_MODE_USR; 13823 return true; 13824 } 13825 return false; 13826 } 13827 13828 bool EmulateInstructionARM::ReadInstruction() { 13829 bool success = false; 13830 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric, 13831 LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13832 if (success) { 13833 addr_t pc = 13834 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 13835 LLDB_INVALID_ADDRESS, &success); 13836 if (success) { 13837 Context read_inst_context; 13838 read_inst_context.type = eContextReadOpcode; 13839 read_inst_context.SetNoArgs(); 13840 13841 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) { 13842 m_opcode_mode = eModeThumb; 13843 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13844 13845 if (success) { 13846 if ((thumb_opcode & 0xe000) != 0xe000 || 13847 ((thumb_opcode & 0x1800u) == 0)) { 13848 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder()); 13849 } else { 13850 m_opcode.SetOpcode32( 13851 (thumb_opcode << 16) | 13852 MemARead(read_inst_context, pc + 2, 2, 0, &success), 13853 GetByteOrder()); 13854 } 13855 } 13856 } else { 13857 m_opcode_mode = eModeARM; 13858 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success), 13859 GetByteOrder()); 13860 } 13861 13862 if (!m_ignore_conditions) { 13863 // If we are not ignoreing the conditions then init the it session from 13864 // the current value of cpsr. 13865 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | 13866 Bits32(m_opcode_cpsr, 26, 25); 13867 if (it != 0) 13868 m_it_session.InitIT(it); 13869 } 13870 } 13871 } 13872 if (!success) { 13873 m_opcode_mode = eModeInvalid; 13874 m_addr = LLDB_INVALID_ADDRESS; 13875 } 13876 return success; 13877 } 13878 13879 uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; } 13880 13881 bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) { 13882 // If we are ignoring conditions, then always return true. this allows us to 13883 // iterate over disassembly code and still emulate an instruction even if we 13884 // don't have all the right bits set in the CPSR register... 13885 if (m_ignore_conditions) 13886 return true; 13887 13888 const uint32_t cond = CurrentCond(opcode); 13889 if (cond == UINT32_MAX) 13890 return false; 13891 13892 bool result = false; 13893 switch (UnsignedBits(cond, 3, 1)) { 13894 case 0: 13895 if (m_opcode_cpsr == 0) 13896 result = true; 13897 else 13898 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13899 break; 13900 case 1: 13901 if (m_opcode_cpsr == 0) 13902 result = true; 13903 else 13904 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13905 break; 13906 case 2: 13907 if (m_opcode_cpsr == 0) 13908 result = true; 13909 else 13910 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13911 break; 13912 case 3: 13913 if (m_opcode_cpsr == 0) 13914 result = true; 13915 else 13916 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13917 break; 13918 case 4: 13919 if (m_opcode_cpsr == 0) 13920 result = true; 13921 else 13922 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && 13923 ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13924 break; 13925 case 5: 13926 if (m_opcode_cpsr == 0) 13927 result = true; 13928 else { 13929 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13930 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13931 result = n == v; 13932 } 13933 break; 13934 case 6: 13935 if (m_opcode_cpsr == 0) 13936 result = true; 13937 else { 13938 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13939 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13940 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13941 } 13942 break; 13943 case 7: 13944 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13945 // opcodes different meanings, but always means execution happens. 13946 return true; 13947 } 13948 13949 if (cond & 1) 13950 result = !result; 13951 return result; 13952 } 13953 13954 uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) { 13955 switch (m_opcode_mode) { 13956 case eModeInvalid: 13957 break; 13958 13959 case eModeARM: 13960 return UnsignedBits(opcode, 31, 28); 13961 13962 case eModeThumb: 13963 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13964 // 'cond' field of the encoding. 13965 { 13966 const uint32_t byte_size = m_opcode.GetByteSize(); 13967 if (byte_size == 2) { 13968 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 13969 return Bits32(opcode, 11, 8); 13970 } else if (byte_size == 4) { 13971 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 && 13972 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) { 13973 return Bits32(opcode, 25, 22); 13974 } 13975 } else 13976 // We have an invalid thumb instruction, let's bail out. 13977 break; 13978 13979 return m_it_session.GetCond(); 13980 } 13981 } 13982 return UINT32_MAX; // Return invalid value 13983 } 13984 13985 bool EmulateInstructionARM::InITBlock() { 13986 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13987 } 13988 13989 bool EmulateInstructionARM::LastInITBlock() { 13990 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13991 } 13992 13993 bool EmulateInstructionARM::BadMode(uint32_t mode) { 13994 13995 switch (mode) { 13996 case 16: 13997 return false; // '10000' 13998 case 17: 13999 return false; // '10001' 14000 case 18: 14001 return false; // '10010' 14002 case 19: 14003 return false; // '10011' 14004 case 22: 14005 return false; // '10110' 14006 case 23: 14007 return false; // '10111' 14008 case 27: 14009 return false; // '11011' 14010 case 31: 14011 return false; // '11111' 14012 default: 14013 return true; 14014 } 14015 return true; 14016 } 14017 14018 bool EmulateInstructionARM::CurrentModeIsPrivileged() { 14019 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0); 14020 14021 if (BadMode(mode)) 14022 return false; 14023 14024 if (mode == 16) 14025 return false; 14026 14027 return true; 14028 } 14029 14030 void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask, 14031 bool affect_execstate) { 14032 bool privileged = CurrentModeIsPrivileged(); 14033 14034 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20; 14035 14036 if (BitIsSet(bytemask, 3)) { 14037 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27); 14038 if (affect_execstate) 14039 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24); 14040 } 14041 14042 if (BitIsSet(bytemask, 2)) { 14043 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16); 14044 } 14045 14046 if (BitIsSet(bytemask, 1)) { 14047 if (affect_execstate) 14048 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10); 14049 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9); 14050 if (privileged) 14051 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8); 14052 } 14053 14054 if (BitIsSet(bytemask, 0)) { 14055 if (privileged) 14056 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6); 14057 if (affect_execstate) 14058 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5); 14059 if (privileged) 14060 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0); 14061 } 14062 14063 m_opcode_cpsr = tmp_cpsr; 14064 } 14065 14066 bool EmulateInstructionARM::BranchWritePC(const Context &context, 14067 uint32_t addr) { 14068 addr_t target; 14069 14070 // Check the current instruction set. 14071 if (CurrentInstrSet() == eModeARM) 14072 target = addr & 0xfffffffc; 14073 else 14074 target = addr & 0xfffffffe; 14075 14076 return WriteRegisterUnsigned(context, eRegisterKindGeneric, 14077 LLDB_REGNUM_GENERIC_PC, target); 14078 } 14079 14080 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by 14081 // inspecting addr. 14082 bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) { 14083 addr_t target; 14084 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 14085 // we want to record it and issue a WriteRegister callback so the clients can 14086 // track the mode changes accordingly. 14087 bool cpsr_changed = false; 14088 14089 if (BitIsSet(addr, 0)) { 14090 if (CurrentInstrSet() != eModeThumb) { 14091 SelectInstrSet(eModeThumb); 14092 cpsr_changed = true; 14093 } 14094 target = addr & 0xfffffffe; 14095 context.SetISA(eModeThumb); 14096 } else if (BitIsClear(addr, 1)) { 14097 if (CurrentInstrSet() != eModeARM) { 14098 SelectInstrSet(eModeARM); 14099 cpsr_changed = true; 14100 } 14101 target = addr & 0xfffffffc; 14102 context.SetISA(eModeARM); 14103 } else 14104 return false; // address<1:0> == '10' => UNPREDICTABLE 14105 14106 if (cpsr_changed) { 14107 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14108 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14109 return false; 14110 } 14111 return WriteRegisterUnsigned(context, eRegisterKindGeneric, 14112 LLDB_REGNUM_GENERIC_PC, target); 14113 } 14114 14115 // Dispatches to either BXWritePC or BranchWritePC based on architecture 14116 // versions. 14117 bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) { 14118 if (ArchVersion() >= ARMv5T) 14119 return BXWritePC(context, addr); 14120 else 14121 return BranchWritePC((const Context)context, addr); 14122 } 14123 14124 // Dispatches to either BXWritePC or BranchWritePC based on architecture 14125 // versions and current instruction set. 14126 bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) { 14127 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 14128 return BXWritePC(context, addr); 14129 else 14130 return BranchWritePC((const Context)context, addr); 14131 } 14132 14133 EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() { 14134 return m_opcode_mode; 14135 } 14136 14137 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 14138 // ReadInstruction() is performed. This function has a side effect of updating 14139 // the m_new_inst_cpsr member variable if necessary. 14140 bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) { 14141 m_new_inst_cpsr = m_opcode_cpsr; 14142 switch (arm_or_thumb) { 14143 default: 14144 return false; 14145 case eModeARM: 14146 // Clear the T bit. 14147 m_new_inst_cpsr &= ~MASK_CPSR_T; 14148 break; 14149 case eModeThumb: 14150 // Set the T bit. 14151 m_new_inst_cpsr |= MASK_CPSR_T; 14152 break; 14153 } 14154 return true; 14155 } 14156 14157 // This function returns TRUE if the processor currently provides support for 14158 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 14159 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 14160 bool EmulateInstructionARM::UnalignedSupport() { 14161 return (ArchVersion() >= ARMv7); 14162 } 14163 14164 // The main addition and subtraction instructions can produce status 14165 // information about both unsigned carry and signed overflow conditions. This 14166 // status information can be used to synthesize multi-word additions and 14167 // subtractions. 14168 EmulateInstructionARM::AddWithCarryResult 14169 EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) { 14170 uint32_t result; 14171 uint8_t carry_out; 14172 uint8_t overflow; 14173 14174 uint64_t unsigned_sum = x + y + carry_in; 14175 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 14176 14177 result = UnsignedBits(unsigned_sum, 31, 0); 14178 // carry_out = (result == unsigned_sum ? 0 : 1); 14179 overflow = ((int32_t)result == signed_sum ? 0 : 1); 14180 14181 if (carry_in) 14182 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0; 14183 else 14184 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0; 14185 14186 AddWithCarryResult res = {result, carry_out, overflow}; 14187 return res; 14188 } 14189 14190 uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) { 14191 lldb::RegisterKind reg_kind; 14192 uint32_t reg_num; 14193 switch (num) { 14194 case SP_REG: 14195 reg_kind = eRegisterKindGeneric; 14196 reg_num = LLDB_REGNUM_GENERIC_SP; 14197 break; 14198 case LR_REG: 14199 reg_kind = eRegisterKindGeneric; 14200 reg_num = LLDB_REGNUM_GENERIC_RA; 14201 break; 14202 case PC_REG: 14203 reg_kind = eRegisterKindGeneric; 14204 reg_num = LLDB_REGNUM_GENERIC_PC; 14205 break; 14206 default: 14207 if (num < SP_REG) { 14208 reg_kind = eRegisterKindDWARF; 14209 reg_num = dwarf_r0 + num; 14210 } else { 14211 // assert(0 && "Invalid register number"); 14212 *success = false; 14213 return UINT32_MAX; 14214 } 14215 break; 14216 } 14217 14218 // Read our register. 14219 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success); 14220 14221 // When executing an ARM instruction , PC reads as the address of the current 14222 // instruction plus 8. When executing a Thumb instruction , PC reads as the 14223 // address of the current instruction plus 4. 14224 if (num == 15) { 14225 if (CurrentInstrSet() == eModeARM) 14226 val += 8; 14227 else 14228 val += 4; 14229 } 14230 14231 return val; 14232 } 14233 14234 // Write the result to the ARM core register Rd, and optionally update the 14235 // condition flags based on the result. 14236 // 14237 // This helper method tries to encapsulate the following pseudocode from the 14238 // ARM Architecture Reference Manual: 14239 // 14240 // if d == 15 then // Can only occur for encoding A1 14241 // ALUWritePC(result); // setflags is always FALSE here 14242 // else 14243 // R[d] = result; 14244 // if setflags then 14245 // APSR.N = result<31>; 14246 // APSR.Z = IsZeroBit(result); 14247 // APSR.C = carry; 14248 // // APSR.V unchanged 14249 // 14250 // In the above case, the API client does not pass in the overflow arg, which 14251 // defaults to ~0u. 14252 bool EmulateInstructionARM::WriteCoreRegOptionalFlags( 14253 Context &context, const uint32_t result, const uint32_t Rd, bool setflags, 14254 const uint32_t carry, const uint32_t overflow) { 14255 if (Rd == 15) { 14256 if (!ALUWritePC(context, result)) 14257 return false; 14258 } else { 14259 lldb::RegisterKind reg_kind; 14260 uint32_t reg_num; 14261 switch (Rd) { 14262 case SP_REG: 14263 reg_kind = eRegisterKindGeneric; 14264 reg_num = LLDB_REGNUM_GENERIC_SP; 14265 break; 14266 case LR_REG: 14267 reg_kind = eRegisterKindGeneric; 14268 reg_num = LLDB_REGNUM_GENERIC_RA; 14269 break; 14270 default: 14271 reg_kind = eRegisterKindDWARF; 14272 reg_num = dwarf_r0 + Rd; 14273 } 14274 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result)) 14275 return false; 14276 if (setflags) 14277 return WriteFlags(context, result, carry, overflow); 14278 } 14279 return true; 14280 } 14281 14282 // This helper method tries to encapsulate the following pseudocode from the 14283 // ARM Architecture Reference Manual: 14284 // 14285 // APSR.N = result<31>; 14286 // APSR.Z = IsZeroBit(result); 14287 // APSR.C = carry; 14288 // APSR.V = overflow 14289 // 14290 // Default arguments can be specified for carry and overflow parameters, which 14291 // means not to update the respective flags. 14292 bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result, 14293 const uint32_t carry, 14294 const uint32_t overflow) { 14295 m_new_inst_cpsr = m_opcode_cpsr; 14296 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 14297 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 14298 if (carry != ~0u) 14299 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 14300 if (overflow != ~0u) 14301 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 14302 if (m_new_inst_cpsr != m_opcode_cpsr) { 14303 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14304 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14305 return false; 14306 } 14307 return true; 14308 } 14309 14310 bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) { 14311 ARMOpcode *opcode_data = nullptr; 14312 14313 if (m_opcode_mode == eModeThumb) 14314 opcode_data = 14315 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14316 else if (m_opcode_mode == eModeARM) 14317 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14318 14319 const bool auto_advance_pc = 14320 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 14321 m_ignore_conditions = 14322 evaluate_options & eEmulateInstructionOptionIgnoreConditions; 14323 14324 bool success = false; 14325 if (m_opcode_cpsr == 0 || !m_ignore_conditions) { 14326 m_opcode_cpsr = 14327 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 14328 } 14329 14330 // Only return false if we are unable to read the CPSR if we care about 14331 // conditions 14332 if (!success && !m_ignore_conditions) 14333 return false; 14334 14335 uint32_t orig_pc_value = 0; 14336 if (auto_advance_pc) { 14337 orig_pc_value = 14338 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14339 if (!success) 14340 return false; 14341 } 14342 14343 // Call the Emulate... function if we managed to decode the opcode. 14344 if (opcode_data) { 14345 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(), 14346 opcode_data->encoding); 14347 if (!success) 14348 return false; 14349 } 14350 14351 // Advance the ITSTATE bits to their values for the next instruction if we 14352 // haven't just executed an IT instruction what initialized it. 14353 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() && 14354 (opcode_data == nullptr || 14355 opcode_data->callback != &EmulateInstructionARM::EmulateIT)) 14356 m_it_session.ITAdvance(); 14357 14358 if (auto_advance_pc) { 14359 uint32_t after_pc_value = 14360 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14361 if (!success) 14362 return false; 14363 14364 if (after_pc_value == orig_pc_value) { 14365 after_pc_value += m_opcode.GetByteSize(); 14366 14367 EmulateInstruction::Context context; 14368 context.type = eContextAdvancePC; 14369 context.SetNoArgs(); 14370 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc, 14371 after_pc_value)) 14372 return false; 14373 } 14374 } 14375 return true; 14376 } 14377 14378 EmulateInstruction::InstructionCondition 14379 EmulateInstructionARM::GetInstructionCondition() { 14380 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32()); 14381 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX) 14382 return EmulateInstruction::UnconditionalCondition; 14383 return cond; 14384 } 14385 14386 bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, 14387 OptionValueDictionary *test_data) { 14388 if (!test_data) { 14389 out_stream->Printf("TestEmulation: Missing test data.\n"); 14390 return false; 14391 } 14392 14393 static ConstString opcode_key("opcode"); 14394 static ConstString before_key("before_state"); 14395 static ConstString after_key("after_state"); 14396 14397 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key); 14398 14399 uint32_t test_opcode; 14400 if ((value_sp.get() == nullptr) || 14401 (value_sp->GetType() != OptionValue::eTypeUInt64)) { 14402 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n"); 14403 return false; 14404 } 14405 test_opcode = value_sp->GetUInt64Value(); 14406 14407 if (arch.GetTriple().getArch() == llvm::Triple::thumb || 14408 arch.IsAlwaysThumbInstructions()) { 14409 m_opcode_mode = eModeThumb; 14410 if (test_opcode < 0x10000) 14411 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder()); 14412 else 14413 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14414 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) { 14415 m_opcode_mode = eModeARM; 14416 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14417 } else { 14418 out_stream->Printf("TestEmulation: Invalid arch.\n"); 14419 return false; 14420 } 14421 14422 EmulationStateARM before_state; 14423 EmulationStateARM after_state; 14424 14425 value_sp = test_data->GetValueForKey(before_key); 14426 if ((value_sp.get() == nullptr) || 14427 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14428 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n"); 14429 return false; 14430 } 14431 14432 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary(); 14433 if (!before_state.LoadStateFromDictionary(state_dictionary)) { 14434 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n"); 14435 return false; 14436 } 14437 14438 value_sp = test_data->GetValueForKey(after_key); 14439 if ((value_sp.get() == nullptr) || 14440 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14441 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n"); 14442 return false; 14443 } 14444 14445 state_dictionary = value_sp->GetAsDictionary(); 14446 if (!after_state.LoadStateFromDictionary(state_dictionary)) { 14447 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n"); 14448 return false; 14449 } 14450 14451 SetBaton((void *)&before_state); 14452 SetCallbacks(&EmulationStateARM::ReadPseudoMemory, 14453 &EmulationStateARM::WritePseudoMemory, 14454 &EmulationStateARM::ReadPseudoRegister, 14455 &EmulationStateARM::WritePseudoRegister); 14456 14457 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 14458 if (!success) { 14459 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n"); 14460 return false; 14461 } 14462 14463 success = before_state.CompareState(after_state); 14464 if (!success) 14465 out_stream->Printf( 14466 "TestEmulation: 'before' and 'after' states do not match.\n"); 14467 14468 return success; 14469 } 14470 // 14471 // 14472 // const char * 14473 // EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 14474 //{ 14475 // if (reg_kind == eRegisterKindGeneric) 14476 // { 14477 // switch (reg_num) 14478 // { 14479 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 14480 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 14481 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 14482 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 14483 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 14484 // default: return NULL; 14485 // } 14486 // } 14487 // else if (reg_kind == eRegisterKindDWARF) 14488 // { 14489 // return GetARMDWARFRegisterName (reg_num); 14490 // } 14491 // return NULL; 14492 //} 14493 // 14494 bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { 14495 unwind_plan.Clear(); 14496 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 14497 14498 UnwindPlan::RowSP row(new UnwindPlan::Row); 14499 14500 // Our previous Call Frame Address is the stack pointer 14501 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0); 14502 14503 unwind_plan.AppendRow(row); 14504 unwind_plan.SetSourceName("EmulateInstructionARM"); 14505 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 14506 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 14507 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 14508 unwind_plan.SetReturnAddressRegister(dwarf_lr); 14509 return true; 14510 } 14511