1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include <stdlib.h> 11 12 #include "EmulateInstructionARM.h" 13 #include "EmulationStateARM.h" 14 #include "lldb/Core/Address.h" 15 #include "lldb/Core/PluginManager.h" 16 #include "lldb/Host/PosixApi.h" 17 #include "lldb/Interpreter/OptionValueArray.h" 18 #include "lldb/Interpreter/OptionValueDictionary.h" 19 #include "lldb/Symbol/UnwindPlan.h" 20 #include "lldb/Utility/ArchSpec.h" 21 #include "lldb/Utility/ConstString.h" 22 #include "lldb/Utility/Stream.h" 23 24 #include "Plugins/Process/Utility/ARMDefines.h" 25 #include "Plugins/Process/Utility/ARMUtils.h" 26 #include "Utility/ARM_DWARF_Registers.h" 27 28 #include "llvm/ADT/STLExtras.h" 29 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function 30 // and countTrailingZeros function 31 32 using namespace lldb; 33 using namespace lldb_private; 34 35 // Convenient macro definitions. 36 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 37 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 38 39 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 40 41 //---------------------------------------------------------------------- 42 // 43 // ITSession implementation 44 // 45 //---------------------------------------------------------------------- 46 47 static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo ®_info) { 48 ::memset(®_info, 0, sizeof(RegisterInfo)); 49 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); 50 51 if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) { 52 reg_info.byte_size = 16; 53 reg_info.format = eFormatVectorOfUInt8; 54 reg_info.encoding = eEncodingVector; 55 } 56 57 if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) { 58 reg_info.byte_size = 8; 59 reg_info.format = eFormatFloat; 60 reg_info.encoding = eEncodingIEEE754; 61 } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) { 62 reg_info.byte_size = 4; 63 reg_info.format = eFormatFloat; 64 reg_info.encoding = eEncodingIEEE754; 65 } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) { 66 reg_info.byte_size = 12; 67 reg_info.format = eFormatFloat; 68 reg_info.encoding = eEncodingIEEE754; 69 } else { 70 reg_info.byte_size = 4; 71 reg_info.format = eFormatHex; 72 reg_info.encoding = eEncodingUint; 73 } 74 75 reg_info.kinds[eRegisterKindDWARF] = reg_num; 76 77 switch (reg_num) { 78 case dwarf_r0: 79 reg_info.name = "r0"; 80 break; 81 case dwarf_r1: 82 reg_info.name = "r1"; 83 break; 84 case dwarf_r2: 85 reg_info.name = "r2"; 86 break; 87 case dwarf_r3: 88 reg_info.name = "r3"; 89 break; 90 case dwarf_r4: 91 reg_info.name = "r4"; 92 break; 93 case dwarf_r5: 94 reg_info.name = "r5"; 95 break; 96 case dwarf_r6: 97 reg_info.name = "r6"; 98 break; 99 case dwarf_r7: 100 reg_info.name = "r7"; 101 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; 102 break; 103 case dwarf_r8: 104 reg_info.name = "r8"; 105 break; 106 case dwarf_r9: 107 reg_info.name = "r9"; 108 break; 109 case dwarf_r10: 110 reg_info.name = "r10"; 111 break; 112 case dwarf_r11: 113 reg_info.name = "r11"; 114 break; 115 case dwarf_r12: 116 reg_info.name = "r12"; 117 break; 118 case dwarf_sp: 119 reg_info.name = "sp"; 120 reg_info.alt_name = "r13"; 121 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; 122 break; 123 case dwarf_lr: 124 reg_info.name = "lr"; 125 reg_info.alt_name = "r14"; 126 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; 127 break; 128 case dwarf_pc: 129 reg_info.name = "pc"; 130 reg_info.alt_name = "r15"; 131 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; 132 break; 133 case dwarf_cpsr: 134 reg_info.name = "cpsr"; 135 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; 136 break; 137 138 case dwarf_s0: 139 reg_info.name = "s0"; 140 break; 141 case dwarf_s1: 142 reg_info.name = "s1"; 143 break; 144 case dwarf_s2: 145 reg_info.name = "s2"; 146 break; 147 case dwarf_s3: 148 reg_info.name = "s3"; 149 break; 150 case dwarf_s4: 151 reg_info.name = "s4"; 152 break; 153 case dwarf_s5: 154 reg_info.name = "s5"; 155 break; 156 case dwarf_s6: 157 reg_info.name = "s6"; 158 break; 159 case dwarf_s7: 160 reg_info.name = "s7"; 161 break; 162 case dwarf_s8: 163 reg_info.name = "s8"; 164 break; 165 case dwarf_s9: 166 reg_info.name = "s9"; 167 break; 168 case dwarf_s10: 169 reg_info.name = "s10"; 170 break; 171 case dwarf_s11: 172 reg_info.name = "s11"; 173 break; 174 case dwarf_s12: 175 reg_info.name = "s12"; 176 break; 177 case dwarf_s13: 178 reg_info.name = "s13"; 179 break; 180 case dwarf_s14: 181 reg_info.name = "s14"; 182 break; 183 case dwarf_s15: 184 reg_info.name = "s15"; 185 break; 186 case dwarf_s16: 187 reg_info.name = "s16"; 188 break; 189 case dwarf_s17: 190 reg_info.name = "s17"; 191 break; 192 case dwarf_s18: 193 reg_info.name = "s18"; 194 break; 195 case dwarf_s19: 196 reg_info.name = "s19"; 197 break; 198 case dwarf_s20: 199 reg_info.name = "s20"; 200 break; 201 case dwarf_s21: 202 reg_info.name = "s21"; 203 break; 204 case dwarf_s22: 205 reg_info.name = "s22"; 206 break; 207 case dwarf_s23: 208 reg_info.name = "s23"; 209 break; 210 case dwarf_s24: 211 reg_info.name = "s24"; 212 break; 213 case dwarf_s25: 214 reg_info.name = "s25"; 215 break; 216 case dwarf_s26: 217 reg_info.name = "s26"; 218 break; 219 case dwarf_s27: 220 reg_info.name = "s27"; 221 break; 222 case dwarf_s28: 223 reg_info.name = "s28"; 224 break; 225 case dwarf_s29: 226 reg_info.name = "s29"; 227 break; 228 case dwarf_s30: 229 reg_info.name = "s30"; 230 break; 231 case dwarf_s31: 232 reg_info.name = "s31"; 233 break; 234 235 // FPA Registers 0-7 236 case dwarf_f0: 237 reg_info.name = "f0"; 238 break; 239 case dwarf_f1: 240 reg_info.name = "f1"; 241 break; 242 case dwarf_f2: 243 reg_info.name = "f2"; 244 break; 245 case dwarf_f3: 246 reg_info.name = "f3"; 247 break; 248 case dwarf_f4: 249 reg_info.name = "f4"; 250 break; 251 case dwarf_f5: 252 reg_info.name = "f5"; 253 break; 254 case dwarf_f6: 255 reg_info.name = "f6"; 256 break; 257 case dwarf_f7: 258 reg_info.name = "f7"; 259 break; 260 261 // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator 262 // register 0 - 7 (they do overlap with wCGR0 - wCGR7) 263 case dwarf_wCGR0: 264 reg_info.name = "wCGR0/ACC0"; 265 break; 266 case dwarf_wCGR1: 267 reg_info.name = "wCGR1/ACC1"; 268 break; 269 case dwarf_wCGR2: 270 reg_info.name = "wCGR2/ACC2"; 271 break; 272 case dwarf_wCGR3: 273 reg_info.name = "wCGR3/ACC3"; 274 break; 275 case dwarf_wCGR4: 276 reg_info.name = "wCGR4/ACC4"; 277 break; 278 case dwarf_wCGR5: 279 reg_info.name = "wCGR5/ACC5"; 280 break; 281 case dwarf_wCGR6: 282 reg_info.name = "wCGR6/ACC6"; 283 break; 284 case dwarf_wCGR7: 285 reg_info.name = "wCGR7/ACC7"; 286 break; 287 288 // Intel wireless MMX data registers 0 - 15 289 case dwarf_wR0: 290 reg_info.name = "wR0"; 291 break; 292 case dwarf_wR1: 293 reg_info.name = "wR1"; 294 break; 295 case dwarf_wR2: 296 reg_info.name = "wR2"; 297 break; 298 case dwarf_wR3: 299 reg_info.name = "wR3"; 300 break; 301 case dwarf_wR4: 302 reg_info.name = "wR4"; 303 break; 304 case dwarf_wR5: 305 reg_info.name = "wR5"; 306 break; 307 case dwarf_wR6: 308 reg_info.name = "wR6"; 309 break; 310 case dwarf_wR7: 311 reg_info.name = "wR7"; 312 break; 313 case dwarf_wR8: 314 reg_info.name = "wR8"; 315 break; 316 case dwarf_wR9: 317 reg_info.name = "wR9"; 318 break; 319 case dwarf_wR10: 320 reg_info.name = "wR10"; 321 break; 322 case dwarf_wR11: 323 reg_info.name = "wR11"; 324 break; 325 case dwarf_wR12: 326 reg_info.name = "wR12"; 327 break; 328 case dwarf_wR13: 329 reg_info.name = "wR13"; 330 break; 331 case dwarf_wR14: 332 reg_info.name = "wR14"; 333 break; 334 case dwarf_wR15: 335 reg_info.name = "wR15"; 336 break; 337 338 case dwarf_spsr: 339 reg_info.name = "spsr"; 340 break; 341 case dwarf_spsr_fiq: 342 reg_info.name = "spsr_fiq"; 343 break; 344 case dwarf_spsr_irq: 345 reg_info.name = "spsr_irq"; 346 break; 347 case dwarf_spsr_abt: 348 reg_info.name = "spsr_abt"; 349 break; 350 case dwarf_spsr_und: 351 reg_info.name = "spsr_und"; 352 break; 353 case dwarf_spsr_svc: 354 reg_info.name = "spsr_svc"; 355 break; 356 357 case dwarf_r8_usr: 358 reg_info.name = "r8_usr"; 359 break; 360 case dwarf_r9_usr: 361 reg_info.name = "r9_usr"; 362 break; 363 case dwarf_r10_usr: 364 reg_info.name = "r10_usr"; 365 break; 366 case dwarf_r11_usr: 367 reg_info.name = "r11_usr"; 368 break; 369 case dwarf_r12_usr: 370 reg_info.name = "r12_usr"; 371 break; 372 case dwarf_r13_usr: 373 reg_info.name = "r13_usr"; 374 break; 375 case dwarf_r14_usr: 376 reg_info.name = "r14_usr"; 377 break; 378 case dwarf_r8_fiq: 379 reg_info.name = "r8_fiq"; 380 break; 381 case dwarf_r9_fiq: 382 reg_info.name = "r9_fiq"; 383 break; 384 case dwarf_r10_fiq: 385 reg_info.name = "r10_fiq"; 386 break; 387 case dwarf_r11_fiq: 388 reg_info.name = "r11_fiq"; 389 break; 390 case dwarf_r12_fiq: 391 reg_info.name = "r12_fiq"; 392 break; 393 case dwarf_r13_fiq: 394 reg_info.name = "r13_fiq"; 395 break; 396 case dwarf_r14_fiq: 397 reg_info.name = "r14_fiq"; 398 break; 399 case dwarf_r13_irq: 400 reg_info.name = "r13_irq"; 401 break; 402 case dwarf_r14_irq: 403 reg_info.name = "r14_irq"; 404 break; 405 case dwarf_r13_abt: 406 reg_info.name = "r13_abt"; 407 break; 408 case dwarf_r14_abt: 409 reg_info.name = "r14_abt"; 410 break; 411 case dwarf_r13_und: 412 reg_info.name = "r13_und"; 413 break; 414 case dwarf_r14_und: 415 reg_info.name = "r14_und"; 416 break; 417 case dwarf_r13_svc: 418 reg_info.name = "r13_svc"; 419 break; 420 case dwarf_r14_svc: 421 reg_info.name = "r14_svc"; 422 break; 423 424 // Intel wireless MMX control register in co-processor 0 - 7 425 case dwarf_wC0: 426 reg_info.name = "wC0"; 427 break; 428 case dwarf_wC1: 429 reg_info.name = "wC1"; 430 break; 431 case dwarf_wC2: 432 reg_info.name = "wC2"; 433 break; 434 case dwarf_wC3: 435 reg_info.name = "wC3"; 436 break; 437 case dwarf_wC4: 438 reg_info.name = "wC4"; 439 break; 440 case dwarf_wC5: 441 reg_info.name = "wC5"; 442 break; 443 case dwarf_wC6: 444 reg_info.name = "wC6"; 445 break; 446 case dwarf_wC7: 447 reg_info.name = "wC7"; 448 break; 449 450 // VFP-v3/Neon 451 case dwarf_d0: 452 reg_info.name = "d0"; 453 break; 454 case dwarf_d1: 455 reg_info.name = "d1"; 456 break; 457 case dwarf_d2: 458 reg_info.name = "d2"; 459 break; 460 case dwarf_d3: 461 reg_info.name = "d3"; 462 break; 463 case dwarf_d4: 464 reg_info.name = "d4"; 465 break; 466 case dwarf_d5: 467 reg_info.name = "d5"; 468 break; 469 case dwarf_d6: 470 reg_info.name = "d6"; 471 break; 472 case dwarf_d7: 473 reg_info.name = "d7"; 474 break; 475 case dwarf_d8: 476 reg_info.name = "d8"; 477 break; 478 case dwarf_d9: 479 reg_info.name = "d9"; 480 break; 481 case dwarf_d10: 482 reg_info.name = "d10"; 483 break; 484 case dwarf_d11: 485 reg_info.name = "d11"; 486 break; 487 case dwarf_d12: 488 reg_info.name = "d12"; 489 break; 490 case dwarf_d13: 491 reg_info.name = "d13"; 492 break; 493 case dwarf_d14: 494 reg_info.name = "d14"; 495 break; 496 case dwarf_d15: 497 reg_info.name = "d15"; 498 break; 499 case dwarf_d16: 500 reg_info.name = "d16"; 501 break; 502 case dwarf_d17: 503 reg_info.name = "d17"; 504 break; 505 case dwarf_d18: 506 reg_info.name = "d18"; 507 break; 508 case dwarf_d19: 509 reg_info.name = "d19"; 510 break; 511 case dwarf_d20: 512 reg_info.name = "d20"; 513 break; 514 case dwarf_d21: 515 reg_info.name = "d21"; 516 break; 517 case dwarf_d22: 518 reg_info.name = "d22"; 519 break; 520 case dwarf_d23: 521 reg_info.name = "d23"; 522 break; 523 case dwarf_d24: 524 reg_info.name = "d24"; 525 break; 526 case dwarf_d25: 527 reg_info.name = "d25"; 528 break; 529 case dwarf_d26: 530 reg_info.name = "d26"; 531 break; 532 case dwarf_d27: 533 reg_info.name = "d27"; 534 break; 535 case dwarf_d28: 536 reg_info.name = "d28"; 537 break; 538 case dwarf_d29: 539 reg_info.name = "d29"; 540 break; 541 case dwarf_d30: 542 reg_info.name = "d30"; 543 break; 544 case dwarf_d31: 545 reg_info.name = "d31"; 546 break; 547 548 // NEON 128-bit vector registers (overlays the d registers) 549 case dwarf_q0: 550 reg_info.name = "q0"; 551 break; 552 case dwarf_q1: 553 reg_info.name = "q1"; 554 break; 555 case dwarf_q2: 556 reg_info.name = "q2"; 557 break; 558 case dwarf_q3: 559 reg_info.name = "q3"; 560 break; 561 case dwarf_q4: 562 reg_info.name = "q4"; 563 break; 564 case dwarf_q5: 565 reg_info.name = "q5"; 566 break; 567 case dwarf_q6: 568 reg_info.name = "q6"; 569 break; 570 case dwarf_q7: 571 reg_info.name = "q7"; 572 break; 573 case dwarf_q8: 574 reg_info.name = "q8"; 575 break; 576 case dwarf_q9: 577 reg_info.name = "q9"; 578 break; 579 case dwarf_q10: 580 reg_info.name = "q10"; 581 break; 582 case dwarf_q11: 583 reg_info.name = "q11"; 584 break; 585 case dwarf_q12: 586 reg_info.name = "q12"; 587 break; 588 case dwarf_q13: 589 reg_info.name = "q13"; 590 break; 591 case dwarf_q14: 592 reg_info.name = "q14"; 593 break; 594 case dwarf_q15: 595 reg_info.name = "q15"; 596 break; 597 598 default: 599 return false; 600 } 601 return true; 602 } 603 604 // A8.6.50 605 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 606 static uint32_t CountITSize(uint32_t ITMask) { 607 // First count the trailing zeros of the IT mask. 608 uint32_t TZ = llvm::countTrailingZeros(ITMask); 609 if (TZ > 3) { 610 #ifdef LLDB_CONFIGURATION_DEBUG 611 printf("Encoding error: IT Mask '0000'\n"); 612 #endif 613 return 0; 614 } 615 return (4 - TZ); 616 } 617 618 // Init ITState. Note that at least one bit is always 1 in mask. 619 bool ITSession::InitIT(uint32_t bits7_0) { 620 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 621 if (ITCounter == 0) 622 return false; 623 624 // A8.6.50 IT 625 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 626 if (FirstCond == 0xF) { 627 #ifdef LLDB_CONFIGURATION_DEBUG 628 printf("Encoding error: IT FirstCond '1111'\n"); 629 #endif 630 return false; 631 } 632 if (FirstCond == 0xE && ITCounter != 1) { 633 #ifdef LLDB_CONFIGURATION_DEBUG 634 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 635 #endif 636 return false; 637 } 638 639 ITState = bits7_0; 640 return true; 641 } 642 643 // Update ITState if necessary. 644 void ITSession::ITAdvance() { 645 // assert(ITCounter); 646 --ITCounter; 647 if (ITCounter == 0) 648 ITState = 0; 649 else { 650 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 651 SetBits32(ITState, 4, 0, NewITState4_0); 652 } 653 } 654 655 // Return true if we're inside an IT Block. 656 bool ITSession::InITBlock() { return ITCounter != 0; } 657 658 // Return true if we're the last instruction inside an IT Block. 659 bool ITSession::LastInITBlock() { return ITCounter == 1; } 660 661 // Get condition bits for the current thumb instruction. 662 uint32_t ITSession::GetCond() { 663 if (InITBlock()) 664 return Bits32(ITState, 7, 4); 665 else 666 return COND_AL; 667 } 668 669 // ARM constants used during decoding 670 #define REG_RD 0 671 #define LDM_REGLIST 1 672 #define SP_REG 13 673 #define LR_REG 14 674 #define PC_REG 15 675 #define PC_REGLIST_BIT 0x8000 676 677 #define ARMv4 (1u << 0) 678 #define ARMv4T (1u << 1) 679 #define ARMv5T (1u << 2) 680 #define ARMv5TE (1u << 3) 681 #define ARMv5TEJ (1u << 4) 682 #define ARMv6 (1u << 5) 683 #define ARMv6K (1u << 6) 684 #define ARMv6T2 (1u << 7) 685 #define ARMv7 (1u << 8) 686 #define ARMv7S (1u << 9) 687 #define ARMv8 (1u << 10) 688 #define ARMvAll (0xffffffffu) 689 690 #define ARMV4T_ABOVE \ 691 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \ 692 ARMv7S | ARMv8) 693 #define ARMV5_ABOVE \ 694 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \ 695 ARMv8) 696 #define ARMV5TE_ABOVE \ 697 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 698 #define ARMV5J_ABOVE \ 699 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 700 #define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 701 #define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 702 #define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8) 703 704 #define No_VFP 0 705 #define VFPv1 (1u << 1) 706 #define VFPv2 (1u << 2) 707 #define VFPv3 (1u << 3) 708 #define AdvancedSIMD (1u << 4) 709 710 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 711 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 712 #define VFPv2v3 (VFPv2 | VFPv3) 713 714 //---------------------------------------------------------------------- 715 // 716 // EmulateInstructionARM implementation 717 // 718 //---------------------------------------------------------------------- 719 720 void EmulateInstructionARM::Initialize() { 721 PluginManager::RegisterPlugin(GetPluginNameStatic(), 722 GetPluginDescriptionStatic(), CreateInstance); 723 } 724 725 void EmulateInstructionARM::Terminate() { 726 PluginManager::UnregisterPlugin(CreateInstance); 727 } 728 729 ConstString EmulateInstructionARM::GetPluginNameStatic() { 730 static ConstString g_name("arm"); 731 return g_name; 732 } 733 734 const char *EmulateInstructionARM::GetPluginDescriptionStatic() { 735 return "Emulate instructions for the ARM architecture."; 736 } 737 738 EmulateInstruction * 739 EmulateInstructionARM::CreateInstance(const ArchSpec &arch, 740 InstructionType inst_type) { 741 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic( 742 inst_type)) { 743 if (arch.GetTriple().getArch() == llvm::Triple::arm) { 744 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap( 745 new EmulateInstructionARM(arch)); 746 747 if (emulate_insn_ap.get()) 748 return emulate_insn_ap.release(); 749 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) { 750 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap( 751 new EmulateInstructionARM(arch)); 752 753 if (emulate_insn_ap.get()) 754 return emulate_insn_ap.release(); 755 } 756 } 757 758 return NULL; 759 } 760 761 bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) { 762 if (arch.GetTriple().getArch() == llvm::Triple::arm) 763 return true; 764 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 765 return true; 766 767 return false; 768 } 769 770 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for 771 // many ARM instructions. 772 bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) { 773 EmulateInstruction::Context context; 774 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 775 context.SetNoArgs(); 776 777 uint32_t random_data = rand(); 778 const uint32_t addr_byte_size = GetAddressByteSize(); 779 780 if (!MemAWrite(context, address, random_data, addr_byte_size)) 781 return false; 782 783 return true; 784 } 785 786 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM 787 // instructions. 788 bool EmulateInstructionARM::WriteBits32Unknown(int n) { 789 EmulateInstruction::Context context; 790 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 791 context.SetNoArgs(); 792 793 bool success; 794 uint32_t data = 795 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 796 797 if (!success) 798 return false; 799 800 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data)) 801 return false; 802 803 return true; 804 } 805 806 bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind, 807 uint32_t reg_num, 808 RegisterInfo ®_info) { 809 if (reg_kind == eRegisterKindGeneric) { 810 switch (reg_num) { 811 case LLDB_REGNUM_GENERIC_PC: 812 reg_kind = eRegisterKindDWARF; 813 reg_num = dwarf_pc; 814 break; 815 case LLDB_REGNUM_GENERIC_SP: 816 reg_kind = eRegisterKindDWARF; 817 reg_num = dwarf_sp; 818 break; 819 case LLDB_REGNUM_GENERIC_FP: 820 reg_kind = eRegisterKindDWARF; 821 reg_num = dwarf_r7; 822 break; 823 case LLDB_REGNUM_GENERIC_RA: 824 reg_kind = eRegisterKindDWARF; 825 reg_num = dwarf_lr; 826 break; 827 case LLDB_REGNUM_GENERIC_FLAGS: 828 reg_kind = eRegisterKindDWARF; 829 reg_num = dwarf_cpsr; 830 break; 831 default: 832 return false; 833 } 834 } 835 836 if (reg_kind == eRegisterKindDWARF) 837 return GetARMDWARFRegisterInfo(reg_num, reg_info); 838 return false; 839 } 840 841 uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const { 842 if (m_arch.GetTriple().isAndroid()) 843 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android 844 bool is_apple = false; 845 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 846 is_apple = true; 847 switch (m_arch.GetTriple().getOS()) { 848 case llvm::Triple::Darwin: 849 case llvm::Triple::MacOSX: 850 case llvm::Triple::IOS: 851 case llvm::Triple::TvOS: 852 case llvm::Triple::WatchOS: 853 // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS: 854 is_apple = true; 855 break; 856 default: 857 break; 858 } 859 860 /* On Apple iOS et al, the frame pointer register is always r7. 861 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 862 */ 863 864 uint32_t fp_regnum = 11; 865 866 if (is_apple) 867 fp_regnum = 7; 868 869 if (m_opcode_mode == eModeThumb) 870 fp_regnum = 7; 871 872 return fp_regnum; 873 } 874 875 uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const { 876 bool is_apple = false; 877 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 878 is_apple = true; 879 switch (m_arch.GetTriple().getOS()) { 880 case llvm::Triple::Darwin: 881 case llvm::Triple::MacOSX: 882 case llvm::Triple::IOS: 883 is_apple = true; 884 break; 885 default: 886 break; 887 } 888 889 /* On Apple iOS et al, the frame pointer register is always r7. 890 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 891 */ 892 893 uint32_t fp_regnum = dwarf_r11; 894 895 if (is_apple) 896 fp_regnum = dwarf_r7; 897 898 if (m_opcode_mode == eModeThumb) 899 fp_regnum = dwarf_r7; 900 901 return fp_regnum; 902 } 903 904 // Push Multiple Registers stores multiple registers to the stack, storing to 905 // consecutive memory locations ending just below the address in SP, and 906 // updates 907 // SP to point to the start of the stored data. 908 bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode, 909 const ARMEncoding encoding) { 910 #if 0 911 // ARM pseudo code... 912 if (ConditionPassed()) 913 { 914 EncodingSpecificOperations(); 915 NullCheckIfThumbEE(13); 916 address = SP - 4*BitCount(registers); 917 918 for (i = 0 to 14) 919 { 920 if (registers<i> == '1') 921 { 922 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 923 MemA[address,4] = bits(32) UNKNOWN; 924 else 925 MemA[address,4] = R[i]; 926 address = address + 4; 927 } 928 } 929 930 if (registers<15> == '1') // Only possible for encoding A1 or A2 931 MemA[address,4] = PCStoreValue(); 932 933 SP = SP - 4*BitCount(registers); 934 } 935 #endif 936 937 bool success = false; 938 if (ConditionPassed(opcode)) { 939 const uint32_t addr_byte_size = GetAddressByteSize(); 940 const addr_t sp = ReadCoreReg(SP_REG, &success); 941 if (!success) 942 return false; 943 uint32_t registers = 0; 944 uint32_t Rt; // the source register 945 switch (encoding) { 946 case eEncodingT1: 947 registers = Bits32(opcode, 7, 0); 948 // The M bit represents LR. 949 if (Bit32(opcode, 8)) 950 registers |= (1u << 14); 951 // if BitCount(registers) < 1 then UNPREDICTABLE; 952 if (BitCount(registers) < 1) 953 return false; 954 break; 955 case eEncodingT2: 956 // Ignore bits 15 & 13. 957 registers = Bits32(opcode, 15, 0) & ~0xa000; 958 // if BitCount(registers) < 2 then UNPREDICTABLE; 959 if (BitCount(registers) < 2) 960 return false; 961 break; 962 case eEncodingT3: 963 Rt = Bits32(opcode, 15, 12); 964 // if BadReg(t) then UNPREDICTABLE; 965 if (BadReg(Rt)) 966 return false; 967 registers = (1u << Rt); 968 break; 969 case eEncodingA1: 970 registers = Bits32(opcode, 15, 0); 971 // Instead of return false, let's handle the following case as well, 972 // which amounts to pushing one reg onto the full descending stacks. 973 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 974 break; 975 case eEncodingA2: 976 Rt = Bits32(opcode, 15, 12); 977 // if t == 13 then UNPREDICTABLE; 978 if (Rt == dwarf_sp) 979 return false; 980 registers = (1u << Rt); 981 break; 982 default: 983 return false; 984 } 985 addr_t sp_offset = addr_byte_size * BitCount(registers); 986 addr_t addr = sp - sp_offset; 987 uint32_t i; 988 989 EmulateInstruction::Context context; 990 context.type = EmulateInstruction::eContextPushRegisterOnStack; 991 RegisterInfo reg_info; 992 RegisterInfo sp_reg; 993 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 994 for (i = 0; i < 15; ++i) { 995 if (BitIsSet(registers, i)) { 996 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info); 997 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 998 uint32_t reg_value = ReadCoreReg(i, &success); 999 if (!success) 1000 return false; 1001 if (!MemAWrite(context, addr, reg_value, addr_byte_size)) 1002 return false; 1003 addr += addr_byte_size; 1004 } 1005 } 1006 1007 if (BitIsSet(registers, 15)) { 1008 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info); 1009 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 1010 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1011 if (!success) 1012 return false; 1013 if (!MemAWrite(context, addr, pc, addr_byte_size)) 1014 return false; 1015 } 1016 1017 context.type = EmulateInstruction::eContextAdjustStackPointer; 1018 context.SetImmediateSigned(-sp_offset); 1019 1020 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1021 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1022 return false; 1023 } 1024 return true; 1025 } 1026 1027 // Pop Multiple Registers loads multiple registers from the stack, loading from 1028 // consecutive memory locations staring at the address in SP, and updates 1029 // SP to point just above the loaded data. 1030 bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode, 1031 const ARMEncoding encoding) { 1032 #if 0 1033 // ARM pseudo code... 1034 if (ConditionPassed()) 1035 { 1036 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 1037 address = SP; 1038 for i = 0 to 14 1039 if registers<i> == '1' then 1040 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 1041 if registers<15> == '1' then 1042 if UnalignedAllowed then 1043 LoadWritePC(MemU[address,4]); 1044 else 1045 LoadWritePC(MemA[address,4]); 1046 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 1047 if registers<13> == '1' then SP = bits(32) UNKNOWN; 1048 } 1049 #endif 1050 1051 bool success = false; 1052 1053 if (ConditionPassed(opcode)) { 1054 const uint32_t addr_byte_size = GetAddressByteSize(); 1055 const addr_t sp = ReadCoreReg(SP_REG, &success); 1056 if (!success) 1057 return false; 1058 uint32_t registers = 0; 1059 uint32_t Rt; // the destination register 1060 switch (encoding) { 1061 case eEncodingT1: 1062 registers = Bits32(opcode, 7, 0); 1063 // The P bit represents PC. 1064 if (Bit32(opcode, 8)) 1065 registers |= (1u << 15); 1066 // if BitCount(registers) < 1 then UNPREDICTABLE; 1067 if (BitCount(registers) < 1) 1068 return false; 1069 break; 1070 case eEncodingT2: 1071 // Ignore bit 13. 1072 registers = Bits32(opcode, 15, 0) & ~0x2000; 1073 // if BitCount(registers) < 2 || (P == '1' && M == '1') then 1074 // UNPREDICTABLE; 1075 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 1076 return false; 1077 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 1078 // UNPREDICTABLE; 1079 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 1080 return false; 1081 break; 1082 case eEncodingT3: 1083 Rt = Bits32(opcode, 15, 12); 1084 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then 1085 // UNPREDICTABLE; 1086 if (Rt == 13) 1087 return false; 1088 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1089 return false; 1090 registers = (1u << Rt); 1091 break; 1092 case eEncodingA1: 1093 registers = Bits32(opcode, 15, 0); 1094 // Instead of return false, let's handle the following case as well, 1095 // which amounts to popping one reg from the full descending stacks. 1096 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 1097 1098 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 1099 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 1100 return false; 1101 break; 1102 case eEncodingA2: 1103 Rt = Bits32(opcode, 15, 12); 1104 // if t == 13 then UNPREDICTABLE; 1105 if (Rt == dwarf_sp) 1106 return false; 1107 registers = (1u << Rt); 1108 break; 1109 default: 1110 return false; 1111 } 1112 addr_t sp_offset = addr_byte_size * BitCount(registers); 1113 addr_t addr = sp; 1114 uint32_t i, data; 1115 1116 EmulateInstruction::Context context; 1117 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1118 1119 RegisterInfo sp_reg; 1120 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1121 1122 for (i = 0; i < 15; ++i) { 1123 if (BitIsSet(registers, i)) { 1124 context.SetAddress(addr); 1125 data = MemARead(context, addr, 4, 0, &success); 1126 if (!success) 1127 return false; 1128 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 1129 data)) 1130 return false; 1131 addr += addr_byte_size; 1132 } 1133 } 1134 1135 if (BitIsSet(registers, 15)) { 1136 context.SetRegisterPlusOffset(sp_reg, addr - sp); 1137 data = MemARead(context, addr, 4, 0, &success); 1138 if (!success) 1139 return false; 1140 // In ARMv5T and above, this is an interworking branch. 1141 if (!LoadWritePC(context, data)) 1142 return false; 1143 // addr += addr_byte_size; 1144 } 1145 1146 context.type = EmulateInstruction::eContextAdjustStackPointer; 1147 context.SetImmediateSigned(sp_offset); 1148 1149 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1150 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1151 return false; 1152 } 1153 return true; 1154 } 1155 1156 // Set r7 or ip to point to saved value residing within the stack. 1157 // ADD (SP plus immediate) 1158 bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode, 1159 const ARMEncoding encoding) { 1160 #if 0 1161 // ARM pseudo code... 1162 if (ConditionPassed()) 1163 { 1164 EncodingSpecificOperations(); 1165 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1166 if d == 15 then 1167 ALUWritePC(result); // setflags is always FALSE here 1168 else 1169 R[d] = result; 1170 if setflags then 1171 APSR.N = result<31>; 1172 APSR.Z = IsZeroBit(result); 1173 APSR.C = carry; 1174 APSR.V = overflow; 1175 } 1176 #endif 1177 1178 bool success = false; 1179 1180 if (ConditionPassed(opcode)) { 1181 const addr_t sp = ReadCoreReg(SP_REG, &success); 1182 if (!success) 1183 return false; 1184 uint32_t Rd; // the destination register 1185 uint32_t imm32; 1186 switch (encoding) { 1187 case eEncodingT1: 1188 Rd = 7; 1189 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 1190 break; 1191 case eEncodingA1: 1192 Rd = Bits32(opcode, 15, 12); 1193 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1194 break; 1195 default: 1196 return false; 1197 } 1198 addr_t sp_offset = imm32; 1199 addr_t addr = sp + sp_offset; // a pointer to the stack area 1200 1201 EmulateInstruction::Context context; 1202 if (Rd == GetFramePointerRegisterNumber()) 1203 context.type = eContextSetFramePointer; 1204 else 1205 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1206 RegisterInfo sp_reg; 1207 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1208 context.SetRegisterPlusOffset(sp_reg, sp_offset); 1209 1210 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, 1211 addr)) 1212 return false; 1213 } 1214 return true; 1215 } 1216 1217 // Set r7 or ip to the current stack pointer. 1218 // MOV (register) 1219 bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode, 1220 const ARMEncoding encoding) { 1221 #if 0 1222 // ARM pseudo code... 1223 if (ConditionPassed()) 1224 { 1225 EncodingSpecificOperations(); 1226 result = R[m]; 1227 if d == 15 then 1228 ALUWritePC(result); // setflags is always FALSE here 1229 else 1230 R[d] = result; 1231 if setflags then 1232 APSR.N = result<31>; 1233 APSR.Z = IsZeroBit(result); 1234 // APSR.C unchanged 1235 // APSR.V unchanged 1236 } 1237 #endif 1238 1239 bool success = false; 1240 1241 if (ConditionPassed(opcode)) { 1242 const addr_t sp = ReadCoreReg(SP_REG, &success); 1243 if (!success) 1244 return false; 1245 uint32_t Rd; // the destination register 1246 switch (encoding) { 1247 case eEncodingT1: 1248 Rd = 7; 1249 break; 1250 case eEncodingA1: 1251 Rd = 12; 1252 break; 1253 default: 1254 return false; 1255 } 1256 1257 EmulateInstruction::Context context; 1258 if (Rd == GetFramePointerRegisterNumber()) 1259 context.type = EmulateInstruction::eContextSetFramePointer; 1260 else 1261 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1262 RegisterInfo sp_reg; 1263 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1264 context.SetRegisterPlusOffset(sp_reg, 0); 1265 1266 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 1267 return false; 1268 } 1269 return true; 1270 } 1271 1272 // Move from high register (r8-r15) to low register (r0-r7). 1273 // MOV (register) 1274 bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode, 1275 const ARMEncoding encoding) { 1276 return EmulateMOVRdRm(opcode, encoding); 1277 } 1278 1279 // Move from register to register. 1280 // MOV (register) 1281 bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode, 1282 const ARMEncoding encoding) { 1283 #if 0 1284 // ARM pseudo code... 1285 if (ConditionPassed()) 1286 { 1287 EncodingSpecificOperations(); 1288 result = R[m]; 1289 if d == 15 then 1290 ALUWritePC(result); // setflags is always FALSE here 1291 else 1292 R[d] = result; 1293 if setflags then 1294 APSR.N = result<31>; 1295 APSR.Z = IsZeroBit(result); 1296 // APSR.C unchanged 1297 // APSR.V unchanged 1298 } 1299 #endif 1300 1301 bool success = false; 1302 1303 if (ConditionPassed(opcode)) { 1304 uint32_t Rm; // the source register 1305 uint32_t Rd; // the destination register 1306 bool setflags; 1307 switch (encoding) { 1308 case eEncodingT1: 1309 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1310 Rm = Bits32(opcode, 6, 3); 1311 setflags = false; 1312 if (Rd == 15 && InITBlock() && !LastInITBlock()) 1313 return false; 1314 break; 1315 case eEncodingT2: 1316 Rd = Bits32(opcode, 2, 0); 1317 Rm = Bits32(opcode, 5, 3); 1318 setflags = true; 1319 if (InITBlock()) 1320 return false; 1321 break; 1322 case eEncodingT3: 1323 Rd = Bits32(opcode, 11, 8); 1324 Rm = Bits32(opcode, 3, 0); 1325 setflags = BitIsSet(opcode, 20); 1326 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1327 if (setflags && (BadReg(Rd) || BadReg(Rm))) 1328 return false; 1329 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then 1330 // UNPREDICTABLE; 1331 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 1332 return false; 1333 break; 1334 case eEncodingA1: 1335 Rd = Bits32(opcode, 15, 12); 1336 Rm = Bits32(opcode, 3, 0); 1337 setflags = BitIsSet(opcode, 20); 1338 1339 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1340 // instructions; 1341 if (Rd == 15 && setflags) 1342 return EmulateSUBSPcLrEtc(opcode, encoding); 1343 break; 1344 default: 1345 return false; 1346 } 1347 uint32_t result = ReadCoreReg(Rm, &success); 1348 if (!success) 1349 return false; 1350 1351 // The context specifies that Rm is to be moved into Rd. 1352 EmulateInstruction::Context context; 1353 if (Rd == 13) 1354 context.type = EmulateInstruction::eContextAdjustStackPointer; 1355 else 1356 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1357 RegisterInfo dwarf_reg; 1358 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1359 context.SetRegisterPlusOffset(dwarf_reg, 0); 1360 1361 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 1362 return false; 1363 } 1364 return true; 1365 } 1366 1367 // Move (immediate) writes an immediate value to the destination register. It 1368 // can optionally update the condition flags based on the value. 1369 // MOV (immediate) 1370 bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode, 1371 const ARMEncoding encoding) { 1372 #if 0 1373 // ARM pseudo code... 1374 if (ConditionPassed()) 1375 { 1376 EncodingSpecificOperations(); 1377 result = imm32; 1378 if d == 15 then // Can only occur for ARM encoding 1379 ALUWritePC(result); // setflags is always FALSE here 1380 else 1381 R[d] = result; 1382 if setflags then 1383 APSR.N = result<31>; 1384 APSR.Z = IsZeroBit(result); 1385 APSR.C = carry; 1386 // APSR.V unchanged 1387 } 1388 #endif 1389 1390 if (ConditionPassed(opcode)) { 1391 uint32_t Rd; // the destination register 1392 uint32_t imm32; // the immediate value to be written to Rd 1393 uint32_t carry = 1394 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 1395 // for setflags == false, this value is a don't care initialized to 1396 // 0 to silence the static analyzer 1397 bool setflags; 1398 switch (encoding) { 1399 case eEncodingT1: 1400 Rd = Bits32(opcode, 10, 8); 1401 setflags = !InITBlock(); 1402 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 1403 carry = APSR_C; 1404 1405 break; 1406 1407 case eEncodingT2: 1408 Rd = Bits32(opcode, 11, 8); 1409 setflags = BitIsSet(opcode, 20); 1410 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1411 if (BadReg(Rd)) 1412 return false; 1413 1414 break; 1415 1416 case eEncodingT3: { 1417 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 1418 // 32); 1419 Rd = Bits32(opcode, 11, 8); 1420 setflags = false; 1421 uint32_t imm4 = Bits32(opcode, 19, 16); 1422 uint32_t imm3 = Bits32(opcode, 14, 12); 1423 uint32_t i = Bit32(opcode, 26); 1424 uint32_t imm8 = Bits32(opcode, 7, 0); 1425 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 1426 1427 // if BadReg(d) then UNPREDICTABLE; 1428 if (BadReg(Rd)) 1429 return false; 1430 } break; 1431 1432 case eEncodingA1: 1433 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = 1434 // ARMExpandImm_C(imm12, APSR.C); 1435 Rd = Bits32(opcode, 15, 12); 1436 setflags = BitIsSet(opcode, 20); 1437 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1438 1439 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1440 // instructions; 1441 if ((Rd == 15) && setflags) 1442 return EmulateSUBSPcLrEtc(opcode, encoding); 1443 1444 break; 1445 1446 case eEncodingA2: { 1447 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 1448 Rd = Bits32(opcode, 15, 12); 1449 setflags = false; 1450 uint32_t imm4 = Bits32(opcode, 19, 16); 1451 uint32_t imm12 = Bits32(opcode, 11, 0); 1452 imm32 = (imm4 << 12) | imm12; 1453 1454 // if d == 15 then UNPREDICTABLE; 1455 if (Rd == 15) 1456 return false; 1457 } break; 1458 1459 default: 1460 return false; 1461 } 1462 uint32_t result = imm32; 1463 1464 // The context specifies that an immediate is to be moved into Rd. 1465 EmulateInstruction::Context context; 1466 context.type = EmulateInstruction::eContextImmediate; 1467 context.SetNoArgs(); 1468 1469 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1470 return false; 1471 } 1472 return true; 1473 } 1474 1475 // MUL multiplies two register values. The least significant 32 bits of the 1476 // result are written to the destination 1477 // register. These 32 bits do not depend on whether the source register values 1478 // are considered to be signed values or unsigned values. 1479 // 1480 // Optionally, it can update the condition flags based on the result. In the 1481 // Thumb instruction set, this option is limited to only a few forms of the 1482 // instruction. 1483 bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode, 1484 const ARMEncoding encoding) { 1485 #if 0 1486 if ConditionPassed() then 1487 EncodingSpecificOperations(); 1488 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1489 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1490 result = operand1 * operand2; 1491 R[d] = result<31:0>; 1492 if setflags then 1493 APSR.N = result<31>; 1494 APSR.Z = IsZeroBit(result); 1495 if ArchVersion() == 4 then 1496 APSR.C = bit UNKNOWN; 1497 // else APSR.C unchanged 1498 // APSR.V always unchanged 1499 #endif 1500 1501 if (ConditionPassed(opcode)) { 1502 uint32_t d; 1503 uint32_t n; 1504 uint32_t m; 1505 bool setflags; 1506 1507 // EncodingSpecificOperations(); 1508 switch (encoding) { 1509 case eEncodingT1: 1510 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 1511 d = Bits32(opcode, 2, 0); 1512 n = Bits32(opcode, 5, 3); 1513 m = Bits32(opcode, 2, 0); 1514 setflags = !InITBlock(); 1515 1516 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1517 if ((ArchVersion() < ARMv6) && (d == n)) 1518 return false; 1519 1520 break; 1521 1522 case eEncodingT2: 1523 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 1524 d = Bits32(opcode, 11, 8); 1525 n = Bits32(opcode, 19, 16); 1526 m = Bits32(opcode, 3, 0); 1527 setflags = false; 1528 1529 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 1530 if (BadReg(d) || BadReg(n) || BadReg(m)) 1531 return false; 1532 1533 break; 1534 1535 case eEncodingA1: 1536 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 1537 d = Bits32(opcode, 19, 16); 1538 n = Bits32(opcode, 3, 0); 1539 m = Bits32(opcode, 11, 8); 1540 setflags = BitIsSet(opcode, 20); 1541 1542 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1543 if ((d == 15) || (n == 15) || (m == 15)) 1544 return false; 1545 1546 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1547 if ((ArchVersion() < ARMv6) && (d == n)) 1548 return false; 1549 1550 break; 1551 1552 default: 1553 return false; 1554 } 1555 1556 bool success = false; 1557 1558 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final 1559 // results 1560 uint64_t operand1 = 1561 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1562 if (!success) 1563 return false; 1564 1565 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final 1566 // results 1567 uint64_t operand2 = 1568 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1569 if (!success) 1570 return false; 1571 1572 // result = operand1 * operand2; 1573 uint64_t result = operand1 * operand2; 1574 1575 // R[d] = result<31:0>; 1576 RegisterInfo op1_reg; 1577 RegisterInfo op2_reg; 1578 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1579 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1580 1581 EmulateInstruction::Context context; 1582 context.type = eContextArithmetic; 1583 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 1584 1585 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 1586 (0x0000ffff & result))) 1587 return false; 1588 1589 // if setflags then 1590 if (setflags) { 1591 // APSR.N = result<31>; 1592 // APSR.Z = IsZeroBit(result); 1593 m_new_inst_cpsr = m_opcode_cpsr; 1594 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31)); 1595 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1596 if (m_new_inst_cpsr != m_opcode_cpsr) { 1597 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1598 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1599 return false; 1600 } 1601 1602 // if ArchVersion() == 4 then 1603 // APSR.C = bit UNKNOWN; 1604 } 1605 } 1606 return true; 1607 } 1608 1609 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to 1610 // the destination register. It can optionally update the condition flags based 1611 // on the value. 1612 bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode, 1613 const ARMEncoding encoding) { 1614 #if 0 1615 // ARM pseudo code... 1616 if (ConditionPassed()) 1617 { 1618 EncodingSpecificOperations(); 1619 result = NOT(imm32); 1620 if d == 15 then // Can only occur for ARM encoding 1621 ALUWritePC(result); // setflags is always FALSE here 1622 else 1623 R[d] = result; 1624 if setflags then 1625 APSR.N = result<31>; 1626 APSR.Z = IsZeroBit(result); 1627 APSR.C = carry; 1628 // APSR.V unchanged 1629 } 1630 #endif 1631 1632 if (ConditionPassed(opcode)) { 1633 uint32_t Rd; // the destination register 1634 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1635 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1636 bool setflags; 1637 switch (encoding) { 1638 case eEncodingT1: 1639 Rd = Bits32(opcode, 11, 8); 1640 setflags = BitIsSet(opcode, 20); 1641 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1642 break; 1643 case eEncodingA1: 1644 Rd = Bits32(opcode, 15, 12); 1645 setflags = BitIsSet(opcode, 20); 1646 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1647 1648 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1649 // instructions; 1650 if (Rd == 15 && setflags) 1651 return EmulateSUBSPcLrEtc(opcode, encoding); 1652 break; 1653 default: 1654 return false; 1655 } 1656 uint32_t result = ~imm32; 1657 1658 // The context specifies that an immediate is to be moved into Rd. 1659 EmulateInstruction::Context context; 1660 context.type = EmulateInstruction::eContextImmediate; 1661 context.SetNoArgs(); 1662 1663 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1664 return false; 1665 } 1666 return true; 1667 } 1668 1669 // Bitwise NOT (register) writes the bitwise inverse of a register value to the 1670 // destination register. It can optionally update the condition flags based on 1671 // the result. 1672 bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode, 1673 const ARMEncoding encoding) { 1674 #if 0 1675 // ARM pseudo code... 1676 if (ConditionPassed()) 1677 { 1678 EncodingSpecificOperations(); 1679 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1680 result = NOT(shifted); 1681 if d == 15 then // Can only occur for ARM encoding 1682 ALUWritePC(result); // setflags is always FALSE here 1683 else 1684 R[d] = result; 1685 if setflags then 1686 APSR.N = result<31>; 1687 APSR.Z = IsZeroBit(result); 1688 APSR.C = carry; 1689 // APSR.V unchanged 1690 } 1691 #endif 1692 1693 if (ConditionPassed(opcode)) { 1694 uint32_t Rm; // the source register 1695 uint32_t Rd; // the destination register 1696 ARM_ShifterType shift_t; 1697 uint32_t shift_n; // the shift applied to the value read from Rm 1698 bool setflags; 1699 uint32_t carry; // the carry bit after the shift operation 1700 switch (encoding) { 1701 case eEncodingT1: 1702 Rd = Bits32(opcode, 2, 0); 1703 Rm = Bits32(opcode, 5, 3); 1704 setflags = !InITBlock(); 1705 shift_t = SRType_LSL; 1706 shift_n = 0; 1707 if (InITBlock()) 1708 return false; 1709 break; 1710 case eEncodingT2: 1711 Rd = Bits32(opcode, 11, 8); 1712 Rm = Bits32(opcode, 3, 0); 1713 setflags = BitIsSet(opcode, 20); 1714 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1715 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1716 if (BadReg(Rd) || BadReg(Rm)) 1717 return false; 1718 break; 1719 case eEncodingA1: 1720 Rd = Bits32(opcode, 15, 12); 1721 Rm = Bits32(opcode, 3, 0); 1722 setflags = BitIsSet(opcode, 20); 1723 shift_n = DecodeImmShiftARM(opcode, shift_t); 1724 break; 1725 default: 1726 return false; 1727 } 1728 bool success = false; 1729 uint32_t value = ReadCoreReg(Rm, &success); 1730 if (!success) 1731 return false; 1732 1733 uint32_t shifted = 1734 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1735 if (!success) 1736 return false; 1737 uint32_t result = ~shifted; 1738 1739 // The context specifies that an immediate is to be moved into Rd. 1740 EmulateInstruction::Context context; 1741 context.type = EmulateInstruction::eContextImmediate; 1742 context.SetNoArgs(); 1743 1744 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1745 return false; 1746 } 1747 return true; 1748 } 1749 1750 // PC relative immediate load into register, possibly followed by ADD (SP plus 1751 // register). 1752 // LDR (literal) 1753 bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode, 1754 const ARMEncoding encoding) { 1755 #if 0 1756 // ARM pseudo code... 1757 if (ConditionPassed()) 1758 { 1759 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1760 base = Align(PC,4); 1761 address = if add then (base + imm32) else (base - imm32); 1762 data = MemU[address,4]; 1763 if t == 15 then 1764 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1765 elsif UnalignedSupport() || address<1:0> = '00' then 1766 R[t] = data; 1767 else // Can only apply before ARMv7 1768 if CurrentInstrSet() == InstrSet_ARM then 1769 R[t] = ROR(data, 8*UInt(address<1:0>)); 1770 else 1771 R[t] = bits(32) UNKNOWN; 1772 } 1773 #endif 1774 1775 if (ConditionPassed(opcode)) { 1776 bool success = false; 1777 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1778 if (!success) 1779 return false; 1780 1781 // PC relative immediate load context 1782 EmulateInstruction::Context context; 1783 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1784 RegisterInfo pc_reg; 1785 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 1786 context.SetRegisterPlusOffset(pc_reg, 0); 1787 1788 uint32_t Rt; // the destination register 1789 uint32_t imm32; // immediate offset from the PC 1790 bool add; // +imm32 or -imm32? 1791 addr_t base; // the base address 1792 addr_t address; // the PC relative address 1793 uint32_t data; // the literal data value from the PC relative load 1794 switch (encoding) { 1795 case eEncodingT1: 1796 Rt = Bits32(opcode, 10, 8); 1797 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1798 add = true; 1799 break; 1800 case eEncodingT2: 1801 Rt = Bits32(opcode, 15, 12); 1802 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1803 add = BitIsSet(opcode, 23); 1804 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1805 return false; 1806 break; 1807 default: 1808 return false; 1809 } 1810 1811 base = Align(pc, 4); 1812 if (add) 1813 address = base + imm32; 1814 else 1815 address = base - imm32; 1816 1817 context.SetRegisterPlusOffset(pc_reg, address - base); 1818 data = MemURead(context, address, 4, 0, &success); 1819 if (!success) 1820 return false; 1821 1822 if (Rt == 15) { 1823 if (Bits32(address, 1, 0) == 0) { 1824 // In ARMv5T and above, this is an interworking branch. 1825 if (!LoadWritePC(context, data)) 1826 return false; 1827 } else 1828 return false; 1829 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 1830 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 1831 data)) 1832 return false; 1833 } else // We don't handle ARM for now. 1834 return false; 1835 } 1836 return true; 1837 } 1838 1839 // An add operation to adjust the SP. 1840 // ADD (SP plus immediate) 1841 bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode, 1842 const ARMEncoding encoding) { 1843 #if 0 1844 // ARM pseudo code... 1845 if (ConditionPassed()) 1846 { 1847 EncodingSpecificOperations(); 1848 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1849 if d == 15 then // Can only occur for ARM encoding 1850 ALUWritePC(result); // setflags is always FALSE here 1851 else 1852 R[d] = result; 1853 if setflags then 1854 APSR.N = result<31>; 1855 APSR.Z = IsZeroBit(result); 1856 APSR.C = carry; 1857 APSR.V = overflow; 1858 } 1859 #endif 1860 1861 bool success = false; 1862 1863 if (ConditionPassed(opcode)) { 1864 const addr_t sp = ReadCoreReg(SP_REG, &success); 1865 if (!success) 1866 return false; 1867 uint32_t imm32; // the immediate operand 1868 uint32_t d; 1869 bool setflags; 1870 switch (encoding) { 1871 case eEncodingT1: 1872 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1873 d = Bits32(opcode, 10, 8); 1874 imm32 = (Bits32(opcode, 7, 0) << 2); 1875 setflags = false; 1876 break; 1877 1878 case eEncodingT2: 1879 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1880 d = 13; 1881 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1882 setflags = false; 1883 break; 1884 1885 case eEncodingT3: 1886 // d = UInt(Rd); setflags = (S == "1"); imm32 = 1887 // ThumbExpandImm(i:imm3:imm8); 1888 d = Bits32(opcode, 11, 8); 1889 imm32 = ThumbExpandImm(opcode); 1890 setflags = Bit32(opcode, 20); 1891 1892 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 1893 if (d == 15 && setflags == 1) 1894 return false; // CMN (immediate) not yet supported 1895 1896 // if d == 15 && S == "0" then UNPREDICTABLE; 1897 if (d == 15 && setflags == 0) 1898 return false; 1899 break; 1900 1901 case eEncodingT4: { 1902 // if Rn == '1111' then SEE ADR; 1903 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 1904 d = Bits32(opcode, 11, 8); 1905 setflags = false; 1906 uint32_t i = Bit32(opcode, 26); 1907 uint32_t imm3 = Bits32(opcode, 14, 12); 1908 uint32_t imm8 = Bits32(opcode, 7, 0); 1909 imm32 = (i << 11) | (imm3 << 8) | imm8; 1910 1911 // if d == 15 then UNPREDICTABLE; 1912 if (d == 15) 1913 return false; 1914 } break; 1915 1916 default: 1917 return false; 1918 } 1919 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 1920 AddWithCarryResult res = AddWithCarry(sp, imm32, 0); 1921 1922 EmulateInstruction::Context context; 1923 if (d == 13) 1924 context.type = EmulateInstruction::eContextAdjustStackPointer; 1925 else 1926 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1927 1928 RegisterInfo sp_reg; 1929 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1930 context.SetRegisterPlusOffset(sp_reg, res.result - sp); 1931 1932 if (d == 15) { 1933 if (!ALUWritePC(context, res.result)) 1934 return false; 1935 } else { 1936 // R[d] = result; 1937 // if setflags then 1938 // APSR.N = result<31>; 1939 // APSR.Z = IsZeroBit(result); 1940 // APSR.C = carry; 1941 // APSR.V = overflow; 1942 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 1943 res.carry_out, res.overflow)) 1944 return false; 1945 } 1946 } 1947 return true; 1948 } 1949 1950 // An add operation to adjust the SP. 1951 // ADD (SP plus register) 1952 bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode, 1953 const ARMEncoding encoding) { 1954 #if 0 1955 // ARM pseudo code... 1956 if (ConditionPassed()) 1957 { 1958 EncodingSpecificOperations(); 1959 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1960 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1961 if d == 15 then 1962 ALUWritePC(result); // setflags is always FALSE here 1963 else 1964 R[d] = result; 1965 if setflags then 1966 APSR.N = result<31>; 1967 APSR.Z = IsZeroBit(result); 1968 APSR.C = carry; 1969 APSR.V = overflow; 1970 } 1971 #endif 1972 1973 bool success = false; 1974 1975 if (ConditionPassed(opcode)) { 1976 const addr_t sp = ReadCoreReg(SP_REG, &success); 1977 if (!success) 1978 return false; 1979 uint32_t Rm; // the second operand 1980 switch (encoding) { 1981 case eEncodingT2: 1982 Rm = Bits32(opcode, 6, 3); 1983 break; 1984 default: 1985 return false; 1986 } 1987 int32_t reg_value = ReadCoreReg(Rm, &success); 1988 if (!success) 1989 return false; 1990 1991 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1992 1993 EmulateInstruction::Context context; 1994 context.type = eContextArithmetic; 1995 RegisterInfo sp_reg; 1996 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1997 1998 RegisterInfo other_reg; 1999 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 2000 context.SetRegisterRegisterOperands(sp_reg, other_reg); 2001 2002 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2003 LLDB_REGNUM_GENERIC_SP, addr)) 2004 return false; 2005 } 2006 return true; 2007 } 2008 2009 // Branch with Link and Exchange Instruction Sets (immediate) calls a 2010 // subroutine at a PC-relative address, and changes instruction set from ARM to 2011 // Thumb, or from Thumb to ARM. 2012 // BLX (immediate) 2013 bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode, 2014 const ARMEncoding encoding) { 2015 #if 0 2016 // ARM pseudo code... 2017 if (ConditionPassed()) 2018 { 2019 EncodingSpecificOperations(); 2020 if CurrentInstrSet() == InstrSet_ARM then 2021 LR = PC - 4; 2022 else 2023 LR = PC<31:1> : '1'; 2024 if targetInstrSet == InstrSet_ARM then 2025 targetAddress = Align(PC,4) + imm32; 2026 else 2027 targetAddress = PC + imm32; 2028 SelectInstrSet(targetInstrSet); 2029 BranchWritePC(targetAddress); 2030 } 2031 #endif 2032 2033 bool success = true; 2034 2035 if (ConditionPassed(opcode)) { 2036 EmulateInstruction::Context context; 2037 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2038 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2039 if (!success) 2040 return false; 2041 addr_t lr; // next instruction address 2042 addr_t target; // target address 2043 int32_t imm32; // PC-relative offset 2044 switch (encoding) { 2045 case eEncodingT1: { 2046 lr = pc | 1u; // return address 2047 uint32_t S = Bit32(opcode, 26); 2048 uint32_t imm10 = Bits32(opcode, 25, 16); 2049 uint32_t J1 = Bit32(opcode, 13); 2050 uint32_t J2 = Bit32(opcode, 11); 2051 uint32_t imm11 = Bits32(opcode, 10, 0); 2052 uint32_t I1 = !(J1 ^ S); 2053 uint32_t I2 = !(J2 ^ S); 2054 uint32_t imm25 = 2055 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2056 imm32 = llvm::SignExtend32<25>(imm25); 2057 target = pc + imm32; 2058 SelectInstrSet(eModeThumb); 2059 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2060 if (InITBlock() && !LastInITBlock()) 2061 return false; 2062 break; 2063 } 2064 case eEncodingT2: { 2065 lr = pc | 1u; // return address 2066 uint32_t S = Bit32(opcode, 26); 2067 uint32_t imm10H = Bits32(opcode, 25, 16); 2068 uint32_t J1 = Bit32(opcode, 13); 2069 uint32_t J2 = Bit32(opcode, 11); 2070 uint32_t imm10L = Bits32(opcode, 10, 1); 2071 uint32_t I1 = !(J1 ^ S); 2072 uint32_t I2 = !(J2 ^ S); 2073 uint32_t imm25 = 2074 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 2075 imm32 = llvm::SignExtend32<25>(imm25); 2076 target = Align(pc, 4) + imm32; 2077 SelectInstrSet(eModeARM); 2078 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32); 2079 if (InITBlock() && !LastInITBlock()) 2080 return false; 2081 break; 2082 } 2083 case eEncodingA1: 2084 lr = pc - 4; // return address 2085 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2086 target = Align(pc, 4) + imm32; 2087 SelectInstrSet(eModeARM); 2088 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2089 break; 2090 case eEncodingA2: 2091 lr = pc - 4; // return address 2092 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | 2093 Bits32(opcode, 24, 24) << 1); 2094 target = pc + imm32; 2095 SelectInstrSet(eModeThumb); 2096 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32); 2097 break; 2098 default: 2099 return false; 2100 } 2101 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2102 LLDB_REGNUM_GENERIC_RA, lr)) 2103 return false; 2104 if (!BranchWritePC(context, target)) 2105 return false; 2106 if (m_opcode_cpsr != m_new_inst_cpsr) 2107 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2108 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2109 return false; 2110 } 2111 return true; 2112 } 2113 2114 // Branch with Link and Exchange (register) calls a subroutine at an address 2115 // and instruction set specified by a register. 2116 // BLX (register) 2117 bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode, 2118 const ARMEncoding encoding) { 2119 #if 0 2120 // ARM pseudo code... 2121 if (ConditionPassed()) 2122 { 2123 EncodingSpecificOperations(); 2124 target = R[m]; 2125 if CurrentInstrSet() == InstrSet_ARM then 2126 next_instr_addr = PC - 4; 2127 LR = next_instr_addr; 2128 else 2129 next_instr_addr = PC - 2; 2130 LR = next_instr_addr<31:1> : '1'; 2131 BXWritePC(target); 2132 } 2133 #endif 2134 2135 bool success = false; 2136 2137 if (ConditionPassed(opcode)) { 2138 EmulateInstruction::Context context; 2139 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2140 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2141 addr_t lr; // next instruction address 2142 if (!success) 2143 return false; 2144 uint32_t Rm; // the register with the target address 2145 switch (encoding) { 2146 case eEncodingT1: 2147 lr = (pc - 2) | 1u; // return address 2148 Rm = Bits32(opcode, 6, 3); 2149 // if m == 15 then UNPREDICTABLE; 2150 if (Rm == 15) 2151 return false; 2152 if (InITBlock() && !LastInITBlock()) 2153 return false; 2154 break; 2155 case eEncodingA1: 2156 lr = pc - 4; // return address 2157 Rm = Bits32(opcode, 3, 0); 2158 // if m == 15 then UNPREDICTABLE; 2159 if (Rm == 15) 2160 return false; 2161 break; 2162 default: 2163 return false; 2164 } 2165 addr_t target = ReadCoreReg(Rm, &success); 2166 if (!success) 2167 return false; 2168 RegisterInfo dwarf_reg; 2169 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2170 context.SetRegister(dwarf_reg); 2171 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2172 LLDB_REGNUM_GENERIC_RA, lr)) 2173 return false; 2174 if (!BXWritePC(context, target)) 2175 return false; 2176 } 2177 return true; 2178 } 2179 2180 // Branch and Exchange causes a branch to an address and instruction set 2181 // specified by a register. 2182 bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode, 2183 const ARMEncoding encoding) { 2184 #if 0 2185 // ARM pseudo code... 2186 if (ConditionPassed()) 2187 { 2188 EncodingSpecificOperations(); 2189 BXWritePC(R[m]); 2190 } 2191 #endif 2192 2193 if (ConditionPassed(opcode)) { 2194 EmulateInstruction::Context context; 2195 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2196 uint32_t Rm; // the register with the target address 2197 switch (encoding) { 2198 case eEncodingT1: 2199 Rm = Bits32(opcode, 6, 3); 2200 if (InITBlock() && !LastInITBlock()) 2201 return false; 2202 break; 2203 case eEncodingA1: 2204 Rm = Bits32(opcode, 3, 0); 2205 break; 2206 default: 2207 return false; 2208 } 2209 bool success = false; 2210 addr_t target = ReadCoreReg(Rm, &success); 2211 if (!success) 2212 return false; 2213 2214 RegisterInfo dwarf_reg; 2215 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2216 context.SetRegister(dwarf_reg); 2217 if (!BXWritePC(context, target)) 2218 return false; 2219 } 2220 return true; 2221 } 2222 2223 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the 2224 // attempt fails, it branches to an address and instruction set specified by a 2225 // register as though it were a BX instruction. 2226 // 2227 // TODO: Emulate Jazelle architecture? 2228 // We currently assume that switching to Jazelle state fails, thus 2229 // treating BXJ as a BX operation. 2230 bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode, 2231 const ARMEncoding encoding) { 2232 #if 0 2233 // ARM pseudo code... 2234 if (ConditionPassed()) 2235 { 2236 EncodingSpecificOperations(); 2237 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 2238 BXWritePC(R[m]); 2239 else 2240 if JazelleAcceptsExecution() then 2241 SwitchToJazelleExecution(); 2242 else 2243 SUBARCHITECTURE_DEFINED handler call; 2244 } 2245 #endif 2246 2247 if (ConditionPassed(opcode)) { 2248 EmulateInstruction::Context context; 2249 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2250 uint32_t Rm; // the register with the target address 2251 switch (encoding) { 2252 case eEncodingT1: 2253 Rm = Bits32(opcode, 19, 16); 2254 if (BadReg(Rm)) 2255 return false; 2256 if (InITBlock() && !LastInITBlock()) 2257 return false; 2258 break; 2259 case eEncodingA1: 2260 Rm = Bits32(opcode, 3, 0); 2261 if (Rm == 15) 2262 return false; 2263 break; 2264 default: 2265 return false; 2266 } 2267 bool success = false; 2268 addr_t target = ReadCoreReg(Rm, &success); 2269 if (!success) 2270 return false; 2271 2272 RegisterInfo dwarf_reg; 2273 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2274 context.SetRegister(dwarf_reg); 2275 if (!BXWritePC(context, target)) 2276 return false; 2277 } 2278 return true; 2279 } 2280 2281 // Set r7 to point to some ip offset. 2282 // SUB (immediate) 2283 bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode, 2284 const ARMEncoding encoding) { 2285 #if 0 2286 // ARM pseudo code... 2287 if (ConditionPassed()) 2288 { 2289 EncodingSpecificOperations(); 2290 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2291 if d == 15 then // Can only occur for ARM encoding 2292 ALUWritePC(result); // setflags is always FALSE here 2293 else 2294 R[d] = result; 2295 if setflags then 2296 APSR.N = result<31>; 2297 APSR.Z = IsZeroBit(result); 2298 APSR.C = carry; 2299 APSR.V = overflow; 2300 } 2301 #endif 2302 2303 if (ConditionPassed(opcode)) { 2304 bool success = false; 2305 const addr_t ip = ReadCoreReg(12, &success); 2306 if (!success) 2307 return false; 2308 uint32_t imm32; 2309 switch (encoding) { 2310 case eEncodingA1: 2311 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2312 break; 2313 default: 2314 return false; 2315 } 2316 addr_t ip_offset = imm32; 2317 addr_t addr = ip - ip_offset; // the adjusted ip value 2318 2319 EmulateInstruction::Context context; 2320 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2321 RegisterInfo dwarf_reg; 2322 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg); 2323 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset); 2324 2325 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr)) 2326 return false; 2327 } 2328 return true; 2329 } 2330 2331 // Set ip to point to some stack offset. 2332 // SUB (SP minus immediate) 2333 bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode, 2334 const ARMEncoding encoding) { 2335 #if 0 2336 // ARM pseudo code... 2337 if (ConditionPassed()) 2338 { 2339 EncodingSpecificOperations(); 2340 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2341 if d == 15 then // Can only occur for ARM encoding 2342 ALUWritePC(result); // setflags is always FALSE here 2343 else 2344 R[d] = result; 2345 if setflags then 2346 APSR.N = result<31>; 2347 APSR.Z = IsZeroBit(result); 2348 APSR.C = carry; 2349 APSR.V = overflow; 2350 } 2351 #endif 2352 2353 if (ConditionPassed(opcode)) { 2354 bool success = false; 2355 const addr_t sp = ReadCoreReg(SP_REG, &success); 2356 if (!success) 2357 return false; 2358 uint32_t imm32; 2359 switch (encoding) { 2360 case eEncodingA1: 2361 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2362 break; 2363 default: 2364 return false; 2365 } 2366 addr_t sp_offset = imm32; 2367 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 2368 2369 EmulateInstruction::Context context; 2370 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2371 RegisterInfo dwarf_reg; 2372 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 2373 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset); 2374 2375 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr)) 2376 return false; 2377 } 2378 return true; 2379 } 2380 2381 // This instruction subtracts an immediate value from the SP value, and writes 2382 // the result to the destination register. 2383 // 2384 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local 2385 // storage. 2386 bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode, 2387 const ARMEncoding encoding) { 2388 #if 0 2389 // ARM pseudo code... 2390 if (ConditionPassed()) 2391 { 2392 EncodingSpecificOperations(); 2393 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2394 if d == 15 then // Can only occur for ARM encoding 2395 ALUWritePC(result); // setflags is always FALSE here 2396 else 2397 R[d] = result; 2398 if setflags then 2399 APSR.N = result<31>; 2400 APSR.Z = IsZeroBit(result); 2401 APSR.C = carry; 2402 APSR.V = overflow; 2403 } 2404 #endif 2405 2406 bool success = false; 2407 if (ConditionPassed(opcode)) { 2408 const addr_t sp = ReadCoreReg(SP_REG, &success); 2409 if (!success) 2410 return false; 2411 2412 uint32_t Rd; 2413 bool setflags; 2414 uint32_t imm32; 2415 switch (encoding) { 2416 case eEncodingT1: 2417 Rd = 13; 2418 setflags = false; 2419 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 2420 break; 2421 case eEncodingT2: 2422 Rd = Bits32(opcode, 11, 8); 2423 setflags = BitIsSet(opcode, 20); 2424 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2425 if (Rd == 15 && setflags) 2426 return EmulateCMPImm(opcode, eEncodingT2); 2427 if (Rd == 15 && !setflags) 2428 return false; 2429 break; 2430 case eEncodingT3: 2431 Rd = Bits32(opcode, 11, 8); 2432 setflags = false; 2433 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 2434 if (Rd == 15) 2435 return false; 2436 break; 2437 case eEncodingA1: 2438 Rd = Bits32(opcode, 15, 12); 2439 setflags = BitIsSet(opcode, 20); 2440 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2441 2442 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 2443 // instructions; 2444 if (Rd == 15 && setflags) 2445 return EmulateSUBSPcLrEtc(opcode, encoding); 2446 break; 2447 default: 2448 return false; 2449 } 2450 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 2451 2452 EmulateInstruction::Context context; 2453 if (Rd == 13) { 2454 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting 2455 // to negate it, or the wrong 2456 // value gets passed down to context.SetImmediateSigned. 2457 context.type = EmulateInstruction::eContextAdjustStackPointer; 2458 context.SetImmediateSigned(-imm64); // the stack pointer offset 2459 } else { 2460 context.type = EmulateInstruction::eContextImmediate; 2461 context.SetNoArgs(); 2462 } 2463 2464 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 2465 res.carry_out, res.overflow)) 2466 return false; 2467 } 2468 return true; 2469 } 2470 2471 // A store operation to the stack that also updates the SP. 2472 bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode, 2473 const ARMEncoding encoding) { 2474 #if 0 2475 // ARM pseudo code... 2476 if (ConditionPassed()) 2477 { 2478 EncodingSpecificOperations(); 2479 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2480 address = if index then offset_addr else R[n]; 2481 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 2482 if wback then R[n] = offset_addr; 2483 } 2484 #endif 2485 2486 bool success = false; 2487 if (ConditionPassed(opcode)) { 2488 const uint32_t addr_byte_size = GetAddressByteSize(); 2489 const addr_t sp = ReadCoreReg(SP_REG, &success); 2490 if (!success) 2491 return false; 2492 uint32_t Rt; // the source register 2493 uint32_t imm12; 2494 uint32_t 2495 Rn; // This function assumes Rn is the SP, but we should verify that. 2496 2497 bool index; 2498 bool add; 2499 bool wback; 2500 switch (encoding) { 2501 case eEncodingA1: 2502 Rt = Bits32(opcode, 15, 12); 2503 imm12 = Bits32(opcode, 11, 0); 2504 Rn = Bits32(opcode, 19, 16); 2505 2506 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 2507 return false; 2508 2509 index = BitIsSet(opcode, 24); 2510 add = BitIsSet(opcode, 23); 2511 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 2512 2513 if (wback && ((Rn == 15) || (Rn == Rt))) 2514 return false; 2515 break; 2516 default: 2517 return false; 2518 } 2519 addr_t offset_addr; 2520 if (add) 2521 offset_addr = sp + imm12; 2522 else 2523 offset_addr = sp - imm12; 2524 2525 addr_t addr; 2526 if (index) 2527 addr = offset_addr; 2528 else 2529 addr = sp; 2530 2531 EmulateInstruction::Context context; 2532 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2533 RegisterInfo sp_reg; 2534 RegisterInfo dwarf_reg; 2535 2536 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2537 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2538 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2539 if (Rt != 15) { 2540 uint32_t reg_value = ReadCoreReg(Rt, &success); 2541 if (!success) 2542 return false; 2543 if (!MemUWrite(context, addr, reg_value, addr_byte_size)) 2544 return false; 2545 } else { 2546 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2547 if (!success) 2548 return false; 2549 if (!MemUWrite(context, addr, pc, addr_byte_size)) 2550 return false; 2551 } 2552 2553 if (wback) { 2554 context.type = EmulateInstruction::eContextAdjustStackPointer; 2555 context.SetImmediateSigned(addr - sp); 2556 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2557 LLDB_REGNUM_GENERIC_SP, offset_addr)) 2558 return false; 2559 } 2560 } 2561 return true; 2562 } 2563 2564 // Vector Push stores multiple extension registers to the stack. It also 2565 // updates SP to point to the start of the stored data. 2566 bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode, 2567 const ARMEncoding encoding) { 2568 #if 0 2569 // ARM pseudo code... 2570 if (ConditionPassed()) 2571 { 2572 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2573 address = SP - imm32; 2574 SP = SP - imm32; 2575 if single_regs then 2576 for r = 0 to regs-1 2577 MemA[address,4] = S[d+r]; address = address+4; 2578 else 2579 for r = 0 to regs-1 2580 // Store as two word-aligned words in the correct order for 2581 // current endianness. 2582 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2583 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2584 address = address+8; 2585 } 2586 #endif 2587 2588 bool success = false; 2589 if (ConditionPassed(opcode)) { 2590 const uint32_t addr_byte_size = GetAddressByteSize(); 2591 const addr_t sp = ReadCoreReg(SP_REG, &success); 2592 if (!success) 2593 return false; 2594 bool single_regs; 2595 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2596 uint32_t imm32; // stack offset 2597 uint32_t regs; // number of registers 2598 switch (encoding) { 2599 case eEncodingT1: 2600 case eEncodingA1: 2601 single_regs = false; 2602 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2603 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2604 // If UInt(imm8) is odd, see "FSTMX". 2605 regs = Bits32(opcode, 7, 0) / 2; 2606 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2607 if (regs == 0 || regs > 16 || (d + regs) > 32) 2608 return false; 2609 break; 2610 case eEncodingT2: 2611 case eEncodingA2: 2612 single_regs = true; 2613 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2614 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2615 regs = Bits32(opcode, 7, 0); 2616 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2617 if (regs == 0 || regs > 16 || (d + regs) > 32) 2618 return false; 2619 break; 2620 default: 2621 return false; 2622 } 2623 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2624 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2625 addr_t sp_offset = imm32; 2626 addr_t addr = sp - sp_offset; 2627 uint32_t i; 2628 2629 EmulateInstruction::Context context; 2630 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2631 2632 RegisterInfo dwarf_reg; 2633 RegisterInfo sp_reg; 2634 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2635 for (i = 0; i < regs; ++i) { 2636 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2637 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2638 // uint64_t to accommodate 64-bit registers. 2639 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success); 2640 if (!success) 2641 return false; 2642 if (!MemAWrite(context, addr, reg_value, reg_byte_size)) 2643 return false; 2644 addr += reg_byte_size; 2645 } 2646 2647 context.type = EmulateInstruction::eContextAdjustStackPointer; 2648 context.SetImmediateSigned(-sp_offset); 2649 2650 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2651 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2652 return false; 2653 } 2654 return true; 2655 } 2656 2657 // Vector Pop loads multiple extension registers from the stack. It also 2658 // updates SP to point just above the loaded data. 2659 bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode, 2660 const ARMEncoding encoding) { 2661 #if 0 2662 // ARM pseudo code... 2663 if (ConditionPassed()) 2664 { 2665 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2666 address = SP; 2667 SP = SP + imm32; 2668 if single_regs then 2669 for r = 0 to regs-1 2670 S[d+r] = MemA[address,4]; address = address+4; 2671 else 2672 for r = 0 to regs-1 2673 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2674 // Combine the word-aligned words in the correct order for 2675 // current endianness. 2676 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2677 } 2678 #endif 2679 2680 bool success = false; 2681 if (ConditionPassed(opcode)) { 2682 const uint32_t addr_byte_size = GetAddressByteSize(); 2683 const addr_t sp = ReadCoreReg(SP_REG, &success); 2684 if (!success) 2685 return false; 2686 bool single_regs; 2687 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2688 uint32_t imm32; // stack offset 2689 uint32_t regs; // number of registers 2690 switch (encoding) { 2691 case eEncodingT1: 2692 case eEncodingA1: 2693 single_regs = false; 2694 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2695 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2696 // If UInt(imm8) is odd, see "FLDMX". 2697 regs = Bits32(opcode, 7, 0) / 2; 2698 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2699 if (regs == 0 || regs > 16 || (d + regs) > 32) 2700 return false; 2701 break; 2702 case eEncodingT2: 2703 case eEncodingA2: 2704 single_regs = true; 2705 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2706 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2707 regs = Bits32(opcode, 7, 0); 2708 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2709 if (regs == 0 || regs > 16 || (d + regs) > 32) 2710 return false; 2711 break; 2712 default: 2713 return false; 2714 } 2715 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2716 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2717 addr_t sp_offset = imm32; 2718 addr_t addr = sp; 2719 uint32_t i; 2720 uint64_t data; // uint64_t to accommodate 64-bit registers. 2721 2722 EmulateInstruction::Context context; 2723 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2724 2725 RegisterInfo dwarf_reg; 2726 RegisterInfo sp_reg; 2727 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2728 for (i = 0; i < regs; ++i) { 2729 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2730 context.SetAddress(addr); 2731 data = MemARead(context, addr, reg_byte_size, 0, &success); 2732 if (!success) 2733 return false; 2734 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2735 return false; 2736 addr += reg_byte_size; 2737 } 2738 2739 context.type = EmulateInstruction::eContextAdjustStackPointer; 2740 context.SetImmediateSigned(sp_offset); 2741 2742 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2743 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2744 return false; 2745 } 2746 return true; 2747 } 2748 2749 // SVC (previously SWI) 2750 bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode, 2751 const ARMEncoding encoding) { 2752 #if 0 2753 // ARM pseudo code... 2754 if (ConditionPassed()) 2755 { 2756 EncodingSpecificOperations(); 2757 CallSupervisor(); 2758 } 2759 #endif 2760 2761 bool success = false; 2762 2763 if (ConditionPassed(opcode)) { 2764 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2765 addr_t lr; // next instruction address 2766 if (!success) 2767 return false; 2768 uint32_t imm32; // the immediate constant 2769 uint32_t mode; // ARM or Thumb mode 2770 switch (encoding) { 2771 case eEncodingT1: 2772 lr = (pc + 2) | 1u; // return address 2773 imm32 = Bits32(opcode, 7, 0); 2774 mode = eModeThumb; 2775 break; 2776 case eEncodingA1: 2777 lr = pc + 4; // return address 2778 imm32 = Bits32(opcode, 23, 0); 2779 mode = eModeARM; 2780 break; 2781 default: 2782 return false; 2783 } 2784 2785 EmulateInstruction::Context context; 2786 context.type = EmulateInstruction::eContextSupervisorCall; 2787 context.SetISAAndImmediate(mode, imm32); 2788 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2789 LLDB_REGNUM_GENERIC_RA, lr)) 2790 return false; 2791 } 2792 return true; 2793 } 2794 2795 // If Then makes up to four following instructions (the IT block) conditional. 2796 bool EmulateInstructionARM::EmulateIT(const uint32_t opcode, 2797 const ARMEncoding encoding) { 2798 #if 0 2799 // ARM pseudo code... 2800 EncodingSpecificOperations(); 2801 ITSTATE.IT<7:0> = firstcond:mask; 2802 #endif 2803 2804 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2805 return true; 2806 } 2807 2808 bool EmulateInstructionARM::EmulateNop(const uint32_t opcode, 2809 const ARMEncoding encoding) { 2810 // NOP, nothing to do... 2811 return true; 2812 } 2813 2814 // Branch causes a branch to a target address. 2815 bool EmulateInstructionARM::EmulateB(const uint32_t opcode, 2816 const ARMEncoding encoding) { 2817 #if 0 2818 // ARM pseudo code... 2819 if (ConditionPassed()) 2820 { 2821 EncodingSpecificOperations(); 2822 BranchWritePC(PC + imm32); 2823 } 2824 #endif 2825 2826 bool success = false; 2827 2828 if (ConditionPassed(opcode)) { 2829 EmulateInstruction::Context context; 2830 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2831 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2832 if (!success) 2833 return false; 2834 addr_t target; // target address 2835 int32_t imm32; // PC-relative offset 2836 switch (encoding) { 2837 case eEncodingT1: 2838 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2839 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2840 target = pc + imm32; 2841 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2842 break; 2843 case eEncodingT2: 2844 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2845 target = pc + imm32; 2846 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2847 break; 2848 case eEncodingT3: 2849 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2850 { 2851 if (Bits32(opcode, 25, 23) == 7) 2852 return false; // See Branches and miscellaneous control on page 2853 // A6-235. 2854 2855 uint32_t S = Bit32(opcode, 26); 2856 uint32_t imm6 = Bits32(opcode, 21, 16); 2857 uint32_t J1 = Bit32(opcode, 13); 2858 uint32_t J2 = Bit32(opcode, 11); 2859 uint32_t imm11 = Bits32(opcode, 10, 0); 2860 uint32_t imm21 = 2861 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2862 imm32 = llvm::SignExtend32<21>(imm21); 2863 target = pc + imm32; 2864 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2865 break; 2866 } 2867 case eEncodingT4: { 2868 uint32_t S = Bit32(opcode, 26); 2869 uint32_t imm10 = Bits32(opcode, 25, 16); 2870 uint32_t J1 = Bit32(opcode, 13); 2871 uint32_t J2 = Bit32(opcode, 11); 2872 uint32_t imm11 = Bits32(opcode, 10, 0); 2873 uint32_t I1 = !(J1 ^ S); 2874 uint32_t I2 = !(J2 ^ S); 2875 uint32_t imm25 = 2876 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2877 imm32 = llvm::SignExtend32<25>(imm25); 2878 target = pc + imm32; 2879 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2880 break; 2881 } 2882 case eEncodingA1: 2883 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2884 target = pc + imm32; 2885 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2886 break; 2887 default: 2888 return false; 2889 } 2890 if (!BranchWritePC(context, target)) 2891 return false; 2892 } 2893 return true; 2894 } 2895 2896 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the 2897 // value in a register with zero and conditionally branch forward a constant 2898 // value. They do not affect the condition flags. CBNZ, CBZ 2899 bool EmulateInstructionARM::EmulateCB(const uint32_t opcode, 2900 const ARMEncoding encoding) { 2901 #if 0 2902 // ARM pseudo code... 2903 EncodingSpecificOperations(); 2904 if nonzero ^ IsZero(R[n]) then 2905 BranchWritePC(PC + imm32); 2906 #endif 2907 2908 bool success = false; 2909 2910 // Read the register value from the operand register Rn. 2911 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2912 if (!success) 2913 return false; 2914 2915 EmulateInstruction::Context context; 2916 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2917 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2918 if (!success) 2919 return false; 2920 2921 addr_t target; // target address 2922 uint32_t imm32; // PC-relative offset to branch forward 2923 bool nonzero; 2924 switch (encoding) { 2925 case eEncodingT1: 2926 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2927 nonzero = BitIsSet(opcode, 11); 2928 target = pc + imm32; 2929 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2930 break; 2931 default: 2932 return false; 2933 } 2934 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2935 if (!BranchWritePC(context, target)) 2936 return false; 2937 2938 return true; 2939 } 2940 2941 // Table Branch Byte causes a PC-relative forward branch using a table of 2942 // single byte offsets. 2943 // A base register provides a pointer to the table, and a second register 2944 // supplies an index into the table. 2945 // The branch length is twice the value of the byte returned from the table. 2946 // 2947 // Table Branch Halfword causes a PC-relative forward branch using a table of 2948 // single halfword offsets. 2949 // A base register provides a pointer to the table, and a second register 2950 // supplies an index into the table. 2951 // The branch length is twice the value of the halfword returned from the 2952 // table. TBB, TBH 2953 bool EmulateInstructionARM::EmulateTB(const uint32_t opcode, 2954 const ARMEncoding encoding) { 2955 #if 0 2956 // ARM pseudo code... 2957 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2958 if is_tbh then 2959 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2960 else 2961 halfwords = UInt(MemU[R[n]+R[m], 1]); 2962 BranchWritePC(PC + 2*halfwords); 2963 #endif 2964 2965 bool success = false; 2966 2967 if (ConditionPassed(opcode)) { 2968 uint32_t Rn; // the base register which contains the address of the table of 2969 // branch lengths 2970 uint32_t Rm; // the index register which contains an integer pointing to a 2971 // byte/halfword in the table 2972 bool is_tbh; // true if table branch halfword 2973 switch (encoding) { 2974 case eEncodingT1: 2975 Rn = Bits32(opcode, 19, 16); 2976 Rm = Bits32(opcode, 3, 0); 2977 is_tbh = BitIsSet(opcode, 4); 2978 if (Rn == 13 || BadReg(Rm)) 2979 return false; 2980 if (InITBlock() && !LastInITBlock()) 2981 return false; 2982 break; 2983 default: 2984 return false; 2985 } 2986 2987 // Read the address of the table from the operand register Rn. The PC can 2988 // be used, in which case the table immediately follows this instruction. 2989 uint32_t base = ReadCoreReg(Rn, &success); 2990 if (!success) 2991 return false; 2992 2993 // the table index 2994 uint32_t index = ReadCoreReg(Rm, &success); 2995 if (!success) 2996 return false; 2997 2998 // the offsetted table address 2999 addr_t addr = base + (is_tbh ? index * 2 : index); 3000 3001 // PC-relative offset to branch forward 3002 EmulateInstruction::Context context; 3003 context.type = EmulateInstruction::eContextTableBranchReadMemory; 3004 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 3005 if (!success) 3006 return false; 3007 3008 const uint32_t pc = ReadCoreReg(PC_REG, &success); 3009 if (!success) 3010 return false; 3011 3012 // target address 3013 addr_t target = pc + offset; 3014 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 3015 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset); 3016 3017 if (!BranchWritePC(context, target)) 3018 return false; 3019 } 3020 3021 return true; 3022 } 3023 3024 // This instruction adds an immediate value to a register value, and writes the 3025 // result to the destination register. It can optionally update the condition 3026 // flags based on the result. 3027 bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode, 3028 const ARMEncoding encoding) { 3029 #if 0 3030 if ConditionPassed() then 3031 EncodingSpecificOperations(); 3032 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3033 R[d] = result; 3034 if setflags then 3035 APSR.N = result<31>; 3036 APSR.Z = IsZeroBit(result); 3037 APSR.C = carry; 3038 APSR.V = overflow; 3039 #endif 3040 3041 bool success = false; 3042 3043 if (ConditionPassed(opcode)) { 3044 uint32_t d; 3045 uint32_t n; 3046 bool setflags; 3047 uint32_t imm32; 3048 uint32_t carry_out; 3049 3050 // EncodingSpecificOperations(); 3051 switch (encoding) { 3052 case eEncodingT1: 3053 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = 3054 // ZeroExtend(imm3, 32); 3055 d = Bits32(opcode, 2, 0); 3056 n = Bits32(opcode, 5, 3); 3057 setflags = !InITBlock(); 3058 imm32 = Bits32(opcode, 8, 6); 3059 3060 break; 3061 3062 case eEncodingT2: 3063 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = 3064 // ZeroExtend(imm8, 32); 3065 d = Bits32(opcode, 10, 8); 3066 n = Bits32(opcode, 10, 8); 3067 setflags = !InITBlock(); 3068 imm32 = Bits32(opcode, 7, 0); 3069 3070 break; 3071 3072 case eEncodingT3: 3073 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 3074 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = 3075 // ThumbExpandImm(i:imm3:imm8); 3076 d = Bits32(opcode, 11, 8); 3077 n = Bits32(opcode, 19, 16); 3078 setflags = BitIsSet(opcode, 20); 3079 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out); 3080 3081 // if Rn == '1101' then SEE ADD (SP plus immediate); 3082 if (n == 13) 3083 return EmulateADDSPImm(opcode, eEncodingT3); 3084 3085 // if BadReg(d) || n == 15 then UNPREDICTABLE; 3086 if (BadReg(d) || (n == 15)) 3087 return false; 3088 3089 break; 3090 3091 case eEncodingT4: { 3092 // if Rn == '1111' then SEE ADR; 3093 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = 3094 // ZeroExtend(i:imm3:imm8, 32); 3095 d = Bits32(opcode, 11, 8); 3096 n = Bits32(opcode, 19, 16); 3097 setflags = false; 3098 uint32_t i = Bit32(opcode, 26); 3099 uint32_t imm3 = Bits32(opcode, 14, 12); 3100 uint32_t imm8 = Bits32(opcode, 7, 0); 3101 imm32 = (i << 11) | (imm3 << 8) | imm8; 3102 3103 // if Rn == '1101' then SEE ADD (SP plus immediate); 3104 if (n == 13) 3105 return EmulateADDSPImm(opcode, eEncodingT4); 3106 3107 // if BadReg(d) then UNPREDICTABLE; 3108 if (BadReg(d)) 3109 return false; 3110 3111 break; 3112 } 3113 3114 default: 3115 return false; 3116 } 3117 3118 uint64_t Rn = 3119 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3120 if (!success) 3121 return false; 3122 3123 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3124 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0); 3125 3126 RegisterInfo reg_n; 3127 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 3128 3129 EmulateInstruction::Context context; 3130 context.type = eContextArithmetic; 3131 context.SetRegisterPlusOffset(reg_n, imm32); 3132 3133 // R[d] = result; 3134 // if setflags then 3135 // APSR.N = result<31>; 3136 // APSR.Z = IsZeroBit(result); 3137 // APSR.C = carry; 3138 // APSR.V = overflow; 3139 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 3140 res.carry_out, res.overflow)) 3141 return false; 3142 } 3143 return true; 3144 } 3145 3146 // This instruction adds an immediate value to a register value, and writes the 3147 // result to the destination register. It can optionally update the condition 3148 // flags based on the result. 3149 bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode, 3150 const ARMEncoding encoding) { 3151 #if 0 3152 // ARM pseudo code... 3153 if ConditionPassed() then 3154 EncodingSpecificOperations(); 3155 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3156 if d == 15 then 3157 ALUWritePC(result); // setflags is always FALSE here 3158 else 3159 R[d] = result; 3160 if setflags then 3161 APSR.N = result<31>; 3162 APSR.Z = IsZeroBit(result); 3163 APSR.C = carry; 3164 APSR.V = overflow; 3165 #endif 3166 3167 bool success = false; 3168 3169 if (ConditionPassed(opcode)) { 3170 uint32_t Rd, Rn; 3171 uint32_t 3172 imm32; // the immediate value to be added to the value obtained from Rn 3173 bool setflags; 3174 switch (encoding) { 3175 case eEncodingA1: 3176 Rd = Bits32(opcode, 15, 12); 3177 Rn = Bits32(opcode, 19, 16); 3178 setflags = BitIsSet(opcode, 20); 3179 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3180 break; 3181 default: 3182 return false; 3183 } 3184 3185 // Read the first operand. 3186 uint32_t val1 = ReadCoreReg(Rn, &success); 3187 if (!success) 3188 return false; 3189 3190 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 3191 3192 EmulateInstruction::Context context; 3193 if (Rd == 13) 3194 context.type = EmulateInstruction::eContextAdjustStackPointer; 3195 else if (Rd == GetFramePointerRegisterNumber()) 3196 context.type = EmulateInstruction::eContextSetFramePointer; 3197 else 3198 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3199 3200 RegisterInfo dwarf_reg; 3201 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 3202 context.SetRegisterPlusOffset(dwarf_reg, imm32); 3203 3204 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3205 res.carry_out, res.overflow)) 3206 return false; 3207 } 3208 return true; 3209 } 3210 3211 // This instruction adds a register value and an optionally-shifted register 3212 // value, and writes the result to the destination register. It can optionally 3213 // update the condition flags based on the result. 3214 bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode, 3215 const ARMEncoding encoding) { 3216 #if 0 3217 // ARM pseudo code... 3218 if ConditionPassed() then 3219 EncodingSpecificOperations(); 3220 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3221 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3222 if d == 15 then 3223 ALUWritePC(result); // setflags is always FALSE here 3224 else 3225 R[d] = result; 3226 if setflags then 3227 APSR.N = result<31>; 3228 APSR.Z = IsZeroBit(result); 3229 APSR.C = carry; 3230 APSR.V = overflow; 3231 #endif 3232 3233 bool success = false; 3234 3235 if (ConditionPassed(opcode)) { 3236 uint32_t Rd, Rn, Rm; 3237 ARM_ShifterType shift_t; 3238 uint32_t shift_n; // the shift applied to the value read from Rm 3239 bool setflags; 3240 switch (encoding) { 3241 case eEncodingT1: 3242 Rd = Bits32(opcode, 2, 0); 3243 Rn = Bits32(opcode, 5, 3); 3244 Rm = Bits32(opcode, 8, 6); 3245 setflags = !InITBlock(); 3246 shift_t = SRType_LSL; 3247 shift_n = 0; 3248 break; 3249 case eEncodingT2: 3250 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3251 Rm = Bits32(opcode, 6, 3); 3252 setflags = false; 3253 shift_t = SRType_LSL; 3254 shift_n = 0; 3255 if (Rn == 15 && Rm == 15) 3256 return false; 3257 if (Rd == 15 && InITBlock() && !LastInITBlock()) 3258 return false; 3259 break; 3260 case eEncodingA1: 3261 Rd = Bits32(opcode, 15, 12); 3262 Rn = Bits32(opcode, 19, 16); 3263 Rm = Bits32(opcode, 3, 0); 3264 setflags = BitIsSet(opcode, 20); 3265 shift_n = DecodeImmShiftARM(opcode, shift_t); 3266 break; 3267 default: 3268 return false; 3269 } 3270 3271 // Read the first operand. 3272 uint32_t val1 = ReadCoreReg(Rn, &success); 3273 if (!success) 3274 return false; 3275 3276 // Read the second operand. 3277 uint32_t val2 = ReadCoreReg(Rm, &success); 3278 if (!success) 3279 return false; 3280 3281 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3282 if (!success) 3283 return false; 3284 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3285 3286 EmulateInstruction::Context context; 3287 context.type = eContextArithmetic; 3288 RegisterInfo op1_reg; 3289 RegisterInfo op2_reg; 3290 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 3291 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 3292 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 3293 3294 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3295 res.carry_out, res.overflow)) 3296 return false; 3297 } 3298 return true; 3299 } 3300 3301 // Compare Negative (immediate) adds a register value and an immediate value. 3302 // It updates the condition flags based on the result, and discards the result. 3303 bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode, 3304 const ARMEncoding encoding) { 3305 #if 0 3306 // ARM pseudo code... 3307 if ConditionPassed() then 3308 EncodingSpecificOperations(); 3309 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3310 APSR.N = result<31>; 3311 APSR.Z = IsZeroBit(result); 3312 APSR.C = carry; 3313 APSR.V = overflow; 3314 #endif 3315 3316 bool success = false; 3317 3318 uint32_t Rn; // the first operand 3319 uint32_t imm32; // the immediate value to be compared with 3320 switch (encoding) { 3321 case eEncodingT1: 3322 Rn = Bits32(opcode, 19, 16); 3323 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3324 if (Rn == 15) 3325 return false; 3326 break; 3327 case eEncodingA1: 3328 Rn = Bits32(opcode, 19, 16); 3329 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3330 break; 3331 default: 3332 return false; 3333 } 3334 // Read the register value from the operand register Rn. 3335 uint32_t reg_val = ReadCoreReg(Rn, &success); 3336 if (!success) 3337 return false; 3338 3339 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 3340 3341 EmulateInstruction::Context context; 3342 context.type = EmulateInstruction::eContextImmediate; 3343 context.SetNoArgs(); 3344 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3345 return false; 3346 3347 return true; 3348 } 3349 3350 // Compare Negative (register) adds a register value and an optionally-shifted 3351 // register value. It updates the condition flags based on the result, and 3352 // discards the result. 3353 bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode, 3354 const ARMEncoding encoding) { 3355 #if 0 3356 // ARM pseudo code... 3357 if ConditionPassed() then 3358 EncodingSpecificOperations(); 3359 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3360 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3361 APSR.N = result<31>; 3362 APSR.Z = IsZeroBit(result); 3363 APSR.C = carry; 3364 APSR.V = overflow; 3365 #endif 3366 3367 bool success = false; 3368 3369 uint32_t Rn; // the first operand 3370 uint32_t Rm; // the second operand 3371 ARM_ShifterType shift_t; 3372 uint32_t shift_n; // the shift applied to the value read from Rm 3373 switch (encoding) { 3374 case eEncodingT1: 3375 Rn = Bits32(opcode, 2, 0); 3376 Rm = Bits32(opcode, 5, 3); 3377 shift_t = SRType_LSL; 3378 shift_n = 0; 3379 break; 3380 case eEncodingT2: 3381 Rn = Bits32(opcode, 19, 16); 3382 Rm = Bits32(opcode, 3, 0); 3383 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3384 // if n == 15 || BadReg(m) then UNPREDICTABLE; 3385 if (Rn == 15 || BadReg(Rm)) 3386 return false; 3387 break; 3388 case eEncodingA1: 3389 Rn = Bits32(opcode, 19, 16); 3390 Rm = Bits32(opcode, 3, 0); 3391 shift_n = DecodeImmShiftARM(opcode, shift_t); 3392 break; 3393 default: 3394 return false; 3395 } 3396 // Read the register value from register Rn. 3397 uint32_t val1 = ReadCoreReg(Rn, &success); 3398 if (!success) 3399 return false; 3400 3401 // Read the register value from register Rm. 3402 uint32_t val2 = ReadCoreReg(Rm, &success); 3403 if (!success) 3404 return false; 3405 3406 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3407 if (!success) 3408 return false; 3409 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3410 3411 EmulateInstruction::Context context; 3412 context.type = EmulateInstruction::eContextImmediate; 3413 context.SetNoArgs(); 3414 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3415 return false; 3416 3417 return true; 3418 } 3419 3420 // Compare (immediate) subtracts an immediate value from a register value. It 3421 // updates the condition flags based on the result, and discards the result. 3422 bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode, 3423 const ARMEncoding encoding) { 3424 #if 0 3425 // ARM pseudo code... 3426 if ConditionPassed() then 3427 EncodingSpecificOperations(); 3428 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 3429 APSR.N = result<31>; 3430 APSR.Z = IsZeroBit(result); 3431 APSR.C = carry; 3432 APSR.V = overflow; 3433 #endif 3434 3435 bool success = false; 3436 3437 uint32_t Rn; // the first operand 3438 uint32_t imm32; // the immediate value to be compared with 3439 switch (encoding) { 3440 case eEncodingT1: 3441 Rn = Bits32(opcode, 10, 8); 3442 imm32 = Bits32(opcode, 7, 0); 3443 break; 3444 case eEncodingT2: 3445 Rn = Bits32(opcode, 19, 16); 3446 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3447 if (Rn == 15) 3448 return false; 3449 break; 3450 case eEncodingA1: 3451 Rn = Bits32(opcode, 19, 16); 3452 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3453 break; 3454 default: 3455 return false; 3456 } 3457 // Read the register value from the operand register Rn. 3458 uint32_t reg_val = ReadCoreReg(Rn, &success); 3459 if (!success) 3460 return false; 3461 3462 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 3463 3464 EmulateInstruction::Context context; 3465 context.type = EmulateInstruction::eContextImmediate; 3466 context.SetNoArgs(); 3467 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3468 return false; 3469 3470 return true; 3471 } 3472 3473 // Compare (register) subtracts an optionally-shifted register value from a 3474 // register value. It updates the condition flags based on the result, and 3475 // discards the result. 3476 bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode, 3477 const ARMEncoding encoding) { 3478 #if 0 3479 // ARM pseudo code... 3480 if ConditionPassed() then 3481 EncodingSpecificOperations(); 3482 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3483 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 3484 APSR.N = result<31>; 3485 APSR.Z = IsZeroBit(result); 3486 APSR.C = carry; 3487 APSR.V = overflow; 3488 #endif 3489 3490 bool success = false; 3491 3492 uint32_t Rn; // the first operand 3493 uint32_t Rm; // the second operand 3494 ARM_ShifterType shift_t; 3495 uint32_t shift_n; // the shift applied to the value read from Rm 3496 switch (encoding) { 3497 case eEncodingT1: 3498 Rn = Bits32(opcode, 2, 0); 3499 Rm = Bits32(opcode, 5, 3); 3500 shift_t = SRType_LSL; 3501 shift_n = 0; 3502 break; 3503 case eEncodingT2: 3504 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3505 Rm = Bits32(opcode, 6, 3); 3506 shift_t = SRType_LSL; 3507 shift_n = 0; 3508 if (Rn < 8 && Rm < 8) 3509 return false; 3510 if (Rn == 15 || Rm == 15) 3511 return false; 3512 break; 3513 case eEncodingT3: 3514 Rn = Bits32(opcode, 19, 16); 3515 Rm = Bits32(opcode, 3, 0); 3516 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3517 if (Rn == 15 || BadReg(Rm)) 3518 return false; 3519 break; 3520 case eEncodingA1: 3521 Rn = Bits32(opcode, 19, 16); 3522 Rm = Bits32(opcode, 3, 0); 3523 shift_n = DecodeImmShiftARM(opcode, shift_t); 3524 break; 3525 default: 3526 return false; 3527 } 3528 // Read the register value from register Rn. 3529 uint32_t val1 = ReadCoreReg(Rn, &success); 3530 if (!success) 3531 return false; 3532 3533 // Read the register value from register Rm. 3534 uint32_t val2 = ReadCoreReg(Rm, &success); 3535 if (!success) 3536 return false; 3537 3538 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3539 if (!success) 3540 return false; 3541 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3542 3543 EmulateInstruction::Context context; 3544 context.type = EmulateInstruction::eContextImmediate; 3545 context.SetNoArgs(); 3546 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3547 return false; 3548 3549 return true; 3550 } 3551 3552 // Arithmetic Shift Right (immediate) shifts a register value right by an 3553 // immediate number of bits, shifting in copies of its sign bit, and writes the 3554 // result to the destination register. It can optionally update the condition 3555 // flags based on the result. 3556 bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode, 3557 const ARMEncoding encoding) { 3558 #if 0 3559 // ARM pseudo code... 3560 if ConditionPassed() then 3561 EncodingSpecificOperations(); 3562 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3563 if d == 15 then // Can only occur for ARM encoding 3564 ALUWritePC(result); // setflags is always FALSE here 3565 else 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 EmulateShiftImm(opcode, encoding, SRType_ASR); 3575 } 3576 3577 // Arithmetic Shift Right (register) shifts a register value right by a 3578 // variable number of bits, shifting in copies of its sign bit, and writes the 3579 // result to the destination register. The variable number of bits is read from 3580 // the bottom byte of a register. It can optionally update the condition flags 3581 // based on the result. 3582 bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode, 3583 const ARMEncoding encoding) { 3584 #if 0 3585 // ARM pseudo code... 3586 if ConditionPassed() then 3587 EncodingSpecificOperations(); 3588 shift_n = UInt(R[m]<7:0>); 3589 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 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 EmulateShiftReg(opcode, encoding, SRType_ASR); 3599 } 3600 3601 // Logical Shift Left (immediate) shifts a register value left by an immediate 3602 // number of bits, shifting in zeros, and writes the result to the destination 3603 // register. It can optionally update the condition flags based on the result. 3604 bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode, 3605 const ARMEncoding encoding) { 3606 #if 0 3607 // ARM pseudo code... 3608 if ConditionPassed() then 3609 EncodingSpecificOperations(); 3610 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3611 if d == 15 then // Can only occur for ARM encoding 3612 ALUWritePC(result); // setflags is always FALSE here 3613 else 3614 R[d] = result; 3615 if setflags then 3616 APSR.N = result<31>; 3617 APSR.Z = IsZeroBit(result); 3618 APSR.C = carry; 3619 // APSR.V unchanged 3620 #endif 3621 3622 return EmulateShiftImm(opcode, encoding, SRType_LSL); 3623 } 3624 3625 // Logical Shift Left (register) shifts a register value left by a variable 3626 // number of bits, shifting in zeros, and writes the result to the destination 3627 // register. The variable number of bits is read from the bottom byte of a 3628 // register. It can optionally update the condition flags based on the result. 3629 bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode, 3630 const ARMEncoding encoding) { 3631 #if 0 3632 // ARM pseudo code... 3633 if ConditionPassed() then 3634 EncodingSpecificOperations(); 3635 shift_n = UInt(R[m]<7:0>); 3636 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3637 R[d] = result; 3638 if setflags then 3639 APSR.N = result<31>; 3640 APSR.Z = IsZeroBit(result); 3641 APSR.C = carry; 3642 // APSR.V unchanged 3643 #endif 3644 3645 return EmulateShiftReg(opcode, encoding, SRType_LSL); 3646 } 3647 3648 // Logical Shift Right (immediate) shifts a register value right by an 3649 // immediate number of bits, shifting in zeros, and writes the result to the 3650 // destination register. It can optionally update the condition flags based on 3651 // the result. 3652 bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode, 3653 const ARMEncoding encoding) { 3654 #if 0 3655 // ARM pseudo code... 3656 if ConditionPassed() then 3657 EncodingSpecificOperations(); 3658 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3659 if d == 15 then // Can only occur for ARM encoding 3660 ALUWritePC(result); // setflags is always FALSE here 3661 else 3662 R[d] = result; 3663 if setflags then 3664 APSR.N = result<31>; 3665 APSR.Z = IsZeroBit(result); 3666 APSR.C = carry; 3667 // APSR.V unchanged 3668 #endif 3669 3670 return EmulateShiftImm(opcode, encoding, SRType_LSR); 3671 } 3672 3673 // Logical Shift Right (register) shifts a register value right by a variable 3674 // number of bits, shifting in zeros, and writes the result to the destination 3675 // register. The variable number of bits is read from the bottom byte of a 3676 // register. It can optionally update the condition flags based on the result. 3677 bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode, 3678 const ARMEncoding encoding) { 3679 #if 0 3680 // ARM pseudo code... 3681 if ConditionPassed() then 3682 EncodingSpecificOperations(); 3683 shift_n = UInt(R[m]<7:0>); 3684 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3685 R[d] = result; 3686 if setflags then 3687 APSR.N = result<31>; 3688 APSR.Z = IsZeroBit(result); 3689 APSR.C = carry; 3690 // APSR.V unchanged 3691 #endif 3692 3693 return EmulateShiftReg(opcode, encoding, SRType_LSR); 3694 } 3695 3696 // Rotate Right (immediate) provides the value of the contents of a register 3697 // rotated by a constant value. The bits that are rotated off the right end are 3698 // inserted into the vacated bit positions on the left. It can optionally 3699 // update the condition flags based on the result. 3700 bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode, 3701 const ARMEncoding encoding) { 3702 #if 0 3703 // ARM pseudo code... 3704 if ConditionPassed() then 3705 EncodingSpecificOperations(); 3706 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3707 if d == 15 then // Can only occur for ARM encoding 3708 ALUWritePC(result); // setflags is always FALSE here 3709 else 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 EmulateShiftImm(opcode, encoding, SRType_ROR); 3719 } 3720 3721 // Rotate Right (register) provides the value of the contents of a register 3722 // rotated by a variable number of bits. The bits that are rotated off the 3723 // right end are inserted into the vacated bit positions on the left. The 3724 // variable number of bits is read from the bottom byte of a register. It can 3725 // optionally update the condition flags based on the result. 3726 bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode, 3727 const ARMEncoding encoding) { 3728 #if 0 3729 // ARM pseudo code... 3730 if ConditionPassed() then 3731 EncodingSpecificOperations(); 3732 shift_n = UInt(R[m]<7:0>); 3733 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3734 R[d] = result; 3735 if setflags then 3736 APSR.N = result<31>; 3737 APSR.Z = IsZeroBit(result); 3738 APSR.C = carry; 3739 // APSR.V unchanged 3740 #endif 3741 3742 return EmulateShiftReg(opcode, encoding, SRType_ROR); 3743 } 3744 3745 // Rotate Right with Extend provides the value of the contents of a register 3746 // shifted right by one place, with the carry flag shifted into bit [31]. 3747 // 3748 // RRX can optionally update the condition flags based on the result. 3749 // In that case, bit [0] is shifted into the carry flag. 3750 bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode, 3751 const ARMEncoding encoding) { 3752 #if 0 3753 // ARM pseudo code... 3754 if ConditionPassed() then 3755 EncodingSpecificOperations(); 3756 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3757 if d == 15 then // Can only occur for ARM encoding 3758 ALUWritePC(result); // setflags is always FALSE here 3759 else 3760 R[d] = result; 3761 if setflags then 3762 APSR.N = result<31>; 3763 APSR.Z = IsZeroBit(result); 3764 APSR.C = carry; 3765 // APSR.V unchanged 3766 #endif 3767 3768 return EmulateShiftImm(opcode, encoding, SRType_RRX); 3769 } 3770 3771 bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode, 3772 const ARMEncoding encoding, 3773 ARM_ShifterType shift_type) { 3774 // assert(shift_type == SRType_ASR 3775 // || shift_type == SRType_LSL 3776 // || shift_type == SRType_LSR 3777 // || shift_type == SRType_ROR 3778 // || shift_type == SRType_RRX); 3779 3780 bool success = false; 3781 3782 if (ConditionPassed(opcode)) { 3783 uint32_t Rd; // the destination register 3784 uint32_t Rm; // the first operand register 3785 uint32_t imm5; // encoding for the shift amount 3786 uint32_t carry; // the carry bit after the shift operation 3787 bool setflags; 3788 3789 // Special case handling! 3790 // A8.6.139 ROR (immediate) -- Encoding T1 3791 ARMEncoding use_encoding = encoding; 3792 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) { 3793 // Morph the T1 encoding from the ARM Architecture Manual into T2 3794 // encoding to have the same decoding of bit fields as the other Thumb2 3795 // shift operations. 3796 use_encoding = eEncodingT2; 3797 } 3798 3799 switch (use_encoding) { 3800 case eEncodingT1: 3801 // Due to the above special case handling! 3802 if (shift_type == SRType_ROR) 3803 return false; 3804 3805 Rd = Bits32(opcode, 2, 0); 3806 Rm = Bits32(opcode, 5, 3); 3807 setflags = !InITBlock(); 3808 imm5 = Bits32(opcode, 10, 6); 3809 break; 3810 case eEncodingT2: 3811 // A8.6.141 RRX 3812 // There's no imm form of RRX instructions. 3813 if (shift_type == SRType_RRX) 3814 return false; 3815 3816 Rd = Bits32(opcode, 11, 8); 3817 Rm = Bits32(opcode, 3, 0); 3818 setflags = BitIsSet(opcode, 20); 3819 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3820 if (BadReg(Rd) || BadReg(Rm)) 3821 return false; 3822 break; 3823 case eEncodingA1: 3824 Rd = Bits32(opcode, 15, 12); 3825 Rm = Bits32(opcode, 3, 0); 3826 setflags = BitIsSet(opcode, 20); 3827 imm5 = Bits32(opcode, 11, 7); 3828 break; 3829 default: 3830 return false; 3831 } 3832 3833 // A8.6.139 ROR (immediate) 3834 if (shift_type == SRType_ROR && imm5 == 0) 3835 shift_type = SRType_RRX; 3836 3837 // Get the first operand. 3838 uint32_t value = ReadCoreReg(Rm, &success); 3839 if (!success) 3840 return false; 3841 3842 // Decode the shift amount if not RRX. 3843 uint32_t amt = 3844 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3845 3846 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3847 if (!success) 3848 return false; 3849 3850 // The context specifies that an immediate is to be moved into Rd. 3851 EmulateInstruction::Context context; 3852 context.type = EmulateInstruction::eContextImmediate; 3853 context.SetNoArgs(); 3854 3855 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3856 return false; 3857 } 3858 return true; 3859 } 3860 3861 bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode, 3862 const ARMEncoding encoding, 3863 ARM_ShifterType shift_type) { 3864 // assert(shift_type == SRType_ASR 3865 // || shift_type == SRType_LSL 3866 // || shift_type == SRType_LSR 3867 // || shift_type == SRType_ROR); 3868 3869 bool success = false; 3870 3871 if (ConditionPassed(opcode)) { 3872 uint32_t Rd; // the destination register 3873 uint32_t Rn; // the first operand register 3874 uint32_t 3875 Rm; // the register whose bottom byte contains the amount to shift by 3876 uint32_t carry; // the carry bit after the shift operation 3877 bool setflags; 3878 switch (encoding) { 3879 case eEncodingT1: 3880 Rd = Bits32(opcode, 2, 0); 3881 Rn = Rd; 3882 Rm = Bits32(opcode, 5, 3); 3883 setflags = !InITBlock(); 3884 break; 3885 case eEncodingT2: 3886 Rd = Bits32(opcode, 11, 8); 3887 Rn = Bits32(opcode, 19, 16); 3888 Rm = Bits32(opcode, 3, 0); 3889 setflags = BitIsSet(opcode, 20); 3890 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3891 return false; 3892 break; 3893 case eEncodingA1: 3894 Rd = Bits32(opcode, 15, 12); 3895 Rn = Bits32(opcode, 3, 0); 3896 Rm = Bits32(opcode, 11, 8); 3897 setflags = BitIsSet(opcode, 20); 3898 if (Rd == 15 || Rn == 15 || Rm == 15) 3899 return false; 3900 break; 3901 default: 3902 return false; 3903 } 3904 3905 // Get the first operand. 3906 uint32_t value = ReadCoreReg(Rn, &success); 3907 if (!success) 3908 return false; 3909 // Get the Rm register content. 3910 uint32_t val = ReadCoreReg(Rm, &success); 3911 if (!success) 3912 return false; 3913 3914 // Get the shift amount. 3915 uint32_t amt = Bits32(val, 7, 0); 3916 3917 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3918 if (!success) 3919 return false; 3920 3921 // The context specifies that an immediate is to be moved into Rd. 3922 EmulateInstruction::Context context; 3923 context.type = EmulateInstruction::eContextImmediate; 3924 context.SetNoArgs(); 3925 3926 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3927 return false; 3928 } 3929 return true; 3930 } 3931 3932 // LDM loads multiple registers from consecutive memory locations, using an 3933 // address from a base register. Optionally the address just above the highest 3934 // of those locations can be written back to the base register. 3935 bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode, 3936 const ARMEncoding encoding) { 3937 #if 0 3938 // ARM pseudo code... 3939 if ConditionPassed() 3940 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3941 address = R[n]; 3942 3943 for i = 0 to 14 3944 if registers<i> == '1' then 3945 R[i] = MemA[address, 4]; address = address + 4; 3946 if registers<15> == '1' then 3947 LoadWritePC (MemA[address, 4]); 3948 3949 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3950 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3951 3952 #endif 3953 3954 bool success = false; 3955 if (ConditionPassed(opcode)) { 3956 uint32_t n; 3957 uint32_t registers = 0; 3958 bool wback; 3959 const uint32_t addr_byte_size = GetAddressByteSize(); 3960 switch (encoding) { 3961 case eEncodingT1: 3962 // n = UInt(Rn); registers = '00000000':register_list; wback = 3963 // (registers<n> == '0'); 3964 n = Bits32(opcode, 10, 8); 3965 registers = Bits32(opcode, 7, 0); 3966 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3967 wback = BitIsClear(registers, n); 3968 // if BitCount(registers) < 1 then UNPREDICTABLE; 3969 if (BitCount(registers) < 1) 3970 return false; 3971 break; 3972 case eEncodingT2: 3973 // if W == '1' && Rn == '1101' then SEE POP; 3974 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3975 n = Bits32(opcode, 19, 16); 3976 registers = Bits32(opcode, 15, 0); 3977 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3978 wback = BitIsSet(opcode, 21); 3979 3980 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 3981 // UNPREDICTABLE; 3982 if ((n == 15) || (BitCount(registers) < 2) || 3983 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 3984 return false; 3985 3986 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 3987 // UNPREDICTABLE; 3988 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 3989 return false; 3990 3991 // if wback && registers<n> == '1' then UNPREDICTABLE; 3992 if (wback && BitIsSet(registers, n)) 3993 return false; 3994 break; 3995 3996 case eEncodingA1: 3997 n = Bits32(opcode, 19, 16); 3998 registers = Bits32(opcode, 15, 0); 3999 wback = BitIsSet(opcode, 21); 4000 if ((n == 15) || (BitCount(registers) < 1)) 4001 return false; 4002 break; 4003 default: 4004 return false; 4005 } 4006 4007 int32_t offset = 0; 4008 const addr_t base_address = 4009 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4010 if (!success) 4011 return false; 4012 4013 EmulateInstruction::Context context; 4014 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4015 RegisterInfo dwarf_reg; 4016 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4017 context.SetRegisterPlusOffset(dwarf_reg, offset); 4018 4019 for (int i = 0; i < 14; ++i) { 4020 if (BitIsSet(registers, i)) { 4021 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4022 context.SetRegisterPlusOffset(dwarf_reg, offset); 4023 if (wback && (n == 13)) // Pop Instruction 4024 { 4025 context.type = EmulateInstruction::eContextPopRegisterOffStack; 4026 context.SetAddress(base_address + offset); 4027 } 4028 4029 // R[i] = MemA [address, 4]; address = address + 4; 4030 uint32_t data = MemARead(context, base_address + offset, addr_byte_size, 4031 0, &success); 4032 if (!success) 4033 return false; 4034 4035 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4036 data)) 4037 return false; 4038 4039 offset += addr_byte_size; 4040 } 4041 } 4042 4043 if (BitIsSet(registers, 15)) { 4044 // LoadWritePC (MemA [address, 4]); 4045 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4046 context.SetRegisterPlusOffset(dwarf_reg, offset); 4047 uint32_t data = 4048 MemARead(context, base_address + offset, addr_byte_size, 0, &success); 4049 if (!success) 4050 return false; 4051 // In ARMv5T and above, this is an interworking branch. 4052 if (!LoadWritePC(context, data)) 4053 return false; 4054 } 4055 4056 if (wback && BitIsClear(registers, n)) { 4057 // R[n] = R[n] + 4 * BitCount (registers) 4058 int32_t offset = addr_byte_size * BitCount(registers); 4059 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4060 context.SetRegisterPlusOffset(dwarf_reg, offset); 4061 4062 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4063 base_address + offset)) 4064 return false; 4065 } 4066 if (wback && BitIsSet(registers, n)) 4067 // R[n] bits(32) UNKNOWN; 4068 return WriteBits32Unknown(n); 4069 } 4070 return true; 4071 } 4072 4073 // LDMDA loads multiple registers from consecutive memory locations using an 4074 // address from a base register. 4075 // The consecutive memory locations end at this address and the address just 4076 // below the lowest of those locations can optionally be written back to the 4077 // base register. 4078 bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode, 4079 const ARMEncoding encoding) { 4080 #if 0 4081 // ARM pseudo code... 4082 if ConditionPassed() then 4083 EncodingSpecificOperations(); 4084 address = R[n] - 4*BitCount(registers) + 4; 4085 4086 for i = 0 to 14 4087 if registers<i> == '1' then 4088 R[i] = MemA[address,4]; address = address + 4; 4089 4090 if registers<15> == '1' then 4091 LoadWritePC(MemA[address,4]); 4092 4093 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4094 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4095 #endif 4096 4097 bool success = false; 4098 4099 if (ConditionPassed(opcode)) { 4100 uint32_t n; 4101 uint32_t registers = 0; 4102 bool wback; 4103 const uint32_t addr_byte_size = GetAddressByteSize(); 4104 4105 // EncodingSpecificOperations(); 4106 switch (encoding) { 4107 case eEncodingA1: 4108 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4109 n = Bits32(opcode, 19, 16); 4110 registers = Bits32(opcode, 15, 0); 4111 wback = BitIsSet(opcode, 21); 4112 4113 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4114 if ((n == 15) || (BitCount(registers) < 1)) 4115 return false; 4116 4117 break; 4118 4119 default: 4120 return false; 4121 } 4122 // address = R[n] - 4*BitCount(registers) + 4; 4123 4124 int32_t offset = 0; 4125 addr_t Rn = ReadCoreReg(n, &success); 4126 4127 if (!success) 4128 return false; 4129 4130 addr_t address = 4131 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size; 4132 4133 EmulateInstruction::Context context; 4134 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4135 RegisterInfo dwarf_reg; 4136 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4137 context.SetRegisterPlusOffset(dwarf_reg, offset); 4138 4139 // for i = 0 to 14 4140 for (int i = 0; i < 14; ++i) { 4141 // if registers<i> == '1' then 4142 if (BitIsSet(registers, i)) { 4143 // R[i] = MemA[address,4]; address = address + 4; 4144 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4145 uint32_t data = 4146 MemARead(context, address + offset, addr_byte_size, 0, &success); 4147 if (!success) 4148 return false; 4149 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4150 data)) 4151 return false; 4152 offset += addr_byte_size; 4153 } 4154 } 4155 4156 // if registers<15> == '1' then 4157 // LoadWritePC(MemA[address,4]); 4158 if (BitIsSet(registers, 15)) { 4159 context.SetRegisterPlusOffset(dwarf_reg, offset); 4160 uint32_t data = 4161 MemARead(context, address + offset, addr_byte_size, 0, &success); 4162 if (!success) 4163 return false; 4164 // In ARMv5T and above, this is an interworking branch. 4165 if (!LoadWritePC(context, data)) 4166 return false; 4167 } 4168 4169 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4170 if (wback && BitIsClear(registers, n)) { 4171 if (!success) 4172 return false; 4173 4174 offset = (addr_byte_size * BitCount(registers)) * -1; 4175 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4176 context.SetImmediateSigned(offset); 4177 addr_t addr = Rn + offset; 4178 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4179 addr)) 4180 return false; 4181 } 4182 4183 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4184 if (wback && BitIsSet(registers, n)) 4185 return WriteBits32Unknown(n); 4186 } 4187 return true; 4188 } 4189 4190 // LDMDB loads multiple registers from consecutive memory locations using an 4191 // address from a base register. The 4192 // consecutive memory locations end just below this address, and the address of 4193 // the lowest of those locations can be optionally written back to the base 4194 // register. 4195 bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode, 4196 const ARMEncoding encoding) { 4197 #if 0 4198 // ARM pseudo code... 4199 if ConditionPassed() then 4200 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4201 address = R[n] - 4*BitCount(registers); 4202 4203 for i = 0 to 14 4204 if registers<i> == '1' then 4205 R[i] = MemA[address,4]; address = address + 4; 4206 if registers<15> == '1' then 4207 LoadWritePC(MemA[address,4]); 4208 4209 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4210 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 4211 #endif 4212 4213 bool success = false; 4214 4215 if (ConditionPassed(opcode)) { 4216 uint32_t n; 4217 uint32_t registers = 0; 4218 bool wback; 4219 const uint32_t addr_byte_size = GetAddressByteSize(); 4220 switch (encoding) { 4221 case eEncodingT1: 4222 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 4223 n = Bits32(opcode, 19, 16); 4224 registers = Bits32(opcode, 15, 0); 4225 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 4226 wback = BitIsSet(opcode, 21); 4227 4228 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 4229 // UNPREDICTABLE; 4230 if ((n == 15) || (BitCount(registers) < 2) || 4231 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 4232 return false; 4233 4234 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 4235 // UNPREDICTABLE; 4236 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 4237 return false; 4238 4239 // if wback && registers<n> == '1' then UNPREDICTABLE; 4240 if (wback && BitIsSet(registers, n)) 4241 return false; 4242 4243 break; 4244 4245 case eEncodingA1: 4246 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4247 n = Bits32(opcode, 19, 16); 4248 registers = Bits32(opcode, 15, 0); 4249 wback = BitIsSet(opcode, 21); 4250 4251 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4252 if ((n == 15) || (BitCount(registers) < 1)) 4253 return false; 4254 4255 break; 4256 4257 default: 4258 return false; 4259 } 4260 4261 // address = R[n] - 4*BitCount(registers); 4262 4263 int32_t offset = 0; 4264 addr_t Rn = 4265 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4266 4267 if (!success) 4268 return false; 4269 4270 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4271 EmulateInstruction::Context context; 4272 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4273 RegisterInfo dwarf_reg; 4274 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4275 context.SetRegisterPlusOffset(dwarf_reg, Rn - address); 4276 4277 for (int i = 0; i < 14; ++i) { 4278 if (BitIsSet(registers, i)) { 4279 // R[i] = MemA[address,4]; address = address + 4; 4280 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4281 uint32_t data = 4282 MemARead(context, address + offset, addr_byte_size, 0, &success); 4283 if (!success) 4284 return false; 4285 4286 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4287 data)) 4288 return false; 4289 4290 offset += addr_byte_size; 4291 } 4292 } 4293 4294 // if registers<15> == '1' then 4295 // LoadWritePC(MemA[address,4]); 4296 if (BitIsSet(registers, 15)) { 4297 context.SetRegisterPlusOffset(dwarf_reg, offset); 4298 uint32_t data = 4299 MemARead(context, address + offset, addr_byte_size, 0, &success); 4300 if (!success) 4301 return false; 4302 // In ARMv5T and above, this is an interworking branch. 4303 if (!LoadWritePC(context, data)) 4304 return false; 4305 } 4306 4307 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4308 if (wback && BitIsClear(registers, n)) { 4309 if (!success) 4310 return false; 4311 4312 offset = (addr_byte_size * BitCount(registers)) * -1; 4313 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4314 context.SetImmediateSigned(offset); 4315 addr_t addr = Rn + offset; 4316 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4317 addr)) 4318 return false; 4319 } 4320 4321 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4322 // possible for encoding A1 4323 if (wback && BitIsSet(registers, n)) 4324 return WriteBits32Unknown(n); 4325 } 4326 return true; 4327 } 4328 4329 // LDMIB loads multiple registers from consecutive memory locations using an 4330 // address from a base register. The 4331 // consecutive memory locations start just above this address, and thea ddress 4332 // of the last of those locations can optinoally be written back to the base 4333 // register. 4334 bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode, 4335 const ARMEncoding encoding) { 4336 #if 0 4337 if ConditionPassed() then 4338 EncodingSpecificOperations(); 4339 address = R[n] + 4; 4340 4341 for i = 0 to 14 4342 if registers<i> == '1' then 4343 R[i] = MemA[address,4]; address = address + 4; 4344 if registers<15> == '1' then 4345 LoadWritePC(MemA[address,4]); 4346 4347 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4348 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4349 #endif 4350 4351 bool success = false; 4352 4353 if (ConditionPassed(opcode)) { 4354 uint32_t n; 4355 uint32_t registers = 0; 4356 bool wback; 4357 const uint32_t addr_byte_size = GetAddressByteSize(); 4358 switch (encoding) { 4359 case eEncodingA1: 4360 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4361 n = Bits32(opcode, 19, 16); 4362 registers = Bits32(opcode, 15, 0); 4363 wback = BitIsSet(opcode, 21); 4364 4365 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4366 if ((n == 15) || (BitCount(registers) < 1)) 4367 return false; 4368 4369 break; 4370 default: 4371 return false; 4372 } 4373 // address = R[n] + 4; 4374 4375 int32_t offset = 0; 4376 addr_t Rn = 4377 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4378 4379 if (!success) 4380 return false; 4381 4382 addr_t address = Rn + addr_byte_size; 4383 4384 EmulateInstruction::Context context; 4385 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4386 RegisterInfo dwarf_reg; 4387 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4388 context.SetRegisterPlusOffset(dwarf_reg, offset); 4389 4390 for (int i = 0; i < 14; ++i) { 4391 if (BitIsSet(registers, i)) { 4392 // R[i] = MemA[address,4]; address = address + 4; 4393 4394 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size); 4395 uint32_t data = 4396 MemARead(context, address + offset, addr_byte_size, 0, &success); 4397 if (!success) 4398 return false; 4399 4400 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4401 data)) 4402 return false; 4403 4404 offset += addr_byte_size; 4405 } 4406 } 4407 4408 // if registers<15> == '1' then 4409 // LoadWritePC(MemA[address,4]); 4410 if (BitIsSet(registers, 15)) { 4411 context.SetRegisterPlusOffset(dwarf_reg, offset); 4412 uint32_t data = 4413 MemARead(context, address + offset, addr_byte_size, 0, &success); 4414 if (!success) 4415 return false; 4416 // In ARMv5T and above, this is an interworking branch. 4417 if (!LoadWritePC(context, data)) 4418 return false; 4419 } 4420 4421 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4422 if (wback && BitIsClear(registers, n)) { 4423 if (!success) 4424 return false; 4425 4426 offset = addr_byte_size * BitCount(registers); 4427 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4428 context.SetImmediateSigned(offset); 4429 addr_t addr = Rn + offset; 4430 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4431 addr)) 4432 return false; 4433 } 4434 4435 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4436 // possible for encoding A1 4437 if (wback && BitIsSet(registers, n)) 4438 return WriteBits32Unknown(n); 4439 } 4440 return true; 4441 } 4442 4443 // Load Register (immediate) calculates an address from a base register value 4444 // and an immediate offset, loads a word from memory, and writes to a register. 4445 // LDR (immediate, Thumb) 4446 bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode, 4447 const ARMEncoding encoding) { 4448 #if 0 4449 // ARM pseudo code... 4450 if (ConditionPassed()) 4451 { 4452 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 4453 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4454 address = if index then offset_addr else R[n]; 4455 data = MemU[address,4]; 4456 if wback then R[n] = offset_addr; 4457 if t == 15 then 4458 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 4459 elsif UnalignedSupport() || address<1:0> = '00' then 4460 R[t] = data; 4461 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 4462 } 4463 #endif 4464 4465 bool success = false; 4466 4467 if (ConditionPassed(opcode)) { 4468 uint32_t Rt; // the destination register 4469 uint32_t Rn; // the base register 4470 uint32_t imm32; // the immediate offset used to form the address 4471 addr_t offset_addr; // the offset address 4472 addr_t address; // the calculated address 4473 uint32_t data; // the literal data value from memory load 4474 bool add, index, wback; 4475 switch (encoding) { 4476 case eEncodingT1: 4477 Rt = Bits32(opcode, 2, 0); 4478 Rn = Bits32(opcode, 5, 3); 4479 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 4480 // index = TRUE; add = TRUE; wback = FALSE 4481 add = true; 4482 index = true; 4483 wback = false; 4484 4485 break; 4486 4487 case eEncodingT2: 4488 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4489 Rt = Bits32(opcode, 10, 8); 4490 Rn = 13; 4491 imm32 = Bits32(opcode, 7, 0) << 2; 4492 4493 // index = TRUE; add = TRUE; wback = FALSE; 4494 index = true; 4495 add = true; 4496 wback = false; 4497 4498 break; 4499 4500 case eEncodingT3: 4501 // if Rn == '1111' then SEE LDR (literal); 4502 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4503 Rt = Bits32(opcode, 15, 12); 4504 Rn = Bits32(opcode, 19, 16); 4505 imm32 = Bits32(opcode, 11, 0); 4506 4507 // index = TRUE; add = TRUE; wback = FALSE; 4508 index = true; 4509 add = true; 4510 wback = false; 4511 4512 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4513 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4514 return false; 4515 4516 break; 4517 4518 case eEncodingT4: 4519 // if Rn == '1111' then SEE LDR (literal); 4520 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4521 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == 4522 // '00000100' then SEE POP; 4523 // if P == '0' && W == '0' then UNDEFINED; 4524 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 4525 return false; 4526 4527 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4528 Rt = Bits32(opcode, 15, 12); 4529 Rn = Bits32(opcode, 19, 16); 4530 imm32 = Bits32(opcode, 7, 0); 4531 4532 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4533 index = BitIsSet(opcode, 10); 4534 add = BitIsSet(opcode, 9); 4535 wback = BitIsSet(opcode, 8); 4536 4537 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) 4538 // then UNPREDICTABLE; 4539 if ((wback && (Rn == Rt)) || 4540 ((Rt == 15) && InITBlock() && !LastInITBlock())) 4541 return false; 4542 4543 break; 4544 4545 default: 4546 return false; 4547 } 4548 uint32_t base = ReadCoreReg(Rn, &success); 4549 if (!success) 4550 return false; 4551 if (add) 4552 offset_addr = base + imm32; 4553 else 4554 offset_addr = base - imm32; 4555 4556 address = (index ? offset_addr : base); 4557 4558 RegisterInfo base_reg; 4559 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4560 if (wback) { 4561 EmulateInstruction::Context ctx; 4562 if (Rn == 13) { 4563 ctx.type = eContextAdjustStackPointer; 4564 ctx.SetImmediateSigned((int32_t)(offset_addr - base)); 4565 } else if (Rn == GetFramePointerRegisterNumber()) { 4566 ctx.type = eContextSetFramePointer; 4567 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4568 } else { 4569 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4570 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4571 } 4572 4573 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn, 4574 offset_addr)) 4575 return false; 4576 } 4577 4578 // Prepare to write to the Rt register. 4579 EmulateInstruction::Context context; 4580 context.type = EmulateInstruction::eContextRegisterLoad; 4581 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4582 4583 // Read memory from the address. 4584 data = MemURead(context, address, 4, 0, &success); 4585 if (!success) 4586 return false; 4587 4588 if (Rt == 15) { 4589 if (Bits32(address, 1, 0) == 0) { 4590 if (!LoadWritePC(context, data)) 4591 return false; 4592 } else 4593 return false; 4594 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 4595 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 4596 data)) 4597 return false; 4598 } else 4599 WriteBits32Unknown(Rt); 4600 } 4601 return true; 4602 } 4603 4604 // STM (Store Multiple Increment After) stores multiple registers to consecutive 4605 // memory locations using an address 4606 // from a base register. The consecutive memory locations start at this 4607 // address, and the address just above the last of those locations can 4608 // optionally be written back to the base register. 4609 bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode, 4610 const ARMEncoding encoding) { 4611 #if 0 4612 if ConditionPassed() then 4613 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4614 address = R[n]; 4615 4616 for i = 0 to 14 4617 if registers<i> == '1' then 4618 if i == n && wback && i != LowestSetBit(registers) then 4619 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4620 else 4621 MemA[address,4] = R[i]; 4622 address = address + 4; 4623 4624 if registers<15> == '1' then // Only possible for encoding A1 4625 MemA[address,4] = PCStoreValue(); 4626 if wback then R[n] = R[n] + 4*BitCount(registers); 4627 #endif 4628 4629 bool success = false; 4630 4631 if (ConditionPassed(opcode)) { 4632 uint32_t n; 4633 uint32_t registers = 0; 4634 bool wback; 4635 const uint32_t addr_byte_size = GetAddressByteSize(); 4636 4637 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4638 switch (encoding) { 4639 case eEncodingT1: 4640 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4641 n = Bits32(opcode, 10, 8); 4642 registers = Bits32(opcode, 7, 0); 4643 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4644 wback = true; 4645 4646 // if BitCount(registers) < 1 then UNPREDICTABLE; 4647 if (BitCount(registers) < 1) 4648 return false; 4649 4650 break; 4651 4652 case eEncodingT2: 4653 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4654 n = Bits32(opcode, 19, 16); 4655 registers = Bits32(opcode, 15, 0); 4656 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4657 wback = BitIsSet(opcode, 21); 4658 4659 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4660 if ((n == 15) || (BitCount(registers) < 2)) 4661 return false; 4662 4663 // if wback && registers<n> == '1' then UNPREDICTABLE; 4664 if (wback && BitIsSet(registers, n)) 4665 return false; 4666 4667 break; 4668 4669 case eEncodingA1: 4670 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4671 n = Bits32(opcode, 19, 16); 4672 registers = Bits32(opcode, 15, 0); 4673 wback = BitIsSet(opcode, 21); 4674 4675 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4676 if ((n == 15) || (BitCount(registers) < 1)) 4677 return false; 4678 4679 break; 4680 4681 default: 4682 return false; 4683 } 4684 4685 // address = R[n]; 4686 int32_t offset = 0; 4687 const addr_t address = 4688 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4689 if (!success) 4690 return false; 4691 4692 EmulateInstruction::Context context; 4693 context.type = EmulateInstruction::eContextRegisterStore; 4694 RegisterInfo base_reg; 4695 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4696 4697 // for i = 0 to 14 4698 uint32_t lowest_set_bit = 14; 4699 for (uint32_t i = 0; i < 14; ++i) { 4700 // if registers<i> == '1' then 4701 if (BitIsSet(registers, i)) { 4702 if (i < lowest_set_bit) 4703 lowest_set_bit = i; 4704 // if i == n && wback && i != LowestSetBit(registers) then 4705 if ((i == n) && wback && (i != lowest_set_bit)) 4706 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings 4707 // T1 and A1 4708 WriteBits32UnknownToMemory(address + offset); 4709 else { 4710 // MemA[address,4] = R[i]; 4711 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4712 0, &success); 4713 if (!success) 4714 return false; 4715 4716 RegisterInfo data_reg; 4717 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4718 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 4719 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4720 return false; 4721 } 4722 4723 // address = address + 4; 4724 offset += addr_byte_size; 4725 } 4726 } 4727 4728 // if registers<15> == '1' then // Only possible for encoding A1 4729 // MemA[address,4] = PCStoreValue(); 4730 if (BitIsSet(registers, 15)) { 4731 RegisterInfo pc_reg; 4732 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4733 context.SetRegisterPlusOffset(pc_reg, 8); 4734 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4735 if (!success) 4736 return false; 4737 4738 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4739 return false; 4740 } 4741 4742 // if wback then R[n] = R[n] + 4*BitCount(registers); 4743 if (wback) { 4744 offset = addr_byte_size * BitCount(registers); 4745 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4746 context.SetImmediateSigned(offset); 4747 addr_t data = address + offset; 4748 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4749 data)) 4750 return false; 4751 } 4752 } 4753 return true; 4754 } 4755 4756 // STMDA (Store Multiple Decrement After) stores multiple registers to 4757 // consecutive memory locations using an address from a base register. The 4758 // consecutive memory locations end at this address, and the address just below 4759 // the lowest of those locations can optionally be written back to the base 4760 // register. 4761 bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode, 4762 const ARMEncoding encoding) { 4763 #if 0 4764 if ConditionPassed() then 4765 EncodingSpecificOperations(); 4766 address = R[n] - 4*BitCount(registers) + 4; 4767 4768 for i = 0 to 14 4769 if registers<i> == '1' then 4770 if i == n && wback && i != LowestSetBit(registers) then 4771 MemA[address,4] = bits(32) UNKNOWN; 4772 else 4773 MemA[address,4] = R[i]; 4774 address = address + 4; 4775 4776 if registers<15> == '1' then 4777 MemA[address,4] = PCStoreValue(); 4778 4779 if wback then R[n] = R[n] - 4*BitCount(registers); 4780 #endif 4781 4782 bool success = false; 4783 4784 if (ConditionPassed(opcode)) { 4785 uint32_t n; 4786 uint32_t registers = 0; 4787 bool wback; 4788 const uint32_t addr_byte_size = GetAddressByteSize(); 4789 4790 // EncodingSpecificOperations(); 4791 switch (encoding) { 4792 case eEncodingA1: 4793 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4794 n = Bits32(opcode, 19, 16); 4795 registers = Bits32(opcode, 15, 0); 4796 wback = BitIsSet(opcode, 21); 4797 4798 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4799 if ((n == 15) || (BitCount(registers) < 1)) 4800 return false; 4801 break; 4802 default: 4803 return false; 4804 } 4805 4806 // address = R[n] - 4*BitCount(registers) + 4; 4807 int32_t offset = 0; 4808 addr_t Rn = ReadCoreReg(n, &success); 4809 if (!success) 4810 return false; 4811 4812 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4; 4813 4814 EmulateInstruction::Context context; 4815 context.type = EmulateInstruction::eContextRegisterStore; 4816 RegisterInfo base_reg; 4817 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4818 4819 // for i = 0 to 14 4820 uint32_t lowest_bit_set = 14; 4821 for (uint32_t i = 0; i < 14; ++i) { 4822 // if registers<i> == '1' then 4823 if (BitIsSet(registers, i)) { 4824 if (i < lowest_bit_set) 4825 lowest_bit_set = i; 4826 // if i == n && wback && i != LowestSetBit(registers) then 4827 if ((i == n) && wback && (i != lowest_bit_set)) 4828 // MemA[address,4] = bits(32) UNKNOWN; 4829 WriteBits32UnknownToMemory(address + offset); 4830 else { 4831 // MemA[address,4] = R[i]; 4832 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4833 0, &success); 4834 if (!success) 4835 return false; 4836 4837 RegisterInfo data_reg; 4838 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4839 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4840 Rn - (address + offset)); 4841 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4842 return false; 4843 } 4844 4845 // address = address + 4; 4846 offset += addr_byte_size; 4847 } 4848 } 4849 4850 // if registers<15> == '1' then 4851 // MemA[address,4] = PCStoreValue(); 4852 if (BitIsSet(registers, 15)) { 4853 RegisterInfo pc_reg; 4854 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4855 context.SetRegisterPlusOffset(pc_reg, 8); 4856 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4857 if (!success) 4858 return false; 4859 4860 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4861 return false; 4862 } 4863 4864 // if wback then R[n] = R[n] - 4*BitCount(registers); 4865 if (wback) { 4866 offset = (addr_byte_size * BitCount(registers)) * -1; 4867 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4868 context.SetImmediateSigned(offset); 4869 addr_t data = Rn + offset; 4870 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4871 data)) 4872 return false; 4873 } 4874 } 4875 return true; 4876 } 4877 4878 // STMDB (Store Multiple Decrement Before) stores multiple registers to 4879 // consecutive memory locations using an address from a base register. The 4880 // consecutive memory locations end just below this address, and the address of 4881 // the first of those locations can optionally be written back to the base 4882 // register. 4883 bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode, 4884 const ARMEncoding encoding) { 4885 #if 0 4886 if ConditionPassed() then 4887 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4888 address = R[n] - 4*BitCount(registers); 4889 4890 for i = 0 to 14 4891 if registers<i> == '1' then 4892 if i == n && wback && i != LowestSetBit(registers) then 4893 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4894 else 4895 MemA[address,4] = R[i]; 4896 address = address + 4; 4897 4898 if registers<15> == '1' then // Only possible for encoding A1 4899 MemA[address,4] = PCStoreValue(); 4900 4901 if wback then R[n] = R[n] - 4*BitCount(registers); 4902 #endif 4903 4904 bool success = false; 4905 4906 if (ConditionPassed(opcode)) { 4907 uint32_t n; 4908 uint32_t registers = 0; 4909 bool wback; 4910 const uint32_t addr_byte_size = GetAddressByteSize(); 4911 4912 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4913 switch (encoding) { 4914 case eEncodingT1: 4915 // if W == '1' && Rn == '1101' then SEE PUSH; 4916 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) { 4917 // See PUSH 4918 } 4919 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4920 n = Bits32(opcode, 19, 16); 4921 registers = Bits32(opcode, 15, 0); 4922 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4923 wback = BitIsSet(opcode, 21); 4924 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4925 if ((n == 15) || BitCount(registers) < 2) 4926 return false; 4927 // if wback && registers<n> == '1' then UNPREDICTABLE; 4928 if (wback && BitIsSet(registers, n)) 4929 return false; 4930 break; 4931 4932 case eEncodingA1: 4933 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE 4934 // PUSH; 4935 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) && 4936 BitCount(Bits32(opcode, 15, 0)) >= 2) { 4937 // See Push 4938 } 4939 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4940 n = Bits32(opcode, 19, 16); 4941 registers = Bits32(opcode, 15, 0); 4942 wback = BitIsSet(opcode, 21); 4943 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4944 if ((n == 15) || BitCount(registers) < 1) 4945 return false; 4946 break; 4947 4948 default: 4949 return false; 4950 } 4951 4952 // address = R[n] - 4*BitCount(registers); 4953 4954 int32_t offset = 0; 4955 addr_t Rn = 4956 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4957 if (!success) 4958 return false; 4959 4960 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4961 4962 EmulateInstruction::Context context; 4963 context.type = EmulateInstruction::eContextRegisterStore; 4964 RegisterInfo base_reg; 4965 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4966 4967 // for i = 0 to 14 4968 uint32_t lowest_set_bit = 14; 4969 for (uint32_t i = 0; i < 14; ++i) { 4970 // if registers<i> == '1' then 4971 if (BitIsSet(registers, i)) { 4972 if (i < lowest_set_bit) 4973 lowest_set_bit = i; 4974 // if i == n && wback && i != LowestSetBit(registers) then 4975 if ((i == n) && wback && (i != lowest_set_bit)) 4976 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding 4977 // A1 4978 WriteBits32UnknownToMemory(address + offset); 4979 else { 4980 // MemA[address,4] = R[i]; 4981 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4982 0, &success); 4983 if (!success) 4984 return false; 4985 4986 RegisterInfo data_reg; 4987 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4988 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4989 Rn - (address + offset)); 4990 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4991 return false; 4992 } 4993 4994 // address = address + 4; 4995 offset += addr_byte_size; 4996 } 4997 } 4998 4999 // if registers<15> == '1' then // Only possible for encoding A1 5000 // MemA[address,4] = PCStoreValue(); 5001 if (BitIsSet(registers, 15)) { 5002 RegisterInfo pc_reg; 5003 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5004 context.SetRegisterPlusOffset(pc_reg, 8); 5005 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5006 if (!success) 5007 return false; 5008 5009 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5010 return false; 5011 } 5012 5013 // if wback then R[n] = R[n] - 4*BitCount(registers); 5014 if (wback) { 5015 offset = (addr_byte_size * BitCount(registers)) * -1; 5016 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5017 context.SetImmediateSigned(offset); 5018 addr_t data = Rn + offset; 5019 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5020 data)) 5021 return false; 5022 } 5023 } 5024 return true; 5025 } 5026 5027 // STMIB (Store Multiple Increment Before) stores multiple registers to 5028 // consecutive memory locations using an address from a base register. The 5029 // consecutive memory locations start just above this address, and the address 5030 // of the last of those locations can optionally be written back to the base 5031 // register. 5032 bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode, 5033 const ARMEncoding encoding) { 5034 #if 0 5035 if ConditionPassed() then 5036 EncodingSpecificOperations(); 5037 address = R[n] + 4; 5038 5039 for i = 0 to 14 5040 if registers<i> == '1' then 5041 if i == n && wback && i != LowestSetBit(registers) then 5042 MemA[address,4] = bits(32) UNKNOWN; 5043 else 5044 MemA[address,4] = R[i]; 5045 address = address + 4; 5046 5047 if registers<15> == '1' then 5048 MemA[address,4] = PCStoreValue(); 5049 5050 if wback then R[n] = R[n] + 4*BitCount(registers); 5051 #endif 5052 5053 bool success = false; 5054 5055 if (ConditionPassed(opcode)) { 5056 uint32_t n; 5057 uint32_t registers = 0; 5058 bool wback; 5059 const uint32_t addr_byte_size = GetAddressByteSize(); 5060 5061 // EncodingSpecificOperations(); 5062 switch (encoding) { 5063 case eEncodingA1: 5064 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 5065 n = Bits32(opcode, 19, 16); 5066 registers = Bits32(opcode, 15, 0); 5067 wback = BitIsSet(opcode, 21); 5068 5069 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 5070 if ((n == 15) && (BitCount(registers) < 1)) 5071 return false; 5072 break; 5073 default: 5074 return false; 5075 } 5076 // address = R[n] + 4; 5077 5078 int32_t offset = 0; 5079 addr_t Rn = ReadCoreReg(n, &success); 5080 if (!success) 5081 return false; 5082 5083 addr_t address = Rn + addr_byte_size; 5084 5085 EmulateInstruction::Context context; 5086 context.type = EmulateInstruction::eContextRegisterStore; 5087 RegisterInfo base_reg; 5088 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5089 5090 uint32_t lowest_set_bit = 14; 5091 // for i = 0 to 14 5092 for (uint32_t i = 0; i < 14; ++i) { 5093 // if registers<i> == '1' then 5094 if (BitIsSet(registers, i)) { 5095 if (i < lowest_set_bit) 5096 lowest_set_bit = i; 5097 // if i == n && wback && i != LowestSetBit(registers) then 5098 if ((i == n) && wback && (i != lowest_set_bit)) 5099 // MemA[address,4] = bits(32) UNKNOWN; 5100 WriteBits32UnknownToMemory(address + offset); 5101 // else 5102 else { 5103 // MemA[address,4] = R[i]; 5104 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5105 0, &success); 5106 if (!success) 5107 return false; 5108 5109 RegisterInfo data_reg; 5110 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5111 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5112 offset + addr_byte_size); 5113 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5114 return false; 5115 } 5116 5117 // address = address + 4; 5118 offset += addr_byte_size; 5119 } 5120 } 5121 5122 // if registers<15> == '1' then 5123 // MemA[address,4] = PCStoreValue(); 5124 if (BitIsSet(registers, 15)) { 5125 RegisterInfo pc_reg; 5126 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5127 context.SetRegisterPlusOffset(pc_reg, 8); 5128 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5129 if (!success) 5130 return false; 5131 5132 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5133 return false; 5134 } 5135 5136 // if wback then R[n] = R[n] + 4*BitCount(registers); 5137 if (wback) { 5138 offset = addr_byte_size * BitCount(registers); 5139 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5140 context.SetImmediateSigned(offset); 5141 addr_t data = Rn + offset; 5142 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5143 data)) 5144 return false; 5145 } 5146 } 5147 return true; 5148 } 5149 5150 // STR (store immediate) calculates an address from a base register value and an 5151 // immediate offset, and stores a word 5152 // from a register to memory. It can use offset, post-indexed, or pre-indexed 5153 // addressing. 5154 bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode, 5155 const ARMEncoding encoding) { 5156 #if 0 5157 if ConditionPassed() then 5158 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5159 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5160 address = if index then offset_addr else R[n]; 5161 if UnalignedSupport() || address<1:0> == '00' then 5162 MemU[address,4] = R[t]; 5163 else // Can only occur before ARMv7 5164 MemU[address,4] = bits(32) UNKNOWN; 5165 if wback then R[n] = offset_addr; 5166 #endif 5167 5168 bool success = false; 5169 5170 if (ConditionPassed(opcode)) { 5171 const uint32_t addr_byte_size = GetAddressByteSize(); 5172 5173 uint32_t t; 5174 uint32_t n; 5175 uint32_t imm32; 5176 bool index; 5177 bool add; 5178 bool wback; 5179 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5180 switch (encoding) { 5181 case eEncodingT1: 5182 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 5183 t = Bits32(opcode, 2, 0); 5184 n = Bits32(opcode, 5, 3); 5185 imm32 = Bits32(opcode, 10, 6) << 2; 5186 5187 // index = TRUE; add = TRUE; wback = FALSE; 5188 index = true; 5189 add = false; 5190 wback = false; 5191 break; 5192 5193 case eEncodingT2: 5194 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 5195 t = Bits32(opcode, 10, 8); 5196 n = 13; 5197 imm32 = Bits32(opcode, 7, 0) << 2; 5198 5199 // index = TRUE; add = TRUE; wback = FALSE; 5200 index = true; 5201 add = true; 5202 wback = false; 5203 break; 5204 5205 case eEncodingT3: 5206 // if Rn == '1111' then UNDEFINED; 5207 if (Bits32(opcode, 19, 16) == 15) 5208 return false; 5209 5210 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5211 t = Bits32(opcode, 15, 12); 5212 n = Bits32(opcode, 19, 16); 5213 imm32 = Bits32(opcode, 11, 0); 5214 5215 // index = TRUE; add = TRUE; wback = FALSE; 5216 index = true; 5217 add = true; 5218 wback = false; 5219 5220 // if t == 15 then UNPREDICTABLE; 5221 if (t == 15) 5222 return false; 5223 break; 5224 5225 case eEncodingT4: 5226 // if P == '1' && U == '1' && W == '0' then SEE STRT; 5227 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == 5228 // '00000100' then SEE PUSH; 5229 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5230 if ((Bits32(opcode, 19, 16) == 15) || 5231 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))) 5232 return false; 5233 5234 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5235 t = Bits32(opcode, 15, 12); 5236 n = Bits32(opcode, 19, 16); 5237 imm32 = Bits32(opcode, 7, 0); 5238 5239 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5240 index = BitIsSet(opcode, 10); 5241 add = BitIsSet(opcode, 9); 5242 wback = BitIsSet(opcode, 8); 5243 5244 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 5245 if ((t == 15) || (wback && (n == t))) 5246 return false; 5247 break; 5248 5249 default: 5250 return false; 5251 } 5252 5253 addr_t offset_addr; 5254 addr_t address; 5255 5256 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5257 uint32_t base_address = ReadCoreReg(n, &success); 5258 if (!success) 5259 return false; 5260 5261 if (add) 5262 offset_addr = base_address + imm32; 5263 else 5264 offset_addr = base_address - imm32; 5265 5266 // address = if index then offset_addr else R[n]; 5267 if (index) 5268 address = offset_addr; 5269 else 5270 address = base_address; 5271 5272 EmulateInstruction::Context context; 5273 if (n == 13) 5274 context.type = eContextPushRegisterOnStack; 5275 else 5276 context.type = eContextRegisterStore; 5277 5278 RegisterInfo base_reg; 5279 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5280 5281 // if UnalignedSupport() || address<1:0> == '00' then 5282 if (UnalignedSupport() || 5283 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 5284 // MemU[address,4] = R[t]; 5285 uint32_t data = 5286 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5287 if (!success) 5288 return false; 5289 5290 RegisterInfo data_reg; 5291 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5292 int32_t offset = address - base_address; 5293 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 5294 if (!MemUWrite(context, address, data, addr_byte_size)) 5295 return false; 5296 } else { 5297 // MemU[address,4] = bits(32) UNKNOWN; 5298 WriteBits32UnknownToMemory(address); 5299 } 5300 5301 // if wback then R[n] = offset_addr; 5302 if (wback) { 5303 if (n == 13) 5304 context.type = eContextAdjustStackPointer; 5305 else 5306 context.type = eContextAdjustBaseRegister; 5307 context.SetAddress(offset_addr); 5308 5309 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5310 offset_addr)) 5311 return false; 5312 } 5313 } 5314 return true; 5315 } 5316 5317 // STR (Store Register) calculates an address from a base register value and an 5318 // offset register value, stores a 5319 // word from a register to memory. The offset register value can optionally 5320 // be shifted. 5321 bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode, 5322 const ARMEncoding encoding) { 5323 #if 0 5324 if ConditionPassed() then 5325 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5326 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5327 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5328 address = if index then offset_addr else R[n]; 5329 if t == 15 then // Only possible for encoding A1 5330 data = PCStoreValue(); 5331 else 5332 data = R[t]; 5333 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 5334 MemU[address,4] = data; 5335 else // Can only occur before ARMv7 5336 MemU[address,4] = bits(32) UNKNOWN; 5337 if wback then R[n] = offset_addr; 5338 #endif 5339 5340 bool success = false; 5341 5342 if (ConditionPassed(opcode)) { 5343 const uint32_t addr_byte_size = GetAddressByteSize(); 5344 5345 uint32_t t; 5346 uint32_t n; 5347 uint32_t m; 5348 ARM_ShifterType shift_t; 5349 uint32_t shift_n; 5350 bool index; 5351 bool add; 5352 bool wback; 5353 5354 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5355 switch (encoding) { 5356 case eEncodingT1: 5357 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5358 // in ThumbEE"; 5359 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5360 t = Bits32(opcode, 2, 0); 5361 n = Bits32(opcode, 5, 3); 5362 m = Bits32(opcode, 8, 6); 5363 5364 // index = TRUE; add = TRUE; wback = FALSE; 5365 index = true; 5366 add = true; 5367 wback = false; 5368 5369 // (shift_t, shift_n) = (SRType_LSL, 0); 5370 shift_t = SRType_LSL; 5371 shift_n = 0; 5372 break; 5373 5374 case eEncodingT2: 5375 // if Rn == '1111' then UNDEFINED; 5376 if (Bits32(opcode, 19, 16) == 15) 5377 return false; 5378 5379 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5380 t = Bits32(opcode, 15, 12); 5381 n = Bits32(opcode, 19, 16); 5382 m = Bits32(opcode, 3, 0); 5383 5384 // index = TRUE; add = TRUE; wback = FALSE; 5385 index = true; 5386 add = true; 5387 wback = false; 5388 5389 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5390 shift_t = SRType_LSL; 5391 shift_n = Bits32(opcode, 5, 4); 5392 5393 // if t == 15 || BadReg(m) then UNPREDICTABLE; 5394 if ((t == 15) || (BadReg(m))) 5395 return false; 5396 break; 5397 5398 case eEncodingA1: { 5399 // if P == '0' && W == '1' then SEE STRT; 5400 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5401 t = Bits32(opcode, 15, 12); 5402 n = Bits32(opcode, 19, 16); 5403 m = Bits32(opcode, 3, 0); 5404 5405 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5406 // (W == '1'); 5407 index = BitIsSet(opcode, 24); 5408 add = BitIsSet(opcode, 23); 5409 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5410 5411 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5412 uint32_t typ = Bits32(opcode, 6, 5); 5413 uint32_t imm5 = Bits32(opcode, 11, 7); 5414 shift_n = DecodeImmShift(typ, imm5, shift_t); 5415 5416 // if m == 15 then UNPREDICTABLE; 5417 if (m == 15) 5418 return false; 5419 5420 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5421 if (wback && ((n == 15) || (n == t))) 5422 return false; 5423 5424 break; 5425 } 5426 default: 5427 return false; 5428 } 5429 5430 addr_t offset_addr; 5431 addr_t address; 5432 int32_t offset = 0; 5433 5434 addr_t base_address = 5435 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5436 if (!success) 5437 return false; 5438 5439 uint32_t Rm_data = 5440 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5441 if (!success) 5442 return false; 5443 5444 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5445 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success); 5446 if (!success) 5447 return false; 5448 5449 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5450 if (add) 5451 offset_addr = base_address + offset; 5452 else 5453 offset_addr = base_address - offset; 5454 5455 // address = if index then offset_addr else R[n]; 5456 if (index) 5457 address = offset_addr; 5458 else 5459 address = base_address; 5460 5461 uint32_t data; 5462 // if t == 15 then // Only possible for encoding A1 5463 if (t == 15) 5464 // data = PCStoreValue(); 5465 data = ReadCoreReg(PC_REG, &success); 5466 else 5467 // data = R[t]; 5468 data = 5469 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5470 5471 if (!success) 5472 return false; 5473 5474 EmulateInstruction::Context context; 5475 context.type = eContextRegisterStore; 5476 5477 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == 5478 // InstrSet_ARM then 5479 if (UnalignedSupport() || 5480 (BitIsClear(address, 1) && BitIsClear(address, 0)) || 5481 CurrentInstrSet() == eModeARM) { 5482 // MemU[address,4] = data; 5483 5484 RegisterInfo base_reg; 5485 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5486 5487 RegisterInfo data_reg; 5488 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5489 5490 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5491 address - base_address); 5492 if (!MemUWrite(context, address, data, addr_byte_size)) 5493 return false; 5494 5495 } else 5496 // MemU[address,4] = bits(32) UNKNOWN; 5497 WriteBits32UnknownToMemory(address); 5498 5499 // if wback then R[n] = offset_addr; 5500 if (wback) { 5501 context.type = eContextRegisterLoad; 5502 context.SetAddress(offset_addr); 5503 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5504 offset_addr)) 5505 return false; 5506 } 5507 } 5508 return true; 5509 } 5510 5511 bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode, 5512 const ARMEncoding encoding) { 5513 #if 0 5514 if ConditionPassed() then 5515 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5516 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5517 address = if index then offset_addr else R[n]; 5518 MemU[address,1] = R[t]<7:0>; 5519 if wback then R[n] = offset_addr; 5520 #endif 5521 5522 bool success = false; 5523 5524 if (ConditionPassed(opcode)) { 5525 uint32_t t; 5526 uint32_t n; 5527 uint32_t imm32; 5528 bool index; 5529 bool add; 5530 bool wback; 5531 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5532 switch (encoding) { 5533 case eEncodingT1: 5534 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5535 t = Bits32(opcode, 2, 0); 5536 n = Bits32(opcode, 5, 3); 5537 imm32 = Bits32(opcode, 10, 6); 5538 5539 // index = TRUE; add = TRUE; wback = FALSE; 5540 index = true; 5541 add = true; 5542 wback = false; 5543 break; 5544 5545 case eEncodingT2: 5546 // if Rn == '1111' then UNDEFINED; 5547 if (Bits32(opcode, 19, 16) == 15) 5548 return false; 5549 5550 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5551 t = Bits32(opcode, 15, 12); 5552 n = Bits32(opcode, 19, 16); 5553 imm32 = Bits32(opcode, 11, 0); 5554 5555 // index = TRUE; add = TRUE; wback = FALSE; 5556 index = true; 5557 add = true; 5558 wback = false; 5559 5560 // if BadReg(t) then UNPREDICTABLE; 5561 if (BadReg(t)) 5562 return false; 5563 break; 5564 5565 case eEncodingT3: 5566 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5567 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5568 if (Bits32(opcode, 19, 16) == 15) 5569 return false; 5570 5571 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5572 t = Bits32(opcode, 15, 12); 5573 n = Bits32(opcode, 19, 16); 5574 imm32 = Bits32(opcode, 7, 0); 5575 5576 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5577 index = BitIsSet(opcode, 10); 5578 add = BitIsSet(opcode, 9); 5579 wback = BitIsSet(opcode, 8); 5580 5581 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5582 if ((BadReg(t)) || (wback && (n == t))) 5583 return false; 5584 break; 5585 5586 default: 5587 return false; 5588 } 5589 5590 addr_t offset_addr; 5591 addr_t address; 5592 addr_t base_address = 5593 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5594 if (!success) 5595 return false; 5596 5597 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5598 if (add) 5599 offset_addr = base_address + imm32; 5600 else 5601 offset_addr = base_address - imm32; 5602 5603 // address = if index then offset_addr else R[n]; 5604 if (index) 5605 address = offset_addr; 5606 else 5607 address = base_address; 5608 5609 // MemU[address,1] = R[t]<7:0> 5610 RegisterInfo base_reg; 5611 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5612 5613 RegisterInfo data_reg; 5614 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5615 5616 EmulateInstruction::Context context; 5617 context.type = eContextRegisterStore; 5618 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5619 address - base_address); 5620 5621 uint32_t data = 5622 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5623 if (!success) 5624 return false; 5625 5626 data = Bits32(data, 7, 0); 5627 5628 if (!MemUWrite(context, address, data, 1)) 5629 return false; 5630 5631 // if wback then R[n] = offset_addr; 5632 if (wback) { 5633 context.type = eContextRegisterLoad; 5634 context.SetAddress(offset_addr); 5635 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5636 offset_addr)) 5637 return false; 5638 } 5639 } 5640 5641 return true; 5642 } 5643 5644 // STRH (register) calculates an address from a base register value and an 5645 // offset register value, and stores a 5646 // halfword from a register to memory. The offset register value can be 5647 // shifted left by 0, 1, 2, or 3 bits. 5648 bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode, 5649 const ARMEncoding encoding) { 5650 #if 0 5651 if ConditionPassed() then 5652 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5653 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5654 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5655 address = if index then offset_addr else R[n]; 5656 if UnalignedSupport() || address<0> == '0' then 5657 MemU[address,2] = R[t]<15:0>; 5658 else // Can only occur before ARMv7 5659 MemU[address,2] = bits(16) UNKNOWN; 5660 if wback then R[n] = offset_addr; 5661 #endif 5662 5663 bool success = false; 5664 5665 if (ConditionPassed(opcode)) { 5666 uint32_t t; 5667 uint32_t n; 5668 uint32_t m; 5669 bool index; 5670 bool add; 5671 bool wback; 5672 ARM_ShifterType shift_t; 5673 uint32_t shift_n; 5674 5675 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5676 switch (encoding) { 5677 case eEncodingT1: 5678 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5679 // in ThumbEE"; 5680 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5681 t = Bits32(opcode, 2, 0); 5682 n = Bits32(opcode, 5, 3); 5683 m = Bits32(opcode, 8, 6); 5684 5685 // index = TRUE; add = TRUE; wback = FALSE; 5686 index = true; 5687 add = true; 5688 wback = false; 5689 5690 // (shift_t, shift_n) = (SRType_LSL, 0); 5691 shift_t = SRType_LSL; 5692 shift_n = 0; 5693 5694 break; 5695 5696 case eEncodingT2: 5697 // if Rn == '1111' then UNDEFINED; 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 if (n == 15) 5703 return false; 5704 5705 // index = TRUE; add = TRUE; wback = FALSE; 5706 index = true; 5707 add = true; 5708 wback = false; 5709 5710 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5711 shift_t = SRType_LSL; 5712 shift_n = Bits32(opcode, 5, 4); 5713 5714 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5715 if (BadReg(t) || BadReg(m)) 5716 return false; 5717 5718 break; 5719 5720 case eEncodingA1: 5721 // if P == '0' && W == '1' then SEE STRHT; 5722 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5723 t = Bits32(opcode, 15, 12); 5724 n = Bits32(opcode, 19, 16); 5725 m = Bits32(opcode, 3, 0); 5726 5727 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5728 // (W == '1'); 5729 index = BitIsSet(opcode, 24); 5730 add = BitIsSet(opcode, 23); 5731 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5732 5733 // (shift_t, shift_n) = (SRType_LSL, 0); 5734 shift_t = SRType_LSL; 5735 shift_n = 0; 5736 5737 // if t == 15 || m == 15 then UNPREDICTABLE; 5738 if ((t == 15) || (m == 15)) 5739 return false; 5740 5741 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5742 if (wback && ((n == 15) || (n == t))) 5743 return false; 5744 5745 break; 5746 5747 default: 5748 return false; 5749 } 5750 5751 uint32_t Rm = ReadCoreReg(m, &success); 5752 if (!success) 5753 return false; 5754 5755 uint32_t Rn = ReadCoreReg(n, &success); 5756 if (!success) 5757 return false; 5758 5759 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5760 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 5761 if (!success) 5762 return false; 5763 5764 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5765 addr_t offset_addr; 5766 if (add) 5767 offset_addr = Rn + offset; 5768 else 5769 offset_addr = Rn - offset; 5770 5771 // address = if index then offset_addr else R[n]; 5772 addr_t address; 5773 if (index) 5774 address = offset_addr; 5775 else 5776 address = Rn; 5777 5778 EmulateInstruction::Context context; 5779 context.type = eContextRegisterStore; 5780 RegisterInfo base_reg; 5781 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5782 RegisterInfo offset_reg; 5783 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5784 5785 // if UnalignedSupport() || address<0> == '0' then 5786 if (UnalignedSupport() || BitIsClear(address, 0)) { 5787 // MemU[address,2] = R[t]<15:0>; 5788 uint32_t Rt = ReadCoreReg(t, &success); 5789 if (!success) 5790 return false; 5791 5792 EmulateInstruction::Context context; 5793 context.type = eContextRegisterStore; 5794 RegisterInfo base_reg; 5795 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5796 RegisterInfo offset_reg; 5797 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5798 RegisterInfo data_reg; 5799 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5800 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 5801 data_reg); 5802 5803 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2)) 5804 return false; 5805 } else // Can only occur before ARMv7 5806 { 5807 // MemU[address,2] = bits(16) UNKNOWN; 5808 } 5809 5810 // if wback then R[n] = offset_addr; 5811 if (wback) { 5812 context.type = eContextAdjustBaseRegister; 5813 context.SetAddress(offset_addr); 5814 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5815 offset_addr)) 5816 return false; 5817 } 5818 } 5819 5820 return true; 5821 } 5822 5823 // Add with Carry (immediate) adds an immediate value and the carry flag value 5824 // to a register value, and writes the result to the destination register. It 5825 // can optionally update the condition flags based on the result. 5826 bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode, 5827 const ARMEncoding encoding) { 5828 #if 0 5829 // ARM pseudo code... 5830 if ConditionPassed() then 5831 EncodingSpecificOperations(); 5832 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5833 if d == 15 then // Can only occur for ARM encoding 5834 ALUWritePC(result); // setflags is always FALSE here 5835 else 5836 R[d] = result; 5837 if setflags then 5838 APSR.N = result<31>; 5839 APSR.Z = IsZeroBit(result); 5840 APSR.C = carry; 5841 APSR.V = overflow; 5842 #endif 5843 5844 bool success = false; 5845 5846 if (ConditionPassed(opcode)) { 5847 uint32_t Rd, Rn; 5848 uint32_t 5849 imm32; // the immediate value to be added to the value obtained from Rn 5850 bool setflags; 5851 switch (encoding) { 5852 case eEncodingT1: 5853 Rd = Bits32(opcode, 11, 8); 5854 Rn = Bits32(opcode, 19, 16); 5855 setflags = BitIsSet(opcode, 20); 5856 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5857 if (BadReg(Rd) || BadReg(Rn)) 5858 return false; 5859 break; 5860 case eEncodingA1: 5861 Rd = Bits32(opcode, 15, 12); 5862 Rn = Bits32(opcode, 19, 16); 5863 setflags = BitIsSet(opcode, 20); 5864 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5865 5866 if (Rd == 15 && setflags) 5867 return EmulateSUBSPcLrEtc(opcode, encoding); 5868 break; 5869 default: 5870 return false; 5871 } 5872 5873 // Read the first operand. 5874 int32_t val1 = ReadCoreReg(Rn, &success); 5875 if (!success) 5876 return false; 5877 5878 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5879 5880 EmulateInstruction::Context context; 5881 context.type = EmulateInstruction::eContextImmediate; 5882 context.SetNoArgs(); 5883 5884 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5885 res.carry_out, res.overflow)) 5886 return false; 5887 } 5888 return true; 5889 } 5890 5891 // Add with Carry (register) adds a register value, the carry flag value, and 5892 // an optionally-shifted register value, and writes the result to the 5893 // destination register. It can optionally update the condition flags based on 5894 // the result. 5895 bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode, 5896 const ARMEncoding encoding) { 5897 #if 0 5898 // ARM pseudo code... 5899 if ConditionPassed() then 5900 EncodingSpecificOperations(); 5901 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5902 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5903 if d == 15 then // Can only occur for ARM encoding 5904 ALUWritePC(result); // setflags is always FALSE here 5905 else 5906 R[d] = result; 5907 if setflags then 5908 APSR.N = result<31>; 5909 APSR.Z = IsZeroBit(result); 5910 APSR.C = carry; 5911 APSR.V = overflow; 5912 #endif 5913 5914 bool success = false; 5915 5916 if (ConditionPassed(opcode)) { 5917 uint32_t Rd, Rn, Rm; 5918 ARM_ShifterType shift_t; 5919 uint32_t shift_n; // the shift applied to the value read from Rm 5920 bool setflags; 5921 switch (encoding) { 5922 case eEncodingT1: 5923 Rd = Rn = Bits32(opcode, 2, 0); 5924 Rm = Bits32(opcode, 5, 3); 5925 setflags = !InITBlock(); 5926 shift_t = SRType_LSL; 5927 shift_n = 0; 5928 break; 5929 case eEncodingT2: 5930 Rd = Bits32(opcode, 11, 8); 5931 Rn = Bits32(opcode, 19, 16); 5932 Rm = Bits32(opcode, 3, 0); 5933 setflags = BitIsSet(opcode, 20); 5934 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5935 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5936 return false; 5937 break; 5938 case eEncodingA1: 5939 Rd = Bits32(opcode, 15, 12); 5940 Rn = Bits32(opcode, 19, 16); 5941 Rm = Bits32(opcode, 3, 0); 5942 setflags = BitIsSet(opcode, 20); 5943 shift_n = DecodeImmShiftARM(opcode, shift_t); 5944 5945 if (Rd == 15 && setflags) 5946 return EmulateSUBSPcLrEtc(opcode, encoding); 5947 break; 5948 default: 5949 return false; 5950 } 5951 5952 // Read the first operand. 5953 int32_t val1 = ReadCoreReg(Rn, &success); 5954 if (!success) 5955 return false; 5956 5957 // Read the second operand. 5958 int32_t val2 = ReadCoreReg(Rm, &success); 5959 if (!success) 5960 return false; 5961 5962 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5963 if (!success) 5964 return false; 5965 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5966 5967 EmulateInstruction::Context context; 5968 context.type = EmulateInstruction::eContextImmediate; 5969 context.SetNoArgs(); 5970 5971 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5972 res.carry_out, res.overflow)) 5973 return false; 5974 } 5975 return true; 5976 } 5977 5978 // This instruction adds an immediate value to the PC value to form a PC- 5979 // relative address, and writes the result to the destination register. 5980 bool EmulateInstructionARM::EmulateADR(const uint32_t opcode, 5981 const ARMEncoding encoding) { 5982 #if 0 5983 // ARM pseudo code... 5984 if ConditionPassed() then 5985 EncodingSpecificOperations(); 5986 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5987 if d == 15 then // Can only occur for ARM encodings 5988 ALUWritePC(result); 5989 else 5990 R[d] = result; 5991 #endif 5992 5993 bool success = false; 5994 5995 if (ConditionPassed(opcode)) { 5996 uint32_t Rd; 5997 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5998 bool add; 5999 switch (encoding) { 6000 case eEncodingT1: 6001 Rd = Bits32(opcode, 10, 8); 6002 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 6003 add = true; 6004 break; 6005 case eEncodingT2: 6006 case eEncodingT3: 6007 Rd = Bits32(opcode, 11, 8); 6008 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 6009 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 6010 if (BadReg(Rd)) 6011 return false; 6012 break; 6013 case eEncodingA1: 6014 case eEncodingA2: 6015 Rd = Bits32(opcode, 15, 12); 6016 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 6017 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 6018 break; 6019 default: 6020 return false; 6021 } 6022 6023 // Read the PC value. 6024 uint32_t pc = ReadCoreReg(PC_REG, &success); 6025 if (!success) 6026 return false; 6027 6028 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 6029 6030 EmulateInstruction::Context context; 6031 context.type = EmulateInstruction::eContextImmediate; 6032 context.SetNoArgs(); 6033 6034 if (!WriteCoreReg(context, result, Rd)) 6035 return false; 6036 } 6037 return true; 6038 } 6039 6040 // This instruction performs a bitwise AND of a register value and an immediate 6041 // value, and writes the result to the destination register. It can optionally 6042 // update the condition flags based on the result. 6043 bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode, 6044 const ARMEncoding encoding) { 6045 #if 0 6046 // ARM pseudo code... 6047 if ConditionPassed() then 6048 EncodingSpecificOperations(); 6049 result = R[n] AND imm32; 6050 if d == 15 then // Can only occur for ARM encoding 6051 ALUWritePC(result); // setflags is always FALSE here 6052 else 6053 R[d] = result; 6054 if setflags then 6055 APSR.N = result<31>; 6056 APSR.Z = IsZeroBit(result); 6057 APSR.C = carry; 6058 // APSR.V unchanged 6059 #endif 6060 6061 bool success = false; 6062 6063 if (ConditionPassed(opcode)) { 6064 uint32_t Rd, Rn; 6065 uint32_t 6066 imm32; // the immediate value to be ANDed to the value obtained from Rn 6067 bool setflags; 6068 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6069 switch (encoding) { 6070 case eEncodingT1: 6071 Rd = Bits32(opcode, 11, 8); 6072 Rn = Bits32(opcode, 19, 16); 6073 setflags = BitIsSet(opcode, 20); 6074 imm32 = ThumbExpandImm_C( 6075 opcode, APSR_C, 6076 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6077 // if Rd == '1111' && S == '1' then SEE TST (immediate); 6078 if (Rd == 15 && setflags) 6079 return EmulateTSTImm(opcode, eEncodingT1); 6080 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 6081 return false; 6082 break; 6083 case eEncodingA1: 6084 Rd = Bits32(opcode, 15, 12); 6085 Rn = Bits32(opcode, 19, 16); 6086 setflags = BitIsSet(opcode, 20); 6087 imm32 = 6088 ARMExpandImm_C(opcode, APSR_C, 6089 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6090 6091 if (Rd == 15 && setflags) 6092 return EmulateSUBSPcLrEtc(opcode, encoding); 6093 break; 6094 default: 6095 return false; 6096 } 6097 6098 // Read the first operand. 6099 uint32_t val1 = ReadCoreReg(Rn, &success); 6100 if (!success) 6101 return false; 6102 6103 uint32_t result = val1 & imm32; 6104 6105 EmulateInstruction::Context context; 6106 context.type = EmulateInstruction::eContextImmediate; 6107 context.SetNoArgs(); 6108 6109 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6110 return false; 6111 } 6112 return true; 6113 } 6114 6115 // This instruction performs a bitwise AND of a register value and an 6116 // optionally-shifted register value, and writes the result to the destination 6117 // register. It can optionally update the condition flags based on the result. 6118 bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode, 6119 const ARMEncoding encoding) { 6120 #if 0 6121 // ARM pseudo code... 6122 if ConditionPassed() then 6123 EncodingSpecificOperations(); 6124 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6125 result = R[n] AND shifted; 6126 if d == 15 then // Can only occur for ARM encoding 6127 ALUWritePC(result); // setflags is always FALSE here 6128 else 6129 R[d] = result; 6130 if setflags then 6131 APSR.N = result<31>; 6132 APSR.Z = IsZeroBit(result); 6133 APSR.C = carry; 6134 // APSR.V unchanged 6135 #endif 6136 6137 bool success = false; 6138 6139 if (ConditionPassed(opcode)) { 6140 uint32_t Rd, Rn, Rm; 6141 ARM_ShifterType shift_t; 6142 uint32_t shift_n; // the shift applied to the value read from Rm 6143 bool setflags; 6144 uint32_t carry; 6145 switch (encoding) { 6146 case eEncodingT1: 6147 Rd = Rn = Bits32(opcode, 2, 0); 6148 Rm = Bits32(opcode, 5, 3); 6149 setflags = !InITBlock(); 6150 shift_t = SRType_LSL; 6151 shift_n = 0; 6152 break; 6153 case eEncodingT2: 6154 Rd = Bits32(opcode, 11, 8); 6155 Rn = Bits32(opcode, 19, 16); 6156 Rm = Bits32(opcode, 3, 0); 6157 setflags = BitIsSet(opcode, 20); 6158 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6159 // if Rd == '1111' && S == '1' then SEE TST (register); 6160 if (Rd == 15 && setflags) 6161 return EmulateTSTReg(opcode, eEncodingT2); 6162 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 6163 return false; 6164 break; 6165 case eEncodingA1: 6166 Rd = Bits32(opcode, 15, 12); 6167 Rn = Bits32(opcode, 19, 16); 6168 Rm = Bits32(opcode, 3, 0); 6169 setflags = BitIsSet(opcode, 20); 6170 shift_n = DecodeImmShiftARM(opcode, shift_t); 6171 6172 if (Rd == 15 && setflags) 6173 return EmulateSUBSPcLrEtc(opcode, encoding); 6174 break; 6175 default: 6176 return false; 6177 } 6178 6179 // Read the first operand. 6180 uint32_t val1 = ReadCoreReg(Rn, &success); 6181 if (!success) 6182 return false; 6183 6184 // Read the second operand. 6185 uint32_t val2 = ReadCoreReg(Rm, &success); 6186 if (!success) 6187 return false; 6188 6189 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6190 if (!success) 6191 return false; 6192 uint32_t result = val1 & shifted; 6193 6194 EmulateInstruction::Context context; 6195 context.type = EmulateInstruction::eContextImmediate; 6196 context.SetNoArgs(); 6197 6198 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6199 return false; 6200 } 6201 return true; 6202 } 6203 6204 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and 6205 // the complement of an immediate value, and writes the result to the 6206 // destination register. It can optionally update the condition flags based on 6207 // the result. 6208 bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode, 6209 const ARMEncoding encoding) { 6210 #if 0 6211 // ARM pseudo code... 6212 if ConditionPassed() then 6213 EncodingSpecificOperations(); 6214 result = R[n] AND NOT(imm32); 6215 if d == 15 then // Can only occur for ARM encoding 6216 ALUWritePC(result); // setflags is always FALSE here 6217 else 6218 R[d] = result; 6219 if setflags then 6220 APSR.N = result<31>; 6221 APSR.Z = IsZeroBit(result); 6222 APSR.C = carry; 6223 // APSR.V unchanged 6224 #endif 6225 6226 bool success = false; 6227 6228 if (ConditionPassed(opcode)) { 6229 uint32_t Rd, Rn; 6230 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to 6231 // the value obtained from Rn 6232 bool setflags; 6233 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6234 switch (encoding) { 6235 case eEncodingT1: 6236 Rd = Bits32(opcode, 11, 8); 6237 Rn = Bits32(opcode, 19, 16); 6238 setflags = BitIsSet(opcode, 20); 6239 imm32 = ThumbExpandImm_C( 6240 opcode, APSR_C, 6241 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6242 if (BadReg(Rd) || BadReg(Rn)) 6243 return false; 6244 break; 6245 case eEncodingA1: 6246 Rd = Bits32(opcode, 15, 12); 6247 Rn = Bits32(opcode, 19, 16); 6248 setflags = BitIsSet(opcode, 20); 6249 imm32 = 6250 ARMExpandImm_C(opcode, APSR_C, 6251 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6252 6253 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6254 // instructions; 6255 if (Rd == 15 && setflags) 6256 return EmulateSUBSPcLrEtc(opcode, encoding); 6257 break; 6258 default: 6259 return false; 6260 } 6261 6262 // Read the first operand. 6263 uint32_t val1 = ReadCoreReg(Rn, &success); 6264 if (!success) 6265 return false; 6266 6267 uint32_t result = val1 & ~imm32; 6268 6269 EmulateInstruction::Context context; 6270 context.type = EmulateInstruction::eContextImmediate; 6271 context.SetNoArgs(); 6272 6273 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6274 return false; 6275 } 6276 return true; 6277 } 6278 6279 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and 6280 // the complement of an optionally-shifted register value, and writes the 6281 // result to the destination register. It can optionally update the condition 6282 // flags based on the result. 6283 bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode, 6284 const ARMEncoding encoding) { 6285 #if 0 6286 // ARM pseudo code... 6287 if ConditionPassed() then 6288 EncodingSpecificOperations(); 6289 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6290 result = R[n] AND NOT(shifted); 6291 if d == 15 then // Can only occur for ARM encoding 6292 ALUWritePC(result); // setflags is always FALSE here 6293 else 6294 R[d] = result; 6295 if setflags then 6296 APSR.N = result<31>; 6297 APSR.Z = IsZeroBit(result); 6298 APSR.C = carry; 6299 // APSR.V unchanged 6300 #endif 6301 6302 bool success = false; 6303 6304 if (ConditionPassed(opcode)) { 6305 uint32_t Rd, Rn, Rm; 6306 ARM_ShifterType shift_t; 6307 uint32_t shift_n; // the shift applied to the value read from Rm 6308 bool setflags; 6309 uint32_t carry; 6310 switch (encoding) { 6311 case eEncodingT1: 6312 Rd = Rn = Bits32(opcode, 2, 0); 6313 Rm = Bits32(opcode, 5, 3); 6314 setflags = !InITBlock(); 6315 shift_t = SRType_LSL; 6316 shift_n = 0; 6317 break; 6318 case eEncodingT2: 6319 Rd = Bits32(opcode, 11, 8); 6320 Rn = Bits32(opcode, 19, 16); 6321 Rm = Bits32(opcode, 3, 0); 6322 setflags = BitIsSet(opcode, 20); 6323 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6324 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 6325 return false; 6326 break; 6327 case eEncodingA1: 6328 Rd = Bits32(opcode, 15, 12); 6329 Rn = Bits32(opcode, 19, 16); 6330 Rm = Bits32(opcode, 3, 0); 6331 setflags = BitIsSet(opcode, 20); 6332 shift_n = DecodeImmShiftARM(opcode, shift_t); 6333 6334 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6335 // instructions; 6336 if (Rd == 15 && setflags) 6337 return EmulateSUBSPcLrEtc(opcode, encoding); 6338 break; 6339 default: 6340 return false; 6341 } 6342 6343 // Read the first operand. 6344 uint32_t val1 = ReadCoreReg(Rn, &success); 6345 if (!success) 6346 return false; 6347 6348 // Read the second operand. 6349 uint32_t val2 = ReadCoreReg(Rm, &success); 6350 if (!success) 6351 return false; 6352 6353 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6354 if (!success) 6355 return false; 6356 uint32_t result = val1 & ~shifted; 6357 6358 EmulateInstruction::Context context; 6359 context.type = EmulateInstruction::eContextImmediate; 6360 context.SetNoArgs(); 6361 6362 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6363 return false; 6364 } 6365 return true; 6366 } 6367 6368 // LDR (immediate, ARM) calculates an address from a base register value and an 6369 // immediate offset, loads a word 6370 // from memory, and writes it to a register. It can use offset, post-indexed, 6371 // or pre-indexed addressing. 6372 bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode, 6373 const ARMEncoding encoding) { 6374 #if 0 6375 if ConditionPassed() then 6376 EncodingSpecificOperations(); 6377 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6378 address = if index then offset_addr else R[n]; 6379 data = MemU[address,4]; 6380 if wback then R[n] = offset_addr; 6381 if t == 15 then 6382 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6383 elsif UnalignedSupport() || address<1:0> = '00' then 6384 R[t] = data; 6385 else // Can only apply before ARMv7 6386 R[t] = ROR(data, 8*UInt(address<1:0>)); 6387 #endif 6388 6389 bool success = false; 6390 6391 if (ConditionPassed(opcode)) { 6392 const uint32_t addr_byte_size = GetAddressByteSize(); 6393 6394 uint32_t t; 6395 uint32_t n; 6396 uint32_t imm32; 6397 bool index; 6398 bool add; 6399 bool wback; 6400 6401 switch (encoding) { 6402 case eEncodingA1: 6403 // if Rn == '1111' then SEE LDR (literal); 6404 // if P == '0' && W == '1' then SEE LDRT; 6405 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == 6406 // '000000000100' then SEE POP; 6407 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6408 t = Bits32(opcode, 15, 12); 6409 n = Bits32(opcode, 19, 16); 6410 imm32 = Bits32(opcode, 11, 0); 6411 6412 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6413 // (W == '1'); 6414 index = BitIsSet(opcode, 24); 6415 add = BitIsSet(opcode, 23); 6416 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6417 6418 // if wback && n == t then UNPREDICTABLE; 6419 if (wback && (n == t)) 6420 return false; 6421 6422 break; 6423 6424 default: 6425 return false; 6426 } 6427 6428 addr_t address; 6429 addr_t offset_addr; 6430 addr_t base_address = ReadCoreReg(n, &success); 6431 if (!success) 6432 return false; 6433 6434 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6435 if (add) 6436 offset_addr = base_address + imm32; 6437 else 6438 offset_addr = base_address - imm32; 6439 6440 // address = if index then offset_addr else R[n]; 6441 if (index) 6442 address = offset_addr; 6443 else 6444 address = base_address; 6445 6446 // data = MemU[address,4]; 6447 6448 RegisterInfo base_reg; 6449 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6450 6451 EmulateInstruction::Context context; 6452 context.type = eContextRegisterLoad; 6453 context.SetRegisterPlusOffset(base_reg, address - base_address); 6454 6455 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6456 if (!success) 6457 return false; 6458 6459 // if wback then R[n] = offset_addr; 6460 if (wback) { 6461 context.type = eContextAdjustBaseRegister; 6462 context.SetAddress(offset_addr); 6463 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6464 offset_addr)) 6465 return false; 6466 } 6467 6468 // if t == 15 then 6469 if (t == 15) { 6470 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6471 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6472 // LoadWritePC (data); 6473 context.type = eContextRegisterLoad; 6474 context.SetRegisterPlusOffset(base_reg, address - base_address); 6475 LoadWritePC(context, data); 6476 } else 6477 return false; 6478 } 6479 // elsif UnalignedSupport() || address<1:0> = '00' then 6480 else if (UnalignedSupport() || 6481 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6482 // R[t] = data; 6483 context.type = eContextRegisterLoad; 6484 context.SetRegisterPlusOffset(base_reg, address - base_address); 6485 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6486 data)) 6487 return false; 6488 } 6489 // else // Can only apply before ARMv7 6490 else { 6491 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6492 data = ROR(data, Bits32(address, 1, 0), &success); 6493 if (!success) 6494 return false; 6495 context.type = eContextRegisterLoad; 6496 context.SetImmediate(data); 6497 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6498 data)) 6499 return false; 6500 } 6501 } 6502 return true; 6503 } 6504 6505 // LDR (register) calculates an address from a base register value and an offset 6506 // register value, loads a word 6507 // from memory, and writes it to a register. The offset register value can 6508 // optionally be shifted. 6509 bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode, 6510 const ARMEncoding encoding) { 6511 #if 0 6512 if ConditionPassed() then 6513 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6514 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6515 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6516 address = if index then offset_addr else R[n]; 6517 data = MemU[address,4]; 6518 if wback then R[n] = offset_addr; 6519 if t == 15 then 6520 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6521 elsif UnalignedSupport() || address<1:0> = '00' then 6522 R[t] = data; 6523 else // Can only apply before ARMv7 6524 if CurrentInstrSet() == InstrSet_ARM then 6525 R[t] = ROR(data, 8*UInt(address<1:0>)); 6526 else 6527 R[t] = bits(32) UNKNOWN; 6528 #endif 6529 6530 bool success = false; 6531 6532 if (ConditionPassed(opcode)) { 6533 const uint32_t addr_byte_size = GetAddressByteSize(); 6534 6535 uint32_t t; 6536 uint32_t n; 6537 uint32_t m; 6538 bool index; 6539 bool add; 6540 bool wback; 6541 ARM_ShifterType shift_t; 6542 uint32_t shift_n; 6543 6544 switch (encoding) { 6545 case eEncodingT1: 6546 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 6547 // in ThumbEE"; 6548 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6549 t = Bits32(opcode, 2, 0); 6550 n = Bits32(opcode, 5, 3); 6551 m = Bits32(opcode, 8, 6); 6552 6553 // index = TRUE; add = TRUE; wback = FALSE; 6554 index = true; 6555 add = true; 6556 wback = false; 6557 6558 // (shift_t, shift_n) = (SRType_LSL, 0); 6559 shift_t = SRType_LSL; 6560 shift_n = 0; 6561 6562 break; 6563 6564 case eEncodingT2: 6565 // if Rn == '1111' then SEE LDR (literal); 6566 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6567 t = Bits32(opcode, 15, 12); 6568 n = Bits32(opcode, 19, 16); 6569 m = Bits32(opcode, 3, 0); 6570 6571 // index = TRUE; add = TRUE; wback = FALSE; 6572 index = true; 6573 add = true; 6574 wback = false; 6575 6576 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6577 shift_t = SRType_LSL; 6578 shift_n = Bits32(opcode, 5, 4); 6579 6580 // if BadReg(m) then UNPREDICTABLE; 6581 if (BadReg(m)) 6582 return false; 6583 6584 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6585 if ((t == 15) && InITBlock() && !LastInITBlock()) 6586 return false; 6587 6588 break; 6589 6590 case eEncodingA1: { 6591 // if P == '0' && W == '1' then SEE LDRT; 6592 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6593 t = Bits32(opcode, 15, 12); 6594 n = Bits32(opcode, 19, 16); 6595 m = Bits32(opcode, 3, 0); 6596 6597 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6598 // (W == '1'); 6599 index = BitIsSet(opcode, 24); 6600 add = BitIsSet(opcode, 23); 6601 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6602 6603 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6604 uint32_t type = Bits32(opcode, 6, 5); 6605 uint32_t imm5 = Bits32(opcode, 11, 7); 6606 shift_n = DecodeImmShift(type, imm5, shift_t); 6607 6608 // if m == 15 then UNPREDICTABLE; 6609 if (m == 15) 6610 return false; 6611 6612 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6613 if (wback && ((n == 15) || (n == t))) 6614 return false; 6615 } break; 6616 6617 default: 6618 return false; 6619 } 6620 6621 uint32_t Rm = 6622 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6623 if (!success) 6624 return false; 6625 6626 uint32_t Rn = 6627 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6628 if (!success) 6629 return false; 6630 6631 addr_t offset_addr; 6632 addr_t address; 6633 6634 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is 6635 // an application level alias for the CPSR". 6636 addr_t offset = 6637 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success); 6638 if (!success) 6639 return false; 6640 6641 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6642 if (add) 6643 offset_addr = Rn + offset; 6644 else 6645 offset_addr = Rn - offset; 6646 6647 // address = if index then offset_addr else R[n]; 6648 if (index) 6649 address = offset_addr; 6650 else 6651 address = Rn; 6652 6653 // data = MemU[address,4]; 6654 RegisterInfo base_reg; 6655 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6656 6657 EmulateInstruction::Context context; 6658 context.type = eContextRegisterLoad; 6659 context.SetRegisterPlusOffset(base_reg, address - Rn); 6660 6661 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6662 if (!success) 6663 return false; 6664 6665 // if wback then R[n] = offset_addr; 6666 if (wback) { 6667 context.type = eContextAdjustBaseRegister; 6668 context.SetAddress(offset_addr); 6669 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6670 offset_addr)) 6671 return false; 6672 } 6673 6674 // if t == 15 then 6675 if (t == 15) { 6676 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6677 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6678 context.type = eContextRegisterLoad; 6679 context.SetRegisterPlusOffset(base_reg, address - Rn); 6680 LoadWritePC(context, data); 6681 } else 6682 return false; 6683 } 6684 // elsif UnalignedSupport() || address<1:0> = '00' then 6685 else if (UnalignedSupport() || 6686 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6687 // R[t] = data; 6688 context.type = eContextRegisterLoad; 6689 context.SetRegisterPlusOffset(base_reg, address - Rn); 6690 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6691 data)) 6692 return false; 6693 } else // Can only apply before ARMv7 6694 { 6695 // if CurrentInstrSet() == InstrSet_ARM then 6696 if (CurrentInstrSet() == eModeARM) { 6697 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6698 data = ROR(data, Bits32(address, 1, 0), &success); 6699 if (!success) 6700 return false; 6701 context.type = eContextRegisterLoad; 6702 context.SetImmediate(data); 6703 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6704 data)) 6705 return false; 6706 } else { 6707 // R[t] = bits(32) UNKNOWN; 6708 WriteBits32Unknown(t); 6709 } 6710 } 6711 } 6712 return true; 6713 } 6714 6715 // LDRB (immediate, Thumb) 6716 bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode, 6717 const ARMEncoding encoding) { 6718 #if 0 6719 if ConditionPassed() then 6720 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6721 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6722 address = if index then offset_addr else R[n]; 6723 R[t] = ZeroExtend(MemU[address,1], 32); 6724 if wback then R[n] = offset_addr; 6725 #endif 6726 6727 bool success = false; 6728 6729 if (ConditionPassed(opcode)) { 6730 uint32_t t; 6731 uint32_t n; 6732 uint32_t imm32; 6733 bool index; 6734 bool add; 6735 bool wback; 6736 6737 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6738 switch (encoding) { 6739 case eEncodingT1: 6740 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6741 t = Bits32(opcode, 2, 0); 6742 n = Bits32(opcode, 5, 3); 6743 imm32 = Bits32(opcode, 10, 6); 6744 6745 // index = TRUE; add = TRUE; wback = FALSE; 6746 index = true; 6747 add = true; 6748 wback = false; 6749 6750 break; 6751 6752 case eEncodingT2: 6753 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6754 t = Bits32(opcode, 15, 12); 6755 n = Bits32(opcode, 19, 16); 6756 imm32 = Bits32(opcode, 11, 0); 6757 6758 // index = TRUE; add = TRUE; wback = FALSE; 6759 index = true; 6760 add = true; 6761 wback = false; 6762 6763 // if Rt == '1111' then SEE PLD; 6764 if (t == 15) 6765 return false; // PLD is not implemented yet 6766 6767 // if Rn == '1111' then SEE LDRB (literal); 6768 if (n == 15) 6769 return EmulateLDRBLiteral(opcode, eEncodingT1); 6770 6771 // if t == 13 then UNPREDICTABLE; 6772 if (t == 13) 6773 return false; 6774 6775 break; 6776 6777 case eEncodingT3: 6778 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6779 // if P == '0' && W == '0' then UNDEFINED; 6780 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 6781 return false; 6782 6783 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6784 t = Bits32(opcode, 15, 12); 6785 n = Bits32(opcode, 19, 16); 6786 imm32 = Bits32(opcode, 7, 0); 6787 6788 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6789 index = BitIsSet(opcode, 10); 6790 add = BitIsSet(opcode, 9); 6791 wback = BitIsSet(opcode, 8); 6792 6793 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6794 if (t == 15) 6795 return false; // PLD is not implemented yet 6796 6797 // if Rn == '1111' then SEE LDRB (literal); 6798 if (n == 15) 6799 return EmulateLDRBLiteral(opcode, eEncodingT1); 6800 6801 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6802 if (BadReg(t) || (wback && (n == t))) 6803 return false; 6804 6805 break; 6806 6807 default: 6808 return false; 6809 } 6810 6811 uint32_t Rn = 6812 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6813 if (!success) 6814 return false; 6815 6816 addr_t address; 6817 addr_t offset_addr; 6818 6819 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6820 if (add) 6821 offset_addr = Rn + imm32; 6822 else 6823 offset_addr = Rn - imm32; 6824 6825 // address = if index then offset_addr else R[n]; 6826 if (index) 6827 address = offset_addr; 6828 else 6829 address = Rn; 6830 6831 // R[t] = ZeroExtend(MemU[address,1], 32); 6832 RegisterInfo base_reg; 6833 RegisterInfo data_reg; 6834 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6835 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6836 6837 EmulateInstruction::Context context; 6838 context.type = eContextRegisterLoad; 6839 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 6840 6841 uint64_t data = MemURead(context, address, 1, 0, &success); 6842 if (!success) 6843 return false; 6844 6845 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6846 return false; 6847 6848 // if wback then R[n] = offset_addr; 6849 if (wback) { 6850 context.type = eContextAdjustBaseRegister; 6851 context.SetAddress(offset_addr); 6852 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6853 offset_addr)) 6854 return false; 6855 } 6856 } 6857 return true; 6858 } 6859 6860 // LDRB (literal) calculates an address from the PC value and an immediate 6861 // offset, loads a byte from memory, 6862 // zero-extends it to form a 32-bit word and writes it to a register. 6863 bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode, 6864 const ARMEncoding encoding) { 6865 #if 0 6866 if ConditionPassed() then 6867 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6868 base = Align(PC,4); 6869 address = if add then (base + imm32) else (base - imm32); 6870 R[t] = ZeroExtend(MemU[address,1], 32); 6871 #endif 6872 6873 bool success = false; 6874 6875 if (ConditionPassed(opcode)) { 6876 uint32_t t; 6877 uint32_t imm32; 6878 bool add; 6879 switch (encoding) { 6880 case eEncodingT1: 6881 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6882 t = Bits32(opcode, 15, 12); 6883 imm32 = Bits32(opcode, 11, 0); 6884 add = BitIsSet(opcode, 23); 6885 6886 // if Rt == '1111' then SEE PLD; 6887 if (t == 15) 6888 return false; // PLD is not implemented yet 6889 6890 // if t == 13 then UNPREDICTABLE; 6891 if (t == 13) 6892 return false; 6893 6894 break; 6895 6896 case eEncodingA1: 6897 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6898 t = Bits32(opcode, 15, 12); 6899 imm32 = Bits32(opcode, 11, 0); 6900 add = BitIsSet(opcode, 23); 6901 6902 // if t == 15 then UNPREDICTABLE; 6903 if (t == 15) 6904 return false; 6905 break; 6906 6907 default: 6908 return false; 6909 } 6910 6911 // base = Align(PC,4); 6912 uint32_t pc_val = ReadCoreReg(PC_REG, &success); 6913 if (!success) 6914 return false; 6915 6916 uint32_t base = AlignPC(pc_val); 6917 6918 addr_t address; 6919 // address = if add then (base + imm32) else (base - imm32); 6920 if (add) 6921 address = base + imm32; 6922 else 6923 address = base - imm32; 6924 6925 // R[t] = ZeroExtend(MemU[address,1], 32); 6926 EmulateInstruction::Context context; 6927 context.type = eContextRelativeBranchImmediate; 6928 context.SetImmediate(address - base); 6929 6930 uint64_t data = MemURead(context, address, 1, 0, &success); 6931 if (!success) 6932 return false; 6933 6934 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6935 return false; 6936 } 6937 return true; 6938 } 6939 6940 // LDRB (register) calculates an address from a base register value and an 6941 // offset rigister value, loads a byte from memory, zero-extends it to form a 6942 // 32-bit word, and writes it to a register. The offset register value can 6943 // optionally be shifted. 6944 bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode, 6945 const ARMEncoding encoding) { 6946 #if 0 6947 if ConditionPassed() then 6948 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6949 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6950 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6951 address = if index then offset_addr else R[n]; 6952 R[t] = ZeroExtend(MemU[address,1],32); 6953 if wback then R[n] = offset_addr; 6954 #endif 6955 6956 bool success = false; 6957 6958 if (ConditionPassed(opcode)) { 6959 uint32_t t; 6960 uint32_t n; 6961 uint32_t m; 6962 bool index; 6963 bool add; 6964 bool wback; 6965 ARM_ShifterType shift_t; 6966 uint32_t shift_n; 6967 6968 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6969 switch (encoding) { 6970 case eEncodingT1: 6971 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6972 t = Bits32(opcode, 2, 0); 6973 n = Bits32(opcode, 5, 3); 6974 m = Bits32(opcode, 8, 6); 6975 6976 // index = TRUE; add = TRUE; wback = FALSE; 6977 index = true; 6978 add = true; 6979 wback = false; 6980 6981 // (shift_t, shift_n) = (SRType_LSL, 0); 6982 shift_t = SRType_LSL; 6983 shift_n = 0; 6984 break; 6985 6986 case eEncodingT2: 6987 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6988 t = Bits32(opcode, 15, 12); 6989 n = Bits32(opcode, 19, 16); 6990 m = Bits32(opcode, 3, 0); 6991 6992 // index = TRUE; add = TRUE; wback = FALSE; 6993 index = true; 6994 add = true; 6995 wback = false; 6996 6997 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6998 shift_t = SRType_LSL; 6999 shift_n = Bits32(opcode, 5, 4); 7000 7001 // if Rt == '1111' then SEE PLD; 7002 if (t == 15) 7003 return false; // PLD is not implemented yet 7004 7005 // if Rn == '1111' then SEE LDRB (literal); 7006 if (n == 15) 7007 return EmulateLDRBLiteral(opcode, eEncodingT1); 7008 7009 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7010 if ((t == 13) || BadReg(m)) 7011 return false; 7012 break; 7013 7014 case eEncodingA1: { 7015 // if P == '0' && W == '1' then SEE LDRBT; 7016 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7017 t = Bits32(opcode, 15, 12); 7018 n = Bits32(opcode, 19, 16); 7019 m = Bits32(opcode, 3, 0); 7020 7021 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7022 // (W == '1'); 7023 index = BitIsSet(opcode, 24); 7024 add = BitIsSet(opcode, 23); 7025 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7026 7027 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 7028 uint32_t type = Bits32(opcode, 6, 5); 7029 uint32_t imm5 = Bits32(opcode, 11, 7); 7030 shift_n = DecodeImmShift(type, imm5, shift_t); 7031 7032 // if t == 15 || m == 15 then UNPREDICTABLE; 7033 if ((t == 15) || (m == 15)) 7034 return false; 7035 7036 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7037 if (wback && ((n == 15) || (n == t))) 7038 return false; 7039 } break; 7040 7041 default: 7042 return false; 7043 } 7044 7045 addr_t offset_addr; 7046 addr_t address; 7047 7048 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7049 uint32_t Rm = 7050 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7051 if (!success) 7052 return false; 7053 7054 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7055 if (!success) 7056 return false; 7057 7058 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7059 uint32_t Rn = 7060 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7061 if (!success) 7062 return false; 7063 7064 if (add) 7065 offset_addr = Rn + offset; 7066 else 7067 offset_addr = Rn - offset; 7068 7069 // address = if index then offset_addr else R[n]; 7070 if (index) 7071 address = offset_addr; 7072 else 7073 address = Rn; 7074 7075 // R[t] = ZeroExtend(MemU[address,1],32); 7076 RegisterInfo base_reg; 7077 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7078 7079 EmulateInstruction::Context context; 7080 context.type = eContextRegisterLoad; 7081 context.SetRegisterPlusOffset(base_reg, address - Rn); 7082 7083 uint64_t data = MemURead(context, address, 1, 0, &success); 7084 if (!success) 7085 return false; 7086 7087 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7088 return false; 7089 7090 // if wback then R[n] = offset_addr; 7091 if (wback) { 7092 context.type = eContextAdjustBaseRegister; 7093 context.SetAddress(offset_addr); 7094 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7095 offset_addr)) 7096 return false; 7097 } 7098 } 7099 return true; 7100 } 7101 7102 // LDRH (immediate, Thumb) calculates an address from a base register value and 7103 // an immediate offset, loads a 7104 // halfword from memory, zero-extends it to form a 32-bit word, and writes it 7105 // to a register. It can use offset, post-indexed, or pre-indexed addressing. 7106 bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode, 7107 const ARMEncoding encoding) { 7108 #if 0 7109 if ConditionPassed() then 7110 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7111 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7112 address = if index then offset_addr else R[n]; 7113 data = MemU[address,2]; 7114 if wback then R[n] = offset_addr; 7115 if UnalignedSupport() || address<0> = '0' then 7116 R[t] = ZeroExtend(data, 32); 7117 else // Can only apply before ARMv7 7118 R[t] = bits(32) UNKNOWN; 7119 #endif 7120 7121 bool success = false; 7122 7123 if (ConditionPassed(opcode)) { 7124 uint32_t t; 7125 uint32_t n; 7126 uint32_t imm32; 7127 bool index; 7128 bool add; 7129 bool wback; 7130 7131 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7132 switch (encoding) { 7133 case eEncodingT1: 7134 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 7135 t = Bits32(opcode, 2, 0); 7136 n = Bits32(opcode, 5, 3); 7137 imm32 = Bits32(opcode, 10, 6) << 1; 7138 7139 // index = TRUE; add = TRUE; wback = FALSE; 7140 index = true; 7141 add = true; 7142 wback = false; 7143 7144 break; 7145 7146 case eEncodingT2: 7147 // if Rt == '1111' then SEE "Unallocated memory hints"; 7148 // if Rn == '1111' then SEE LDRH (literal); 7149 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7150 t = Bits32(opcode, 15, 12); 7151 n = Bits32(opcode, 19, 16); 7152 imm32 = Bits32(opcode, 11, 0); 7153 7154 // index = TRUE; add = TRUE; wback = FALSE; 7155 index = true; 7156 add = true; 7157 wback = false; 7158 7159 // if t == 13 then UNPREDICTABLE; 7160 if (t == 13) 7161 return false; 7162 break; 7163 7164 case eEncodingT3: 7165 // if Rn == '1111' then SEE LDRH (literal); 7166 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7167 // "Unallocated memory hints"; 7168 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 7169 // if P == '0' && W == '0' then UNDEFINED; 7170 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7171 return false; 7172 7173 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7174 t = Bits32(opcode, 15, 12); 7175 n = Bits32(opcode, 19, 16); 7176 imm32 = Bits32(opcode, 7, 0); 7177 7178 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7179 index = BitIsSet(opcode, 10); 7180 add = BitIsSet(opcode, 9); 7181 wback = BitIsSet(opcode, 8); 7182 7183 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7184 if (BadReg(t) || (wback && (n == t))) 7185 return false; 7186 break; 7187 7188 default: 7189 return false; 7190 } 7191 7192 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7193 uint32_t Rn = 7194 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7195 if (!success) 7196 return false; 7197 7198 addr_t offset_addr; 7199 addr_t address; 7200 7201 if (add) 7202 offset_addr = Rn + imm32; 7203 else 7204 offset_addr = Rn - imm32; 7205 7206 // address = if index then offset_addr else R[n]; 7207 if (index) 7208 address = offset_addr; 7209 else 7210 address = Rn; 7211 7212 // data = MemU[address,2]; 7213 RegisterInfo base_reg; 7214 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7215 7216 EmulateInstruction::Context context; 7217 context.type = eContextRegisterLoad; 7218 context.SetRegisterPlusOffset(base_reg, address - Rn); 7219 7220 uint64_t data = MemURead(context, address, 2, 0, &success); 7221 if (!success) 7222 return false; 7223 7224 // if wback then R[n] = offset_addr; 7225 if (wback) { 7226 context.type = eContextAdjustBaseRegister; 7227 context.SetAddress(offset_addr); 7228 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7229 offset_addr)) 7230 return false; 7231 } 7232 7233 // if UnalignedSupport() || address<0> = '0' then 7234 if (UnalignedSupport() || BitIsClear(address, 0)) { 7235 // R[t] = ZeroExtend(data, 32); 7236 context.type = eContextRegisterLoad; 7237 context.SetRegisterPlusOffset(base_reg, address - Rn); 7238 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7239 data)) 7240 return false; 7241 } else // Can only apply before ARMv7 7242 { 7243 // R[t] = bits(32) UNKNOWN; 7244 WriteBits32Unknown(t); 7245 } 7246 } 7247 return true; 7248 } 7249 7250 // LDRH (literal) caculates an address from the PC value and an immediate 7251 // offset, loads a halfword from memory, 7252 // zero-extends it to form a 32-bit word, and writes it to a register. 7253 bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode, 7254 const ARMEncoding encoding) { 7255 #if 0 7256 if ConditionPassed() then 7257 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7258 base = Align(PC,4); 7259 address = if add then (base + imm32) else (base - imm32); 7260 data = MemU[address,2]; 7261 if UnalignedSupport() || address<0> = '0' then 7262 R[t] = ZeroExtend(data, 32); 7263 else // Can only apply before ARMv7 7264 R[t] = bits(32) UNKNOWN; 7265 #endif 7266 7267 bool success = false; 7268 7269 if (ConditionPassed(opcode)) { 7270 uint32_t t; 7271 uint32_t imm32; 7272 bool add; 7273 7274 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7275 switch (encoding) { 7276 case eEncodingT1: 7277 // if Rt == '1111' then SEE "Unallocated memory hints"; 7278 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7279 t = Bits32(opcode, 15, 12); 7280 imm32 = Bits32(opcode, 11, 0); 7281 add = BitIsSet(opcode, 23); 7282 7283 // if t == 13 then UNPREDICTABLE; 7284 if (t == 13) 7285 return false; 7286 7287 break; 7288 7289 case eEncodingA1: { 7290 uint32_t imm4H = Bits32(opcode, 11, 8); 7291 uint32_t imm4L = Bits32(opcode, 3, 0); 7292 7293 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7294 t = Bits32(opcode, 15, 12); 7295 imm32 = (imm4H << 4) | imm4L; 7296 add = BitIsSet(opcode, 23); 7297 7298 // if t == 15 then UNPREDICTABLE; 7299 if (t == 15) 7300 return false; 7301 break; 7302 } 7303 7304 default: 7305 return false; 7306 } 7307 7308 // base = Align(PC,4); 7309 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7310 if (!success) 7311 return false; 7312 7313 addr_t base = AlignPC(pc_value); 7314 addr_t address; 7315 7316 // address = if add then (base + imm32) else (base - imm32); 7317 if (add) 7318 address = base + imm32; 7319 else 7320 address = base - imm32; 7321 7322 // data = MemU[address,2]; 7323 RegisterInfo base_reg; 7324 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7325 7326 EmulateInstruction::Context context; 7327 context.type = eContextRegisterLoad; 7328 context.SetRegisterPlusOffset(base_reg, address - base); 7329 7330 uint64_t data = MemURead(context, address, 2, 0, &success); 7331 if (!success) 7332 return false; 7333 7334 // if UnalignedSupport() || address<0> = '0' then 7335 if (UnalignedSupport() || BitIsClear(address, 0)) { 7336 // R[t] = ZeroExtend(data, 32); 7337 context.type = eContextRegisterLoad; 7338 context.SetRegisterPlusOffset(base_reg, address - base); 7339 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7340 data)) 7341 return false; 7342 7343 } else // Can only apply before ARMv7 7344 { 7345 // R[t] = bits(32) UNKNOWN; 7346 WriteBits32Unknown(t); 7347 } 7348 } 7349 return true; 7350 } 7351 7352 // LDRH (literal) calculates an address from a base register value and an offset 7353 // register value, loads a halfword 7354 // from memory, zero-extends it to form a 32-bit word, and writes it to a 7355 // register. The offset register value can be shifted left by 0, 1, 2, or 3 7356 // bits. 7357 bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode, 7358 const ARMEncoding encoding) { 7359 #if 0 7360 if ConditionPassed() then 7361 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7362 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7363 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7364 address = if index then offset_addr else R[n]; 7365 data = MemU[address,2]; 7366 if wback then R[n] = offset_addr; 7367 if UnalignedSupport() || address<0> = '0' then 7368 R[t] = ZeroExtend(data, 32); 7369 else // Can only apply before ARMv7 7370 R[t] = bits(32) UNKNOWN; 7371 #endif 7372 7373 bool success = false; 7374 7375 if (ConditionPassed(opcode)) { 7376 uint32_t t; 7377 uint32_t n; 7378 uint32_t m; 7379 bool index; 7380 bool add; 7381 bool wback; 7382 ARM_ShifterType shift_t; 7383 uint32_t shift_n; 7384 7385 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7386 switch (encoding) { 7387 case eEncodingT1: 7388 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 7389 // in ThumbEE"; 7390 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7391 t = Bits32(opcode, 2, 0); 7392 n = Bits32(opcode, 5, 3); 7393 m = Bits32(opcode, 8, 6); 7394 7395 // index = TRUE; add = TRUE; wback = FALSE; 7396 index = true; 7397 add = true; 7398 wback = false; 7399 7400 // (shift_t, shift_n) = (SRType_LSL, 0); 7401 shift_t = SRType_LSL; 7402 shift_n = 0; 7403 7404 break; 7405 7406 case eEncodingT2: 7407 // if Rn == '1111' then SEE LDRH (literal); 7408 // if Rt == '1111' then SEE "Unallocated memory hints"; 7409 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7410 t = Bits32(opcode, 15, 12); 7411 n = Bits32(opcode, 19, 16); 7412 m = Bits32(opcode, 3, 0); 7413 7414 // index = TRUE; add = TRUE; wback = FALSE; 7415 index = true; 7416 add = true; 7417 wback = false; 7418 7419 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7420 shift_t = SRType_LSL; 7421 shift_n = Bits32(opcode, 5, 4); 7422 7423 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7424 if ((t == 13) || BadReg(m)) 7425 return false; 7426 break; 7427 7428 case eEncodingA1: 7429 // if P == '0' && W == '1' then SEE LDRHT; 7430 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7431 t = Bits32(opcode, 15, 12); 7432 n = Bits32(opcode, 19, 16); 7433 m = Bits32(opcode, 3, 0); 7434 7435 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7436 // (W == '1'); 7437 index = BitIsSet(opcode, 24); 7438 add = BitIsSet(opcode, 23); 7439 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7440 7441 // (shift_t, shift_n) = (SRType_LSL, 0); 7442 shift_t = SRType_LSL; 7443 shift_n = 0; 7444 7445 // if t == 15 || m == 15 then UNPREDICTABLE; 7446 if ((t == 15) || (m == 15)) 7447 return false; 7448 7449 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7450 if (wback && ((n == 15) || (n == t))) 7451 return false; 7452 7453 break; 7454 7455 default: 7456 return false; 7457 } 7458 7459 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7460 7461 uint64_t Rm = 7462 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7463 if (!success) 7464 return false; 7465 7466 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7467 if (!success) 7468 return false; 7469 7470 addr_t offset_addr; 7471 addr_t address; 7472 7473 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7474 uint64_t Rn = 7475 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7476 if (!success) 7477 return false; 7478 7479 if (add) 7480 offset_addr = Rn + offset; 7481 else 7482 offset_addr = Rn - offset; 7483 7484 // address = if index then offset_addr else R[n]; 7485 if (index) 7486 address = offset_addr; 7487 else 7488 address = Rn; 7489 7490 // data = MemU[address,2]; 7491 RegisterInfo base_reg; 7492 RegisterInfo offset_reg; 7493 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7494 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7495 7496 EmulateInstruction::Context context; 7497 context.type = eContextRegisterLoad; 7498 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7499 uint64_t data = MemURead(context, address, 2, 0, &success); 7500 if (!success) 7501 return false; 7502 7503 // if wback then R[n] = offset_addr; 7504 if (wback) { 7505 context.type = eContextAdjustBaseRegister; 7506 context.SetAddress(offset_addr); 7507 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7508 offset_addr)) 7509 return false; 7510 } 7511 7512 // if UnalignedSupport() || address<0> = '0' then 7513 if (UnalignedSupport() || BitIsClear(address, 0)) { 7514 // R[t] = ZeroExtend(data, 32); 7515 context.type = eContextRegisterLoad; 7516 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7517 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7518 data)) 7519 return false; 7520 } else // Can only apply before ARMv7 7521 { 7522 // R[t] = bits(32) UNKNOWN; 7523 WriteBits32Unknown(t); 7524 } 7525 } 7526 return true; 7527 } 7528 7529 // LDRSB (immediate) calculates an address from a base register value and an 7530 // immediate offset, loads a byte from 7531 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7532 // It can use offset, post-indexed, or pre-indexed addressing. 7533 bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode, 7534 const ARMEncoding encoding) { 7535 #if 0 7536 if ConditionPassed() then 7537 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7538 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7539 address = if index then offset_addr else R[n]; 7540 R[t] = SignExtend(MemU[address,1], 32); 7541 if wback then R[n] = offset_addr; 7542 #endif 7543 7544 bool success = false; 7545 7546 if (ConditionPassed(opcode)) { 7547 uint32_t t; 7548 uint32_t n; 7549 uint32_t imm32; 7550 bool index; 7551 bool add; 7552 bool wback; 7553 7554 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7555 switch (encoding) { 7556 case eEncodingT1: 7557 // if Rt == '1111' then SEE PLI; 7558 // if Rn == '1111' then SEE LDRSB (literal); 7559 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7560 t = Bits32(opcode, 15, 12); 7561 n = Bits32(opcode, 19, 16); 7562 imm32 = Bits32(opcode, 11, 0); 7563 7564 // index = TRUE; add = TRUE; wback = FALSE; 7565 index = true; 7566 add = true; 7567 wback = false; 7568 7569 // if t == 13 then UNPREDICTABLE; 7570 if (t == 13) 7571 return false; 7572 7573 break; 7574 7575 case eEncodingT2: 7576 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7577 // if Rn == '1111' then SEE LDRSB (literal); 7578 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7579 // if P == '0' && W == '0' then UNDEFINED; 7580 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7581 return false; 7582 7583 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7584 t = Bits32(opcode, 15, 12); 7585 n = Bits32(opcode, 19, 16); 7586 imm32 = Bits32(opcode, 7, 0); 7587 7588 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7589 index = BitIsSet(opcode, 10); 7590 add = BitIsSet(opcode, 9); 7591 wback = BitIsSet(opcode, 8); 7592 7593 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7594 if (((t == 13) || 7595 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) || 7596 BitIsSet(opcode, 8)))) || 7597 (wback && (n == t))) 7598 return false; 7599 7600 break; 7601 7602 case eEncodingA1: { 7603 // if Rn == '1111' then SEE LDRSB (literal); 7604 // if P == '0' && W == '1' then SEE LDRSBT; 7605 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7606 t = Bits32(opcode, 15, 12); 7607 n = Bits32(opcode, 19, 16); 7608 7609 uint32_t imm4H = Bits32(opcode, 11, 8); 7610 uint32_t imm4L = Bits32(opcode, 3, 0); 7611 imm32 = (imm4H << 4) | imm4L; 7612 7613 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7614 // (W == '1'); 7615 index = BitIsSet(opcode, 24); 7616 add = BitIsSet(opcode, 23); 7617 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7618 7619 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7620 if ((t == 15) || (wback && (n == t))) 7621 return false; 7622 7623 break; 7624 } 7625 7626 default: 7627 return false; 7628 } 7629 7630 uint64_t Rn = ReadCoreReg(n, &success); 7631 if (!success) 7632 return false; 7633 7634 addr_t offset_addr; 7635 addr_t address; 7636 7637 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7638 if (add) 7639 offset_addr = Rn + imm32; 7640 else 7641 offset_addr = Rn - imm32; 7642 7643 // address = if index then offset_addr else R[n]; 7644 if (index) 7645 address = offset_addr; 7646 else 7647 address = Rn; 7648 7649 // R[t] = SignExtend(MemU[address,1], 32); 7650 RegisterInfo base_reg; 7651 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7652 7653 EmulateInstruction::Context context; 7654 context.type = eContextRegisterLoad; 7655 context.SetRegisterPlusOffset(base_reg, address - Rn); 7656 7657 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7658 if (!success) 7659 return false; 7660 7661 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7662 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7663 (uint64_t)signed_data)) 7664 return false; 7665 7666 // if wback then R[n] = offset_addr; 7667 if (wback) { 7668 context.type = eContextAdjustBaseRegister; 7669 context.SetAddress(offset_addr); 7670 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7671 offset_addr)) 7672 return false; 7673 } 7674 } 7675 7676 return true; 7677 } 7678 7679 // LDRSB (literal) calculates an address from the PC value and an immediate 7680 // offset, loads a byte from memory, 7681 // sign-extends it to form a 32-bit word, and writes tit to a register. 7682 bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode, 7683 const ARMEncoding encoding) { 7684 #if 0 7685 if ConditionPassed() then 7686 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7687 base = Align(PC,4); 7688 address = if add then (base + imm32) else (base - imm32); 7689 R[t] = SignExtend(MemU[address,1], 32); 7690 #endif 7691 7692 bool success = false; 7693 7694 if (ConditionPassed(opcode)) { 7695 uint32_t t; 7696 uint32_t imm32; 7697 bool add; 7698 7699 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7700 switch (encoding) { 7701 case eEncodingT1: 7702 // if Rt == '1111' then SEE PLI; 7703 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7704 t = Bits32(opcode, 15, 12); 7705 imm32 = Bits32(opcode, 11, 0); 7706 add = BitIsSet(opcode, 23); 7707 7708 // if t == 13 then UNPREDICTABLE; 7709 if (t == 13) 7710 return false; 7711 7712 break; 7713 7714 case eEncodingA1: { 7715 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7716 t = Bits32(opcode, 15, 12); 7717 uint32_t imm4H = Bits32(opcode, 11, 8); 7718 uint32_t imm4L = Bits32(opcode, 3, 0); 7719 imm32 = (imm4H << 4) | imm4L; 7720 add = BitIsSet(opcode, 23); 7721 7722 // if t == 15 then UNPREDICTABLE; 7723 if (t == 15) 7724 return false; 7725 7726 break; 7727 } 7728 7729 default: 7730 return false; 7731 } 7732 7733 // base = Align(PC,4); 7734 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7735 if (!success) 7736 return false; 7737 uint64_t base = AlignPC(pc_value); 7738 7739 // address = if add then (base + imm32) else (base - imm32); 7740 addr_t address; 7741 if (add) 7742 address = base + imm32; 7743 else 7744 address = base - imm32; 7745 7746 // R[t] = SignExtend(MemU[address,1], 32); 7747 RegisterInfo base_reg; 7748 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7749 7750 EmulateInstruction::Context context; 7751 context.type = eContextRegisterLoad; 7752 context.SetRegisterPlusOffset(base_reg, address - base); 7753 7754 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7755 if (!success) 7756 return false; 7757 7758 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7759 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7760 (uint64_t)signed_data)) 7761 return false; 7762 } 7763 return true; 7764 } 7765 7766 // LDRSB (register) calculates an address from a base register value and an 7767 // offset register value, loadsa byte from 7768 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7769 // The offset register value can be shifted left by 0, 1, 2, or 3 bits. 7770 bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode, 7771 const ARMEncoding encoding) { 7772 #if 0 7773 if ConditionPassed() then 7774 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7775 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7776 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7777 address = if index then offset_addr else R[n]; 7778 R[t] = SignExtend(MemU[address,1], 32); 7779 if wback then R[n] = offset_addr; 7780 #endif 7781 7782 bool success = false; 7783 7784 if (ConditionPassed(opcode)) { 7785 uint32_t t; 7786 uint32_t n; 7787 uint32_t m; 7788 bool index; 7789 bool add; 7790 bool wback; 7791 ARM_ShifterType shift_t; 7792 uint32_t shift_n; 7793 7794 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7795 switch (encoding) { 7796 case eEncodingT1: 7797 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7798 t = Bits32(opcode, 2, 0); 7799 n = Bits32(opcode, 5, 3); 7800 m = Bits32(opcode, 8, 6); 7801 7802 // index = TRUE; add = TRUE; wback = FALSE; 7803 index = true; 7804 add = true; 7805 wback = false; 7806 7807 // (shift_t, shift_n) = (SRType_LSL, 0); 7808 shift_t = SRType_LSL; 7809 shift_n = 0; 7810 7811 break; 7812 7813 case eEncodingT2: 7814 // if Rt == '1111' then SEE PLI; 7815 // if Rn == '1111' then SEE LDRSB (literal); 7816 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7817 t = Bits32(opcode, 15, 12); 7818 n = Bits32(opcode, 19, 16); 7819 m = Bits32(opcode, 3, 0); 7820 7821 // index = TRUE; add = TRUE; wback = FALSE; 7822 index = true; 7823 add = true; 7824 wback = false; 7825 7826 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7827 shift_t = SRType_LSL; 7828 shift_n = Bits32(opcode, 5, 4); 7829 7830 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7831 if ((t == 13) || BadReg(m)) 7832 return false; 7833 break; 7834 7835 case eEncodingA1: 7836 // if P == '0' && W == '1' then SEE LDRSBT; 7837 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7838 t = Bits32(opcode, 15, 12); 7839 n = Bits32(opcode, 19, 16); 7840 m = Bits32(opcode, 3, 0); 7841 7842 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7843 // (W == '1'); 7844 index = BitIsSet(opcode, 24); 7845 add = BitIsSet(opcode, 23); 7846 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7847 7848 // (shift_t, shift_n) = (SRType_LSL, 0); 7849 shift_t = SRType_LSL; 7850 shift_n = 0; 7851 7852 // if t == 15 || m == 15 then UNPREDICTABLE; 7853 if ((t == 15) || (m == 15)) 7854 return false; 7855 7856 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7857 if (wback && ((n == 15) || (n == t))) 7858 return false; 7859 break; 7860 7861 default: 7862 return false; 7863 } 7864 7865 uint64_t Rm = 7866 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7867 if (!success) 7868 return false; 7869 7870 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7871 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7872 if (!success) 7873 return false; 7874 7875 addr_t offset_addr; 7876 addr_t address; 7877 7878 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7879 uint64_t Rn = 7880 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7881 if (!success) 7882 return false; 7883 7884 if (add) 7885 offset_addr = Rn + offset; 7886 else 7887 offset_addr = Rn - offset; 7888 7889 // address = if index then offset_addr else R[n]; 7890 if (index) 7891 address = offset_addr; 7892 else 7893 address = Rn; 7894 7895 // R[t] = SignExtend(MemU[address,1], 32); 7896 RegisterInfo base_reg; 7897 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7898 RegisterInfo offset_reg; 7899 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7900 7901 EmulateInstruction::Context context; 7902 context.type = eContextRegisterLoad; 7903 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7904 7905 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7906 if (!success) 7907 return false; 7908 7909 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7910 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7911 (uint64_t)signed_data)) 7912 return false; 7913 7914 // if wback then R[n] = offset_addr; 7915 if (wback) { 7916 context.type = eContextAdjustBaseRegister; 7917 context.SetAddress(offset_addr); 7918 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7919 offset_addr)) 7920 return false; 7921 } 7922 } 7923 return true; 7924 } 7925 7926 // LDRSH (immediate) calculates an address from a base register value and an 7927 // immediate offset, loads a halfword from 7928 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7929 // It can use offset, post-indexed, or pre-indexed addressing. 7930 bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode, 7931 const ARMEncoding encoding) { 7932 #if 0 7933 if ConditionPassed() then 7934 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7935 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7936 address = if index then offset_addr else R[n]; 7937 data = MemU[address,2]; 7938 if wback then R[n] = offset_addr; 7939 if UnalignedSupport() || address<0> = '0' then 7940 R[t] = SignExtend(data, 32); 7941 else // Can only apply before ARMv7 7942 R[t] = bits(32) UNKNOWN; 7943 #endif 7944 7945 bool success = false; 7946 7947 if (ConditionPassed(opcode)) { 7948 uint32_t t; 7949 uint32_t n; 7950 uint32_t imm32; 7951 bool index; 7952 bool add; 7953 bool wback; 7954 7955 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7956 switch (encoding) { 7957 case eEncodingT1: 7958 // if Rn == '1111' then SEE LDRSH (literal); 7959 // if Rt == '1111' then SEE "Unallocated memory hints"; 7960 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7961 t = Bits32(opcode, 15, 12); 7962 n = Bits32(opcode, 19, 16); 7963 imm32 = Bits32(opcode, 11, 0); 7964 7965 // index = TRUE; add = TRUE; wback = FALSE; 7966 index = true; 7967 add = true; 7968 wback = false; 7969 7970 // if t == 13 then UNPREDICTABLE; 7971 if (t == 13) 7972 return false; 7973 7974 break; 7975 7976 case eEncodingT2: 7977 // if Rn == '1111' then SEE LDRSH (literal); 7978 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7979 // "Unallocated memory hints"; 7980 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7981 // if P == '0' && W == '0' then UNDEFINED; 7982 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7983 return false; 7984 7985 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7986 t = Bits32(opcode, 15, 12); 7987 n = Bits32(opcode, 19, 16); 7988 imm32 = Bits32(opcode, 7, 0); 7989 7990 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7991 index = BitIsSet(opcode, 10); 7992 add = BitIsSet(opcode, 9); 7993 wback = BitIsSet(opcode, 8); 7994 7995 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7996 if (BadReg(t) || (wback && (n == t))) 7997 return false; 7998 7999 break; 8000 8001 case eEncodingA1: { 8002 // if Rn == '1111' then SEE LDRSH (literal); 8003 // if P == '0' && W == '1' then SEE LDRSHT; 8004 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 8005 t = Bits32(opcode, 15, 12); 8006 n = Bits32(opcode, 19, 16); 8007 uint32_t imm4H = Bits32(opcode, 11, 8); 8008 uint32_t imm4L = Bits32(opcode, 3, 0); 8009 imm32 = (imm4H << 4) | imm4L; 8010 8011 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8012 // (W == '1'); 8013 index = BitIsSet(opcode, 24); 8014 add = BitIsSet(opcode, 23); 8015 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8016 8017 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 8018 if ((t == 15) || (wback && (n == t))) 8019 return false; 8020 8021 break; 8022 } 8023 8024 default: 8025 return false; 8026 } 8027 8028 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 8029 uint64_t Rn = 8030 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8031 if (!success) 8032 return false; 8033 8034 addr_t offset_addr; 8035 if (add) 8036 offset_addr = Rn + imm32; 8037 else 8038 offset_addr = Rn - imm32; 8039 8040 // address = if index then offset_addr else R[n]; 8041 addr_t address; 8042 if (index) 8043 address = offset_addr; 8044 else 8045 address = Rn; 8046 8047 // data = MemU[address,2]; 8048 RegisterInfo base_reg; 8049 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8050 8051 EmulateInstruction::Context context; 8052 context.type = eContextRegisterLoad; 8053 context.SetRegisterPlusOffset(base_reg, address - Rn); 8054 8055 uint64_t data = MemURead(context, address, 2, 0, &success); 8056 if (!success) 8057 return false; 8058 8059 // if wback then R[n] = offset_addr; 8060 if (wback) { 8061 context.type = eContextAdjustBaseRegister; 8062 context.SetAddress(offset_addr); 8063 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8064 offset_addr)) 8065 return false; 8066 } 8067 8068 // if UnalignedSupport() || address<0> = '0' then 8069 if (UnalignedSupport() || BitIsClear(address, 0)) { 8070 // R[t] = SignExtend(data, 32); 8071 int64_t signed_data = llvm::SignExtend64<16>(data); 8072 context.type = eContextRegisterLoad; 8073 context.SetRegisterPlusOffset(base_reg, address - Rn); 8074 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8075 (uint64_t)signed_data)) 8076 return false; 8077 } else // Can only apply before ARMv7 8078 { 8079 // R[t] = bits(32) UNKNOWN; 8080 WriteBits32Unknown(t); 8081 } 8082 } 8083 return true; 8084 } 8085 8086 // LDRSH (literal) calculates an address from the PC value and an immediate 8087 // offset, loads a halfword from memory, 8088 // sign-extends it to from a 32-bit word, and writes it to a register. 8089 bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode, 8090 const ARMEncoding encoding) { 8091 #if 0 8092 if ConditionPassed() then 8093 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8094 base = Align(PC,4); 8095 address = if add then (base + imm32) else (base - imm32); 8096 data = MemU[address,2]; 8097 if UnalignedSupport() || address<0> = '0' then 8098 R[t] = SignExtend(data, 32); 8099 else // Can only apply before ARMv7 8100 R[t] = bits(32) UNKNOWN; 8101 #endif 8102 8103 bool success = false; 8104 8105 if (ConditionPassed(opcode)) { 8106 uint32_t t; 8107 uint32_t imm32; 8108 bool add; 8109 8110 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8111 switch (encoding) { 8112 case eEncodingT1: 8113 // if Rt == '1111' then SEE "Unallocated memory hints"; 8114 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 8115 t = Bits32(opcode, 15, 12); 8116 imm32 = Bits32(opcode, 11, 0); 8117 add = BitIsSet(opcode, 23); 8118 8119 // if t == 13 then UNPREDICTABLE; 8120 if (t == 13) 8121 return false; 8122 8123 break; 8124 8125 case eEncodingA1: { 8126 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 8127 t = Bits32(opcode, 15, 12); 8128 uint32_t imm4H = Bits32(opcode, 11, 8); 8129 uint32_t imm4L = Bits32(opcode, 3, 0); 8130 imm32 = (imm4H << 4) | imm4L; 8131 add = BitIsSet(opcode, 23); 8132 8133 // if t == 15 then UNPREDICTABLE; 8134 if (t == 15) 8135 return false; 8136 8137 break; 8138 } 8139 default: 8140 return false; 8141 } 8142 8143 // base = Align(PC,4); 8144 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 8145 if (!success) 8146 return false; 8147 8148 uint64_t base = AlignPC(pc_value); 8149 8150 addr_t address; 8151 // address = if add then (base + imm32) else (base - imm32); 8152 if (add) 8153 address = base + imm32; 8154 else 8155 address = base - imm32; 8156 8157 // data = MemU[address,2]; 8158 RegisterInfo base_reg; 8159 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 8160 8161 EmulateInstruction::Context context; 8162 context.type = eContextRegisterLoad; 8163 context.SetRegisterPlusOffset(base_reg, imm32); 8164 8165 uint64_t data = MemURead(context, address, 2, 0, &success); 8166 if (!success) 8167 return false; 8168 8169 // if UnalignedSupport() || address<0> = '0' then 8170 if (UnalignedSupport() || BitIsClear(address, 0)) { 8171 // R[t] = SignExtend(data, 32); 8172 int64_t signed_data = llvm::SignExtend64<16>(data); 8173 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8174 (uint64_t)signed_data)) 8175 return false; 8176 } else // Can only apply before ARMv7 8177 { 8178 // R[t] = bits(32) UNKNOWN; 8179 WriteBits32Unknown(t); 8180 } 8181 } 8182 return true; 8183 } 8184 8185 // LDRSH (register) calculates an address from a base register value and an 8186 // offset register value, loads a halfword 8187 // from memory, sign-extends it to form a 32-bit word, and writes it to a 8188 // register. The offset register value can be shifted left by 0, 1, 2, or 3 8189 // bits. 8190 bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode, 8191 const ARMEncoding encoding) { 8192 #if 0 8193 if ConditionPassed() then 8194 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8195 offset = Shift(R[m], shift_t, shift_n, APSR.C); 8196 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8197 address = if index then offset_addr else R[n]; 8198 data = MemU[address,2]; 8199 if wback then R[n] = offset_addr; 8200 if UnalignedSupport() || address<0> = '0' then 8201 R[t] = SignExtend(data, 32); 8202 else // Can only apply before ARMv7 8203 R[t] = bits(32) UNKNOWN; 8204 #endif 8205 8206 bool success = false; 8207 8208 if (ConditionPassed(opcode)) { 8209 uint32_t t; 8210 uint32_t n; 8211 uint32_t m; 8212 bool index; 8213 bool add; 8214 bool wback; 8215 ARM_ShifterType shift_t; 8216 uint32_t shift_n; 8217 8218 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8219 switch (encoding) { 8220 case eEncodingT1: 8221 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 8222 // in ThumbEE"; 8223 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8224 t = Bits32(opcode, 2, 0); 8225 n = Bits32(opcode, 5, 3); 8226 m = Bits32(opcode, 8, 6); 8227 8228 // index = TRUE; add = TRUE; wback = FALSE; 8229 index = true; 8230 add = true; 8231 wback = false; 8232 8233 // (shift_t, shift_n) = (SRType_LSL, 0); 8234 shift_t = SRType_LSL; 8235 shift_n = 0; 8236 8237 break; 8238 8239 case eEncodingT2: 8240 // if Rn == '1111' then SEE LDRSH (literal); 8241 // if Rt == '1111' then SEE "Unallocated memory hints"; 8242 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8243 t = Bits32(opcode, 15, 12); 8244 n = Bits32(opcode, 19, 16); 8245 m = Bits32(opcode, 3, 0); 8246 8247 // index = TRUE; add = TRUE; wback = FALSE; 8248 index = true; 8249 add = true; 8250 wback = false; 8251 8252 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 8253 shift_t = SRType_LSL; 8254 shift_n = Bits32(opcode, 5, 4); 8255 8256 // if t == 13 || BadReg(m) then UNPREDICTABLE; 8257 if ((t == 13) || BadReg(m)) 8258 return false; 8259 8260 break; 8261 8262 case eEncodingA1: 8263 // if P == '0' && W == '1' then SEE LDRSHT; 8264 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8265 t = Bits32(opcode, 15, 12); 8266 n = Bits32(opcode, 19, 16); 8267 m = Bits32(opcode, 3, 0); 8268 8269 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8270 // (W == '1'); 8271 index = BitIsSet(opcode, 24); 8272 add = BitIsSet(opcode, 23); 8273 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8274 8275 // (shift_t, shift_n) = (SRType_LSL, 0); 8276 shift_t = SRType_LSL; 8277 shift_n = 0; 8278 8279 // if t == 15 || m == 15 then UNPREDICTABLE; 8280 if ((t == 15) || (m == 15)) 8281 return false; 8282 8283 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 8284 if (wback && ((n == 15) || (n == t))) 8285 return false; 8286 8287 break; 8288 8289 default: 8290 return false; 8291 } 8292 8293 uint64_t Rm = 8294 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8295 if (!success) 8296 return false; 8297 8298 uint64_t Rn = 8299 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8300 if (!success) 8301 return false; 8302 8303 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 8304 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 8305 if (!success) 8306 return false; 8307 8308 addr_t offset_addr; 8309 addr_t address; 8310 8311 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8312 if (add) 8313 offset_addr = Rn + offset; 8314 else 8315 offset_addr = Rn - offset; 8316 8317 // address = if index then offset_addr else R[n]; 8318 if (index) 8319 address = offset_addr; 8320 else 8321 address = Rn; 8322 8323 // data = MemU[address,2]; 8324 RegisterInfo base_reg; 8325 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8326 8327 RegisterInfo offset_reg; 8328 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 8329 8330 EmulateInstruction::Context context; 8331 context.type = eContextRegisterLoad; 8332 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8333 8334 uint64_t data = MemURead(context, address, 2, 0, &success); 8335 if (!success) 8336 return false; 8337 8338 // if wback then R[n] = offset_addr; 8339 if (wback) { 8340 context.type = eContextAdjustBaseRegister; 8341 context.SetAddress(offset_addr); 8342 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8343 offset_addr)) 8344 return false; 8345 } 8346 8347 // if UnalignedSupport() || address<0> = '0' then 8348 if (UnalignedSupport() || BitIsClear(address, 0)) { 8349 // R[t] = SignExtend(data, 32); 8350 context.type = eContextRegisterLoad; 8351 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8352 8353 int64_t signed_data = llvm::SignExtend64<16>(data); 8354 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8355 (uint64_t)signed_data)) 8356 return false; 8357 } else // Can only apply before ARMv7 8358 { 8359 // R[t] = bits(32) UNKNOWN; 8360 WriteBits32Unknown(t); 8361 } 8362 } 8363 return true; 8364 } 8365 8366 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and 8367 // writes the result to the destination 8368 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before 8369 // extracting the 8-bit value. 8370 bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode, 8371 const ARMEncoding encoding) { 8372 #if 0 8373 if ConditionPassed() then 8374 EncodingSpecificOperations(); 8375 rotated = ROR(R[m], rotation); 8376 R[d] = SignExtend(rotated<7:0>, 32); 8377 #endif 8378 8379 bool success = false; 8380 8381 if (ConditionPassed(opcode)) { 8382 uint32_t d; 8383 uint32_t m; 8384 uint32_t rotation; 8385 8386 // EncodingSpecificOperations(); 8387 switch (encoding) { 8388 case eEncodingT1: 8389 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8390 d = Bits32(opcode, 2, 0); 8391 m = Bits32(opcode, 5, 3); 8392 rotation = 0; 8393 8394 break; 8395 8396 case eEncodingT2: 8397 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8398 d = Bits32(opcode, 11, 8); 8399 m = Bits32(opcode, 3, 0); 8400 rotation = Bits32(opcode, 5, 4) << 3; 8401 8402 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8403 if (BadReg(d) || BadReg(m)) 8404 return false; 8405 8406 break; 8407 8408 case eEncodingA1: 8409 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8410 d = Bits32(opcode, 15, 12); 8411 m = Bits32(opcode, 3, 0); 8412 rotation = Bits32(opcode, 11, 10) << 3; 8413 8414 // if d == 15 || m == 15 then UNPREDICTABLE; 8415 if ((d == 15) || (m == 15)) 8416 return false; 8417 8418 break; 8419 8420 default: 8421 return false; 8422 } 8423 8424 uint64_t Rm = 8425 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8426 if (!success) 8427 return false; 8428 8429 // rotated = ROR(R[m], rotation); 8430 uint64_t rotated = ROR(Rm, rotation, &success); 8431 if (!success) 8432 return false; 8433 8434 // R[d] = SignExtend(rotated<7:0>, 32); 8435 int64_t data = llvm::SignExtend64<8>(rotated); 8436 8437 RegisterInfo source_reg; 8438 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8439 8440 EmulateInstruction::Context context; 8441 context.type = eContextRegisterLoad; 8442 context.SetRegister(source_reg); 8443 8444 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8445 (uint64_t)data)) 8446 return false; 8447 } 8448 return true; 8449 } 8450 8451 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and 8452 // writes the result to the destination 8453 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8454 // extracting the 16-bit value. 8455 bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode, 8456 const ARMEncoding encoding) { 8457 #if 0 8458 if ConditionPassed() then 8459 EncodingSpecificOperations(); 8460 rotated = ROR(R[m], rotation); 8461 R[d] = SignExtend(rotated<15:0>, 32); 8462 #endif 8463 8464 bool success = false; 8465 8466 if (ConditionPassed(opcode)) { 8467 uint32_t d; 8468 uint32_t m; 8469 uint32_t rotation; 8470 8471 // EncodingSpecificOperations(); 8472 switch (encoding) { 8473 case eEncodingT1: 8474 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8475 d = Bits32(opcode, 2, 0); 8476 m = Bits32(opcode, 5, 3); 8477 rotation = 0; 8478 8479 break; 8480 8481 case eEncodingT2: 8482 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8483 d = Bits32(opcode, 11, 8); 8484 m = Bits32(opcode, 3, 0); 8485 rotation = Bits32(opcode, 5, 4) << 3; 8486 8487 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8488 if (BadReg(d) || BadReg(m)) 8489 return false; 8490 8491 break; 8492 8493 case eEncodingA1: 8494 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8495 d = Bits32(opcode, 15, 12); 8496 m = Bits32(opcode, 3, 0); 8497 rotation = Bits32(opcode, 11, 10) << 3; 8498 8499 // if d == 15 || m == 15 then UNPREDICTABLE; 8500 if ((d == 15) || (m == 15)) 8501 return false; 8502 8503 break; 8504 8505 default: 8506 return false; 8507 } 8508 8509 uint64_t Rm = 8510 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8511 if (!success) 8512 return false; 8513 8514 // rotated = ROR(R[m], rotation); 8515 uint64_t rotated = ROR(Rm, rotation, &success); 8516 if (!success) 8517 return false; 8518 8519 // R[d] = SignExtend(rotated<15:0>, 32); 8520 RegisterInfo source_reg; 8521 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8522 8523 EmulateInstruction::Context context; 8524 context.type = eContextRegisterLoad; 8525 context.SetRegister(source_reg); 8526 8527 int64_t data = llvm::SignExtend64<16>(rotated); 8528 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8529 (uint64_t)data)) 8530 return false; 8531 } 8532 8533 return true; 8534 } 8535 8536 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and 8537 // writes the result to the destination 8538 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8539 // extracting the 8-bit value. 8540 bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode, 8541 const ARMEncoding encoding) { 8542 #if 0 8543 if ConditionPassed() then 8544 EncodingSpecificOperations(); 8545 rotated = ROR(R[m], rotation); 8546 R[d] = ZeroExtend(rotated<7:0>, 32); 8547 #endif 8548 8549 bool success = false; 8550 8551 if (ConditionPassed(opcode)) { 8552 uint32_t d; 8553 uint32_t m; 8554 uint32_t rotation; 8555 8556 // EncodingSpecificOperations(); 8557 switch (encoding) { 8558 case eEncodingT1: 8559 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8560 d = Bits32(opcode, 2, 0); 8561 m = Bits32(opcode, 5, 3); 8562 rotation = 0; 8563 8564 break; 8565 8566 case eEncodingT2: 8567 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8568 d = Bits32(opcode, 11, 8); 8569 m = Bits32(opcode, 3, 0); 8570 rotation = Bits32(opcode, 5, 4) << 3; 8571 8572 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8573 if (BadReg(d) || BadReg(m)) 8574 return false; 8575 8576 break; 8577 8578 case eEncodingA1: 8579 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8580 d = Bits32(opcode, 15, 12); 8581 m = Bits32(opcode, 3, 0); 8582 rotation = Bits32(opcode, 11, 10) << 3; 8583 8584 // if d == 15 || m == 15 then UNPREDICTABLE; 8585 if ((d == 15) || (m == 15)) 8586 return false; 8587 8588 break; 8589 8590 default: 8591 return false; 8592 } 8593 8594 uint64_t Rm = 8595 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8596 if (!success) 8597 return false; 8598 8599 // rotated = ROR(R[m], rotation); 8600 uint64_t rotated = ROR(Rm, rotation, &success); 8601 if (!success) 8602 return false; 8603 8604 // R[d] = ZeroExtend(rotated<7:0>, 32); 8605 RegisterInfo source_reg; 8606 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8607 8608 EmulateInstruction::Context context; 8609 context.type = eContextRegisterLoad; 8610 context.SetRegister(source_reg); 8611 8612 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8613 Bits32(rotated, 7, 0))) 8614 return false; 8615 } 8616 return true; 8617 } 8618 8619 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and 8620 // writes the result to the destination 8621 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8622 // extracting the 16-bit value. 8623 bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode, 8624 const ARMEncoding encoding) { 8625 #if 0 8626 if ConditionPassed() then 8627 EncodingSpecificOperations(); 8628 rotated = ROR(R[m], rotation); 8629 R[d] = ZeroExtend(rotated<15:0>, 32); 8630 #endif 8631 8632 bool success = false; 8633 8634 if (ConditionPassed(opcode)) { 8635 uint32_t d; 8636 uint32_t m; 8637 uint32_t rotation; 8638 8639 switch (encoding) { 8640 case eEncodingT1: 8641 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8642 d = Bits32(opcode, 2, 0); 8643 m = Bits32(opcode, 5, 3); 8644 rotation = 0; 8645 8646 break; 8647 8648 case eEncodingT2: 8649 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8650 d = Bits32(opcode, 11, 8); 8651 m = Bits32(opcode, 3, 0); 8652 rotation = Bits32(opcode, 5, 4) << 3; 8653 8654 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8655 if (BadReg(d) || BadReg(m)) 8656 return false; 8657 8658 break; 8659 8660 case eEncodingA1: 8661 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8662 d = Bits32(opcode, 15, 12); 8663 m = Bits32(opcode, 3, 0); 8664 rotation = Bits32(opcode, 11, 10) << 3; 8665 8666 // if d == 15 || m == 15 then UNPREDICTABLE; 8667 if ((d == 15) || (m == 15)) 8668 return false; 8669 8670 break; 8671 8672 default: 8673 return false; 8674 } 8675 8676 uint64_t Rm = 8677 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8678 if (!success) 8679 return false; 8680 8681 // rotated = ROR(R[m], rotation); 8682 uint64_t rotated = ROR(Rm, rotation, &success); 8683 if (!success) 8684 return false; 8685 8686 // R[d] = ZeroExtend(rotated<15:0>, 32); 8687 RegisterInfo source_reg; 8688 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8689 8690 EmulateInstruction::Context context; 8691 context.type = eContextRegisterLoad; 8692 context.SetRegister(source_reg); 8693 8694 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8695 Bits32(rotated, 15, 0))) 8696 return false; 8697 } 8698 return true; 8699 } 8700 8701 // RFE (Return From Exception) loads the PC and the CPSR from the word at the 8702 // specified address and the following 8703 // word respectively. 8704 bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode, 8705 const ARMEncoding encoding) { 8706 #if 0 8707 if ConditionPassed() then 8708 EncodingSpecificOperations(); 8709 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8710 UNPREDICTABLE; 8711 else 8712 address = if increment then R[n] else R[n]-8; 8713 if wordhigher then address = address+4; 8714 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8715 BranchWritePC(MemA[address,4]); 8716 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8717 #endif 8718 8719 bool success = false; 8720 8721 if (ConditionPassed(opcode)) { 8722 uint32_t n; 8723 bool wback; 8724 bool increment; 8725 bool wordhigher; 8726 8727 // EncodingSpecificOperations(); 8728 switch (encoding) { 8729 case eEncodingT1: 8730 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = 8731 // FALSE; 8732 n = Bits32(opcode, 19, 16); 8733 wback = BitIsSet(opcode, 21); 8734 increment = false; 8735 wordhigher = false; 8736 8737 // if n == 15 then UNPREDICTABLE; 8738 if (n == 15) 8739 return false; 8740 8741 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8742 if (InITBlock() && !LastInITBlock()) 8743 return false; 8744 8745 break; 8746 8747 case eEncodingT2: 8748 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8749 n = Bits32(opcode, 19, 16); 8750 wback = BitIsSet(opcode, 21); 8751 increment = true; 8752 wordhigher = false; 8753 8754 // if n == 15 then UNPREDICTABLE; 8755 if (n == 15) 8756 return false; 8757 8758 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8759 if (InITBlock() && !LastInITBlock()) 8760 return false; 8761 8762 break; 8763 8764 case eEncodingA1: 8765 // n = UInt(Rn); 8766 n = Bits32(opcode, 19, 16); 8767 8768 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8769 wback = BitIsSet(opcode, 21); 8770 increment = BitIsSet(opcode, 23); 8771 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23)); 8772 8773 // if n == 15 then UNPREDICTABLE; 8774 if (n == 15) 8775 return false; 8776 8777 break; 8778 8779 default: 8780 return false; 8781 } 8782 8783 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE 8784 // then 8785 if (!CurrentModeIsPrivileged()) 8786 // UNPREDICTABLE; 8787 return false; 8788 else { 8789 uint64_t Rn = 8790 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8791 if (!success) 8792 return false; 8793 8794 addr_t address; 8795 // address = if increment then R[n] else R[n]-8; 8796 if (increment) 8797 address = Rn; 8798 else 8799 address = Rn - 8; 8800 8801 // if wordhigher then address = address+4; 8802 if (wordhigher) 8803 address = address + 4; 8804 8805 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8806 RegisterInfo base_reg; 8807 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8808 8809 EmulateInstruction::Context context; 8810 context.type = eContextReturnFromException; 8811 context.SetRegisterPlusOffset(base_reg, address - Rn); 8812 8813 uint64_t data = MemARead(context, address + 4, 4, 0, &success); 8814 if (!success) 8815 return false; 8816 8817 CPSRWriteByInstr(data, 15, true); 8818 8819 // BranchWritePC(MemA[address,4]); 8820 uint64_t data2 = MemARead(context, address, 4, 0, &success); 8821 if (!success) 8822 return false; 8823 8824 BranchWritePC(context, data2); 8825 8826 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8827 if (wback) { 8828 context.type = eContextAdjustBaseRegister; 8829 if (increment) { 8830 context.SetOffset(8); 8831 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8832 Rn + 8)) 8833 return false; 8834 } else { 8835 context.SetOffset(-8); 8836 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8837 Rn - 8)) 8838 return false; 8839 } 8840 } // if wback 8841 } 8842 } // if ConditionPassed() 8843 return true; 8844 } 8845 8846 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a 8847 // register value and an immediate value, and writes the result to the 8848 // destination register. It can optionally update the condition flags based on 8849 // the result. 8850 bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode, 8851 const ARMEncoding encoding) { 8852 #if 0 8853 // ARM pseudo code... 8854 if ConditionPassed() then 8855 EncodingSpecificOperations(); 8856 result = R[n] EOR imm32; 8857 if d == 15 then // Can only occur for ARM encoding 8858 ALUWritePC(result); // setflags is always FALSE here 8859 else 8860 R[d] = result; 8861 if setflags then 8862 APSR.N = result<31>; 8863 APSR.Z = IsZeroBit(result); 8864 APSR.C = carry; 8865 // APSR.V unchanged 8866 #endif 8867 8868 bool success = false; 8869 8870 if (ConditionPassed(opcode)) { 8871 uint32_t Rd, Rn; 8872 uint32_t 8873 imm32; // the immediate value to be ORed to the value obtained from Rn 8874 bool setflags; 8875 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8876 switch (encoding) { 8877 case eEncodingT1: 8878 Rd = Bits32(opcode, 11, 8); 8879 Rn = Bits32(opcode, 19, 16); 8880 setflags = BitIsSet(opcode, 20); 8881 imm32 = ThumbExpandImm_C( 8882 opcode, APSR_C, 8883 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8884 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8885 if (Rd == 15 && setflags) 8886 return EmulateTEQImm(opcode, eEncodingT1); 8887 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8888 return false; 8889 break; 8890 case eEncodingA1: 8891 Rd = Bits32(opcode, 15, 12); 8892 Rn = Bits32(opcode, 19, 16); 8893 setflags = BitIsSet(opcode, 20); 8894 imm32 = 8895 ARMExpandImm_C(opcode, APSR_C, 8896 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8897 8898 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8899 // instructions; 8900 if (Rd == 15 && setflags) 8901 return EmulateSUBSPcLrEtc(opcode, encoding); 8902 break; 8903 default: 8904 return false; 8905 } 8906 8907 // Read the first operand. 8908 uint32_t val1 = ReadCoreReg(Rn, &success); 8909 if (!success) 8910 return false; 8911 8912 uint32_t result = val1 ^ imm32; 8913 8914 EmulateInstruction::Context context; 8915 context.type = EmulateInstruction::eContextImmediate; 8916 context.SetNoArgs(); 8917 8918 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8919 return false; 8920 } 8921 return true; 8922 } 8923 8924 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a 8925 // register value and an optionally-shifted register value, and writes the 8926 // result to the destination register. It can optionally update the condition 8927 // flags based on the result. 8928 bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode, 8929 const ARMEncoding encoding) { 8930 #if 0 8931 // ARM pseudo code... 8932 if ConditionPassed() then 8933 EncodingSpecificOperations(); 8934 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8935 result = R[n] EOR shifted; 8936 if d == 15 then // Can only occur for ARM encoding 8937 ALUWritePC(result); // setflags is always FALSE here 8938 else 8939 R[d] = result; 8940 if setflags then 8941 APSR.N = result<31>; 8942 APSR.Z = IsZeroBit(result); 8943 APSR.C = carry; 8944 // APSR.V unchanged 8945 #endif 8946 8947 bool success = false; 8948 8949 if (ConditionPassed(opcode)) { 8950 uint32_t Rd, Rn, Rm; 8951 ARM_ShifterType shift_t; 8952 uint32_t shift_n; // the shift applied to the value read from Rm 8953 bool setflags; 8954 uint32_t carry; 8955 switch (encoding) { 8956 case eEncodingT1: 8957 Rd = Rn = Bits32(opcode, 2, 0); 8958 Rm = Bits32(opcode, 5, 3); 8959 setflags = !InITBlock(); 8960 shift_t = SRType_LSL; 8961 shift_n = 0; 8962 break; 8963 case eEncodingT2: 8964 Rd = Bits32(opcode, 11, 8); 8965 Rn = Bits32(opcode, 19, 16); 8966 Rm = Bits32(opcode, 3, 0); 8967 setflags = BitIsSet(opcode, 20); 8968 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8969 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8970 if (Rd == 15 && setflags) 8971 return EmulateTEQReg(opcode, eEncodingT1); 8972 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8973 return false; 8974 break; 8975 case eEncodingA1: 8976 Rd = Bits32(opcode, 15, 12); 8977 Rn = Bits32(opcode, 19, 16); 8978 Rm = Bits32(opcode, 3, 0); 8979 setflags = BitIsSet(opcode, 20); 8980 shift_n = DecodeImmShiftARM(opcode, shift_t); 8981 8982 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8983 // instructions; 8984 if (Rd == 15 && setflags) 8985 return EmulateSUBSPcLrEtc(opcode, encoding); 8986 break; 8987 default: 8988 return false; 8989 } 8990 8991 // Read the first operand. 8992 uint32_t val1 = ReadCoreReg(Rn, &success); 8993 if (!success) 8994 return false; 8995 8996 // Read the second operand. 8997 uint32_t val2 = ReadCoreReg(Rm, &success); 8998 if (!success) 8999 return false; 9000 9001 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9002 if (!success) 9003 return false; 9004 uint32_t result = val1 ^ shifted; 9005 9006 EmulateInstruction::Context context; 9007 context.type = EmulateInstruction::eContextImmediate; 9008 context.SetNoArgs(); 9009 9010 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9011 return false; 9012 } 9013 return true; 9014 } 9015 9016 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value 9017 // and an immediate value, and writes the result to the destination register. 9018 // It can optionally update the condition flags based on the result. 9019 bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode, 9020 const ARMEncoding encoding) { 9021 #if 0 9022 // ARM pseudo code... 9023 if ConditionPassed() then 9024 EncodingSpecificOperations(); 9025 result = R[n] OR imm32; 9026 if d == 15 then // Can only occur for ARM encoding 9027 ALUWritePC(result); // setflags is always FALSE here 9028 else 9029 R[d] = result; 9030 if setflags then 9031 APSR.N = result<31>; 9032 APSR.Z = IsZeroBit(result); 9033 APSR.C = carry; 9034 // APSR.V unchanged 9035 #endif 9036 9037 bool success = false; 9038 9039 if (ConditionPassed(opcode)) { 9040 uint32_t Rd, Rn; 9041 uint32_t 9042 imm32; // the immediate value to be ORed to the value obtained from Rn 9043 bool setflags; 9044 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9045 switch (encoding) { 9046 case eEncodingT1: 9047 Rd = Bits32(opcode, 11, 8); 9048 Rn = Bits32(opcode, 19, 16); 9049 setflags = BitIsSet(opcode, 20); 9050 imm32 = ThumbExpandImm_C( 9051 opcode, APSR_C, 9052 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9053 // if Rn == '1111' then SEE MOV (immediate); 9054 if (Rn == 15) 9055 return EmulateMOVRdImm(opcode, eEncodingT2); 9056 if (BadReg(Rd) || Rn == 13) 9057 return false; 9058 break; 9059 case eEncodingA1: 9060 Rd = Bits32(opcode, 15, 12); 9061 Rn = Bits32(opcode, 19, 16); 9062 setflags = BitIsSet(opcode, 20); 9063 imm32 = 9064 ARMExpandImm_C(opcode, APSR_C, 9065 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9066 9067 if (Rd == 15 && setflags) 9068 return EmulateSUBSPcLrEtc(opcode, encoding); 9069 break; 9070 default: 9071 return false; 9072 } 9073 9074 // Read the first operand. 9075 uint32_t val1 = ReadCoreReg(Rn, &success); 9076 if (!success) 9077 return false; 9078 9079 uint32_t result = val1 | imm32; 9080 9081 EmulateInstruction::Context context; 9082 context.type = EmulateInstruction::eContextImmediate; 9083 context.SetNoArgs(); 9084 9085 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9086 return false; 9087 } 9088 return true; 9089 } 9090 9091 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value 9092 // and an optionally-shifted register value, and writes the result to the 9093 // destination register. It can optionally update the condition flags based on 9094 // the result. 9095 bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode, 9096 const ARMEncoding encoding) { 9097 #if 0 9098 // ARM pseudo code... 9099 if ConditionPassed() then 9100 EncodingSpecificOperations(); 9101 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9102 result = R[n] OR shifted; 9103 if d == 15 then // Can only occur for ARM encoding 9104 ALUWritePC(result); // setflags is always FALSE here 9105 else 9106 R[d] = result; 9107 if setflags then 9108 APSR.N = result<31>; 9109 APSR.Z = IsZeroBit(result); 9110 APSR.C = carry; 9111 // APSR.V unchanged 9112 #endif 9113 9114 bool success = false; 9115 9116 if (ConditionPassed(opcode)) { 9117 uint32_t Rd, Rn, Rm; 9118 ARM_ShifterType shift_t; 9119 uint32_t shift_n; // the shift applied to the value read from Rm 9120 bool setflags; 9121 uint32_t carry; 9122 switch (encoding) { 9123 case eEncodingT1: 9124 Rd = Rn = Bits32(opcode, 2, 0); 9125 Rm = Bits32(opcode, 5, 3); 9126 setflags = !InITBlock(); 9127 shift_t = SRType_LSL; 9128 shift_n = 0; 9129 break; 9130 case eEncodingT2: 9131 Rd = Bits32(opcode, 11, 8); 9132 Rn = Bits32(opcode, 19, 16); 9133 Rm = Bits32(opcode, 3, 0); 9134 setflags = BitIsSet(opcode, 20); 9135 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9136 // if Rn == '1111' then SEE MOV (register); 9137 if (Rn == 15) 9138 return EmulateMOVRdRm(opcode, eEncodingT3); 9139 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 9140 return false; 9141 break; 9142 case eEncodingA1: 9143 Rd = Bits32(opcode, 15, 12); 9144 Rn = Bits32(opcode, 19, 16); 9145 Rm = Bits32(opcode, 3, 0); 9146 setflags = BitIsSet(opcode, 20); 9147 shift_n = DecodeImmShiftARM(opcode, shift_t); 9148 9149 if (Rd == 15 && setflags) 9150 return EmulateSUBSPcLrEtc(opcode, encoding); 9151 break; 9152 default: 9153 return false; 9154 } 9155 9156 // Read the first operand. 9157 uint32_t val1 = ReadCoreReg(Rn, &success); 9158 if (!success) 9159 return false; 9160 9161 // Read the second operand. 9162 uint32_t val2 = ReadCoreReg(Rm, &success); 9163 if (!success) 9164 return false; 9165 9166 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9167 if (!success) 9168 return false; 9169 uint32_t result = val1 | shifted; 9170 9171 EmulateInstruction::Context context; 9172 context.type = EmulateInstruction::eContextImmediate; 9173 context.SetNoArgs(); 9174 9175 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9176 return false; 9177 } 9178 return true; 9179 } 9180 9181 // Reverse Subtract (immediate) subtracts a register value from an immediate 9182 // value, and writes the result to the destination register. It can optionally 9183 // update the condition flags based on the result. 9184 bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode, 9185 const ARMEncoding encoding) { 9186 #if 0 9187 // ARM pseudo code... 9188 if ConditionPassed() then 9189 EncodingSpecificOperations(); 9190 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 9191 if d == 15 then // Can only occur for ARM encoding 9192 ALUWritePC(result); // setflags is always FALSE here 9193 else 9194 R[d] = result; 9195 if setflags then 9196 APSR.N = result<31>; 9197 APSR.Z = IsZeroBit(result); 9198 APSR.C = carry; 9199 APSR.V = overflow; 9200 #endif 9201 9202 bool success = false; 9203 9204 uint32_t Rd; // the destination register 9205 uint32_t Rn; // the first operand 9206 bool setflags; 9207 uint32_t 9208 imm32; // the immediate value to be added to the value obtained from Rn 9209 switch (encoding) { 9210 case eEncodingT1: 9211 Rd = Bits32(opcode, 2, 0); 9212 Rn = Bits32(opcode, 5, 3); 9213 setflags = !InITBlock(); 9214 imm32 = 0; 9215 break; 9216 case eEncodingT2: 9217 Rd = Bits32(opcode, 11, 8); 9218 Rn = Bits32(opcode, 19, 16); 9219 setflags = BitIsSet(opcode, 20); 9220 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9221 if (BadReg(Rd) || BadReg(Rn)) 9222 return false; 9223 break; 9224 case eEncodingA1: 9225 Rd = Bits32(opcode, 15, 12); 9226 Rn = Bits32(opcode, 19, 16); 9227 setflags = BitIsSet(opcode, 20); 9228 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9229 9230 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9231 // instructions; 9232 if (Rd == 15 && setflags) 9233 return EmulateSUBSPcLrEtc(opcode, encoding); 9234 break; 9235 default: 9236 return false; 9237 } 9238 // Read the register value from the operand register Rn. 9239 uint32_t reg_val = ReadCoreReg(Rn, &success); 9240 if (!success) 9241 return false; 9242 9243 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 9244 9245 EmulateInstruction::Context context; 9246 context.type = EmulateInstruction::eContextImmediate; 9247 context.SetNoArgs(); 9248 9249 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9250 res.carry_out, res.overflow)) 9251 return false; 9252 9253 return true; 9254 } 9255 9256 // Reverse Subtract (register) subtracts a register value from an optionally- 9257 // shifted register value, and writes the result to the destination register. 9258 // It can optionally update the condition flags based on the result. 9259 bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode, 9260 const ARMEncoding encoding) { 9261 #if 0 9262 // ARM pseudo code... 9263 if ConditionPassed() then 9264 EncodingSpecificOperations(); 9265 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9266 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 9267 if d == 15 then // Can only occur for ARM encoding 9268 ALUWritePC(result); // setflags is always FALSE here 9269 else 9270 R[d] = result; 9271 if setflags then 9272 APSR.N = result<31>; 9273 APSR.Z = IsZeroBit(result); 9274 APSR.C = carry; 9275 APSR.V = overflow; 9276 #endif 9277 9278 bool success = false; 9279 9280 uint32_t Rd; // the destination register 9281 uint32_t Rn; // the first operand 9282 uint32_t Rm; // the second operand 9283 bool setflags; 9284 ARM_ShifterType shift_t; 9285 uint32_t shift_n; // the shift applied to the value read from Rm 9286 switch (encoding) { 9287 case eEncodingT1: 9288 Rd = Bits32(opcode, 11, 8); 9289 Rn = Bits32(opcode, 19, 16); 9290 Rm = Bits32(opcode, 3, 0); 9291 setflags = BitIsSet(opcode, 20); 9292 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9293 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 9294 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9295 return false; 9296 break; 9297 case eEncodingA1: 9298 Rd = Bits32(opcode, 15, 12); 9299 Rn = Bits32(opcode, 19, 16); 9300 Rm = Bits32(opcode, 3, 0); 9301 setflags = BitIsSet(opcode, 20); 9302 shift_n = DecodeImmShiftARM(opcode, shift_t); 9303 9304 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9305 // instructions; 9306 if (Rd == 15 && setflags) 9307 return EmulateSUBSPcLrEtc(opcode, encoding); 9308 break; 9309 default: 9310 return false; 9311 } 9312 // Read the register value from register Rn. 9313 uint32_t val1 = ReadCoreReg(Rn, &success); 9314 if (!success) 9315 return false; 9316 9317 // Read the register value from register Rm. 9318 uint32_t val2 = ReadCoreReg(Rm, &success); 9319 if (!success) 9320 return false; 9321 9322 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9323 if (!success) 9324 return false; 9325 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 9326 9327 EmulateInstruction::Context context; 9328 context.type = EmulateInstruction::eContextImmediate; 9329 context.SetNoArgs(); 9330 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9331 res.carry_out, res.overflow)) 9332 return false; 9333 9334 return true; 9335 } 9336 9337 // Reverse Subtract with Carry (immediate) subtracts a register value and the 9338 // value of NOT (Carry flag) from an immediate value, and writes the result to 9339 // the destination register. It can optionally update the condition flags based 9340 // on the result. 9341 bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode, 9342 const ARMEncoding encoding) { 9343 #if 0 9344 // ARM pseudo code... 9345 if ConditionPassed() then 9346 EncodingSpecificOperations(); 9347 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 9348 if d == 15 then 9349 ALUWritePC(result); // setflags is always FALSE here 9350 else 9351 R[d] = result; 9352 if setflags then 9353 APSR.N = result<31>; 9354 APSR.Z = IsZeroBit(result); 9355 APSR.C = carry; 9356 APSR.V = overflow; 9357 #endif 9358 9359 bool success = false; 9360 9361 uint32_t Rd; // the destination register 9362 uint32_t Rn; // the first operand 9363 bool setflags; 9364 uint32_t 9365 imm32; // the immediate value to be added to the value obtained from Rn 9366 switch (encoding) { 9367 case eEncodingA1: 9368 Rd = Bits32(opcode, 15, 12); 9369 Rn = Bits32(opcode, 19, 16); 9370 setflags = BitIsSet(opcode, 20); 9371 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9372 9373 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9374 // instructions; 9375 if (Rd == 15 && setflags) 9376 return EmulateSUBSPcLrEtc(opcode, encoding); 9377 break; 9378 default: 9379 return false; 9380 } 9381 // Read the register value from the operand register Rn. 9382 uint32_t reg_val = ReadCoreReg(Rn, &success); 9383 if (!success) 9384 return false; 9385 9386 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 9387 9388 EmulateInstruction::Context context; 9389 context.type = EmulateInstruction::eContextImmediate; 9390 context.SetNoArgs(); 9391 9392 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9393 res.carry_out, res.overflow)) 9394 return false; 9395 9396 return true; 9397 } 9398 9399 // Reverse Subtract with Carry (register) subtracts a register value and the 9400 // value of NOT (Carry flag) from an optionally-shifted register value, and 9401 // writes the result to the destination register. It can optionally update the 9402 // condition flags based on the result. 9403 bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode, 9404 const ARMEncoding encoding) { 9405 #if 0 9406 // ARM pseudo code... 9407 if ConditionPassed() then 9408 EncodingSpecificOperations(); 9409 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9410 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 9411 if d == 15 then 9412 ALUWritePC(result); // setflags is always FALSE here 9413 else 9414 R[d] = result; 9415 if setflags then 9416 APSR.N = result<31>; 9417 APSR.Z = IsZeroBit(result); 9418 APSR.C = carry; 9419 APSR.V = overflow; 9420 #endif 9421 9422 bool success = false; 9423 9424 uint32_t Rd; // the destination register 9425 uint32_t Rn; // the first operand 9426 uint32_t Rm; // the second operand 9427 bool setflags; 9428 ARM_ShifterType shift_t; 9429 uint32_t shift_n; // the shift applied to the value read from Rm 9430 switch (encoding) { 9431 case eEncodingA1: 9432 Rd = Bits32(opcode, 15, 12); 9433 Rn = Bits32(opcode, 19, 16); 9434 Rm = Bits32(opcode, 3, 0); 9435 setflags = BitIsSet(opcode, 20); 9436 shift_n = DecodeImmShiftARM(opcode, shift_t); 9437 9438 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9439 // instructions; 9440 if (Rd == 15 && setflags) 9441 return EmulateSUBSPcLrEtc(opcode, encoding); 9442 break; 9443 default: 9444 return false; 9445 } 9446 // Read the register value from register Rn. 9447 uint32_t val1 = ReadCoreReg(Rn, &success); 9448 if (!success) 9449 return false; 9450 9451 // Read the register value from register Rm. 9452 uint32_t val2 = ReadCoreReg(Rm, &success); 9453 if (!success) 9454 return false; 9455 9456 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9457 if (!success) 9458 return false; 9459 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 9460 9461 EmulateInstruction::Context context; 9462 context.type = EmulateInstruction::eContextImmediate; 9463 context.SetNoArgs(); 9464 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9465 res.carry_out, res.overflow)) 9466 return false; 9467 9468 return true; 9469 } 9470 9471 // Subtract with Carry (immediate) subtracts an immediate value and the value 9472 // of 9473 // NOT (Carry flag) from a register value, and writes the result to the 9474 // destination register. 9475 // It can optionally update the condition flags based on the result. 9476 bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode, 9477 const ARMEncoding encoding) { 9478 #if 0 9479 // ARM pseudo code... 9480 if ConditionPassed() then 9481 EncodingSpecificOperations(); 9482 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 9483 if d == 15 then // Can only occur for ARM encoding 9484 ALUWritePC(result); // setflags is always FALSE here 9485 else 9486 R[d] = result; 9487 if setflags then 9488 APSR.N = result<31>; 9489 APSR.Z = IsZeroBit(result); 9490 APSR.C = carry; 9491 APSR.V = overflow; 9492 #endif 9493 9494 bool success = false; 9495 9496 uint32_t Rd; // the destination register 9497 uint32_t Rn; // the first operand 9498 bool setflags; 9499 uint32_t 9500 imm32; // the immediate value to be added to the value obtained from Rn 9501 switch (encoding) { 9502 case eEncodingT1: 9503 Rd = Bits32(opcode, 11, 8); 9504 Rn = Bits32(opcode, 19, 16); 9505 setflags = BitIsSet(opcode, 20); 9506 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9507 if (BadReg(Rd) || BadReg(Rn)) 9508 return false; 9509 break; 9510 case eEncodingA1: 9511 Rd = Bits32(opcode, 15, 12); 9512 Rn = Bits32(opcode, 19, 16); 9513 setflags = BitIsSet(opcode, 20); 9514 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9515 9516 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9517 // instructions; 9518 if (Rd == 15 && setflags) 9519 return EmulateSUBSPcLrEtc(opcode, encoding); 9520 break; 9521 default: 9522 return false; 9523 } 9524 // Read the register value from the operand register Rn. 9525 uint32_t reg_val = ReadCoreReg(Rn, &success); 9526 if (!success) 9527 return false; 9528 9529 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9530 9531 EmulateInstruction::Context context; 9532 context.type = EmulateInstruction::eContextImmediate; 9533 context.SetNoArgs(); 9534 9535 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9536 res.carry_out, res.overflow)) 9537 return false; 9538 9539 return true; 9540 } 9541 9542 // Subtract with Carry (register) subtracts an optionally-shifted register 9543 // value and the value of 9544 // NOT (Carry flag) from a register value, and writes the result to the 9545 // destination register. 9546 // It can optionally update the condition flags based on the result. 9547 bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode, 9548 const ARMEncoding encoding) { 9549 #if 0 9550 // ARM pseudo code... 9551 if ConditionPassed() then 9552 EncodingSpecificOperations(); 9553 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9554 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9555 if d == 15 then // Can only occur for ARM encoding 9556 ALUWritePC(result); // setflags is always FALSE here 9557 else 9558 R[d] = result; 9559 if setflags then 9560 APSR.N = result<31>; 9561 APSR.Z = IsZeroBit(result); 9562 APSR.C = carry; 9563 APSR.V = overflow; 9564 #endif 9565 9566 bool success = false; 9567 9568 uint32_t Rd; // the destination register 9569 uint32_t Rn; // the first operand 9570 uint32_t Rm; // the second operand 9571 bool setflags; 9572 ARM_ShifterType shift_t; 9573 uint32_t shift_n; // the shift applied to the value read from Rm 9574 switch (encoding) { 9575 case eEncodingT1: 9576 Rd = Rn = Bits32(opcode, 2, 0); 9577 Rm = Bits32(opcode, 5, 3); 9578 setflags = !InITBlock(); 9579 shift_t = SRType_LSL; 9580 shift_n = 0; 9581 break; 9582 case eEncodingT2: 9583 Rd = Bits32(opcode, 11, 8); 9584 Rn = Bits32(opcode, 19, 16); 9585 Rm = Bits32(opcode, 3, 0); 9586 setflags = BitIsSet(opcode, 20); 9587 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9588 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9589 return false; 9590 break; 9591 case eEncodingA1: 9592 Rd = Bits32(opcode, 15, 12); 9593 Rn = Bits32(opcode, 19, 16); 9594 Rm = Bits32(opcode, 3, 0); 9595 setflags = BitIsSet(opcode, 20); 9596 shift_n = DecodeImmShiftARM(opcode, shift_t); 9597 9598 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9599 // instructions; 9600 if (Rd == 15 && setflags) 9601 return EmulateSUBSPcLrEtc(opcode, encoding); 9602 break; 9603 default: 9604 return false; 9605 } 9606 // Read the register value from register Rn. 9607 uint32_t val1 = ReadCoreReg(Rn, &success); 9608 if (!success) 9609 return false; 9610 9611 // Read the register value from register Rm. 9612 uint32_t val2 = ReadCoreReg(Rm, &success); 9613 if (!success) 9614 return false; 9615 9616 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9617 if (!success) 9618 return false; 9619 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9620 9621 EmulateInstruction::Context context; 9622 context.type = EmulateInstruction::eContextImmediate; 9623 context.SetNoArgs(); 9624 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9625 res.carry_out, res.overflow)) 9626 return false; 9627 9628 return true; 9629 } 9630 9631 // This instruction subtracts an immediate value from a register value, and 9632 // writes the result to the destination register. It can optionally update the 9633 // condition flags based on the result. 9634 bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode, 9635 const ARMEncoding encoding) { 9636 #if 0 9637 // ARM pseudo code... 9638 if ConditionPassed() then 9639 EncodingSpecificOperations(); 9640 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9641 R[d] = result; 9642 if setflags then 9643 APSR.N = result<31>; 9644 APSR.Z = IsZeroBit(result); 9645 APSR.C = carry; 9646 APSR.V = overflow; 9647 #endif 9648 9649 bool success = false; 9650 9651 uint32_t Rd; // the destination register 9652 uint32_t Rn; // the first operand 9653 bool setflags; 9654 uint32_t imm32; // the immediate value to be subtracted from the value 9655 // obtained from Rn 9656 switch (encoding) { 9657 case eEncodingT1: 9658 Rd = Bits32(opcode, 2, 0); 9659 Rn = Bits32(opcode, 5, 3); 9660 setflags = !InITBlock(); 9661 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9662 break; 9663 case eEncodingT2: 9664 Rd = Rn = Bits32(opcode, 10, 8); 9665 setflags = !InITBlock(); 9666 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9667 break; 9668 case eEncodingT3: 9669 Rd = Bits32(opcode, 11, 8); 9670 Rn = Bits32(opcode, 19, 16); 9671 setflags = BitIsSet(opcode, 20); 9672 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9673 9674 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9675 if (Rd == 15 && setflags) 9676 return EmulateCMPImm(opcode, eEncodingT2); 9677 9678 // if Rn == '1101' then SEE SUB (SP minus immediate); 9679 if (Rn == 13) 9680 return EmulateSUBSPImm(opcode, eEncodingT2); 9681 9682 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9683 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9684 return false; 9685 break; 9686 case eEncodingT4: 9687 Rd = Bits32(opcode, 11, 8); 9688 Rn = Bits32(opcode, 19, 16); 9689 setflags = BitIsSet(opcode, 20); 9690 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9691 9692 // if Rn == '1111' then SEE ADR; 9693 if (Rn == 15) 9694 return EmulateADR(opcode, eEncodingT2); 9695 9696 // if Rn == '1101' then SEE SUB (SP minus immediate); 9697 if (Rn == 13) 9698 return EmulateSUBSPImm(opcode, eEncodingT3); 9699 9700 if (BadReg(Rd)) 9701 return false; 9702 break; 9703 default: 9704 return false; 9705 } 9706 // Read the register value from the operand register Rn. 9707 uint32_t reg_val = ReadCoreReg(Rn, &success); 9708 if (!success) 9709 return false; 9710 9711 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9712 9713 EmulateInstruction::Context context; 9714 context.type = EmulateInstruction::eContextImmediate; 9715 context.SetNoArgs(); 9716 9717 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9718 res.carry_out, res.overflow)) 9719 return false; 9720 9721 return true; 9722 } 9723 9724 // This instruction subtracts an immediate value from a register value, and 9725 // writes the result to the destination register. It can optionally update the 9726 // condition flags based on the result. 9727 bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode, 9728 const ARMEncoding encoding) { 9729 #if 0 9730 // ARM pseudo code... 9731 if ConditionPassed() then 9732 EncodingSpecificOperations(); 9733 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9734 if d == 15 then 9735 ALUWritePC(result); // setflags is always FALSE here 9736 else 9737 R[d] = result; 9738 if setflags then 9739 APSR.N = result<31>; 9740 APSR.Z = IsZeroBit(result); 9741 APSR.C = carry; 9742 APSR.V = overflow; 9743 #endif 9744 9745 bool success = false; 9746 9747 if (ConditionPassed(opcode)) { 9748 uint32_t Rd; // the destination register 9749 uint32_t Rn; // the first operand 9750 bool setflags; 9751 uint32_t imm32; // the immediate value to be subtracted from the value 9752 // obtained from Rn 9753 switch (encoding) { 9754 case eEncodingA1: 9755 Rd = Bits32(opcode, 15, 12); 9756 Rn = Bits32(opcode, 19, 16); 9757 setflags = BitIsSet(opcode, 20); 9758 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9759 9760 // if Rn == '1111' && S == '0' then SEE ADR; 9761 if (Rn == 15 && !setflags) 9762 return EmulateADR(opcode, eEncodingA2); 9763 9764 // if Rn == '1101' then SEE SUB (SP minus immediate); 9765 if (Rn == 13) 9766 return EmulateSUBSPImm(opcode, eEncodingA1); 9767 9768 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9769 // instructions; 9770 if (Rd == 15 && setflags) 9771 return EmulateSUBSPcLrEtc(opcode, encoding); 9772 break; 9773 default: 9774 return false; 9775 } 9776 // Read the register value from the operand register Rn. 9777 uint32_t reg_val = ReadCoreReg(Rn, &success); 9778 if (!success) 9779 return false; 9780 9781 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9782 9783 EmulateInstruction::Context context; 9784 if (Rd == 13) 9785 context.type = EmulateInstruction::eContextAdjustStackPointer; 9786 else 9787 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9788 9789 RegisterInfo dwarf_reg; 9790 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 9791 int64_t imm32_signed = imm32; 9792 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed); 9793 9794 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9795 res.carry_out, res.overflow)) 9796 return false; 9797 } 9798 return true; 9799 } 9800 9801 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a 9802 // register value and an immediate value. It updates the condition flags based 9803 // on the result, and discards the result. 9804 bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode, 9805 const ARMEncoding encoding) { 9806 #if 0 9807 // ARM pseudo code... 9808 if ConditionPassed() then 9809 EncodingSpecificOperations(); 9810 result = R[n] EOR imm32; 9811 APSR.N = result<31>; 9812 APSR.Z = IsZeroBit(result); 9813 APSR.C = carry; 9814 // APSR.V unchanged 9815 #endif 9816 9817 bool success = false; 9818 9819 if (ConditionPassed(opcode)) { 9820 uint32_t Rn; 9821 uint32_t 9822 imm32; // the immediate value to be ANDed to the value obtained from Rn 9823 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9824 switch (encoding) { 9825 case eEncodingT1: 9826 Rn = Bits32(opcode, 19, 16); 9827 imm32 = ThumbExpandImm_C( 9828 opcode, APSR_C, 9829 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9830 if (BadReg(Rn)) 9831 return false; 9832 break; 9833 case eEncodingA1: 9834 Rn = Bits32(opcode, 19, 16); 9835 imm32 = 9836 ARMExpandImm_C(opcode, APSR_C, 9837 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9838 break; 9839 default: 9840 return false; 9841 } 9842 9843 // Read the first operand. 9844 uint32_t val1 = ReadCoreReg(Rn, &success); 9845 if (!success) 9846 return false; 9847 9848 uint32_t result = val1 ^ imm32; 9849 9850 EmulateInstruction::Context context; 9851 context.type = EmulateInstruction::eContextImmediate; 9852 context.SetNoArgs(); 9853 9854 if (!WriteFlags(context, result, carry)) 9855 return false; 9856 } 9857 return true; 9858 } 9859 9860 // Test Equivalence (register) performs a bitwise exclusive OR operation on a 9861 // register value and an optionally-shifted register value. It updates the 9862 // condition flags based on the result, and discards the result. 9863 bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode, 9864 const ARMEncoding encoding) { 9865 #if 0 9866 // ARM pseudo code... 9867 if ConditionPassed() then 9868 EncodingSpecificOperations(); 9869 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9870 result = R[n] EOR shifted; 9871 APSR.N = result<31>; 9872 APSR.Z = IsZeroBit(result); 9873 APSR.C = carry; 9874 // APSR.V unchanged 9875 #endif 9876 9877 bool success = false; 9878 9879 if (ConditionPassed(opcode)) { 9880 uint32_t Rn, Rm; 9881 ARM_ShifterType shift_t; 9882 uint32_t shift_n; // the shift applied to the value read from Rm 9883 uint32_t carry; 9884 switch (encoding) { 9885 case eEncodingT1: 9886 Rn = Bits32(opcode, 19, 16); 9887 Rm = Bits32(opcode, 3, 0); 9888 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9889 if (BadReg(Rn) || BadReg(Rm)) 9890 return false; 9891 break; 9892 case eEncodingA1: 9893 Rn = Bits32(opcode, 19, 16); 9894 Rm = Bits32(opcode, 3, 0); 9895 shift_n = DecodeImmShiftARM(opcode, shift_t); 9896 break; 9897 default: 9898 return false; 9899 } 9900 9901 // Read the first operand. 9902 uint32_t val1 = ReadCoreReg(Rn, &success); 9903 if (!success) 9904 return false; 9905 9906 // Read the second operand. 9907 uint32_t val2 = ReadCoreReg(Rm, &success); 9908 if (!success) 9909 return false; 9910 9911 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9912 if (!success) 9913 return false; 9914 uint32_t result = val1 ^ shifted; 9915 9916 EmulateInstruction::Context context; 9917 context.type = EmulateInstruction::eContextImmediate; 9918 context.SetNoArgs(); 9919 9920 if (!WriteFlags(context, result, carry)) 9921 return false; 9922 } 9923 return true; 9924 } 9925 9926 // Test (immediate) performs a bitwise AND operation on a register value and an 9927 // immediate value. It updates the condition flags based on the result, and 9928 // discards the result. 9929 bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode, 9930 const ARMEncoding encoding) { 9931 #if 0 9932 // ARM pseudo code... 9933 if ConditionPassed() then 9934 EncodingSpecificOperations(); 9935 result = R[n] AND imm32; 9936 APSR.N = result<31>; 9937 APSR.Z = IsZeroBit(result); 9938 APSR.C = carry; 9939 // APSR.V unchanged 9940 #endif 9941 9942 bool success = false; 9943 9944 if (ConditionPassed(opcode)) { 9945 uint32_t Rn; 9946 uint32_t 9947 imm32; // the immediate value to be ANDed to the value obtained from Rn 9948 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9949 switch (encoding) { 9950 case eEncodingT1: 9951 Rn = Bits32(opcode, 19, 16); 9952 imm32 = ThumbExpandImm_C( 9953 opcode, APSR_C, 9954 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9955 if (BadReg(Rn)) 9956 return false; 9957 break; 9958 case eEncodingA1: 9959 Rn = Bits32(opcode, 19, 16); 9960 imm32 = 9961 ARMExpandImm_C(opcode, APSR_C, 9962 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9963 break; 9964 default: 9965 return false; 9966 } 9967 9968 // Read the first operand. 9969 uint32_t val1 = ReadCoreReg(Rn, &success); 9970 if (!success) 9971 return false; 9972 9973 uint32_t result = val1 & imm32; 9974 9975 EmulateInstruction::Context context; 9976 context.type = EmulateInstruction::eContextImmediate; 9977 context.SetNoArgs(); 9978 9979 if (!WriteFlags(context, result, carry)) 9980 return false; 9981 } 9982 return true; 9983 } 9984 9985 // Test (register) performs a bitwise AND operation on a register value and an 9986 // optionally-shifted register value. It updates the condition flags based on 9987 // the result, and discards the result. 9988 bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode, 9989 const ARMEncoding encoding) { 9990 #if 0 9991 // ARM pseudo code... 9992 if ConditionPassed() then 9993 EncodingSpecificOperations(); 9994 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9995 result = R[n] AND shifted; 9996 APSR.N = result<31>; 9997 APSR.Z = IsZeroBit(result); 9998 APSR.C = carry; 9999 // APSR.V unchanged 10000 #endif 10001 10002 bool success = false; 10003 10004 if (ConditionPassed(opcode)) { 10005 uint32_t Rn, Rm; 10006 ARM_ShifterType shift_t; 10007 uint32_t shift_n; // the shift applied to the value read from Rm 10008 uint32_t carry; 10009 switch (encoding) { 10010 case eEncodingT1: 10011 Rn = Bits32(opcode, 2, 0); 10012 Rm = Bits32(opcode, 5, 3); 10013 shift_t = SRType_LSL; 10014 shift_n = 0; 10015 break; 10016 case eEncodingT2: 10017 Rn = Bits32(opcode, 19, 16); 10018 Rm = Bits32(opcode, 3, 0); 10019 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10020 if (BadReg(Rn) || BadReg(Rm)) 10021 return false; 10022 break; 10023 case eEncodingA1: 10024 Rn = Bits32(opcode, 19, 16); 10025 Rm = Bits32(opcode, 3, 0); 10026 shift_n = DecodeImmShiftARM(opcode, shift_t); 10027 break; 10028 default: 10029 return false; 10030 } 10031 10032 // Read the first operand. 10033 uint32_t val1 = ReadCoreReg(Rn, &success); 10034 if (!success) 10035 return false; 10036 10037 // Read the second operand. 10038 uint32_t val2 = ReadCoreReg(Rm, &success); 10039 if (!success) 10040 return false; 10041 10042 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 10043 if (!success) 10044 return false; 10045 uint32_t result = val1 & shifted; 10046 10047 EmulateInstruction::Context context; 10048 context.type = EmulateInstruction::eContextImmediate; 10049 context.SetNoArgs(); 10050 10051 if (!WriteFlags(context, result, carry)) 10052 return false; 10053 } 10054 return true; 10055 } 10056 10057 // A8.6.216 SUB (SP minus register) 10058 bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode, 10059 const ARMEncoding encoding) { 10060 #if 0 10061 if ConditionPassed() then 10062 EncodingSpecificOperations(); 10063 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10064 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10065 if d == 15 then // Can only occur for ARM encoding 10066 ALUWritePC(result); // setflags is always FALSE here 10067 else 10068 R[d] = result; 10069 if setflags then 10070 APSR.N = result<31>; 10071 APSR.Z = IsZeroBit(result); 10072 APSR.C = carry; 10073 APSR.V = overflow; 10074 #endif 10075 10076 bool success = false; 10077 10078 if (ConditionPassed(opcode)) { 10079 uint32_t d; 10080 uint32_t m; 10081 bool setflags; 10082 ARM_ShifterType shift_t; 10083 uint32_t shift_n; 10084 10085 switch (encoding) { 10086 case eEncodingT1: 10087 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10088 d = Bits32(opcode, 11, 8); 10089 m = Bits32(opcode, 3, 0); 10090 setflags = BitIsSet(opcode, 20); 10091 10092 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10093 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10094 10095 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then 10096 // UNPREDICTABLE; 10097 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 10098 return false; 10099 10100 // if d == 15 || BadReg(m) then UNPREDICTABLE; 10101 if ((d == 15) || BadReg(m)) 10102 return false; 10103 break; 10104 10105 case eEncodingA1: 10106 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10107 d = Bits32(opcode, 15, 12); 10108 m = Bits32(opcode, 3, 0); 10109 setflags = BitIsSet(opcode, 20); 10110 10111 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10112 // instructions; 10113 if (d == 15 && setflags) 10114 EmulateSUBSPcLrEtc(opcode, encoding); 10115 10116 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10117 shift_n = DecodeImmShiftARM(opcode, shift_t); 10118 break; 10119 10120 default: 10121 return false; 10122 } 10123 10124 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10125 uint32_t Rm = ReadCoreReg(m, &success); 10126 if (!success) 10127 return false; 10128 10129 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10130 if (!success) 10131 return false; 10132 10133 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10134 uint32_t sp_val = ReadCoreReg(SP_REG, &success); 10135 if (!success) 10136 return false; 10137 10138 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1); 10139 10140 EmulateInstruction::Context context; 10141 context.type = eContextArithmetic; 10142 RegisterInfo sp_reg; 10143 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 10144 RegisterInfo dwarf_reg; 10145 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 10146 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg); 10147 10148 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10149 res.carry_out, res.overflow)) 10150 return false; 10151 } 10152 return true; 10153 } 10154 10155 // A8.6.7 ADD (register-shifted register) 10156 bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode, 10157 const ARMEncoding encoding) { 10158 #if 0 10159 if ConditionPassed() then 10160 EncodingSpecificOperations(); 10161 shift_n = UInt(R[s]<7:0>); 10162 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10163 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10164 R[d] = result; 10165 if setflags then 10166 APSR.N = result<31>; 10167 APSR.Z = IsZeroBit(result); 10168 APSR.C = carry; 10169 APSR.V = overflow; 10170 #endif 10171 10172 bool success = false; 10173 10174 if (ConditionPassed(opcode)) { 10175 uint32_t d; 10176 uint32_t n; 10177 uint32_t m; 10178 uint32_t s; 10179 bool setflags; 10180 ARM_ShifterType shift_t; 10181 10182 switch (encoding) { 10183 case eEncodingA1: 10184 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 10185 d = Bits32(opcode, 15, 12); 10186 n = Bits32(opcode, 19, 16); 10187 m = Bits32(opcode, 3, 0); 10188 s = Bits32(opcode, 11, 8); 10189 10190 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 10191 setflags = BitIsSet(opcode, 20); 10192 shift_t = DecodeRegShift(Bits32(opcode, 6, 5)); 10193 10194 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 10195 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 10196 return false; 10197 break; 10198 10199 default: 10200 return false; 10201 } 10202 10203 // shift_n = UInt(R[s]<7:0>); 10204 uint32_t Rs = ReadCoreReg(s, &success); 10205 if (!success) 10206 return false; 10207 10208 uint32_t shift_n = Bits32(Rs, 7, 0); 10209 10210 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10211 uint32_t Rm = ReadCoreReg(m, &success); 10212 if (!success) 10213 return false; 10214 10215 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10216 if (!success) 10217 return false; 10218 10219 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10220 uint32_t Rn = ReadCoreReg(n, &success); 10221 if (!success) 10222 return false; 10223 10224 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0); 10225 10226 // R[d] = result; 10227 EmulateInstruction::Context context; 10228 context.type = eContextArithmetic; 10229 RegisterInfo reg_n; 10230 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10231 RegisterInfo reg_m; 10232 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10233 10234 context.SetRegisterRegisterOperands(reg_n, reg_m); 10235 10236 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 10237 res.result)) 10238 return false; 10239 10240 // if setflags then 10241 // APSR.N = result<31>; 10242 // APSR.Z = IsZeroBit(result); 10243 // APSR.C = carry; 10244 // APSR.V = overflow; 10245 if (setflags) 10246 return WriteFlags(context, res.result, res.carry_out, res.overflow); 10247 } 10248 return true; 10249 } 10250 10251 // A8.6.213 SUB (register) 10252 bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode, 10253 const ARMEncoding encoding) { 10254 #if 0 10255 if ConditionPassed() then 10256 EncodingSpecificOperations(); 10257 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10258 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10259 if d == 15 then // Can only occur for ARM encoding 10260 ALUWritePC(result); // setflags is always FALSE here 10261 else 10262 R[d] = result; 10263 if setflags then 10264 APSR.N = result<31>; 10265 APSR.Z = IsZeroBit(result); 10266 APSR.C = carry; 10267 APSR.V = overflow; 10268 #endif 10269 10270 bool success = false; 10271 10272 if (ConditionPassed(opcode)) { 10273 uint32_t d; 10274 uint32_t n; 10275 uint32_t m; 10276 bool setflags; 10277 ARM_ShifterType shift_t; 10278 uint32_t shift_n; 10279 10280 switch (encoding) { 10281 case eEncodingT1: 10282 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 10283 d = Bits32(opcode, 2, 0); 10284 n = Bits32(opcode, 5, 3); 10285 m = Bits32(opcode, 8, 6); 10286 setflags = !InITBlock(); 10287 10288 // (shift_t, shift_n) = (SRType_LSL, 0); 10289 shift_t = SRType_LSL; 10290 shift_n = 0; 10291 10292 break; 10293 10294 case eEncodingT2: 10295 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 10296 d = Bits32(opcode, 11, 8); 10297 n = Bits32(opcode, 19, 16); 10298 m = Bits32(opcode, 3, 0); 10299 setflags = BitIsSet(opcode, 20); 10300 10301 // if Rd == "1111" && S == "1" then SEE CMP (register); 10302 if (d == 15 && setflags == 1) 10303 return EmulateCMPImm(opcode, eEncodingT3); 10304 10305 // if Rn == "1101" then SEE SUB (SP minus register); 10306 if (n == 13) 10307 return EmulateSUBSPReg(opcode, eEncodingT1); 10308 10309 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10310 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10311 10312 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then 10313 // UNPREDICTABLE; 10314 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) || 10315 BadReg(m)) 10316 return false; 10317 10318 break; 10319 10320 case eEncodingA1: 10321 // if Rn == '1101' then SEE SUB (SP minus register); 10322 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 10323 d = Bits32(opcode, 15, 12); 10324 n = Bits32(opcode, 19, 16); 10325 m = Bits32(opcode, 3, 0); 10326 setflags = BitIsSet(opcode, 20); 10327 10328 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10329 // instructions; 10330 if ((d == 15) && setflags) 10331 EmulateSUBSPcLrEtc(opcode, encoding); 10332 10333 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10334 shift_n = DecodeImmShiftARM(opcode, shift_t); 10335 10336 break; 10337 10338 default: 10339 return false; 10340 } 10341 10342 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10343 uint32_t Rm = ReadCoreReg(m, &success); 10344 if (!success) 10345 return false; 10346 10347 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10348 if (!success) 10349 return false; 10350 10351 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10352 uint32_t Rn = ReadCoreReg(n, &success); 10353 if (!success) 10354 return false; 10355 10356 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1); 10357 10358 // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result); 10359 // // setflags is always FALSE here else 10360 // R[d] = result; 10361 // if setflags then 10362 // APSR.N = result<31>; 10363 // APSR.Z = IsZeroBit(result); 10364 // APSR.C = carry; 10365 // APSR.V = overflow; 10366 10367 EmulateInstruction::Context context; 10368 context.type = eContextArithmetic; 10369 RegisterInfo reg_n; 10370 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10371 RegisterInfo reg_m; 10372 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10373 context.SetRegisterRegisterOperands(reg_n, reg_m); 10374 10375 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10376 res.carry_out, res.overflow)) 10377 return false; 10378 } 10379 return true; 10380 } 10381 10382 // A8.6.202 STREX 10383 // Store Register Exclusive calculates an address from a base register value 10384 // and an immediate offset, and stores a word from a register to memory if the 10385 // executing processor has exclusive access to the memory addressed. 10386 bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode, 10387 const ARMEncoding encoding) { 10388 #if 0 10389 if ConditionPassed() then 10390 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10391 address = R[n] + imm32; 10392 if ExclusiveMonitorsPass(address,4) then 10393 MemA[address,4] = R[t]; 10394 R[d] = 0; 10395 else 10396 R[d] = 1; 10397 #endif 10398 10399 bool success = false; 10400 10401 if (ConditionPassed(opcode)) { 10402 uint32_t d; 10403 uint32_t t; 10404 uint32_t n; 10405 uint32_t imm32; 10406 const uint32_t addr_byte_size = GetAddressByteSize(); 10407 10408 switch (encoding) { 10409 case eEncodingT1: 10410 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = 10411 // ZeroExtend(imm8:'00', 10412 // 32); 10413 d = Bits32(opcode, 11, 8); 10414 t = Bits32(opcode, 15, 12); 10415 n = Bits32(opcode, 19, 16); 10416 imm32 = Bits32(opcode, 7, 0) << 2; 10417 10418 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 10419 if (BadReg(d) || BadReg(t) || (n == 15)) 10420 return false; 10421 10422 // if d == n || d == t then UNPREDICTABLE; 10423 if ((d == n) || (d == t)) 10424 return false; 10425 10426 break; 10427 10428 case eEncodingA1: 10429 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero 10430 // offset 10431 d = Bits32(opcode, 15, 12); 10432 t = Bits32(opcode, 3, 0); 10433 n = Bits32(opcode, 19, 16); 10434 imm32 = 0; 10435 10436 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 10437 if ((d == 15) || (t == 15) || (n == 15)) 10438 return false; 10439 10440 // if d == n || d == t then UNPREDICTABLE; 10441 if ((d == n) || (d == t)) 10442 return false; 10443 10444 break; 10445 10446 default: 10447 return false; 10448 } 10449 10450 // address = R[n] + imm32; 10451 uint32_t Rn = ReadCoreReg(n, &success); 10452 if (!success) 10453 return false; 10454 10455 addr_t address = Rn + imm32; 10456 10457 RegisterInfo base_reg; 10458 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10459 RegisterInfo data_reg; 10460 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10461 EmulateInstruction::Context context; 10462 context.type = eContextRegisterStore; 10463 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32); 10464 10465 // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass 10466 // (address, addr_byte_size)) -- For now, for the sake of emulation, we 10467 // will say this 10468 // always return 10469 // true. 10470 if (true) { 10471 // MemA[address,4] = R[t]; 10472 uint32_t Rt = 10473 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 10474 if (!success) 10475 return false; 10476 10477 if (!MemAWrite(context, address, Rt, addr_byte_size)) 10478 return false; 10479 10480 // R[d] = 0; 10481 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 10482 return false; 10483 } 10484 #if 0 // unreachable because if true 10485 else 10486 { 10487 // R[d] = 1; 10488 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 10489 return false; 10490 } 10491 #endif // unreachable because if true 10492 } 10493 return true; 10494 } 10495 10496 // A8.6.197 STRB (immediate, ARM) 10497 bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode, 10498 const ARMEncoding encoding) { 10499 #if 0 10500 if ConditionPassed() then 10501 EncodingSpecificOperations(); 10502 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10503 address = if index then offset_addr else R[n]; 10504 MemU[address,1] = R[t]<7:0>; 10505 if wback then R[n] = offset_addr; 10506 #endif 10507 10508 bool success = false; 10509 10510 if (ConditionPassed(opcode)) { 10511 uint32_t t; 10512 uint32_t n; 10513 uint32_t imm32; 10514 bool index; 10515 bool add; 10516 bool wback; 10517 10518 switch (encoding) { 10519 case eEncodingA1: 10520 // if P == '0' && W == '1' then SEE STRBT; 10521 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10522 t = Bits32(opcode, 15, 12); 10523 n = Bits32(opcode, 19, 16); 10524 imm32 = Bits32(opcode, 11, 0); 10525 10526 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10527 index = BitIsSet(opcode, 24); 10528 add = BitIsSet(opcode, 23); 10529 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10530 10531 // if t == 15 then UNPREDICTABLE; 10532 if (t == 15) 10533 return false; 10534 10535 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10536 if (wback && ((n == 15) || (n == t))) 10537 return false; 10538 10539 break; 10540 10541 default: 10542 return false; 10543 } 10544 10545 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10546 uint32_t Rn = ReadCoreReg(n, &success); 10547 if (!success) 10548 return false; 10549 10550 addr_t offset_addr; 10551 if (add) 10552 offset_addr = Rn + imm32; 10553 else 10554 offset_addr = Rn - imm32; 10555 10556 // address = if index then offset_addr else R[n]; 10557 addr_t address; 10558 if (index) 10559 address = offset_addr; 10560 else 10561 address = Rn; 10562 10563 // MemU[address,1] = R[t]<7:0>; 10564 uint32_t Rt = ReadCoreReg(t, &success); 10565 if (!success) 10566 return false; 10567 10568 RegisterInfo base_reg; 10569 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10570 RegisterInfo data_reg; 10571 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10572 EmulateInstruction::Context context; 10573 context.type = eContextRegisterStore; 10574 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10575 10576 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1)) 10577 return false; 10578 10579 // if wback then R[n] = offset_addr; 10580 if (wback) { 10581 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10582 offset_addr)) 10583 return false; 10584 } 10585 } 10586 return true; 10587 } 10588 10589 // A8.6.194 STR (immediate, ARM) 10590 bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode, 10591 const ARMEncoding encoding) { 10592 #if 0 10593 if ConditionPassed() then 10594 EncodingSpecificOperations(); 10595 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10596 address = if index then offset_addr else R[n]; 10597 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10598 if wback then R[n] = offset_addr; 10599 #endif 10600 10601 bool success = false; 10602 10603 if (ConditionPassed(opcode)) { 10604 uint32_t t; 10605 uint32_t n; 10606 uint32_t imm32; 10607 bool index; 10608 bool add; 10609 bool wback; 10610 10611 const uint32_t addr_byte_size = GetAddressByteSize(); 10612 10613 switch (encoding) { 10614 case eEncodingA1: 10615 // if P == '0' && W == '1' then SEE STRT; 10616 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == 10617 // '000000000100' then SEE PUSH; 10618 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10619 t = Bits32(opcode, 15, 12); 10620 n = Bits32(opcode, 19, 16); 10621 imm32 = Bits32(opcode, 11, 0); 10622 10623 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10624 index = BitIsSet(opcode, 24); 10625 add = BitIsSet(opcode, 23); 10626 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10627 10628 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10629 if (wback && ((n == 15) || (n == t))) 10630 return false; 10631 10632 break; 10633 10634 default: 10635 return false; 10636 } 10637 10638 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10639 uint32_t Rn = ReadCoreReg(n, &success); 10640 if (!success) 10641 return false; 10642 10643 addr_t offset_addr; 10644 if (add) 10645 offset_addr = Rn + imm32; 10646 else 10647 offset_addr = Rn - imm32; 10648 10649 // address = if index then offset_addr else R[n]; 10650 addr_t address; 10651 if (index) 10652 address = offset_addr; 10653 else 10654 address = Rn; 10655 10656 RegisterInfo base_reg; 10657 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10658 RegisterInfo data_reg; 10659 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10660 EmulateInstruction::Context context; 10661 context.type = eContextRegisterStore; 10662 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10663 10664 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10665 uint32_t Rt = ReadCoreReg(t, &success); 10666 if (!success) 10667 return false; 10668 10669 if (t == 15) { 10670 uint32_t pc_value = ReadCoreReg(PC_REG, &success); 10671 if (!success) 10672 return false; 10673 10674 if (!MemUWrite(context, address, pc_value, addr_byte_size)) 10675 return false; 10676 } else { 10677 if (!MemUWrite(context, address, Rt, addr_byte_size)) 10678 return false; 10679 } 10680 10681 // if wback then R[n] = offset_addr; 10682 if (wback) { 10683 context.type = eContextAdjustBaseRegister; 10684 context.SetImmediate(offset_addr); 10685 10686 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10687 offset_addr)) 10688 return false; 10689 } 10690 } 10691 return true; 10692 } 10693 10694 // A8.6.66 LDRD (immediate) 10695 // Load Register Dual (immediate) calculates an address from a base register 10696 // value and an immediate offset, loads two words from memory, and writes them 10697 // to two registers. It can use offset, post-indexed, or pre-indexed 10698 // addressing. 10699 bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode, 10700 const ARMEncoding encoding) { 10701 #if 0 10702 if ConditionPassed() then 10703 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10704 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10705 address = if index then offset_addr else R[n]; 10706 R[t] = MemA[address,4]; 10707 R[t2] = MemA[address+4,4]; 10708 if wback then R[n] = offset_addr; 10709 #endif 10710 10711 bool success = false; 10712 10713 if (ConditionPassed(opcode)) { 10714 uint32_t t; 10715 uint32_t t2; 10716 uint32_t n; 10717 uint32_t imm32; 10718 bool index; 10719 bool add; 10720 bool wback; 10721 10722 switch (encoding) { 10723 case eEncodingT1: 10724 // if P == '0' && W == '0' then SEE 'Related encodings'; 10725 // if Rn == '1111' then SEE LDRD (literal); 10726 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10727 // ZeroExtend(imm8:'00', 32); 10728 t = Bits32(opcode, 15, 12); 10729 t2 = Bits32(opcode, 11, 8); 10730 n = Bits32(opcode, 19, 16); 10731 imm32 = Bits32(opcode, 7, 0) << 2; 10732 10733 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10734 index = BitIsSet(opcode, 24); 10735 add = BitIsSet(opcode, 23); 10736 wback = BitIsSet(opcode, 21); 10737 10738 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10739 if (wback && ((n == t) || (n == t2))) 10740 return false; 10741 10742 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10743 if (BadReg(t) || BadReg(t2) || (t == t2)) 10744 return false; 10745 10746 break; 10747 10748 case eEncodingA1: 10749 // if Rn == '1111' then SEE LDRD (literal); 10750 // if Rt<0> == '1' then UNPREDICTABLE; 10751 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10752 // 32); 10753 t = Bits32(opcode, 15, 12); 10754 if (BitIsSet(t, 0)) 10755 return false; 10756 t2 = t + 1; 10757 n = Bits32(opcode, 19, 16); 10758 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10759 10760 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10761 index = BitIsSet(opcode, 24); 10762 add = BitIsSet(opcode, 23); 10763 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10764 10765 // if P == '0' && W == '1' then UNPREDICTABLE; 10766 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10767 return false; 10768 10769 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10770 if (wback && ((n == t) || (n == t2))) 10771 return false; 10772 10773 // if t2 == 15 then UNPREDICTABLE; 10774 if (t2 == 15) 10775 return false; 10776 10777 break; 10778 10779 default: 10780 return false; 10781 } 10782 10783 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10784 uint32_t Rn = ReadCoreReg(n, &success); 10785 if (!success) 10786 return false; 10787 10788 addr_t offset_addr; 10789 if (add) 10790 offset_addr = Rn + imm32; 10791 else 10792 offset_addr = Rn - imm32; 10793 10794 // address = if index then offset_addr else R[n]; 10795 addr_t address; 10796 if (index) 10797 address = offset_addr; 10798 else 10799 address = Rn; 10800 10801 // R[t] = MemA[address,4]; 10802 RegisterInfo base_reg; 10803 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10804 10805 EmulateInstruction::Context context; 10806 if (n == 13) 10807 context.type = eContextPopRegisterOffStack; 10808 else 10809 context.type = eContextRegisterLoad; 10810 context.SetAddress(address); 10811 10812 const uint32_t addr_byte_size = GetAddressByteSize(); 10813 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10814 if (!success) 10815 return false; 10816 10817 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10818 return false; 10819 10820 // R[t2] = MemA[address+4,4]; 10821 context.SetAddress(address + 4); 10822 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10823 if (!success) 10824 return false; 10825 10826 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10827 data)) 10828 return false; 10829 10830 // if wback then R[n] = offset_addr; 10831 if (wback) { 10832 context.type = eContextAdjustBaseRegister; 10833 context.SetAddress(offset_addr); 10834 10835 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10836 offset_addr)) 10837 return false; 10838 } 10839 } 10840 return true; 10841 } 10842 10843 // A8.6.68 LDRD (register) 10844 // Load Register Dual (register) calculates an address from a base register 10845 // value and a register offset, loads two words from memory, and writes them to 10846 // two registers. It can use offset, post-indexed or pre-indexed addressing. 10847 bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode, 10848 const ARMEncoding encoding) { 10849 #if 0 10850 if ConditionPassed() then 10851 EncodingSpecificOperations(); 10852 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10853 address = if index then offset_addr else R[n]; 10854 R[t] = MemA[address,4]; 10855 R[t2] = MemA[address+4,4]; 10856 if wback then R[n] = offset_addr; 10857 #endif 10858 10859 bool success = false; 10860 10861 if (ConditionPassed(opcode)) { 10862 uint32_t t; 10863 uint32_t t2; 10864 uint32_t n; 10865 uint32_t m; 10866 bool index; 10867 bool add; 10868 bool wback; 10869 10870 switch (encoding) { 10871 case eEncodingA1: 10872 // if Rt<0> == '1' then UNPREDICTABLE; 10873 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10874 t = Bits32(opcode, 15, 12); 10875 if (BitIsSet(t, 0)) 10876 return false; 10877 t2 = t + 1; 10878 n = Bits32(opcode, 19, 16); 10879 m = Bits32(opcode, 3, 0); 10880 10881 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10882 index = BitIsSet(opcode, 24); 10883 add = BitIsSet(opcode, 23); 10884 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10885 10886 // if P == '0' && W == '1' then UNPREDICTABLE; 10887 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10888 return false; 10889 10890 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10891 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10892 return false; 10893 10894 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10895 if (wback && ((n == 15) || (n == t) || (n == t2))) 10896 return false; 10897 10898 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10899 if ((ArchVersion() < 6) && wback && (m == n)) 10900 return false; 10901 break; 10902 10903 default: 10904 return false; 10905 } 10906 10907 uint32_t Rn = ReadCoreReg(n, &success); 10908 if (!success) 10909 return false; 10910 RegisterInfo base_reg; 10911 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10912 10913 uint32_t Rm = ReadCoreReg(m, &success); 10914 if (!success) 10915 return false; 10916 RegisterInfo offset_reg; 10917 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10918 10919 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10920 addr_t offset_addr; 10921 if (add) 10922 offset_addr = Rn + Rm; 10923 else 10924 offset_addr = Rn - Rm; 10925 10926 // address = if index then offset_addr else R[n]; 10927 addr_t address; 10928 if (index) 10929 address = offset_addr; 10930 else 10931 address = Rn; 10932 10933 EmulateInstruction::Context context; 10934 if (n == 13) 10935 context.type = eContextPopRegisterOffStack; 10936 else 10937 context.type = eContextRegisterLoad; 10938 context.SetAddress(address); 10939 10940 // R[t] = MemA[address,4]; 10941 const uint32_t addr_byte_size = GetAddressByteSize(); 10942 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10943 if (!success) 10944 return false; 10945 10946 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10947 return false; 10948 10949 // R[t2] = MemA[address+4,4]; 10950 10951 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10952 if (!success) 10953 return false; 10954 10955 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10956 data)) 10957 return false; 10958 10959 // if wback then R[n] = offset_addr; 10960 if (wback) { 10961 context.type = eContextAdjustBaseRegister; 10962 context.SetAddress(offset_addr); 10963 10964 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10965 offset_addr)) 10966 return false; 10967 } 10968 } 10969 return true; 10970 } 10971 10972 // A8.6.200 STRD (immediate) 10973 // Store Register Dual (immediate) calculates an address from a base register 10974 // value and an immediate offset, and stores two words from two registers to 10975 // memory. It can use offset, post-indexed, or pre-indexed addressing. 10976 bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode, 10977 const ARMEncoding encoding) { 10978 #if 0 10979 if ConditionPassed() then 10980 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10981 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10982 address = if index then offset_addr else R[n]; 10983 MemA[address,4] = R[t]; 10984 MemA[address+4,4] = R[t2]; 10985 if wback then R[n] = offset_addr; 10986 #endif 10987 10988 bool success = false; 10989 10990 if (ConditionPassed(opcode)) { 10991 uint32_t t; 10992 uint32_t t2; 10993 uint32_t n; 10994 uint32_t imm32; 10995 bool index; 10996 bool add; 10997 bool wback; 10998 10999 switch (encoding) { 11000 case eEncodingT1: 11001 // if P == '0' && W == '0' then SEE 'Related encodings'; 11002 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 11003 // ZeroExtend(imm8:'00', 32); 11004 t = Bits32(opcode, 15, 12); 11005 t2 = Bits32(opcode, 11, 8); 11006 n = Bits32(opcode, 19, 16); 11007 imm32 = Bits32(opcode, 7, 0) << 2; 11008 11009 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 11010 index = BitIsSet(opcode, 24); 11011 add = BitIsSet(opcode, 23); 11012 wback = BitIsSet(opcode, 21); 11013 11014 // if wback && (n == t || n == t2) then UNPREDICTABLE; 11015 if (wback && ((n == t) || (n == t2))) 11016 return false; 11017 11018 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 11019 if ((n == 15) || BadReg(t) || BadReg(t2)) 11020 return false; 11021 11022 break; 11023 11024 case eEncodingA1: 11025 // if Rt<0> == '1' then UNPREDICTABLE; 11026 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 11027 // 32); 11028 t = Bits32(opcode, 15, 12); 11029 if (BitIsSet(t, 0)) 11030 return false; 11031 11032 t2 = t + 1; 11033 n = Bits32(opcode, 19, 16); 11034 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 11035 11036 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11037 index = BitIsSet(opcode, 24); 11038 add = BitIsSet(opcode, 23); 11039 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11040 11041 // if P == '0' && W == '1' then UNPREDICTABLE; 11042 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11043 return false; 11044 11045 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11046 if (wback && ((n == 15) || (n == t) || (n == t2))) 11047 return false; 11048 11049 // if t2 == 15 then UNPREDICTABLE; 11050 if (t2 == 15) 11051 return false; 11052 11053 break; 11054 11055 default: 11056 return false; 11057 } 11058 11059 RegisterInfo base_reg; 11060 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11061 11062 uint32_t Rn = ReadCoreReg(n, &success); 11063 if (!success) 11064 return false; 11065 11066 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11067 addr_t offset_addr; 11068 if (add) 11069 offset_addr = Rn + imm32; 11070 else 11071 offset_addr = Rn - imm32; 11072 11073 // address = if index then offset_addr else R[n]; 11074 addr_t address; 11075 if (index) 11076 address = offset_addr; 11077 else 11078 address = Rn; 11079 11080 // MemA[address,4] = R[t]; 11081 RegisterInfo data_reg; 11082 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11083 11084 uint32_t data = ReadCoreReg(t, &success); 11085 if (!success) 11086 return false; 11087 11088 EmulateInstruction::Context context; 11089 if (n == 13) 11090 context.type = eContextPushRegisterOnStack; 11091 else 11092 context.type = eContextRegisterStore; 11093 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11094 11095 const uint32_t addr_byte_size = GetAddressByteSize(); 11096 11097 if (!MemAWrite(context, address, data, addr_byte_size)) 11098 return false; 11099 11100 // MemA[address+4,4] = R[t2]; 11101 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11102 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11103 (address + 4) - Rn); 11104 11105 data = ReadCoreReg(t2, &success); 11106 if (!success) 11107 return false; 11108 11109 if (!MemAWrite(context, address + 4, data, addr_byte_size)) 11110 return false; 11111 11112 // if wback then R[n] = offset_addr; 11113 if (wback) { 11114 if (n == 13) 11115 context.type = eContextAdjustStackPointer; 11116 else 11117 context.type = eContextAdjustBaseRegister; 11118 context.SetAddress(offset_addr); 11119 11120 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11121 offset_addr)) 11122 return false; 11123 } 11124 } 11125 return true; 11126 } 11127 11128 // A8.6.201 STRD (register) 11129 bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode, 11130 const ARMEncoding encoding) { 11131 #if 0 11132 if ConditionPassed() then 11133 EncodingSpecificOperations(); 11134 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11135 address = if index then offset_addr else R[n]; 11136 MemA[address,4] = R[t]; 11137 MemA[address+4,4] = R[t2]; 11138 if wback then R[n] = offset_addr; 11139 #endif 11140 11141 bool success = false; 11142 11143 if (ConditionPassed(opcode)) { 11144 uint32_t t; 11145 uint32_t t2; 11146 uint32_t n; 11147 uint32_t m; 11148 bool index; 11149 bool add; 11150 bool wback; 11151 11152 switch (encoding) { 11153 case eEncodingA1: 11154 // if Rt<0> == '1' then UNPREDICTABLE; 11155 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 11156 t = Bits32(opcode, 15, 12); 11157 if (BitIsSet(t, 0)) 11158 return false; 11159 11160 t2 = t + 1; 11161 n = Bits32(opcode, 19, 16); 11162 m = Bits32(opcode, 3, 0); 11163 11164 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11165 index = BitIsSet(opcode, 24); 11166 add = BitIsSet(opcode, 23); 11167 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11168 11169 // if P == '0' && W == '1' then UNPREDICTABLE; 11170 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11171 return false; 11172 11173 // if t2 == 15 || m == 15 then UNPREDICTABLE; 11174 if ((t2 == 15) || (m == 15)) 11175 return false; 11176 11177 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11178 if (wback && ((n == 15) || (n == t) || (n == t2))) 11179 return false; 11180 11181 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 11182 if ((ArchVersion() < 6) && wback && (m == n)) 11183 return false; 11184 11185 break; 11186 11187 default: 11188 return false; 11189 } 11190 11191 RegisterInfo base_reg; 11192 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11193 RegisterInfo offset_reg; 11194 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 11195 RegisterInfo data_reg; 11196 11197 uint32_t Rn = ReadCoreReg(n, &success); 11198 if (!success) 11199 return false; 11200 11201 uint32_t Rm = ReadCoreReg(m, &success); 11202 if (!success) 11203 return false; 11204 11205 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11206 addr_t offset_addr; 11207 if (add) 11208 offset_addr = Rn + Rm; 11209 else 11210 offset_addr = Rn - Rm; 11211 11212 // address = if index then offset_addr else R[n]; 11213 addr_t address; 11214 if (index) 11215 address = offset_addr; 11216 else 11217 address = Rn; 11218 // MemA[address,4] = R[t]; 11219 uint32_t Rt = ReadCoreReg(t, &success); 11220 if (!success) 11221 return false; 11222 11223 EmulateInstruction::Context context; 11224 if (t == 13) 11225 context.type = eContextPushRegisterOnStack; 11226 else 11227 context.type = eContextRegisterStore; 11228 11229 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11230 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11231 data_reg); 11232 11233 const uint32_t addr_byte_size = GetAddressByteSize(); 11234 11235 if (!MemAWrite(context, address, Rt, addr_byte_size)) 11236 return false; 11237 11238 // MemA[address+4,4] = R[t2]; 11239 uint32_t Rt2 = ReadCoreReg(t2, &success); 11240 if (!success) 11241 return false; 11242 11243 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11244 11245 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11246 data_reg); 11247 11248 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size)) 11249 return false; 11250 11251 // if wback then R[n] = offset_addr; 11252 if (wback) { 11253 context.type = eContextAdjustBaseRegister; 11254 context.SetAddress(offset_addr); 11255 11256 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11257 offset_addr)) 11258 return false; 11259 } 11260 } 11261 return true; 11262 } 11263 11264 // A8.6.319 VLDM 11265 // Vector Load Multiple loads multiple extension registers from consecutive 11266 // memory locations using an address from an ARM core register. 11267 bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode, 11268 const ARMEncoding encoding) { 11269 #if 0 11270 if ConditionPassed() then 11271 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11272 address = if add then R[n] else R[n]-imm32; 11273 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11274 for r = 0 to regs-1 11275 if single_regs then 11276 S[d+r] = MemA[address,4]; address = address+4; 11277 else 11278 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 11279 // Combine the word-aligned words in the correct order for 11280 // current endianness. 11281 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11282 #endif 11283 11284 bool success = false; 11285 11286 if (ConditionPassed(opcode)) { 11287 bool single_regs; 11288 bool add; 11289 bool wback; 11290 uint32_t d; 11291 uint32_t n; 11292 uint32_t imm32; 11293 uint32_t regs; 11294 11295 switch (encoding) { 11296 case eEncodingT1: 11297 case eEncodingA1: 11298 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11299 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11300 // if P == '1' && W == '0' then SEE VLDR; 11301 // if P == U && W == '1' then UNDEFINED; 11302 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11303 return false; 11304 11305 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11306 // !), 101 (DB with !) 11307 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11308 single_regs = false; 11309 add = BitIsSet(opcode, 23); 11310 wback = BitIsSet(opcode, 21); 11311 11312 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11313 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11314 n = Bits32(opcode, 19, 16); 11315 imm32 = Bits32(opcode, 7, 0) << 2; 11316 11317 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 11318 regs = Bits32(opcode, 7, 0) / 2; 11319 11320 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11321 // UNPREDICTABLE; 11322 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 11323 return false; 11324 11325 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11326 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11327 return false; 11328 11329 break; 11330 11331 case eEncodingT2: 11332 case eEncodingA2: 11333 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11334 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11335 // if P == '1' && W == '0' then SEE VLDR; 11336 // if P == U && W == '1' then UNDEFINED; 11337 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11338 return false; 11339 11340 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11341 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11342 // == '1'); d = 11343 // UInt(Vd:D); n = UInt(Rn); 11344 single_regs = true; 11345 add = BitIsSet(opcode, 23); 11346 wback = BitIsSet(opcode, 21); 11347 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11348 n = Bits32(opcode, 19, 16); 11349 11350 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11351 imm32 = Bits32(opcode, 7, 0) << 2; 11352 regs = Bits32(opcode, 7, 0); 11353 11354 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11355 // UNPREDICTABLE; 11356 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11357 return false; 11358 11359 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11360 if ((regs == 0) || ((d + regs) > 32)) 11361 return false; 11362 break; 11363 11364 default: 11365 return false; 11366 } 11367 11368 RegisterInfo base_reg; 11369 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11370 11371 uint32_t Rn = ReadCoreReg(n, &success); 11372 if (!success) 11373 return false; 11374 11375 // address = if add then R[n] else R[n]-imm32; 11376 addr_t address; 11377 if (add) 11378 address = Rn; 11379 else 11380 address = Rn - imm32; 11381 11382 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11383 EmulateInstruction::Context context; 11384 11385 if (wback) { 11386 uint32_t value; 11387 if (add) 11388 value = Rn + imm32; 11389 else 11390 value = Rn - imm32; 11391 11392 context.type = eContextAdjustBaseRegister; 11393 context.SetImmediateSigned(value - Rn); 11394 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11395 value)) 11396 return false; 11397 } 11398 11399 const uint32_t addr_byte_size = GetAddressByteSize(); 11400 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11401 11402 context.type = eContextRegisterLoad; 11403 11404 // for r = 0 to regs-1 11405 for (uint32_t r = 0; r < regs; ++r) { 11406 if (single_regs) { 11407 // S[d+r] = MemA[address,4]; address = address+4; 11408 context.SetRegisterPlusOffset(base_reg, address - Rn); 11409 11410 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11411 if (!success) 11412 return false; 11413 11414 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11415 start_reg + d + r, data)) 11416 return false; 11417 11418 address = address + 4; 11419 } else { 11420 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = 11421 // address+8; 11422 context.SetRegisterPlusOffset(base_reg, address - Rn); 11423 uint32_t word1 = 11424 MemARead(context, address, addr_byte_size, 0, &success); 11425 if (!success) 11426 return false; 11427 11428 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn); 11429 uint32_t word2 = 11430 MemARead(context, address + 4, addr_byte_size, 0, &success); 11431 if (!success) 11432 return false; 11433 11434 address = address + 8; 11435 // // Combine the word-aligned words in the correct order for current 11436 // endianness. 11437 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11438 uint64_t data; 11439 if (GetByteOrder() == eByteOrderBig) { 11440 data = word1; 11441 data = (data << 32) | word2; 11442 } else { 11443 data = word2; 11444 data = (data << 32) | word1; 11445 } 11446 11447 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11448 start_reg + d + r, data)) 11449 return false; 11450 } 11451 } 11452 } 11453 return true; 11454 } 11455 11456 // A8.6.399 VSTM 11457 // Vector Store Multiple stores multiple extension registers to consecutive 11458 // memory locations using an address from an 11459 // ARM core register. 11460 bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode, 11461 const ARMEncoding encoding) { 11462 #if 0 11463 if ConditionPassed() then 11464 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11465 address = if add then R[n] else R[n]-imm32; 11466 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11467 for r = 0 to regs-1 11468 if single_regs then 11469 MemA[address,4] = S[d+r]; address = address+4; 11470 else 11471 // Store as two word-aligned words in the correct order for 11472 // current endianness. 11473 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11474 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11475 address = address+8; 11476 #endif 11477 11478 bool success = false; 11479 11480 if (ConditionPassed(opcode)) { 11481 bool single_regs; 11482 bool add; 11483 bool wback; 11484 uint32_t d; 11485 uint32_t n; 11486 uint32_t imm32; 11487 uint32_t regs; 11488 11489 switch (encoding) { 11490 case eEncodingT1: 11491 case eEncodingA1: 11492 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11493 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11494 // if P == '1' && W == '0' then SEE VSTR; 11495 // if P == U && W == '1' then UNDEFINED; 11496 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11497 return false; 11498 11499 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11500 // !), 101 (DB with !) 11501 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11502 single_regs = false; 11503 add = BitIsSet(opcode, 23); 11504 wback = BitIsSet(opcode, 21); 11505 11506 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11507 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11508 n = Bits32(opcode, 19, 16); 11509 imm32 = Bits32(opcode, 7, 0) << 2; 11510 11511 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11512 regs = Bits32(opcode, 7, 0) / 2; 11513 11514 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11515 // UNPREDICTABLE; 11516 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11517 return false; 11518 11519 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11520 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11521 return false; 11522 11523 break; 11524 11525 case eEncodingT2: 11526 case eEncodingA2: 11527 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11528 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11529 // if P == '1' && W == '0' then SEE VSTR; 11530 // if P == U && W == '1' then UNDEFINED; 11531 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11532 return false; 11533 11534 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11535 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11536 // == '1'); d = 11537 // UInt(Vd:D); n = UInt(Rn); 11538 single_regs = true; 11539 add = BitIsSet(opcode, 23); 11540 wback = BitIsSet(opcode, 21); 11541 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11542 n = Bits32(opcode, 19, 16); 11543 11544 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11545 imm32 = Bits32(opcode, 7, 0) << 2; 11546 regs = Bits32(opcode, 7, 0); 11547 11548 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11549 // UNPREDICTABLE; 11550 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11551 return false; 11552 11553 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11554 if ((regs == 0) || ((d + regs) > 32)) 11555 return false; 11556 11557 break; 11558 11559 default: 11560 return false; 11561 } 11562 11563 RegisterInfo base_reg; 11564 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11565 11566 uint32_t Rn = ReadCoreReg(n, &success); 11567 if (!success) 11568 return false; 11569 11570 // address = if add then R[n] else R[n]-imm32; 11571 addr_t address; 11572 if (add) 11573 address = Rn; 11574 else 11575 address = Rn - imm32; 11576 11577 EmulateInstruction::Context context; 11578 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11579 if (wback) { 11580 uint32_t value; 11581 if (add) 11582 value = Rn + imm32; 11583 else 11584 value = Rn - imm32; 11585 11586 context.type = eContextAdjustBaseRegister; 11587 context.SetRegisterPlusOffset(base_reg, value - Rn); 11588 11589 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11590 value)) 11591 return false; 11592 } 11593 11594 const uint32_t addr_byte_size = GetAddressByteSize(); 11595 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11596 11597 context.type = eContextRegisterStore; 11598 // for r = 0 to regs-1 11599 for (uint32_t r = 0; r < regs; ++r) { 11600 11601 if (single_regs) { 11602 // MemA[address,4] = S[d+r]; address = address+4; 11603 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11604 start_reg + d + r, 0, &success); 11605 if (!success) 11606 return false; 11607 11608 RegisterInfo data_reg; 11609 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11610 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11611 address - Rn); 11612 if (!MemAWrite(context, address, data, addr_byte_size)) 11613 return false; 11614 11615 address = address + 4; 11616 } else { 11617 // // Store as two word-aligned words in the correct order for current 11618 // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else 11619 // D[d+r]<31:0>; 11620 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else 11621 // D[d+r]<63:32>; 11622 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11623 start_reg + d + r, 0, &success); 11624 if (!success) 11625 return false; 11626 11627 RegisterInfo data_reg; 11628 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11629 11630 if (GetByteOrder() == eByteOrderBig) { 11631 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11632 address - Rn); 11633 if (!MemAWrite(context, address, Bits64(data, 63, 32), 11634 addr_byte_size)) 11635 return false; 11636 11637 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11638 (address + 4) - Rn); 11639 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11640 addr_byte_size)) 11641 return false; 11642 } else { 11643 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11644 address - Rn); 11645 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11646 return false; 11647 11648 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11649 (address + 4) - Rn); 11650 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11651 addr_byte_size)) 11652 return false; 11653 } 11654 // address = address+8; 11655 address = address + 8; 11656 } 11657 } 11658 } 11659 return true; 11660 } 11661 11662 // A8.6.320 11663 // This instruction loads a single extension register from memory, using an 11664 // address from an ARM core register, with an optional offset. 11665 bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode, 11666 ARMEncoding encoding) { 11667 #if 0 11668 if ConditionPassed() then 11669 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11670 base = if n == 15 then Align(PC,4) else R[n]; 11671 address = if add then (base + imm32) else (base - imm32); 11672 if single_reg then 11673 S[d] = MemA[address,4]; 11674 else 11675 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11676 // Combine the word-aligned words in the correct order for current 11677 // endianness. 11678 D[d] = if BigEndian() then word1:word2 else word2:word1; 11679 #endif 11680 11681 bool success = false; 11682 11683 if (ConditionPassed(opcode)) { 11684 bool single_reg; 11685 bool add; 11686 uint32_t imm32; 11687 uint32_t d; 11688 uint32_t n; 11689 11690 switch (encoding) { 11691 case eEncodingT1: 11692 case eEncodingA1: 11693 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11694 // 32); 11695 single_reg = false; 11696 add = BitIsSet(opcode, 23); 11697 imm32 = Bits32(opcode, 7, 0) << 2; 11698 11699 // d = UInt(D:Vd); n = UInt(Rn); 11700 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11701 n = Bits32(opcode, 19, 16); 11702 11703 break; 11704 11705 case eEncodingT2: 11706 case eEncodingA2: 11707 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11708 single_reg = true; 11709 add = BitIsSet(opcode, 23); 11710 imm32 = Bits32(opcode, 7, 0) << 2; 11711 11712 // d = UInt(Vd:D); n = UInt(Rn); 11713 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11714 n = Bits32(opcode, 19, 16); 11715 11716 break; 11717 11718 default: 11719 return false; 11720 } 11721 RegisterInfo base_reg; 11722 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11723 11724 uint32_t Rn = ReadCoreReg(n, &success); 11725 if (!success) 11726 return false; 11727 11728 // base = if n == 15 then Align(PC,4) else R[n]; 11729 uint32_t base; 11730 if (n == 15) 11731 base = AlignPC(Rn); 11732 else 11733 base = Rn; 11734 11735 // address = if add then (base + imm32) else (base - imm32); 11736 addr_t address; 11737 if (add) 11738 address = base + imm32; 11739 else 11740 address = base - imm32; 11741 11742 const uint32_t addr_byte_size = GetAddressByteSize(); 11743 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11744 11745 EmulateInstruction::Context context; 11746 context.type = eContextRegisterLoad; 11747 context.SetRegisterPlusOffset(base_reg, address - base); 11748 11749 if (single_reg) { 11750 // S[d] = MemA[address,4]; 11751 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11752 if (!success) 11753 return false; 11754 11755 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11756 data)) 11757 return false; 11758 } else { 11759 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11760 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success); 11761 if (!success) 11762 return false; 11763 11764 context.SetRegisterPlusOffset(base_reg, (address + 4) - base); 11765 uint32_t word2 = 11766 MemARead(context, address + 4, addr_byte_size, 0, &success); 11767 if (!success) 11768 return false; 11769 // // Combine the word-aligned words in the correct order for current 11770 // endianness. 11771 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11772 uint64_t data64; 11773 if (GetByteOrder() == eByteOrderBig) { 11774 data64 = word1; 11775 data64 = (data64 << 32) | word2; 11776 } else { 11777 data64 = word2; 11778 data64 = (data64 << 32) | word1; 11779 } 11780 11781 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11782 data64)) 11783 return false; 11784 } 11785 } 11786 return true; 11787 } 11788 11789 // A8.6.400 VSTR 11790 // This instruction stores a signle extension register to memory, using an 11791 // address from an ARM core register, with an optional offset. 11792 bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode, 11793 ARMEncoding encoding) { 11794 #if 0 11795 if ConditionPassed() then 11796 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11797 address = if add then (R[n] + imm32) else (R[n] - imm32); 11798 if single_reg then 11799 MemA[address,4] = S[d]; 11800 else 11801 // Store as two word-aligned words in the correct order for current 11802 // endianness. 11803 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11804 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11805 #endif 11806 11807 bool success = false; 11808 11809 if (ConditionPassed(opcode)) { 11810 bool single_reg; 11811 bool add; 11812 uint32_t imm32; 11813 uint32_t d; 11814 uint32_t n; 11815 11816 switch (encoding) { 11817 case eEncodingT1: 11818 case eEncodingA1: 11819 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11820 // 32); 11821 single_reg = false; 11822 add = BitIsSet(opcode, 23); 11823 imm32 = Bits32(opcode, 7, 0) << 2; 11824 11825 // d = UInt(D:Vd); n = UInt(Rn); 11826 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11827 n = Bits32(opcode, 19, 16); 11828 11829 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11830 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11831 return false; 11832 11833 break; 11834 11835 case eEncodingT2: 11836 case eEncodingA2: 11837 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11838 single_reg = true; 11839 add = BitIsSet(opcode, 23); 11840 imm32 = Bits32(opcode, 7, 0) << 2; 11841 11842 // d = UInt(Vd:D); n = UInt(Rn); 11843 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11844 n = Bits32(opcode, 19, 16); 11845 11846 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11847 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11848 return false; 11849 11850 break; 11851 11852 default: 11853 return false; 11854 } 11855 11856 RegisterInfo base_reg; 11857 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11858 11859 uint32_t Rn = ReadCoreReg(n, &success); 11860 if (!success) 11861 return false; 11862 11863 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11864 addr_t address; 11865 if (add) 11866 address = Rn + imm32; 11867 else 11868 address = Rn - imm32; 11869 11870 const uint32_t addr_byte_size = GetAddressByteSize(); 11871 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11872 11873 RegisterInfo data_reg; 11874 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg); 11875 EmulateInstruction::Context context; 11876 context.type = eContextRegisterStore; 11877 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11878 11879 if (single_reg) { 11880 // MemA[address,4] = S[d]; 11881 uint32_t data = 11882 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11883 if (!success) 11884 return false; 11885 11886 if (!MemAWrite(context, address, data, addr_byte_size)) 11887 return false; 11888 } else { 11889 // // Store as two word-aligned words in the correct order for current 11890 // endianness. 11891 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11892 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11893 uint64_t data = 11894 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11895 if (!success) 11896 return false; 11897 11898 if (GetByteOrder() == eByteOrderBig) { 11899 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size)) 11900 return false; 11901 11902 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11903 (address + 4) - Rn); 11904 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11905 addr_byte_size)) 11906 return false; 11907 } else { 11908 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11909 return false; 11910 11911 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11912 (address + 4) - Rn); 11913 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11914 addr_byte_size)) 11915 return false; 11916 } 11917 } 11918 } 11919 return true; 11920 } 11921 11922 // A8.6.307 VLDI1 (multiple single elements) This instruction loads elements 11923 // from memory into one, two, three or four registers, without de-interleaving. 11924 // Every element of each register is loaded. 11925 bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode, 11926 ARMEncoding encoding) { 11927 #if 0 11928 if ConditionPassed() then 11929 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11930 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11931 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11932 for r = 0 to regs-1 11933 for e = 0 to elements-1 11934 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11935 address = address + ebytes; 11936 #endif 11937 11938 bool success = false; 11939 11940 if (ConditionPassed(opcode)) { 11941 uint32_t regs; 11942 uint32_t alignment; 11943 uint32_t ebytes; 11944 uint32_t esize; 11945 uint32_t elements; 11946 uint32_t d; 11947 uint32_t n; 11948 uint32_t m; 11949 bool wback; 11950 bool register_index; 11951 11952 switch (encoding) { 11953 case eEncodingT1: 11954 case eEncodingA1: { 11955 // case type of 11956 // when '0111' 11957 // regs = 1; if align<1> == '1' then UNDEFINED; 11958 // when '1010' 11959 // regs = 2; if align == '11' then UNDEFINED; 11960 // when '0110' 11961 // regs = 3; if align<1> == '1' then UNDEFINED; 11962 // when '0010' 11963 // regs = 4; 11964 // otherwise 11965 // SEE 'Related encodings'; 11966 uint32_t type = Bits32(opcode, 11, 8); 11967 uint32_t align = Bits32(opcode, 5, 4); 11968 if (type == 7) // '0111' 11969 { 11970 regs = 1; 11971 if (BitIsSet(align, 1)) 11972 return false; 11973 } else if (type == 10) // '1010' 11974 { 11975 regs = 2; 11976 if (align == 3) 11977 return false; 11978 11979 } else if (type == 6) // '0110' 11980 { 11981 regs = 3; 11982 if (BitIsSet(align, 1)) 11983 return false; 11984 } else if (type == 2) // '0010' 11985 { 11986 regs = 4; 11987 } else 11988 return false; 11989 11990 // alignment = if align == '00' then 1 else 4 << UInt(align); 11991 if (align == 0) 11992 alignment = 1; 11993 else 11994 alignment = 4 << align; 11995 11996 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11997 ebytes = 1 << Bits32(opcode, 7, 6); 11998 esize = 8 * ebytes; 11999 elements = 8 / ebytes; 12000 12001 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12002 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12003 n = Bits32(opcode, 19, 15); 12004 m = Bits32(opcode, 3, 0); 12005 12006 // wback = (m != 15); register_index = (m != 15 && m != 13); 12007 wback = (m != 15); 12008 register_index = ((m != 15) && (m != 13)); 12009 12010 // if d+regs > 32 then UNPREDICTABLE; 12011 if ((d + regs) > 32) 12012 return false; 12013 } break; 12014 12015 default: 12016 return false; 12017 } 12018 12019 RegisterInfo base_reg; 12020 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12021 12022 uint32_t Rn = ReadCoreReg(n, &success); 12023 if (!success) 12024 return false; 12025 12026 // address = R[n]; if (address MOD alignment) != 0 then 12027 // GenerateAlignmentException(); 12028 addr_t address = Rn; 12029 if ((address % alignment) != 0) 12030 return false; 12031 12032 EmulateInstruction::Context context; 12033 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12034 if (wback) { 12035 uint32_t Rm = ReadCoreReg(m, &success); 12036 if (!success) 12037 return false; 12038 12039 uint32_t offset; 12040 if (register_index) 12041 offset = Rm; 12042 else 12043 offset = 8 * regs; 12044 12045 uint32_t value = Rn + offset; 12046 context.type = eContextAdjustBaseRegister; 12047 context.SetRegisterPlusOffset(base_reg, offset); 12048 12049 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12050 value)) 12051 return false; 12052 } 12053 12054 // for r = 0 to regs-1 12055 for (uint32_t r = 0; r < regs; ++r) { 12056 // for e = 0 to elements-1 12057 uint64_t assembled_data = 0; 12058 for (uint32_t e = 0; e < elements; ++e) { 12059 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 12060 context.type = eContextRegisterLoad; 12061 context.SetRegisterPlusOffset(base_reg, address - Rn); 12062 uint64_t data = MemURead(context, address, ebytes, 0, &success); 12063 if (!success) 12064 return false; 12065 12066 assembled_data = 12067 (data << (e * esize)) | 12068 assembled_data; // New data goes to the left of existing data 12069 12070 // address = address + ebytes; 12071 address = address + ebytes; 12072 } 12073 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12074 assembled_data)) 12075 return false; 12076 } 12077 } 12078 return true; 12079 } 12080 12081 // A8.6.308 VLD1 (single element to one lane) 12082 // 12083 bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode, 12084 const ARMEncoding encoding) { 12085 #if 0 12086 if ConditionPassed() then 12087 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12088 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12089 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12090 Elem[D[d],index,esize] = MemU[address,ebytes]; 12091 #endif 12092 12093 bool success = false; 12094 12095 if (ConditionPassed(opcode)) { 12096 uint32_t ebytes; 12097 uint32_t esize; 12098 uint32_t index; 12099 uint32_t alignment; 12100 uint32_t d; 12101 uint32_t n; 12102 uint32_t m; 12103 bool wback; 12104 bool register_index; 12105 12106 switch (encoding) { 12107 case eEncodingT1: 12108 case eEncodingA1: { 12109 uint32_t size = Bits32(opcode, 11, 10); 12110 uint32_t index_align = Bits32(opcode, 7, 4); 12111 // if size == '11' then SEE VLD1 (single element to all lanes); 12112 if (size == 3) 12113 return EmulateVLD1SingleAll(opcode, encoding); 12114 // case size of 12115 if (size == 0) // when '00' 12116 { 12117 // if index_align<0> != '0' then UNDEFINED; 12118 if (BitIsClear(index_align, 0)) 12119 return false; 12120 12121 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12122 ebytes = 1; 12123 esize = 8; 12124 index = Bits32(index_align, 3, 1); 12125 alignment = 1; 12126 } else if (size == 1) // when '01' 12127 { 12128 // if index_align<1> != '0' then UNDEFINED; 12129 if (BitIsClear(index_align, 1)) 12130 return false; 12131 12132 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12133 ebytes = 2; 12134 esize = 16; 12135 index = Bits32(index_align, 3, 2); 12136 12137 // alignment = if index_align<0> == '0' then 1 else 2; 12138 if (BitIsClear(index_align, 0)) 12139 alignment = 1; 12140 else 12141 alignment = 2; 12142 } else if (size == 2) // when '10' 12143 { 12144 // if index_align<2> != '0' then UNDEFINED; 12145 if (BitIsClear(index_align, 2)) 12146 return false; 12147 12148 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12149 // UNDEFINED; 12150 if ((Bits32(index_align, 1, 0) != 0) && 12151 (Bits32(index_align, 1, 0) != 3)) 12152 return false; 12153 12154 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12155 ebytes = 4; 12156 esize = 32; 12157 index = Bit32(index_align, 3); 12158 12159 // alignment = if index_align<1:0> == '00' then 1 else 4; 12160 if (Bits32(index_align, 1, 0) == 0) 12161 alignment = 1; 12162 else 12163 alignment = 4; 12164 } else { 12165 return false; 12166 } 12167 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12168 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12169 n = Bits32(opcode, 19, 16); 12170 m = Bits32(opcode, 3, 0); 12171 12172 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12173 // then UNPREDICTABLE; 12174 wback = (m != 15); 12175 register_index = ((m != 15) && (m != 13)); 12176 12177 if (n == 15) 12178 return false; 12179 12180 } break; 12181 12182 default: 12183 return false; 12184 } 12185 12186 RegisterInfo base_reg; 12187 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12188 12189 uint32_t Rn = ReadCoreReg(n, &success); 12190 if (!success) 12191 return false; 12192 12193 // address = R[n]; if (address MOD alignment) != 0 then 12194 // GenerateAlignmentException(); 12195 addr_t address = Rn; 12196 if ((address % alignment) != 0) 12197 return false; 12198 12199 EmulateInstruction::Context context; 12200 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12201 if (wback) { 12202 uint32_t Rm = ReadCoreReg(m, &success); 12203 if (!success) 12204 return false; 12205 12206 uint32_t offset; 12207 if (register_index) 12208 offset = Rm; 12209 else 12210 offset = ebytes; 12211 12212 uint32_t value = Rn + offset; 12213 12214 context.type = eContextAdjustBaseRegister; 12215 context.SetRegisterPlusOffset(base_reg, offset); 12216 12217 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12218 value)) 12219 return false; 12220 } 12221 12222 // Elem[D[d],index,esize] = MemU[address,ebytes]; 12223 uint32_t element = MemURead(context, address, esize, 0, &success); 12224 if (!success) 12225 return false; 12226 12227 element = element << (index * esize); 12228 12229 uint64_t reg_data = 12230 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12231 if (!success) 12232 return false; 12233 12234 uint64_t all_ones = -1; 12235 uint64_t mask = all_ones 12236 << ((index + 1) * esize); // mask is all 1's to left of 12237 // where 'element' goes, & all 0's 12238 // at element & to the right of element. 12239 if (index > 0) 12240 mask = mask | Bits64(all_ones, (index * esize) - 1, 12241 0); // add 1's to the right of where 'element' goes. 12242 // now mask should be 0's where element goes & 1's everywhere else. 12243 12244 uint64_t masked_reg = 12245 reg_data & mask; // Take original reg value & zero out 'element' bits 12246 reg_data = 12247 masked_reg & element; // Put 'element' into those bits in reg_data. 12248 12249 context.type = eContextRegisterLoad; 12250 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 12251 reg_data)) 12252 return false; 12253 } 12254 return true; 12255 } 12256 12257 // A8.6.391 VST1 (multiple single elements) Vector Store (multiple single 12258 // elements) stores elements to memory from one, two, three, or four registers, 12259 // without interleaving. Every element of each register is stored. 12260 bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode, 12261 ARMEncoding encoding) { 12262 #if 0 12263 if ConditionPassed() then 12264 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12265 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12266 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12267 for r = 0 to regs-1 12268 for e = 0 to elements-1 12269 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12270 address = address + ebytes; 12271 #endif 12272 12273 bool success = false; 12274 12275 if (ConditionPassed(opcode)) { 12276 uint32_t regs; 12277 uint32_t alignment; 12278 uint32_t ebytes; 12279 uint32_t esize; 12280 uint32_t elements; 12281 uint32_t d; 12282 uint32_t n; 12283 uint32_t m; 12284 bool wback; 12285 bool register_index; 12286 12287 switch (encoding) { 12288 case eEncodingT1: 12289 case eEncodingA1: { 12290 uint32_t type = Bits32(opcode, 11, 8); 12291 uint32_t align = Bits32(opcode, 5, 4); 12292 12293 // case type of 12294 if (type == 7) // when '0111' 12295 { 12296 // regs = 1; if align<1> == '1' then UNDEFINED; 12297 regs = 1; 12298 if (BitIsSet(align, 1)) 12299 return false; 12300 } else if (type == 10) // when '1010' 12301 { 12302 // regs = 2; if align == '11' then UNDEFINED; 12303 regs = 2; 12304 if (align == 3) 12305 return false; 12306 } else if (type == 6) // when '0110' 12307 { 12308 // regs = 3; if align<1> == '1' then UNDEFINED; 12309 regs = 3; 12310 if (BitIsSet(align, 1)) 12311 return false; 12312 } else if (type == 2) // when '0010' 12313 // regs = 4; 12314 regs = 4; 12315 else // otherwise 12316 // SEE 'Related encodings'; 12317 return false; 12318 12319 // alignment = if align == '00' then 1 else 4 << UInt(align); 12320 if (align == 0) 12321 alignment = 1; 12322 else 12323 alignment = 4 << align; 12324 12325 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 12326 ebytes = 1 << Bits32(opcode, 7, 6); 12327 esize = 8 * ebytes; 12328 elements = 8 / ebytes; 12329 12330 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12331 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12332 n = Bits32(opcode, 19, 16); 12333 m = Bits32(opcode, 3, 0); 12334 12335 // wback = (m != 15); register_index = (m != 15 && m != 13); 12336 wback = (m != 15); 12337 register_index = ((m != 15) && (m != 13)); 12338 12339 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12340 if ((d + regs) > 32) 12341 return false; 12342 12343 if (n == 15) 12344 return false; 12345 12346 } break; 12347 12348 default: 12349 return false; 12350 } 12351 12352 RegisterInfo base_reg; 12353 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12354 12355 uint32_t Rn = ReadCoreReg(n, &success); 12356 if (!success) 12357 return false; 12358 12359 // address = R[n]; if (address MOD alignment) != 0 then 12360 // GenerateAlignmentException(); 12361 addr_t address = Rn; 12362 if ((address % alignment) != 0) 12363 return false; 12364 12365 EmulateInstruction::Context context; 12366 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12367 if (wback) { 12368 uint32_t Rm = ReadCoreReg(m, &success); 12369 if (!success) 12370 return false; 12371 12372 uint32_t offset; 12373 if (register_index) 12374 offset = Rm; 12375 else 12376 offset = 8 * regs; 12377 12378 context.type = eContextAdjustBaseRegister; 12379 context.SetRegisterPlusOffset(base_reg, offset); 12380 12381 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12382 Rn + offset)) 12383 return false; 12384 } 12385 12386 RegisterInfo data_reg; 12387 context.type = eContextRegisterStore; 12388 // for r = 0 to regs-1 12389 for (uint32_t r = 0; r < regs; ++r) { 12390 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 12391 uint64_t register_data = ReadRegisterUnsigned( 12392 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 12393 if (!success) 12394 return false; 12395 12396 // for e = 0 to elements-1 12397 for (uint32_t e = 0; e < elements; ++e) { 12398 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12399 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize); 12400 12401 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12402 address - Rn); 12403 if (!MemUWrite(context, address, word, ebytes)) 12404 return false; 12405 12406 // address = address + ebytes; 12407 address = address + ebytes; 12408 } 12409 } 12410 } 12411 return true; 12412 } 12413 12414 // A8.6.392 VST1 (single element from one lane) This instruction stores one 12415 // element to memory from one element of a register. 12416 bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode, 12417 ARMEncoding encoding) { 12418 #if 0 12419 if ConditionPassed() then 12420 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12421 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12422 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12423 MemU[address,ebytes] = Elem[D[d],index,esize]; 12424 #endif 12425 12426 bool success = false; 12427 12428 if (ConditionPassed(opcode)) { 12429 uint32_t ebytes; 12430 uint32_t esize; 12431 uint32_t index; 12432 uint32_t alignment; 12433 uint32_t d; 12434 uint32_t n; 12435 uint32_t m; 12436 bool wback; 12437 bool register_index; 12438 12439 switch (encoding) { 12440 case eEncodingT1: 12441 case eEncodingA1: { 12442 uint32_t size = Bits32(opcode, 11, 10); 12443 uint32_t index_align = Bits32(opcode, 7, 4); 12444 12445 // if size == '11' then UNDEFINED; 12446 if (size == 3) 12447 return false; 12448 12449 // case size of 12450 if (size == 0) // when '00' 12451 { 12452 // if index_align<0> != '0' then UNDEFINED; 12453 if (BitIsClear(index_align, 0)) 12454 return false; 12455 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12456 ebytes = 1; 12457 esize = 8; 12458 index = Bits32(index_align, 3, 1); 12459 alignment = 1; 12460 } else if (size == 1) // when '01' 12461 { 12462 // if index_align<1> != '0' then UNDEFINED; 12463 if (BitIsClear(index_align, 1)) 12464 return false; 12465 12466 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12467 ebytes = 2; 12468 esize = 16; 12469 index = Bits32(index_align, 3, 2); 12470 12471 // alignment = if index_align<0> == '0' then 1 else 2; 12472 if (BitIsClear(index_align, 0)) 12473 alignment = 1; 12474 else 12475 alignment = 2; 12476 } else if (size == 2) // when '10' 12477 { 12478 // if index_align<2> != '0' then UNDEFINED; 12479 if (BitIsClear(index_align, 2)) 12480 return false; 12481 12482 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12483 // UNDEFINED; 12484 if ((Bits32(index_align, 1, 0) != 0) && 12485 (Bits32(index_align, 1, 0) != 3)) 12486 return false; 12487 12488 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12489 ebytes = 4; 12490 esize = 32; 12491 index = Bit32(index_align, 3); 12492 12493 // alignment = if index_align<1:0> == '00' then 1 else 4; 12494 if (Bits32(index_align, 1, 0) == 0) 12495 alignment = 1; 12496 else 12497 alignment = 4; 12498 } else { 12499 return false; 12500 } 12501 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12502 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12503 n = Bits32(opcode, 19, 16); 12504 m = Bits32(opcode, 3, 0); 12505 12506 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12507 // then UNPREDICTABLE; 12508 wback = (m != 15); 12509 register_index = ((m != 15) && (m != 13)); 12510 12511 if (n == 15) 12512 return false; 12513 } break; 12514 12515 default: 12516 return false; 12517 } 12518 12519 RegisterInfo base_reg; 12520 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12521 12522 uint32_t Rn = ReadCoreReg(n, &success); 12523 if (!success) 12524 return false; 12525 12526 // address = R[n]; if (address MOD alignment) != 0 then 12527 // GenerateAlignmentException(); 12528 addr_t address = Rn; 12529 if ((address % alignment) != 0) 12530 return false; 12531 12532 EmulateInstruction::Context context; 12533 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12534 if (wback) { 12535 uint32_t Rm = ReadCoreReg(m, &success); 12536 if (!success) 12537 return false; 12538 12539 uint32_t offset; 12540 if (register_index) 12541 offset = Rm; 12542 else 12543 offset = ebytes; 12544 12545 context.type = eContextAdjustBaseRegister; 12546 context.SetRegisterPlusOffset(base_reg, offset); 12547 12548 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12549 Rn + offset)) 12550 return false; 12551 } 12552 12553 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12554 uint64_t register_data = 12555 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12556 if (!success) 12557 return false; 12558 12559 uint64_t word = 12560 Bits64(register_data, ((index + 1) * esize) - 1, index * esize); 12561 12562 RegisterInfo data_reg; 12563 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12564 context.type = eContextRegisterStore; 12565 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 12566 12567 if (!MemUWrite(context, address, word, ebytes)) 12568 return false; 12569 } 12570 return true; 12571 } 12572 12573 // A8.6.309 VLD1 (single element to all lanes) This instruction loads one 12574 // element from memory into every element of one or two vectors. 12575 bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode, 12576 const ARMEncoding encoding) { 12577 #if 0 12578 if ConditionPassed() then 12579 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12580 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12581 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12582 replicated_element = Replicate(MemU[address,ebytes], elements); 12583 for r = 0 to regs-1 12584 D[d+r] = replicated_element; 12585 #endif 12586 12587 bool success = false; 12588 12589 if (ConditionPassed(opcode)) { 12590 uint32_t ebytes; 12591 uint32_t elements; 12592 uint32_t regs; 12593 uint32_t alignment; 12594 uint32_t d; 12595 uint32_t n; 12596 uint32_t m; 12597 bool wback; 12598 bool register_index; 12599 12600 switch (encoding) { 12601 case eEncodingT1: 12602 case eEncodingA1: { 12603 // if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12604 uint32_t size = Bits32(opcode, 7, 6); 12605 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4))) 12606 return false; 12607 12608 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' 12609 // then 1 else 2; 12610 ebytes = 1 << size; 12611 elements = 8 / ebytes; 12612 if (BitIsClear(opcode, 5)) 12613 regs = 1; 12614 else 12615 regs = 2; 12616 12617 // alignment = if a == '0' then 1 else ebytes; 12618 if (BitIsClear(opcode, 4)) 12619 alignment = 1; 12620 else 12621 alignment = ebytes; 12622 12623 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12624 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12625 n = Bits32(opcode, 19, 16); 12626 m = Bits32(opcode, 3, 0); 12627 12628 // wback = (m != 15); register_index = (m != 15 && m != 13); 12629 wback = (m != 15); 12630 register_index = ((m != 15) && (m != 13)); 12631 12632 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12633 if ((d + regs) > 32) 12634 return false; 12635 12636 if (n == 15) 12637 return false; 12638 } break; 12639 12640 default: 12641 return false; 12642 } 12643 12644 RegisterInfo base_reg; 12645 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12646 12647 uint32_t Rn = ReadCoreReg(n, &success); 12648 if (!success) 12649 return false; 12650 12651 // address = R[n]; if (address MOD alignment) != 0 then 12652 // GenerateAlignmentException(); 12653 addr_t address = Rn; 12654 if ((address % alignment) != 0) 12655 return false; 12656 12657 EmulateInstruction::Context context; 12658 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12659 if (wback) { 12660 uint32_t Rm = ReadCoreReg(m, &success); 12661 if (!success) 12662 return false; 12663 12664 uint32_t offset; 12665 if (register_index) 12666 offset = Rm; 12667 else 12668 offset = ebytes; 12669 12670 context.type = eContextAdjustBaseRegister; 12671 context.SetRegisterPlusOffset(base_reg, offset); 12672 12673 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12674 Rn + offset)) 12675 return false; 12676 } 12677 12678 // replicated_element = Replicate(MemU[address,ebytes], elements); 12679 12680 context.type = eContextRegisterLoad; 12681 uint64_t word = MemURead(context, address, ebytes, 0, &success); 12682 if (!success) 12683 return false; 12684 12685 uint64_t replicated_element = 0; 12686 uint32_t esize = ebytes * 8; 12687 for (uint32_t e = 0; e < elements; ++e) 12688 replicated_element = 12689 (replicated_element << esize) | Bits64(word, esize - 1, 0); 12690 12691 // for r = 0 to regs-1 12692 for (uint32_t r = 0; r < regs; ++r) { 12693 // D[d+r] = replicated_element; 12694 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12695 replicated_element)) 12696 return false; 12697 } 12698 } 12699 return true; 12700 } 12701 12702 // B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const? 12703 // instruction provides an exception return without the use of the stack. It 12704 // subtracts the immediate constant from the LR, branches to the resulting 12705 // address, and also copies the SPSR to the CPSR. 12706 bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode, 12707 const ARMEncoding encoding) { 12708 #if 0 12709 if ConditionPassed() then 12710 EncodingSpecificOperations(); 12711 if CurrentInstrSet() == InstrSet_ThumbEE then 12712 UNPREDICTABLE; 12713 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12714 case opcode of 12715 when '0000' result = R[n] AND operand2; // AND 12716 when '0001' result = R[n] EOR operand2; // EOR 12717 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12718 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12719 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12720 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12721 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12722 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12723 when '1100' result = R[n] OR operand2; // ORR 12724 when '1101' result = operand2; // MOV 12725 when '1110' result = R[n] AND NOT(operand2); // BIC 12726 when '1111' result = NOT(operand2); // MVN 12727 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12728 BranchWritePC(result); 12729 #endif 12730 12731 bool success = false; 12732 12733 if (ConditionPassed(opcode)) { 12734 uint32_t n; 12735 uint32_t m; 12736 uint32_t imm32; 12737 bool register_form; 12738 ARM_ShifterType shift_t; 12739 uint32_t shift_n; 12740 uint32_t code; 12741 12742 switch (encoding) { 12743 case eEncodingT1: 12744 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14; 12745 // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; 12746 // // = SUB 12747 n = 14; 12748 imm32 = Bits32(opcode, 7, 0); 12749 register_form = false; 12750 code = 2; 12751 12752 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12753 if (InITBlock() && !LastInITBlock()) 12754 return false; 12755 12756 break; 12757 12758 case eEncodingA1: 12759 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12760 n = Bits32(opcode, 19, 16); 12761 imm32 = ARMExpandImm(opcode); 12762 register_form = false; 12763 code = Bits32(opcode, 24, 21); 12764 12765 break; 12766 12767 case eEncodingA2: 12768 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12769 n = Bits32(opcode, 19, 16); 12770 m = Bits32(opcode, 3, 0); 12771 register_form = true; 12772 12773 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12774 shift_n = DecodeImmShiftARM(opcode, shift_t); 12775 12776 break; 12777 12778 default: 12779 return false; 12780 } 12781 12782 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) 12783 // else imm32; 12784 uint32_t operand2; 12785 if (register_form) { 12786 uint32_t Rm = ReadCoreReg(m, &success); 12787 if (!success) 12788 return false; 12789 12790 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success); 12791 if (!success) 12792 return false; 12793 } else { 12794 operand2 = imm32; 12795 } 12796 12797 uint32_t Rn = ReadCoreReg(n, &success); 12798 if (!success) 12799 return false; 12800 12801 AddWithCarryResult result; 12802 12803 // case opcode of 12804 switch (code) { 12805 case 0: // when '0000' 12806 // result = R[n] AND operand2; // AND 12807 result.result = Rn & operand2; 12808 break; 12809 12810 case 1: // when '0001' 12811 // result = R[n] EOR operand2; // EOR 12812 result.result = Rn ^ operand2; 12813 break; 12814 12815 case 2: // when '0010' 12816 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12817 result = AddWithCarry(Rn, ~(operand2), 1); 12818 break; 12819 12820 case 3: // when '0011' 12821 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12822 result = AddWithCarry(~(Rn), operand2, 1); 12823 break; 12824 12825 case 4: // when '0100' 12826 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12827 result = AddWithCarry(Rn, operand2, 0); 12828 break; 12829 12830 case 5: // when '0101' 12831 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12832 result = AddWithCarry(Rn, operand2, APSR_C); 12833 break; 12834 12835 case 6: // when '0110' 12836 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12837 result = AddWithCarry(Rn, ~(operand2), APSR_C); 12838 break; 12839 12840 case 7: // when '0111' 12841 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12842 result = AddWithCarry(~(Rn), operand2, APSR_C); 12843 break; 12844 12845 case 10: // when '1100' 12846 // result = R[n] OR operand2; // ORR 12847 result.result = Rn | operand2; 12848 break; 12849 12850 case 11: // when '1101' 12851 // result = operand2; // MOV 12852 result.result = operand2; 12853 break; 12854 12855 case 12: // when '1110' 12856 // result = R[n] AND NOT(operand2); // BIC 12857 result.result = Rn & ~(operand2); 12858 break; 12859 12860 case 15: // when '1111' 12861 // result = NOT(operand2); // MVN 12862 result.result = ~(operand2); 12863 break; 12864 12865 default: 12866 return false; 12867 } 12868 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12869 12870 // For now, in emulation mode, we don't have access to the SPSR, so we will 12871 // use the CPSR instead, and hope for the best. 12872 uint32_t spsr = 12873 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12874 if (!success) 12875 return false; 12876 12877 CPSRWriteByInstr(spsr, 15, true); 12878 12879 // BranchWritePC(result); 12880 EmulateInstruction::Context context; 12881 context.type = eContextAdjustPC; 12882 context.SetImmediate(result.result); 12883 12884 BranchWritePC(context, result.result); 12885 } 12886 return true; 12887 } 12888 12889 EmulateInstructionARM::ARMOpcode * 12890 EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode, 12891 uint32_t arm_isa) { 12892 static ARMOpcode g_arm_opcodes[] = { 12893 //---------------------------------------------------------------------- 12894 // Prologue instructions 12895 //---------------------------------------------------------------------- 12896 12897 // push register(s) 12898 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12899 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 12900 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12901 &EmulateInstructionARM::EmulatePUSH, "push <register>"}, 12902 12903 // set r7 to point to a stack offset 12904 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12905 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"}, 12906 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12907 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12908 // copy the stack pointer to ip 12909 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, 12910 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"}, 12911 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12912 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"}, 12913 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12914 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12915 12916 // adjust the stack pointer 12917 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12918 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12919 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12920 &EmulateInstructionARM::EmulateSUBSPReg, 12921 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 12922 12923 // push one register 12924 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12925 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12926 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"}, 12927 12928 // vector push consecutive extension register(s) 12929 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12930 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12931 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12932 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12933 12934 //---------------------------------------------------------------------- 12935 // Epilogue instructions 12936 //---------------------------------------------------------------------- 12937 12938 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12939 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12940 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12941 &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12942 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12943 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12944 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12945 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12946 12947 //---------------------------------------------------------------------- 12948 // Supervisor Call (previously Software Interrupt) 12949 //---------------------------------------------------------------------- 12950 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12951 &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12952 12953 //---------------------------------------------------------------------- 12954 // Branch instructions 12955 //---------------------------------------------------------------------- 12956 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and 12957 // "bl <label>". 12958 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, 12959 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12960 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12961 &EmulateInstructionARM::EmulateB, "b #imm24"}, 12962 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12963 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12964 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, 12965 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12966 // for example, "bx lr" 12967 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, 12968 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12969 // bxj 12970 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, 12971 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12972 12973 //---------------------------------------------------------------------- 12974 // Data-processing instructions 12975 //---------------------------------------------------------------------- 12976 // adc (immediate) 12977 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12978 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12979 // adc (register) 12980 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12981 &EmulateInstructionARM::EmulateADCReg, 12982 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12983 // add (immediate) 12984 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12985 &EmulateInstructionARM::EmulateADDImmARM, 12986 "add{s}<c> <Rd>, <Rn>, #const"}, 12987 // add (register) 12988 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12989 &EmulateInstructionARM::EmulateADDReg, 12990 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12991 // add (register-shifted register) 12992 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, 12993 &EmulateInstructionARM::EmulateADDRegShift, 12994 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12995 // adr 12996 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12997 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12998 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, 12999 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 13000 // and (immediate) 13001 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13002 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 13003 // and (register) 13004 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13005 &EmulateInstructionARM::EmulateANDReg, 13006 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13007 // bic (immediate) 13008 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13009 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 13010 // bic (register) 13011 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13012 &EmulateInstructionARM::EmulateBICReg, 13013 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13014 // eor (immediate) 13015 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13016 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 13017 // eor (register) 13018 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13019 &EmulateInstructionARM::EmulateEORReg, 13020 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13021 // orr (immediate) 13022 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13023 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 13024 // orr (register) 13025 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13026 &EmulateInstructionARM::EmulateORRReg, 13027 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13028 // rsb (immediate) 13029 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13030 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 13031 // rsb (register) 13032 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13033 &EmulateInstructionARM::EmulateRSBReg, 13034 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13035 // rsc (immediate) 13036 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13037 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 13038 // rsc (register) 13039 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13040 &EmulateInstructionARM::EmulateRSCReg, 13041 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13042 // sbc (immediate) 13043 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13044 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13045 // sbc (register) 13046 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13047 &EmulateInstructionARM::EmulateSBCReg, 13048 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13049 // sub (immediate, ARM) 13050 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13051 &EmulateInstructionARM::EmulateSUBImmARM, 13052 "sub{s}<c> <Rd>, <Rn>, #<const>"}, 13053 // sub (sp minus immediate) 13054 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13055 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 13056 // sub (register) 13057 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13058 &EmulateInstructionARM::EmulateSUBReg, 13059 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 13060 // teq (immediate) 13061 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13062 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 13063 // teq (register) 13064 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13065 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13066 // tst (immediate) 13067 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13068 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 13069 // tst (register) 13070 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13071 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 13072 13073 // mov (immediate) 13074 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13075 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 13076 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 13077 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"}, 13078 // mov (register) 13079 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13080 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 13081 // mvn (immediate) 13082 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13083 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 13084 // mvn (register) 13085 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13086 &EmulateInstructionARM::EmulateMVNReg, 13087 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 13088 // cmn (immediate) 13089 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13090 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13091 // cmn (register) 13092 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13093 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13094 // cmp (immediate) 13095 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13096 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 13097 // cmp (register) 13098 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13099 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 13100 // asr (immediate) 13101 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, 13102 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 13103 // asr (register) 13104 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13105 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 13106 // lsl (immediate) 13107 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13108 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 13109 // lsl (register) 13110 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, 13111 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 13112 // lsr (immediate) 13113 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, 13114 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 13115 // lsr (register) 13116 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13117 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 13118 // rrx is a special case encoding of ror (immediate) 13119 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13120 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 13121 // ror (immediate) 13122 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13123 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 13124 // ror (register) 13125 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, 13126 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 13127 // mul 13128 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, 13129 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"}, 13130 13131 // subs pc, lr and related instructions 13132 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13133 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13134 "<opc>S<c> PC,#<const> | <Rn>,#<const>"}, 13135 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, 13136 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13137 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"}, 13138 13139 //---------------------------------------------------------------------- 13140 // Load instructions 13141 //---------------------------------------------------------------------- 13142 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13143 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13144 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13145 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"}, 13146 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13147 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13148 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13149 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"}, 13150 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13151 &EmulateInstructionARM::EmulateLDRImmediateARM, 13152 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"}, 13153 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13154 &EmulateInstructionARM::EmulateLDRRegister, 13155 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"}, 13156 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13157 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 13158 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13159 &EmulateInstructionARM::EmulateLDRBRegister, 13160 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"}, 13161 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13162 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13163 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13164 &EmulateInstructionARM::EmulateLDRHRegister, 13165 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13166 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13167 &EmulateInstructionARM::EmulateLDRSBImmediate, 13168 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"}, 13169 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13170 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"}, 13171 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13172 &EmulateInstructionARM::EmulateLDRSBRegister, 13173 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13174 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13175 &EmulateInstructionARM::EmulateLDRSHImmediate, 13176 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 13177 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13178 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13179 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13180 &EmulateInstructionARM::EmulateLDRSHRegister, 13181 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13182 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13183 &EmulateInstructionARM::EmulateLDRDImmediate, 13184 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 13185 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13186 &EmulateInstructionARM::EmulateLDRDRegister, 13187 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13188 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13189 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13190 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13191 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13192 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13193 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13194 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13195 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13196 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13197 &EmulateInstructionARM::EmulateVLD1Multiple, 13198 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13199 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13200 &EmulateInstructionARM::EmulateVLD1Single, 13201 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13202 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13203 &EmulateInstructionARM::EmulateVLD1SingleAll, 13204 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13205 13206 //---------------------------------------------------------------------- 13207 // Store instructions 13208 //---------------------------------------------------------------------- 13209 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13210 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13211 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13212 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"}, 13213 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13214 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13215 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13216 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"}, 13217 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13218 &EmulateInstructionARM::EmulateSTRRegister, 13219 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"}, 13220 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13221 &EmulateInstructionARM::EmulateSTRHRegister, 13222 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"}, 13223 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13224 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 13225 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13226 &EmulateInstructionARM::EmulateSTRBImmARM, 13227 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13228 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13229 &EmulateInstructionARM::EmulateSTRImmARM, 13230 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13231 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13232 &EmulateInstructionARM::EmulateSTRDImm, 13233 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 13234 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13235 &EmulateInstructionARM::EmulateSTRDReg, 13236 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13237 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13238 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13239 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13240 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13241 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13242 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 13243 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13244 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 13245 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13246 &EmulateInstructionARM::EmulateVST1Multiple, 13247 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13248 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13249 &EmulateInstructionARM::EmulateVST1Single, 13250 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13251 13252 //---------------------------------------------------------------------- 13253 // Other instructions 13254 //---------------------------------------------------------------------- 13255 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13256 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13257 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13258 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"}, 13259 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13260 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13261 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13262 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"}, 13263 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13264 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"} 13265 13266 }; 13267 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 13268 13269 for (size_t i = 0; i < k_num_arm_opcodes; ++i) { 13270 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 13271 (g_arm_opcodes[i].variants & arm_isa) != 0) 13272 return &g_arm_opcodes[i]; 13273 } 13274 return NULL; 13275 } 13276 13277 EmulateInstructionARM::ARMOpcode * 13278 EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode, 13279 uint32_t arm_isa) { 13280 13281 static ARMOpcode g_thumb_opcodes[] = { 13282 //---------------------------------------------------------------------- 13283 // Prologue instructions 13284 //---------------------------------------------------------------------- 13285 13286 // push register(s) 13287 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, 13288 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 13289 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13290 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"}, 13291 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13292 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"}, 13293 13294 // set r7 to point to a stack offset 13295 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13296 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"}, 13297 // copy the stack pointer to r7 13298 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, 13299 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"}, 13300 // move from high register to low register (comes after "mov r7, sp" to 13301 // resolve ambiguity) 13302 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, 13303 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"}, 13304 13305 // PC-relative load into register (see also EmulateADDSPRm) 13306 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13307 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 13308 13309 // adjust the stack pointer 13310 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, 13311 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 13312 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13313 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 13314 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13315 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 13316 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13317 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 13318 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13319 &EmulateInstructionARM::EmulateSUBSPReg, 13320 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 13321 13322 // vector push consecutive extension register(s) 13323 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13324 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 13325 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13326 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 13327 13328 //---------------------------------------------------------------------- 13329 // Epilogue instructions 13330 //---------------------------------------------------------------------- 13331 13332 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13333 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 13334 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13335 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 13336 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13337 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 13338 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13339 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"}, 13340 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13341 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"}, 13342 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13343 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 13344 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13345 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 13346 13347 //---------------------------------------------------------------------- 13348 // Supervisor Call (previously Software Interrupt) 13349 //---------------------------------------------------------------------- 13350 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13351 &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 13352 13353 //---------------------------------------------------------------------- 13354 // If Then makes up to four following instructions conditional. 13355 //---------------------------------------------------------------------- 13356 // The next 5 opcode _must_ come before the if then instruction 13357 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13358 &EmulateInstructionARM::EmulateNop, "nop"}, 13359 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13360 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 13361 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13362 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 13363 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13364 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 13365 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13366 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 13367 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13368 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 13369 13370 //---------------------------------------------------------------------- 13371 // Branch instructions 13372 //---------------------------------------------------------------------- 13373 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 13374 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13375 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 13376 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13377 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 13378 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13379 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 13380 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13381 &EmulateInstructionARM::EmulateB, 13382 "b<c>.w #imm8 (outside or last in IT)"}, 13383 // J1 == J2 == 1 13384 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, 13385 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 13386 // J1 == J2 == 1 13387 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, 13388 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 13389 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, 13390 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 13391 // for example, "bx lr" 13392 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, 13393 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 13394 // bxj 13395 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, 13396 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 13397 // compare and branch 13398 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13399 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 13400 // table branch byte 13401 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13402 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 13403 // table branch halfword 13404 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13405 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 13406 13407 //---------------------------------------------------------------------- 13408 // Data-processing instructions 13409 //---------------------------------------------------------------------- 13410 // adc (immediate) 13411 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13412 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 13413 // adc (register) 13414 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, 13415 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 13416 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13417 &EmulateInstructionARM::EmulateADCReg, 13418 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13419 // add (register) 13420 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13421 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 13422 // Make sure "add sp, <Rm>" comes before this instruction, so there's no 13423 // ambiguity decoding the two. 13424 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, 13425 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 13426 // adr 13427 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13428 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13429 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13430 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 13431 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13432 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13433 // and (immediate) 13434 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13435 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 13436 // and (register) 13437 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13438 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 13439 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13440 &EmulateInstructionARM::EmulateANDReg, 13441 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13442 // bic (immediate) 13443 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13444 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 13445 // bic (register) 13446 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, 13447 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 13448 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13449 &EmulateInstructionARM::EmulateBICReg, 13450 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13451 // eor (immediate) 13452 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13453 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 13454 // eor (register) 13455 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, 13456 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 13457 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13458 &EmulateInstructionARM::EmulateEORReg, 13459 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13460 // orr (immediate) 13461 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13462 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 13463 // orr (register) 13464 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, 13465 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 13466 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13467 &EmulateInstructionARM::EmulateORRReg, 13468 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13469 // rsb (immediate) 13470 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, 13471 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 13472 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13473 &EmulateInstructionARM::EmulateRSBImm, 13474 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 13475 // rsb (register) 13476 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13477 &EmulateInstructionARM::EmulateRSBReg, 13478 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13479 // sbc (immediate) 13480 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13481 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13482 // sbc (register) 13483 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, 13484 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 13485 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13486 &EmulateInstructionARM::EmulateSBCReg, 13487 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13488 // add (immediate, Thumb) 13489 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13490 &EmulateInstructionARM::EmulateADDImmThumb, 13491 "adds|add<c> <Rd>,<Rn>,#<imm3>"}, 13492 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13493 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"}, 13494 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13495 &EmulateInstructionARM::EmulateADDImmThumb, 13496 "add{s}<c>.w <Rd>,<Rn>,#<const>"}, 13497 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13498 &EmulateInstructionARM::EmulateADDImmThumb, 13499 "addw<c> <Rd>,<Rn>,#<imm12>"}, 13500 // sub (immediate, Thumb) 13501 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13502 &EmulateInstructionARM::EmulateSUBImmThumb, 13503 "subs|sub<c> <Rd>, <Rn> #imm3"}, 13504 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, 13505 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 13506 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13507 &EmulateInstructionARM::EmulateSUBImmThumb, 13508 "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 13509 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13510 &EmulateInstructionARM::EmulateSUBImmThumb, 13511 "subw<c> <Rd>, <Rn>, #imm12"}, 13512 // sub (sp minus immediate) 13513 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13514 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 13515 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13516 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 13517 // sub (register) 13518 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13519 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 13520 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13521 &EmulateInstructionARM::EmulateSUBReg, 13522 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 13523 // teq (immediate) 13524 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13525 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 13526 // teq (register) 13527 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13528 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13529 // tst (immediate) 13530 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13531 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 13532 // tst (register) 13533 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, 13534 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 13535 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13536 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 13537 13538 // move from high register to high register 13539 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, 13540 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 13541 // move from low register to low register 13542 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13543 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 13544 // mov{s}<c>.w <Rd>, <Rm> 13545 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13546 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 13547 // move immediate 13548 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13549 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 13550 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13551 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 13552 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13553 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 13554 // mvn (immediate) 13555 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13556 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 13557 // mvn (register) 13558 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13559 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 13560 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13561 &EmulateInstructionARM::EmulateMVNReg, 13562 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 13563 // cmn (immediate) 13564 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13565 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13566 // cmn (register) 13567 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13568 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 13569 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13570 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13571 // cmp (immediate) 13572 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13573 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 13574 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13575 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 13576 // cmp (register) (Rn and Rm both from r0-r7) 13577 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, 13578 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13579 // cmp (register) (Rn and Rm not both from r0-r7) 13580 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, 13581 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13582 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, 13583 &EmulateInstructionARM::EmulateCMPReg, 13584 "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 13585 // asr (immediate) 13586 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13587 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 13588 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13589 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 13590 // asr (register) 13591 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, 13592 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 13593 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13594 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13595 // lsl (immediate) 13596 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13597 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 13598 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13599 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 13600 // lsl (register) 13601 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13602 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 13603 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13604 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13605 // lsr (immediate) 13606 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13607 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 13608 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13609 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 13610 // lsr (register) 13611 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13612 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 13613 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13614 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13615 // rrx is a special case encoding of ror (immediate) 13616 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13617 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 13618 // ror (immediate) 13619 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13620 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 13621 // ror (register) 13622 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13623 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 13624 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13625 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13626 // mul 13627 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13628 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"}, 13629 // mul 13630 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13631 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"}, 13632 13633 // subs pc, lr and related instructions 13634 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13635 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"}, 13636 13637 //---------------------------------------------------------------------- 13638 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE 13639 // LDM.. Instructions in this table; 13640 // otherwise the wrong instructions will be selected. 13641 //---------------------------------------------------------------------- 13642 13643 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13644 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"}, 13645 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13646 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"}, 13647 13648 //---------------------------------------------------------------------- 13649 // Load instructions 13650 //---------------------------------------------------------------------- 13651 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13652 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13653 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13654 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"}, 13655 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13656 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13657 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13658 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 13659 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13660 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 13661 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13662 &EmulateInstructionARM::EmulateLDRRtRnImm, 13663 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 13664 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13665 &EmulateInstructionARM::EmulateLDRRtRnImm, 13666 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 13667 // Thumb2 PC-relative load into register 13668 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13669 &EmulateInstructionARM::EmulateLDRRtPCRelative, 13670 "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 13671 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13672 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"}, 13673 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13674 &EmulateInstructionARM::EmulateLDRRegister, 13675 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"}, 13676 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13677 &EmulateInstructionARM::EmulateLDRBImmediate, 13678 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"}, 13679 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13680 &EmulateInstructionARM::EmulateLDRBImmediate, 13681 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13682 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13683 &EmulateInstructionARM::EmulateLDRBImmediate, 13684 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"}, 13685 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13686 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"}, 13687 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13688 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"}, 13689 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13690 &EmulateInstructionARM::EmulateLDRBRegister, 13691 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13692 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13693 &EmulateInstructionARM::EmulateLDRHImmediate, 13694 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"}, 13695 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13696 &EmulateInstructionARM::EmulateLDRHImmediate, 13697 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13698 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13699 &EmulateInstructionARM::EmulateLDRHImmediate, 13700 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"}, 13701 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13702 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13703 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13704 &EmulateInstructionARM::EmulateLDRHRegister, 13705 "ldrh<c> <Rt>, [<Rn>,<Rm>]"}, 13706 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13707 &EmulateInstructionARM::EmulateLDRHRegister, 13708 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13709 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13710 &EmulateInstructionARM::EmulateLDRSBImmediate, 13711 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"}, 13712 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13713 &EmulateInstructionARM::EmulateLDRSBImmediate, 13714 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13715 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13716 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"}, 13717 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13718 &EmulateInstructionARM::EmulateLDRSBRegister, 13719 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"}, 13720 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13721 &EmulateInstructionARM::EmulateLDRSBRegister, 13722 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13723 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13724 &EmulateInstructionARM::EmulateLDRSHImmediate, 13725 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"}, 13726 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13727 &EmulateInstructionARM::EmulateLDRSHImmediate, 13728 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13729 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13730 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13731 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13732 &EmulateInstructionARM::EmulateLDRSHRegister, 13733 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"}, 13734 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13735 &EmulateInstructionARM::EmulateLDRSHRegister, 13736 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13737 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13738 &EmulateInstructionARM::EmulateLDRDImmediate, 13739 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 13740 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13741 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13742 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13743 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13744 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13745 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13746 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13747 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 13748 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13749 &EmulateInstructionARM::EmulateVLD1Multiple, 13750 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13751 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13752 &EmulateInstructionARM::EmulateVLD1Single, 13753 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13754 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13755 &EmulateInstructionARM::EmulateVLD1SingleAll, 13756 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13757 13758 //---------------------------------------------------------------------- 13759 // Store instructions 13760 //---------------------------------------------------------------------- 13761 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13762 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13763 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13764 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"}, 13765 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13766 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13767 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13768 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"}, 13769 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13770 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"}, 13771 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13772 &EmulateInstructionARM::EmulateSTRThumb, 13773 "str<c>.w <Rt>, [<Rn>,#<imm12>]"}, 13774 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13775 &EmulateInstructionARM::EmulateSTRThumb, 13776 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"}, 13777 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13778 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"}, 13779 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13780 &EmulateInstructionARM::EmulateSTRRegister, 13781 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"}, 13782 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13783 &EmulateInstructionARM::EmulateSTRBThumb, 13784 "strb<c> <Rt>, [<Rn>, #<imm5>]"}, 13785 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13786 &EmulateInstructionARM::EmulateSTRBThumb, 13787 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"}, 13788 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13789 &EmulateInstructionARM::EmulateSTRBThumb, 13790 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"}, 13791 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13792 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"}, 13793 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13794 &EmulateInstructionARM::EmulateSTRHRegister, 13795 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13796 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13797 &EmulateInstructionARM::EmulateSTREX, 13798 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"}, 13799 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13800 &EmulateInstructionARM::EmulateSTRDImm, 13801 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 13802 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13803 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13804 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13805 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13806 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13807 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13808 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13809 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13810 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13811 &EmulateInstructionARM::EmulateVST1Multiple, 13812 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13813 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13814 &EmulateInstructionARM::EmulateVST1Single, 13815 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13816 13817 //---------------------------------------------------------------------- 13818 // Other instructions 13819 //---------------------------------------------------------------------- 13820 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13821 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"}, 13822 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, 13823 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13824 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13825 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"}, 13826 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13827 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13828 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13829 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"}, 13830 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13831 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13832 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13833 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"}, 13834 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13835 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13836 }; 13837 13838 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 13839 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) { 13840 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 13841 (g_thumb_opcodes[i].variants & arm_isa) != 0) 13842 return &g_thumb_opcodes[i]; 13843 } 13844 return NULL; 13845 } 13846 13847 bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) { 13848 m_arch = arch; 13849 m_arm_isa = 0; 13850 const char *arch_cstr = arch.GetArchitectureName(); 13851 if (arch_cstr) { 13852 if (0 == ::strcasecmp(arch_cstr, "armv4t")) 13853 m_arm_isa = ARMv4T; 13854 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) 13855 m_arm_isa = ARMv5TEJ; 13856 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) 13857 m_arm_isa = ARMv5TE; 13858 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) 13859 m_arm_isa = ARMv5T; 13860 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) 13861 m_arm_isa = ARMv6K; 13862 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) 13863 m_arm_isa = ARMv6T2; 13864 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) 13865 m_arm_isa = ARMv7S; 13866 else if (0 == ::strcasecmp(arch_cstr, "arm")) 13867 m_arm_isa = ARMvAll; 13868 else if (0 == ::strcasecmp(arch_cstr, "thumb")) 13869 m_arm_isa = ARMvAll; 13870 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5)) 13871 m_arm_isa = ARMv4; 13872 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5)) 13873 m_arm_isa = ARMv6; 13874 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5)) 13875 m_arm_isa = ARMv7; 13876 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5)) 13877 m_arm_isa = ARMv8; 13878 } 13879 return m_arm_isa != 0; 13880 } 13881 13882 bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode, 13883 const Address &inst_addr, 13884 Target *target) { 13885 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { 13886 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || 13887 m_arch.IsAlwaysThumbInstructions()) 13888 m_opcode_mode = eModeThumb; 13889 else { 13890 AddressClass addr_class = inst_addr.GetAddressClass(); 13891 13892 if ((addr_class == AddressClass::eCode) || 13893 (addr_class == AddressClass::eUnknown)) 13894 m_opcode_mode = eModeARM; 13895 else if (addr_class == AddressClass::eCodeAlternateISA) 13896 m_opcode_mode = eModeThumb; 13897 else 13898 return false; 13899 } 13900 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions()) 13901 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13902 else 13903 m_opcode_cpsr = CPSR_MODE_USR; 13904 return true; 13905 } 13906 return false; 13907 } 13908 13909 bool EmulateInstructionARM::ReadInstruction() { 13910 bool success = false; 13911 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric, 13912 LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13913 if (success) { 13914 addr_t pc = 13915 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 13916 LLDB_INVALID_ADDRESS, &success); 13917 if (success) { 13918 Context read_inst_context; 13919 read_inst_context.type = eContextReadOpcode; 13920 read_inst_context.SetNoArgs(); 13921 13922 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) { 13923 m_opcode_mode = eModeThumb; 13924 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13925 13926 if (success) { 13927 if ((thumb_opcode & 0xe000) != 0xe000 || 13928 ((thumb_opcode & 0x1800u) == 0)) { 13929 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder()); 13930 } else { 13931 m_opcode.SetOpcode32( 13932 (thumb_opcode << 16) | 13933 MemARead(read_inst_context, pc + 2, 2, 0, &success), 13934 GetByteOrder()); 13935 } 13936 } 13937 } else { 13938 m_opcode_mode = eModeARM; 13939 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success), 13940 GetByteOrder()); 13941 } 13942 13943 if (!m_ignore_conditions) { 13944 // If we are not ignoreing the conditions then init the it session from 13945 // the current value of cpsr. 13946 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | 13947 Bits32(m_opcode_cpsr, 26, 25); 13948 if (it != 0) 13949 m_it_session.InitIT(it); 13950 } 13951 } 13952 } 13953 if (!success) { 13954 m_opcode_mode = eModeInvalid; 13955 m_addr = LLDB_INVALID_ADDRESS; 13956 } 13957 return success; 13958 } 13959 13960 uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; } 13961 13962 bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) { 13963 // If we are ignoring conditions, then always return true. this allows us to 13964 // iterate over disassembly code and still emulate an instruction even if we 13965 // don't have all the right bits set in the CPSR register... 13966 if (m_ignore_conditions) 13967 return true; 13968 13969 const uint32_t cond = CurrentCond(opcode); 13970 if (cond == UINT32_MAX) 13971 return false; 13972 13973 bool result = false; 13974 switch (UnsignedBits(cond, 3, 1)) { 13975 case 0: 13976 if (m_opcode_cpsr == 0) 13977 result = true; 13978 else 13979 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13980 break; 13981 case 1: 13982 if (m_opcode_cpsr == 0) 13983 result = true; 13984 else 13985 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13986 break; 13987 case 2: 13988 if (m_opcode_cpsr == 0) 13989 result = true; 13990 else 13991 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13992 break; 13993 case 3: 13994 if (m_opcode_cpsr == 0) 13995 result = true; 13996 else 13997 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13998 break; 13999 case 4: 14000 if (m_opcode_cpsr == 0) 14001 result = true; 14002 else 14003 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && 14004 ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 14005 break; 14006 case 5: 14007 if (m_opcode_cpsr == 0) 14008 result = true; 14009 else { 14010 bool n = (m_opcode_cpsr & MASK_CPSR_N); 14011 bool v = (m_opcode_cpsr & MASK_CPSR_V); 14012 result = n == v; 14013 } 14014 break; 14015 case 6: 14016 if (m_opcode_cpsr == 0) 14017 result = true; 14018 else { 14019 bool n = (m_opcode_cpsr & MASK_CPSR_N); 14020 bool v = (m_opcode_cpsr & MASK_CPSR_V); 14021 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 14022 } 14023 break; 14024 case 7: 14025 // Always execute (cond == 0b1110, or the special 0b1111 which gives 14026 // opcodes different meanings, but always means execution happens. 14027 return true; 14028 } 14029 14030 if (cond & 1) 14031 result = !result; 14032 return result; 14033 } 14034 14035 uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) { 14036 switch (m_opcode_mode) { 14037 case eModeInvalid: 14038 break; 14039 14040 case eModeARM: 14041 return UnsignedBits(opcode, 31, 28); 14042 14043 case eModeThumb: 14044 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 14045 // 'cond' field of the encoding. 14046 { 14047 const uint32_t byte_size = m_opcode.GetByteSize(); 14048 if (byte_size == 2) { 14049 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 14050 return Bits32(opcode, 11, 8); 14051 } else if (byte_size == 4) { 14052 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 && 14053 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) { 14054 return Bits32(opcode, 25, 22); 14055 } 14056 } else 14057 // We have an invalid thumb instruction, let's bail out. 14058 break; 14059 14060 return m_it_session.GetCond(); 14061 } 14062 } 14063 return UINT32_MAX; // Return invalid value 14064 } 14065 14066 bool EmulateInstructionARM::InITBlock() { 14067 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 14068 } 14069 14070 bool EmulateInstructionARM::LastInITBlock() { 14071 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 14072 } 14073 14074 bool EmulateInstructionARM::BadMode(uint32_t mode) { 14075 14076 switch (mode) { 14077 case 16: 14078 return false; // '10000' 14079 case 17: 14080 return false; // '10001' 14081 case 18: 14082 return false; // '10010' 14083 case 19: 14084 return false; // '10011' 14085 case 22: 14086 return false; // '10110' 14087 case 23: 14088 return false; // '10111' 14089 case 27: 14090 return false; // '11011' 14091 case 31: 14092 return false; // '11111' 14093 default: 14094 return true; 14095 } 14096 return true; 14097 } 14098 14099 bool EmulateInstructionARM::CurrentModeIsPrivileged() { 14100 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0); 14101 14102 if (BadMode(mode)) 14103 return false; 14104 14105 if (mode == 16) 14106 return false; 14107 14108 return true; 14109 } 14110 14111 void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask, 14112 bool affect_execstate) { 14113 bool privileged = CurrentModeIsPrivileged(); 14114 14115 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20; 14116 14117 if (BitIsSet(bytemask, 3)) { 14118 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27); 14119 if (affect_execstate) 14120 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24); 14121 } 14122 14123 if (BitIsSet(bytemask, 2)) { 14124 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16); 14125 } 14126 14127 if (BitIsSet(bytemask, 1)) { 14128 if (affect_execstate) 14129 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10); 14130 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9); 14131 if (privileged) 14132 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8); 14133 } 14134 14135 if (BitIsSet(bytemask, 0)) { 14136 if (privileged) 14137 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6); 14138 if (affect_execstate) 14139 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5); 14140 if (privileged) 14141 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0); 14142 } 14143 14144 m_opcode_cpsr = tmp_cpsr; 14145 } 14146 14147 bool EmulateInstructionARM::BranchWritePC(const Context &context, 14148 uint32_t addr) { 14149 addr_t target; 14150 14151 // Check the current instruction set. 14152 if (CurrentInstrSet() == eModeARM) 14153 target = addr & 0xfffffffc; 14154 else 14155 target = addr & 0xfffffffe; 14156 14157 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14158 LLDB_REGNUM_GENERIC_PC, target)) 14159 return false; 14160 14161 return true; 14162 } 14163 14164 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by 14165 // inspecting addr. 14166 bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) { 14167 addr_t target; 14168 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 14169 // we want to record it and issue a WriteRegister callback so the clients can 14170 // track the mode changes accordingly. 14171 bool cpsr_changed = false; 14172 14173 if (BitIsSet(addr, 0)) { 14174 if (CurrentInstrSet() != eModeThumb) { 14175 SelectInstrSet(eModeThumb); 14176 cpsr_changed = true; 14177 } 14178 target = addr & 0xfffffffe; 14179 context.SetISA(eModeThumb); 14180 } else if (BitIsClear(addr, 1)) { 14181 if (CurrentInstrSet() != eModeARM) { 14182 SelectInstrSet(eModeARM); 14183 cpsr_changed = true; 14184 } 14185 target = addr & 0xfffffffc; 14186 context.SetISA(eModeARM); 14187 } else 14188 return false; // address<1:0> == '10' => UNPREDICTABLE 14189 14190 if (cpsr_changed) { 14191 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14192 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14193 return false; 14194 } 14195 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14196 LLDB_REGNUM_GENERIC_PC, target)) 14197 return false; 14198 14199 return true; 14200 } 14201 14202 // Dispatches to either BXWritePC or BranchWritePC based on architecture 14203 // versions. 14204 bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) { 14205 if (ArchVersion() >= ARMv5T) 14206 return BXWritePC(context, addr); 14207 else 14208 return BranchWritePC((const Context)context, addr); 14209 } 14210 14211 // Dispatches to either BXWritePC or BranchWritePC based on architecture 14212 // versions and current instruction set. 14213 bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) { 14214 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 14215 return BXWritePC(context, addr); 14216 else 14217 return BranchWritePC((const Context)context, addr); 14218 } 14219 14220 EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() { 14221 return m_opcode_mode; 14222 } 14223 14224 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 14225 // ReadInstruction() is performed. This function has a side effect of updating 14226 // the m_new_inst_cpsr member variable if necessary. 14227 bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) { 14228 m_new_inst_cpsr = m_opcode_cpsr; 14229 switch (arm_or_thumb) { 14230 default: 14231 return false; 14232 case eModeARM: 14233 // Clear the T bit. 14234 m_new_inst_cpsr &= ~MASK_CPSR_T; 14235 break; 14236 case eModeThumb: 14237 // Set the T bit. 14238 m_new_inst_cpsr |= MASK_CPSR_T; 14239 break; 14240 } 14241 return true; 14242 } 14243 14244 // This function returns TRUE if the processor currently provides support for 14245 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 14246 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 14247 bool EmulateInstructionARM::UnalignedSupport() { 14248 return (ArchVersion() >= ARMv7); 14249 } 14250 14251 // The main addition and subtraction instructions can produce status 14252 // information about both unsigned carry and signed overflow conditions. This 14253 // status information can be used to synthesize multi-word additions and 14254 // subtractions. 14255 EmulateInstructionARM::AddWithCarryResult 14256 EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) { 14257 uint32_t result; 14258 uint8_t carry_out; 14259 uint8_t overflow; 14260 14261 uint64_t unsigned_sum = x + y + carry_in; 14262 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 14263 14264 result = UnsignedBits(unsigned_sum, 31, 0); 14265 // carry_out = (result == unsigned_sum ? 0 : 1); 14266 overflow = ((int32_t)result == signed_sum ? 0 : 1); 14267 14268 if (carry_in) 14269 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0; 14270 else 14271 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0; 14272 14273 AddWithCarryResult res = {result, carry_out, overflow}; 14274 return res; 14275 } 14276 14277 uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) { 14278 lldb::RegisterKind reg_kind; 14279 uint32_t reg_num; 14280 switch (num) { 14281 case SP_REG: 14282 reg_kind = eRegisterKindGeneric; 14283 reg_num = LLDB_REGNUM_GENERIC_SP; 14284 break; 14285 case LR_REG: 14286 reg_kind = eRegisterKindGeneric; 14287 reg_num = LLDB_REGNUM_GENERIC_RA; 14288 break; 14289 case PC_REG: 14290 reg_kind = eRegisterKindGeneric; 14291 reg_num = LLDB_REGNUM_GENERIC_PC; 14292 break; 14293 default: 14294 if (num < SP_REG) { 14295 reg_kind = eRegisterKindDWARF; 14296 reg_num = dwarf_r0 + num; 14297 } else { 14298 // assert(0 && "Invalid register number"); 14299 *success = false; 14300 return UINT32_MAX; 14301 } 14302 break; 14303 } 14304 14305 // Read our register. 14306 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success); 14307 14308 // When executing an ARM instruction , PC reads as the address of the current 14309 // instruction plus 8. When executing a Thumb instruction , PC reads as the 14310 // address of the current instruction plus 4. 14311 if (num == 15) { 14312 if (CurrentInstrSet() == eModeARM) 14313 val += 8; 14314 else 14315 val += 4; 14316 } 14317 14318 return val; 14319 } 14320 14321 // Write the result to the ARM core register Rd, and optionally update the 14322 // condition flags based on the result. 14323 // 14324 // This helper method tries to encapsulate the following pseudocode from the 14325 // ARM Architecture Reference Manual: 14326 // 14327 // if d == 15 then // Can only occur for encoding A1 14328 // ALUWritePC(result); // setflags is always FALSE here 14329 // else 14330 // R[d] = result; 14331 // if setflags then 14332 // APSR.N = result<31>; 14333 // APSR.Z = IsZeroBit(result); 14334 // APSR.C = carry; 14335 // // APSR.V unchanged 14336 // 14337 // In the above case, the API client does not pass in the overflow arg, which 14338 // defaults to ~0u. 14339 bool EmulateInstructionARM::WriteCoreRegOptionalFlags( 14340 Context &context, const uint32_t result, const uint32_t Rd, bool setflags, 14341 const uint32_t carry, const uint32_t overflow) { 14342 if (Rd == 15) { 14343 if (!ALUWritePC(context, result)) 14344 return false; 14345 } else { 14346 lldb::RegisterKind reg_kind; 14347 uint32_t reg_num; 14348 switch (Rd) { 14349 case SP_REG: 14350 reg_kind = eRegisterKindGeneric; 14351 reg_num = LLDB_REGNUM_GENERIC_SP; 14352 break; 14353 case LR_REG: 14354 reg_kind = eRegisterKindGeneric; 14355 reg_num = LLDB_REGNUM_GENERIC_RA; 14356 break; 14357 default: 14358 reg_kind = eRegisterKindDWARF; 14359 reg_num = dwarf_r0 + Rd; 14360 } 14361 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result)) 14362 return false; 14363 if (setflags) 14364 return WriteFlags(context, result, carry, overflow); 14365 } 14366 return true; 14367 } 14368 14369 // This helper method tries to encapsulate the following pseudocode from the 14370 // ARM Architecture Reference Manual: 14371 // 14372 // APSR.N = result<31>; 14373 // APSR.Z = IsZeroBit(result); 14374 // APSR.C = carry; 14375 // APSR.V = overflow 14376 // 14377 // Default arguments can be specified for carry and overflow parameters, which 14378 // means not to update the respective flags. 14379 bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result, 14380 const uint32_t carry, 14381 const uint32_t overflow) { 14382 m_new_inst_cpsr = m_opcode_cpsr; 14383 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 14384 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 14385 if (carry != ~0u) 14386 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 14387 if (overflow != ~0u) 14388 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 14389 if (m_new_inst_cpsr != m_opcode_cpsr) { 14390 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14391 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14392 return false; 14393 } 14394 return true; 14395 } 14396 14397 bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) { 14398 ARMOpcode *opcode_data = NULL; 14399 14400 if (m_opcode_mode == eModeThumb) 14401 opcode_data = 14402 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14403 else if (m_opcode_mode == eModeARM) 14404 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14405 14406 const bool auto_advance_pc = 14407 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 14408 m_ignore_conditions = 14409 evaluate_options & eEmulateInstructionOptionIgnoreConditions; 14410 14411 bool success = false; 14412 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) { 14413 m_opcode_cpsr = 14414 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 14415 } 14416 14417 // Only return false if we are unable to read the CPSR if we care about 14418 // conditions 14419 if (success == false && m_ignore_conditions == false) 14420 return false; 14421 14422 uint32_t orig_pc_value = 0; 14423 if (auto_advance_pc) { 14424 orig_pc_value = 14425 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14426 if (!success) 14427 return false; 14428 } 14429 14430 // Call the Emulate... function if we managed to decode the opcode. 14431 if (opcode_data) { 14432 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(), 14433 opcode_data->encoding); 14434 if (!success) 14435 return false; 14436 } 14437 14438 // Advance the ITSTATE bits to their values for the next instruction if we 14439 // haven't just executed an IT instruction what initialized it. 14440 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() && 14441 (opcode_data == nullptr || 14442 opcode_data->callback != &EmulateInstructionARM::EmulateIT)) 14443 m_it_session.ITAdvance(); 14444 14445 if (auto_advance_pc) { 14446 uint32_t after_pc_value = 14447 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14448 if (!success) 14449 return false; 14450 14451 if (auto_advance_pc && (after_pc_value == orig_pc_value)) { 14452 after_pc_value += m_opcode.GetByteSize(); 14453 14454 EmulateInstruction::Context context; 14455 context.type = eContextAdvancePC; 14456 context.SetNoArgs(); 14457 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc, 14458 after_pc_value)) 14459 return false; 14460 } 14461 } 14462 return true; 14463 } 14464 14465 EmulateInstruction::InstructionCondition 14466 EmulateInstructionARM::GetInstructionCondition() { 14467 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32()); 14468 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX) 14469 return EmulateInstruction::UnconditionalCondition; 14470 return cond; 14471 } 14472 14473 bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, 14474 OptionValueDictionary *test_data) { 14475 if (!test_data) { 14476 out_stream->Printf("TestEmulation: Missing test data.\n"); 14477 return false; 14478 } 14479 14480 static ConstString opcode_key("opcode"); 14481 static ConstString before_key("before_state"); 14482 static ConstString after_key("after_state"); 14483 14484 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key); 14485 14486 uint32_t test_opcode; 14487 if ((value_sp.get() == NULL) || 14488 (value_sp->GetType() != OptionValue::eTypeUInt64)) { 14489 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n"); 14490 return false; 14491 } 14492 test_opcode = value_sp->GetUInt64Value(); 14493 14494 if (arch.GetTriple().getArch() == llvm::Triple::thumb || 14495 arch.IsAlwaysThumbInstructions()) { 14496 m_opcode_mode = eModeThumb; 14497 if (test_opcode < 0x10000) 14498 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder()); 14499 else 14500 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14501 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) { 14502 m_opcode_mode = eModeARM; 14503 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14504 } else { 14505 out_stream->Printf("TestEmulation: Invalid arch.\n"); 14506 return false; 14507 } 14508 14509 EmulationStateARM before_state; 14510 EmulationStateARM after_state; 14511 14512 value_sp = test_data->GetValueForKey(before_key); 14513 if ((value_sp.get() == NULL) || 14514 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14515 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n"); 14516 return false; 14517 } 14518 14519 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary(); 14520 if (!before_state.LoadStateFromDictionary(state_dictionary)) { 14521 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n"); 14522 return false; 14523 } 14524 14525 value_sp = test_data->GetValueForKey(after_key); 14526 if ((value_sp.get() == NULL) || 14527 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14528 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n"); 14529 return false; 14530 } 14531 14532 state_dictionary = value_sp->GetAsDictionary(); 14533 if (!after_state.LoadStateFromDictionary(state_dictionary)) { 14534 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n"); 14535 return false; 14536 } 14537 14538 SetBaton((void *)&before_state); 14539 SetCallbacks(&EmulationStateARM::ReadPseudoMemory, 14540 &EmulationStateARM::WritePseudoMemory, 14541 &EmulationStateARM::ReadPseudoRegister, 14542 &EmulationStateARM::WritePseudoRegister); 14543 14544 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 14545 if (!success) { 14546 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n"); 14547 return false; 14548 } 14549 14550 success = before_state.CompareState(after_state); 14551 if (!success) 14552 out_stream->Printf( 14553 "TestEmulation: 'before' and 'after' states do not match.\n"); 14554 14555 return success; 14556 } 14557 // 14558 // 14559 // const char * 14560 // EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 14561 //{ 14562 // if (reg_kind == eRegisterKindGeneric) 14563 // { 14564 // switch (reg_num) 14565 // { 14566 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 14567 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 14568 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 14569 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 14570 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 14571 // default: return NULL; 14572 // } 14573 // } 14574 // else if (reg_kind == eRegisterKindDWARF) 14575 // { 14576 // return GetARMDWARFRegisterName (reg_num); 14577 // } 14578 // return NULL; 14579 //} 14580 // 14581 bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { 14582 unwind_plan.Clear(); 14583 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 14584 14585 UnwindPlan::RowSP row(new UnwindPlan::Row); 14586 14587 // Our previous Call Frame Address is the stack pointer 14588 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0); 14589 14590 unwind_plan.AppendRow(row); 14591 unwind_plan.SetSourceName("EmulateInstructionARM"); 14592 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 14593 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 14594 unwind_plan.SetReturnAddressRegister(dwarf_lr); 14595 return true; 14596 } 14597