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" 30 31 using namespace lldb; 32 using namespace lldb_private; 33 34 // Convenient macro definitions. 35 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 36 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 37 38 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 39 40 //---------------------------------------------------------------------- 41 // 42 // ITSession implementation 43 // 44 //---------------------------------------------------------------------- 45 46 static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo ®_info) { 47 ::memset(®_info, 0, sizeof(RegisterInfo)); 48 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); 49 50 if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) { 51 reg_info.byte_size = 16; 52 reg_info.format = eFormatVectorOfUInt8; 53 reg_info.encoding = eEncodingVector; 54 } 55 56 if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) { 57 reg_info.byte_size = 8; 58 reg_info.format = eFormatFloat; 59 reg_info.encoding = eEncodingIEEE754; 60 } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) { 61 reg_info.byte_size = 4; 62 reg_info.format = eFormatFloat; 63 reg_info.encoding = eEncodingIEEE754; 64 } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) { 65 reg_info.byte_size = 12; 66 reg_info.format = eFormatFloat; 67 reg_info.encoding = eEncodingIEEE754; 68 } else { 69 reg_info.byte_size = 4; 70 reg_info.format = eFormatHex; 71 reg_info.encoding = eEncodingUint; 72 } 73 74 reg_info.kinds[eRegisterKindDWARF] = reg_num; 75 76 switch (reg_num) { 77 case dwarf_r0: 78 reg_info.name = "r0"; 79 break; 80 case dwarf_r1: 81 reg_info.name = "r1"; 82 break; 83 case dwarf_r2: 84 reg_info.name = "r2"; 85 break; 86 case dwarf_r3: 87 reg_info.name = "r3"; 88 break; 89 case dwarf_r4: 90 reg_info.name = "r4"; 91 break; 92 case dwarf_r5: 93 reg_info.name = "r5"; 94 break; 95 case dwarf_r6: 96 reg_info.name = "r6"; 97 break; 98 case dwarf_r7: 99 reg_info.name = "r7"; 100 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; 101 break; 102 case dwarf_r8: 103 reg_info.name = "r8"; 104 break; 105 case dwarf_r9: 106 reg_info.name = "r9"; 107 break; 108 case dwarf_r10: 109 reg_info.name = "r10"; 110 break; 111 case dwarf_r11: 112 reg_info.name = "r11"; 113 break; 114 case dwarf_r12: 115 reg_info.name = "r12"; 116 break; 117 case dwarf_sp: 118 reg_info.name = "sp"; 119 reg_info.alt_name = "r13"; 120 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; 121 break; 122 case dwarf_lr: 123 reg_info.name = "lr"; 124 reg_info.alt_name = "r14"; 125 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; 126 break; 127 case dwarf_pc: 128 reg_info.name = "pc"; 129 reg_info.alt_name = "r15"; 130 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; 131 break; 132 case dwarf_cpsr: 133 reg_info.name = "cpsr"; 134 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; 135 break; 136 137 case dwarf_s0: 138 reg_info.name = "s0"; 139 break; 140 case dwarf_s1: 141 reg_info.name = "s1"; 142 break; 143 case dwarf_s2: 144 reg_info.name = "s2"; 145 break; 146 case dwarf_s3: 147 reg_info.name = "s3"; 148 break; 149 case dwarf_s4: 150 reg_info.name = "s4"; 151 break; 152 case dwarf_s5: 153 reg_info.name = "s5"; 154 break; 155 case dwarf_s6: 156 reg_info.name = "s6"; 157 break; 158 case dwarf_s7: 159 reg_info.name = "s7"; 160 break; 161 case dwarf_s8: 162 reg_info.name = "s8"; 163 break; 164 case dwarf_s9: 165 reg_info.name = "s9"; 166 break; 167 case dwarf_s10: 168 reg_info.name = "s10"; 169 break; 170 case dwarf_s11: 171 reg_info.name = "s11"; 172 break; 173 case dwarf_s12: 174 reg_info.name = "s12"; 175 break; 176 case dwarf_s13: 177 reg_info.name = "s13"; 178 break; 179 case dwarf_s14: 180 reg_info.name = "s14"; 181 break; 182 case dwarf_s15: 183 reg_info.name = "s15"; 184 break; 185 case dwarf_s16: 186 reg_info.name = "s16"; 187 break; 188 case dwarf_s17: 189 reg_info.name = "s17"; 190 break; 191 case dwarf_s18: 192 reg_info.name = "s18"; 193 break; 194 case dwarf_s19: 195 reg_info.name = "s19"; 196 break; 197 case dwarf_s20: 198 reg_info.name = "s20"; 199 break; 200 case dwarf_s21: 201 reg_info.name = "s21"; 202 break; 203 case dwarf_s22: 204 reg_info.name = "s22"; 205 break; 206 case dwarf_s23: 207 reg_info.name = "s23"; 208 break; 209 case dwarf_s24: 210 reg_info.name = "s24"; 211 break; 212 case dwarf_s25: 213 reg_info.name = "s25"; 214 break; 215 case dwarf_s26: 216 reg_info.name = "s26"; 217 break; 218 case dwarf_s27: 219 reg_info.name = "s27"; 220 break; 221 case dwarf_s28: 222 reg_info.name = "s28"; 223 break; 224 case dwarf_s29: 225 reg_info.name = "s29"; 226 break; 227 case dwarf_s30: 228 reg_info.name = "s30"; 229 break; 230 case dwarf_s31: 231 reg_info.name = "s31"; 232 break; 233 234 // FPA Registers 0-7 235 case dwarf_f0: 236 reg_info.name = "f0"; 237 break; 238 case dwarf_f1: 239 reg_info.name = "f1"; 240 break; 241 case dwarf_f2: 242 reg_info.name = "f2"; 243 break; 244 case dwarf_f3: 245 reg_info.name = "f3"; 246 break; 247 case dwarf_f4: 248 reg_info.name = "f4"; 249 break; 250 case dwarf_f5: 251 reg_info.name = "f5"; 252 break; 253 case dwarf_f6: 254 reg_info.name = "f6"; 255 break; 256 case dwarf_f7: 257 reg_info.name = "f7"; 258 break; 259 260 // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator 261 // register 0 - 7 (they do overlap with wCGR0 - wCGR7) 262 case dwarf_wCGR0: 263 reg_info.name = "wCGR0/ACC0"; 264 break; 265 case dwarf_wCGR1: 266 reg_info.name = "wCGR1/ACC1"; 267 break; 268 case dwarf_wCGR2: 269 reg_info.name = "wCGR2/ACC2"; 270 break; 271 case dwarf_wCGR3: 272 reg_info.name = "wCGR3/ACC3"; 273 break; 274 case dwarf_wCGR4: 275 reg_info.name = "wCGR4/ACC4"; 276 break; 277 case dwarf_wCGR5: 278 reg_info.name = "wCGR5/ACC5"; 279 break; 280 case dwarf_wCGR6: 281 reg_info.name = "wCGR6/ACC6"; 282 break; 283 case dwarf_wCGR7: 284 reg_info.name = "wCGR7/ACC7"; 285 break; 286 287 // Intel wireless MMX data registers 0 - 15 288 case dwarf_wR0: 289 reg_info.name = "wR0"; 290 break; 291 case dwarf_wR1: 292 reg_info.name = "wR1"; 293 break; 294 case dwarf_wR2: 295 reg_info.name = "wR2"; 296 break; 297 case dwarf_wR3: 298 reg_info.name = "wR3"; 299 break; 300 case dwarf_wR4: 301 reg_info.name = "wR4"; 302 break; 303 case dwarf_wR5: 304 reg_info.name = "wR5"; 305 break; 306 case dwarf_wR6: 307 reg_info.name = "wR6"; 308 break; 309 case dwarf_wR7: 310 reg_info.name = "wR7"; 311 break; 312 case dwarf_wR8: 313 reg_info.name = "wR8"; 314 break; 315 case dwarf_wR9: 316 reg_info.name = "wR9"; 317 break; 318 case dwarf_wR10: 319 reg_info.name = "wR10"; 320 break; 321 case dwarf_wR11: 322 reg_info.name = "wR11"; 323 break; 324 case dwarf_wR12: 325 reg_info.name = "wR12"; 326 break; 327 case dwarf_wR13: 328 reg_info.name = "wR13"; 329 break; 330 case dwarf_wR14: 331 reg_info.name = "wR14"; 332 break; 333 case dwarf_wR15: 334 reg_info.name = "wR15"; 335 break; 336 337 case dwarf_spsr: 338 reg_info.name = "spsr"; 339 break; 340 case dwarf_spsr_fiq: 341 reg_info.name = "spsr_fiq"; 342 break; 343 case dwarf_spsr_irq: 344 reg_info.name = "spsr_irq"; 345 break; 346 case dwarf_spsr_abt: 347 reg_info.name = "spsr_abt"; 348 break; 349 case dwarf_spsr_und: 350 reg_info.name = "spsr_und"; 351 break; 352 case dwarf_spsr_svc: 353 reg_info.name = "spsr_svc"; 354 break; 355 356 case dwarf_r8_usr: 357 reg_info.name = "r8_usr"; 358 break; 359 case dwarf_r9_usr: 360 reg_info.name = "r9_usr"; 361 break; 362 case dwarf_r10_usr: 363 reg_info.name = "r10_usr"; 364 break; 365 case dwarf_r11_usr: 366 reg_info.name = "r11_usr"; 367 break; 368 case dwarf_r12_usr: 369 reg_info.name = "r12_usr"; 370 break; 371 case dwarf_r13_usr: 372 reg_info.name = "r13_usr"; 373 break; 374 case dwarf_r14_usr: 375 reg_info.name = "r14_usr"; 376 break; 377 case dwarf_r8_fiq: 378 reg_info.name = "r8_fiq"; 379 break; 380 case dwarf_r9_fiq: 381 reg_info.name = "r9_fiq"; 382 break; 383 case dwarf_r10_fiq: 384 reg_info.name = "r10_fiq"; 385 break; 386 case dwarf_r11_fiq: 387 reg_info.name = "r11_fiq"; 388 break; 389 case dwarf_r12_fiq: 390 reg_info.name = "r12_fiq"; 391 break; 392 case dwarf_r13_fiq: 393 reg_info.name = "r13_fiq"; 394 break; 395 case dwarf_r14_fiq: 396 reg_info.name = "r14_fiq"; 397 break; 398 case dwarf_r13_irq: 399 reg_info.name = "r13_irq"; 400 break; 401 case dwarf_r14_irq: 402 reg_info.name = "r14_irq"; 403 break; 404 case dwarf_r13_abt: 405 reg_info.name = "r13_abt"; 406 break; 407 case dwarf_r14_abt: 408 reg_info.name = "r14_abt"; 409 break; 410 case dwarf_r13_und: 411 reg_info.name = "r13_und"; 412 break; 413 case dwarf_r14_und: 414 reg_info.name = "r14_und"; 415 break; 416 case dwarf_r13_svc: 417 reg_info.name = "r13_svc"; 418 break; 419 case dwarf_r14_svc: 420 reg_info.name = "r14_svc"; 421 break; 422 423 // Intel wireless MMX control register in co-processor 0 - 7 424 case dwarf_wC0: 425 reg_info.name = "wC0"; 426 break; 427 case dwarf_wC1: 428 reg_info.name = "wC1"; 429 break; 430 case dwarf_wC2: 431 reg_info.name = "wC2"; 432 break; 433 case dwarf_wC3: 434 reg_info.name = "wC3"; 435 break; 436 case dwarf_wC4: 437 reg_info.name = "wC4"; 438 break; 439 case dwarf_wC5: 440 reg_info.name = "wC5"; 441 break; 442 case dwarf_wC6: 443 reg_info.name = "wC6"; 444 break; 445 case dwarf_wC7: 446 reg_info.name = "wC7"; 447 break; 448 449 // VFP-v3/Neon 450 case dwarf_d0: 451 reg_info.name = "d0"; 452 break; 453 case dwarf_d1: 454 reg_info.name = "d1"; 455 break; 456 case dwarf_d2: 457 reg_info.name = "d2"; 458 break; 459 case dwarf_d3: 460 reg_info.name = "d3"; 461 break; 462 case dwarf_d4: 463 reg_info.name = "d4"; 464 break; 465 case dwarf_d5: 466 reg_info.name = "d5"; 467 break; 468 case dwarf_d6: 469 reg_info.name = "d6"; 470 break; 471 case dwarf_d7: 472 reg_info.name = "d7"; 473 break; 474 case dwarf_d8: 475 reg_info.name = "d8"; 476 break; 477 case dwarf_d9: 478 reg_info.name = "d9"; 479 break; 480 case dwarf_d10: 481 reg_info.name = "d10"; 482 break; 483 case dwarf_d11: 484 reg_info.name = "d11"; 485 break; 486 case dwarf_d12: 487 reg_info.name = "d12"; 488 break; 489 case dwarf_d13: 490 reg_info.name = "d13"; 491 break; 492 case dwarf_d14: 493 reg_info.name = "d14"; 494 break; 495 case dwarf_d15: 496 reg_info.name = "d15"; 497 break; 498 case dwarf_d16: 499 reg_info.name = "d16"; 500 break; 501 case dwarf_d17: 502 reg_info.name = "d17"; 503 break; 504 case dwarf_d18: 505 reg_info.name = "d18"; 506 break; 507 case dwarf_d19: 508 reg_info.name = "d19"; 509 break; 510 case dwarf_d20: 511 reg_info.name = "d20"; 512 break; 513 case dwarf_d21: 514 reg_info.name = "d21"; 515 break; 516 case dwarf_d22: 517 reg_info.name = "d22"; 518 break; 519 case dwarf_d23: 520 reg_info.name = "d23"; 521 break; 522 case dwarf_d24: 523 reg_info.name = "d24"; 524 break; 525 case dwarf_d25: 526 reg_info.name = "d25"; 527 break; 528 case dwarf_d26: 529 reg_info.name = "d26"; 530 break; 531 case dwarf_d27: 532 reg_info.name = "d27"; 533 break; 534 case dwarf_d28: 535 reg_info.name = "d28"; 536 break; 537 case dwarf_d29: 538 reg_info.name = "d29"; 539 break; 540 case dwarf_d30: 541 reg_info.name = "d30"; 542 break; 543 case dwarf_d31: 544 reg_info.name = "d31"; 545 break; 546 547 // NEON 128-bit vector registers (overlays the d registers) 548 case dwarf_q0: 549 reg_info.name = "q0"; 550 break; 551 case dwarf_q1: 552 reg_info.name = "q1"; 553 break; 554 case dwarf_q2: 555 reg_info.name = "q2"; 556 break; 557 case dwarf_q3: 558 reg_info.name = "q3"; 559 break; 560 case dwarf_q4: 561 reg_info.name = "q4"; 562 break; 563 case dwarf_q5: 564 reg_info.name = "q5"; 565 break; 566 case dwarf_q6: 567 reg_info.name = "q6"; 568 break; 569 case dwarf_q7: 570 reg_info.name = "q7"; 571 break; 572 case dwarf_q8: 573 reg_info.name = "q8"; 574 break; 575 case dwarf_q9: 576 reg_info.name = "q9"; 577 break; 578 case dwarf_q10: 579 reg_info.name = "q10"; 580 break; 581 case dwarf_q11: 582 reg_info.name = "q11"; 583 break; 584 case dwarf_q12: 585 reg_info.name = "q12"; 586 break; 587 case dwarf_q13: 588 reg_info.name = "q13"; 589 break; 590 case dwarf_q14: 591 reg_info.name = "q14"; 592 break; 593 case dwarf_q15: 594 reg_info.name = "q15"; 595 break; 596 597 default: 598 return false; 599 } 600 return true; 601 } 602 603 // A8.6.50 604 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 605 static uint32_t CountITSize(uint32_t ITMask) { 606 // First count the trailing zeros of the IT mask. 607 uint32_t TZ = llvm::countTrailingZeros(ITMask); 608 if (TZ > 3) { 609 #ifdef LLDB_CONFIGURATION_DEBUG 610 printf("Encoding error: IT Mask '0000'\n"); 611 #endif 612 return 0; 613 } 614 return (4 - TZ); 615 } 616 617 // Init ITState. Note that at least one bit is always 1 in mask. 618 bool ITSession::InitIT(uint32_t bits7_0) { 619 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 620 if (ITCounter == 0) 621 return false; 622 623 // A8.6.50 IT 624 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 625 if (FirstCond == 0xF) { 626 #ifdef LLDB_CONFIGURATION_DEBUG 627 printf("Encoding error: IT FirstCond '1111'\n"); 628 #endif 629 return false; 630 } 631 if (FirstCond == 0xE && ITCounter != 1) { 632 #ifdef LLDB_CONFIGURATION_DEBUG 633 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 634 #endif 635 return false; 636 } 637 638 ITState = bits7_0; 639 return true; 640 } 641 642 // Update ITState if necessary. 643 void ITSession::ITAdvance() { 644 // assert(ITCounter); 645 --ITCounter; 646 if (ITCounter == 0) 647 ITState = 0; 648 else { 649 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 650 SetBits32(ITState, 4, 0, NewITState4_0); 651 } 652 } 653 654 // Return true if we're inside an IT Block. 655 bool ITSession::InITBlock() { return ITCounter != 0; } 656 657 // Return true if we're the last instruction inside an IT Block. 658 bool ITSession::LastInITBlock() { return ITCounter == 1; } 659 660 // Get condition bits for the current thumb instruction. 661 uint32_t ITSession::GetCond() { 662 if (InITBlock()) 663 return Bits32(ITState, 7, 4); 664 else 665 return COND_AL; 666 } 667 668 // ARM constants used during decoding 669 #define REG_RD 0 670 #define LDM_REGLIST 1 671 #define SP_REG 13 672 #define LR_REG 14 673 #define PC_REG 15 674 #define PC_REGLIST_BIT 0x8000 675 676 #define ARMv4 (1u << 0) 677 #define ARMv4T (1u << 1) 678 #define ARMv5T (1u << 2) 679 #define ARMv5TE (1u << 3) 680 #define ARMv5TEJ (1u << 4) 681 #define ARMv6 (1u << 5) 682 #define ARMv6K (1u << 6) 683 #define ARMv6T2 (1u << 7) 684 #define ARMv7 (1u << 8) 685 #define ARMv7S (1u << 9) 686 #define ARMv8 (1u << 10) 687 #define ARMvAll (0xffffffffu) 688 689 #define ARMV4T_ABOVE \ 690 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \ 691 ARMv7S | ARMv8) 692 #define ARMV5_ABOVE \ 693 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \ 694 ARMv8) 695 #define ARMV5TE_ABOVE \ 696 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 697 #define ARMV5J_ABOVE \ 698 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 699 #define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 700 #define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 701 #define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8) 702 703 #define No_VFP 0 704 #define VFPv1 (1u << 1) 705 #define VFPv2 (1u << 2) 706 #define VFPv3 (1u << 3) 707 #define AdvancedSIMD (1u << 4) 708 709 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 710 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 711 #define VFPv2v3 (VFPv2 | VFPv3) 712 713 //---------------------------------------------------------------------- 714 // 715 // EmulateInstructionARM implementation 716 // 717 //---------------------------------------------------------------------- 718 719 void EmulateInstructionARM::Initialize() { 720 PluginManager::RegisterPlugin(GetPluginNameStatic(), 721 GetPluginDescriptionStatic(), CreateInstance); 722 } 723 724 void EmulateInstructionARM::Terminate() { 725 PluginManager::UnregisterPlugin(CreateInstance); 726 } 727 728 ConstString EmulateInstructionARM::GetPluginNameStatic() { 729 static ConstString g_name("arm"); 730 return g_name; 731 } 732 733 const char *EmulateInstructionARM::GetPluginDescriptionStatic() { 734 return "Emulate instructions for the ARM architecture."; 735 } 736 737 EmulateInstruction * 738 EmulateInstructionARM::CreateInstance(const ArchSpec &arch, 739 InstructionType inst_type) { 740 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic( 741 inst_type)) { 742 if (arch.GetTriple().getArch() == llvm::Triple::arm) { 743 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap( 744 new EmulateInstructionARM(arch)); 745 746 if (emulate_insn_ap.get()) 747 return emulate_insn_ap.release(); 748 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) { 749 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap( 750 new EmulateInstructionARM(arch)); 751 752 if (emulate_insn_ap.get()) 753 return emulate_insn_ap.release(); 754 } 755 } 756 757 return NULL; 758 } 759 760 bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) { 761 if (arch.GetTriple().getArch() == llvm::Triple::arm) 762 return true; 763 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 764 return true; 765 766 return false; 767 } 768 769 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for 770 // many ARM instructions. 771 bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) { 772 EmulateInstruction::Context context; 773 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 774 context.SetNoArgs(); 775 776 uint32_t random_data = rand(); 777 const uint32_t addr_byte_size = GetAddressByteSize(); 778 779 return MemAWrite(context, address, random_data, addr_byte_size); 780 } 781 782 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM 783 // instructions. 784 bool EmulateInstructionARM::WriteBits32Unknown(int n) { 785 EmulateInstruction::Context context; 786 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 787 context.SetNoArgs(); 788 789 bool success; 790 uint32_t data = 791 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 792 793 if (!success) 794 return false; 795 796 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data)) 797 return false; 798 799 return true; 800 } 801 802 bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind, 803 uint32_t reg_num, 804 RegisterInfo ®_info) { 805 if (reg_kind == eRegisterKindGeneric) { 806 switch (reg_num) { 807 case LLDB_REGNUM_GENERIC_PC: 808 reg_kind = eRegisterKindDWARF; 809 reg_num = dwarf_pc; 810 break; 811 case LLDB_REGNUM_GENERIC_SP: 812 reg_kind = eRegisterKindDWARF; 813 reg_num = dwarf_sp; 814 break; 815 case LLDB_REGNUM_GENERIC_FP: 816 reg_kind = eRegisterKindDWARF; 817 reg_num = dwarf_r7; 818 break; 819 case LLDB_REGNUM_GENERIC_RA: 820 reg_kind = eRegisterKindDWARF; 821 reg_num = dwarf_lr; 822 break; 823 case LLDB_REGNUM_GENERIC_FLAGS: 824 reg_kind = eRegisterKindDWARF; 825 reg_num = dwarf_cpsr; 826 break; 827 default: 828 return false; 829 } 830 } 831 832 if (reg_kind == eRegisterKindDWARF) 833 return GetARMDWARFRegisterInfo(reg_num, reg_info); 834 return false; 835 } 836 837 uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const { 838 if (m_arch.GetTriple().isAndroid()) 839 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android 840 bool is_apple = false; 841 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 842 is_apple = true; 843 switch (m_arch.GetTriple().getOS()) { 844 case llvm::Triple::Darwin: 845 case llvm::Triple::MacOSX: 846 case llvm::Triple::IOS: 847 case llvm::Triple::TvOS: 848 case llvm::Triple::WatchOS: 849 // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS: 850 is_apple = true; 851 break; 852 default: 853 break; 854 } 855 856 /* On Apple iOS et al, the frame pointer register is always r7. 857 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 858 */ 859 860 uint32_t fp_regnum = 11; 861 862 if (is_apple) 863 fp_regnum = 7; 864 865 if (m_opcode_mode == eModeThumb) 866 fp_regnum = 7; 867 868 return fp_regnum; 869 } 870 871 uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const { 872 bool is_apple = false; 873 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 874 is_apple = true; 875 switch (m_arch.GetTriple().getOS()) { 876 case llvm::Triple::Darwin: 877 case llvm::Triple::MacOSX: 878 case llvm::Triple::IOS: 879 is_apple = true; 880 break; 881 default: 882 break; 883 } 884 885 /* On Apple iOS et al, the frame pointer register is always r7. 886 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 887 */ 888 889 uint32_t fp_regnum = dwarf_r11; 890 891 if (is_apple) 892 fp_regnum = dwarf_r7; 893 894 if (m_opcode_mode == eModeThumb) 895 fp_regnum = dwarf_r7; 896 897 return fp_regnum; 898 } 899 900 // Push Multiple Registers stores multiple registers to the stack, storing to 901 // consecutive memory locations ending just below the address in SP, and 902 // updates 903 // SP to point to the start of the stored data. 904 bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode, 905 const ARMEncoding encoding) { 906 #if 0 907 // ARM pseudo code... 908 if (ConditionPassed()) 909 { 910 EncodingSpecificOperations(); 911 NullCheckIfThumbEE(13); 912 address = SP - 4*BitCount(registers); 913 914 for (i = 0 to 14) 915 { 916 if (registers<i> == '1') 917 { 918 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 919 MemA[address,4] = bits(32) UNKNOWN; 920 else 921 MemA[address,4] = R[i]; 922 address = address + 4; 923 } 924 } 925 926 if (registers<15> == '1') // Only possible for encoding A1 or A2 927 MemA[address,4] = PCStoreValue(); 928 929 SP = SP - 4*BitCount(registers); 930 } 931 #endif 932 933 bool success = false; 934 if (ConditionPassed(opcode)) { 935 const uint32_t addr_byte_size = GetAddressByteSize(); 936 const addr_t sp = ReadCoreReg(SP_REG, &success); 937 if (!success) 938 return false; 939 uint32_t registers = 0; 940 uint32_t Rt; // the source register 941 switch (encoding) { 942 case eEncodingT1: 943 registers = Bits32(opcode, 7, 0); 944 // The M bit represents LR. 945 if (Bit32(opcode, 8)) 946 registers |= (1u << 14); 947 // if BitCount(registers) < 1 then UNPREDICTABLE; 948 if (BitCount(registers) < 1) 949 return false; 950 break; 951 case eEncodingT2: 952 // Ignore bits 15 & 13. 953 registers = Bits32(opcode, 15, 0) & ~0xa000; 954 // if BitCount(registers) < 2 then UNPREDICTABLE; 955 if (BitCount(registers) < 2) 956 return false; 957 break; 958 case eEncodingT3: 959 Rt = Bits32(opcode, 15, 12); 960 // if BadReg(t) then UNPREDICTABLE; 961 if (BadReg(Rt)) 962 return false; 963 registers = (1u << Rt); 964 break; 965 case eEncodingA1: 966 registers = Bits32(opcode, 15, 0); 967 // Instead of return false, let's handle the following case as well, 968 // which amounts to pushing one reg onto the full descending stacks. 969 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 970 break; 971 case eEncodingA2: 972 Rt = Bits32(opcode, 15, 12); 973 // if t == 13 then UNPREDICTABLE; 974 if (Rt == dwarf_sp) 975 return false; 976 registers = (1u << Rt); 977 break; 978 default: 979 return false; 980 } 981 addr_t sp_offset = addr_byte_size * BitCount(registers); 982 addr_t addr = sp - sp_offset; 983 uint32_t i; 984 985 EmulateInstruction::Context context; 986 context.type = EmulateInstruction::eContextPushRegisterOnStack; 987 RegisterInfo reg_info; 988 RegisterInfo sp_reg; 989 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 990 for (i = 0; i < 15; ++i) { 991 if (BitIsSet(registers, i)) { 992 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info); 993 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 994 uint32_t reg_value = ReadCoreReg(i, &success); 995 if (!success) 996 return false; 997 if (!MemAWrite(context, addr, reg_value, addr_byte_size)) 998 return false; 999 addr += addr_byte_size; 1000 } 1001 } 1002 1003 if (BitIsSet(registers, 15)) { 1004 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info); 1005 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 1006 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1007 if (!success) 1008 return false; 1009 if (!MemAWrite(context, addr, pc, addr_byte_size)) 1010 return false; 1011 } 1012 1013 context.type = EmulateInstruction::eContextAdjustStackPointer; 1014 context.SetImmediateSigned(-sp_offset); 1015 1016 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1017 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1018 return false; 1019 } 1020 return true; 1021 } 1022 1023 // Pop Multiple Registers loads multiple registers from the stack, loading from 1024 // consecutive memory locations staring at the address in SP, and updates 1025 // SP to point just above the loaded data. 1026 bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode, 1027 const ARMEncoding encoding) { 1028 #if 0 1029 // ARM pseudo code... 1030 if (ConditionPassed()) 1031 { 1032 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 1033 address = SP; 1034 for i = 0 to 14 1035 if registers<i> == '1' then 1036 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 1037 if registers<15> == '1' then 1038 if UnalignedAllowed then 1039 LoadWritePC(MemU[address,4]); 1040 else 1041 LoadWritePC(MemA[address,4]); 1042 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 1043 if registers<13> == '1' then SP = bits(32) UNKNOWN; 1044 } 1045 #endif 1046 1047 bool success = false; 1048 1049 if (ConditionPassed(opcode)) { 1050 const uint32_t addr_byte_size = GetAddressByteSize(); 1051 const addr_t sp = ReadCoreReg(SP_REG, &success); 1052 if (!success) 1053 return false; 1054 uint32_t registers = 0; 1055 uint32_t Rt; // the destination register 1056 switch (encoding) { 1057 case eEncodingT1: 1058 registers = Bits32(opcode, 7, 0); 1059 // The P bit represents PC. 1060 if (Bit32(opcode, 8)) 1061 registers |= (1u << 15); 1062 // if BitCount(registers) < 1 then UNPREDICTABLE; 1063 if (BitCount(registers) < 1) 1064 return false; 1065 break; 1066 case eEncodingT2: 1067 // Ignore bit 13. 1068 registers = Bits32(opcode, 15, 0) & ~0x2000; 1069 // if BitCount(registers) < 2 || (P == '1' && M == '1') then 1070 // UNPREDICTABLE; 1071 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 1072 return false; 1073 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 1074 // UNPREDICTABLE; 1075 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 1076 return false; 1077 break; 1078 case eEncodingT3: 1079 Rt = Bits32(opcode, 15, 12); 1080 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then 1081 // UNPREDICTABLE; 1082 if (Rt == 13) 1083 return false; 1084 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1085 return false; 1086 registers = (1u << Rt); 1087 break; 1088 case eEncodingA1: 1089 registers = Bits32(opcode, 15, 0); 1090 // Instead of return false, let's handle the following case as well, 1091 // which amounts to popping one reg from the full descending stacks. 1092 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 1093 1094 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 1095 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 1096 return false; 1097 break; 1098 case eEncodingA2: 1099 Rt = Bits32(opcode, 15, 12); 1100 // if t == 13 then UNPREDICTABLE; 1101 if (Rt == dwarf_sp) 1102 return false; 1103 registers = (1u << Rt); 1104 break; 1105 default: 1106 return false; 1107 } 1108 addr_t sp_offset = addr_byte_size * BitCount(registers); 1109 addr_t addr = sp; 1110 uint32_t i, data; 1111 1112 EmulateInstruction::Context context; 1113 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1114 1115 RegisterInfo sp_reg; 1116 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1117 1118 for (i = 0; i < 15; ++i) { 1119 if (BitIsSet(registers, i)) { 1120 context.SetAddress(addr); 1121 data = MemARead(context, addr, 4, 0, &success); 1122 if (!success) 1123 return false; 1124 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 1125 data)) 1126 return false; 1127 addr += addr_byte_size; 1128 } 1129 } 1130 1131 if (BitIsSet(registers, 15)) { 1132 context.SetRegisterPlusOffset(sp_reg, addr - sp); 1133 data = MemARead(context, addr, 4, 0, &success); 1134 if (!success) 1135 return false; 1136 // In ARMv5T and above, this is an interworking branch. 1137 if (!LoadWritePC(context, data)) 1138 return false; 1139 // addr += addr_byte_size; 1140 } 1141 1142 context.type = EmulateInstruction::eContextAdjustStackPointer; 1143 context.SetImmediateSigned(sp_offset); 1144 1145 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1146 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1147 return false; 1148 } 1149 return true; 1150 } 1151 1152 // Set r7 or ip to point to saved value residing within the stack. 1153 // ADD (SP plus immediate) 1154 bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode, 1155 const ARMEncoding encoding) { 1156 #if 0 1157 // ARM pseudo code... 1158 if (ConditionPassed()) 1159 { 1160 EncodingSpecificOperations(); 1161 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1162 if d == 15 then 1163 ALUWritePC(result); // setflags is always FALSE here 1164 else 1165 R[d] = result; 1166 if setflags then 1167 APSR.N = result<31>; 1168 APSR.Z = IsZeroBit(result); 1169 APSR.C = carry; 1170 APSR.V = overflow; 1171 } 1172 #endif 1173 1174 bool success = false; 1175 1176 if (ConditionPassed(opcode)) { 1177 const addr_t sp = ReadCoreReg(SP_REG, &success); 1178 if (!success) 1179 return false; 1180 uint32_t Rd; // the destination register 1181 uint32_t imm32; 1182 switch (encoding) { 1183 case eEncodingT1: 1184 Rd = 7; 1185 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 1186 break; 1187 case eEncodingA1: 1188 Rd = Bits32(opcode, 15, 12); 1189 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1190 break; 1191 default: 1192 return false; 1193 } 1194 addr_t sp_offset = imm32; 1195 addr_t addr = sp + sp_offset; // a pointer to the stack area 1196 1197 EmulateInstruction::Context context; 1198 if (Rd == GetFramePointerRegisterNumber()) 1199 context.type = eContextSetFramePointer; 1200 else 1201 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1202 RegisterInfo sp_reg; 1203 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1204 context.SetRegisterPlusOffset(sp_reg, sp_offset); 1205 1206 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, 1207 addr)) 1208 return false; 1209 } 1210 return true; 1211 } 1212 1213 // Set r7 or ip to the current stack pointer. 1214 // MOV (register) 1215 bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode, 1216 const ARMEncoding encoding) { 1217 #if 0 1218 // ARM pseudo code... 1219 if (ConditionPassed()) 1220 { 1221 EncodingSpecificOperations(); 1222 result = R[m]; 1223 if d == 15 then 1224 ALUWritePC(result); // setflags is always FALSE here 1225 else 1226 R[d] = result; 1227 if setflags then 1228 APSR.N = result<31>; 1229 APSR.Z = IsZeroBit(result); 1230 // APSR.C unchanged 1231 // APSR.V unchanged 1232 } 1233 #endif 1234 1235 bool success = false; 1236 1237 if (ConditionPassed(opcode)) { 1238 const addr_t sp = ReadCoreReg(SP_REG, &success); 1239 if (!success) 1240 return false; 1241 uint32_t Rd; // the destination register 1242 switch (encoding) { 1243 case eEncodingT1: 1244 Rd = 7; 1245 break; 1246 case eEncodingA1: 1247 Rd = 12; 1248 break; 1249 default: 1250 return false; 1251 } 1252 1253 EmulateInstruction::Context context; 1254 if (Rd == GetFramePointerRegisterNumber()) 1255 context.type = EmulateInstruction::eContextSetFramePointer; 1256 else 1257 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1258 RegisterInfo sp_reg; 1259 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1260 context.SetRegisterPlusOffset(sp_reg, 0); 1261 1262 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 1263 return false; 1264 } 1265 return true; 1266 } 1267 1268 // Move from high register (r8-r15) to low register (r0-r7). 1269 // MOV (register) 1270 bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode, 1271 const ARMEncoding encoding) { 1272 return EmulateMOVRdRm(opcode, encoding); 1273 } 1274 1275 // Move from register to register. 1276 // MOV (register) 1277 bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode, 1278 const ARMEncoding encoding) { 1279 #if 0 1280 // ARM pseudo code... 1281 if (ConditionPassed()) 1282 { 1283 EncodingSpecificOperations(); 1284 result = R[m]; 1285 if d == 15 then 1286 ALUWritePC(result); // setflags is always FALSE here 1287 else 1288 R[d] = result; 1289 if setflags then 1290 APSR.N = result<31>; 1291 APSR.Z = IsZeroBit(result); 1292 // APSR.C unchanged 1293 // APSR.V unchanged 1294 } 1295 #endif 1296 1297 bool success = false; 1298 1299 if (ConditionPassed(opcode)) { 1300 uint32_t Rm; // the source register 1301 uint32_t Rd; // the destination register 1302 bool setflags; 1303 switch (encoding) { 1304 case eEncodingT1: 1305 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1306 Rm = Bits32(opcode, 6, 3); 1307 setflags = false; 1308 if (Rd == 15 && InITBlock() && !LastInITBlock()) 1309 return false; 1310 break; 1311 case eEncodingT2: 1312 Rd = Bits32(opcode, 2, 0); 1313 Rm = Bits32(opcode, 5, 3); 1314 setflags = true; 1315 if (InITBlock()) 1316 return false; 1317 break; 1318 case eEncodingT3: 1319 Rd = Bits32(opcode, 11, 8); 1320 Rm = Bits32(opcode, 3, 0); 1321 setflags = BitIsSet(opcode, 20); 1322 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1323 if (setflags && (BadReg(Rd) || BadReg(Rm))) 1324 return false; 1325 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then 1326 // UNPREDICTABLE; 1327 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 1328 return false; 1329 break; 1330 case eEncodingA1: 1331 Rd = Bits32(opcode, 15, 12); 1332 Rm = Bits32(opcode, 3, 0); 1333 setflags = BitIsSet(opcode, 20); 1334 1335 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1336 // instructions; 1337 if (Rd == 15 && setflags) 1338 return EmulateSUBSPcLrEtc(opcode, encoding); 1339 break; 1340 default: 1341 return false; 1342 } 1343 uint32_t result = ReadCoreReg(Rm, &success); 1344 if (!success) 1345 return false; 1346 1347 // The context specifies that Rm is to be moved into Rd. 1348 EmulateInstruction::Context context; 1349 if (Rd == 13) 1350 context.type = EmulateInstruction::eContextAdjustStackPointer; 1351 else 1352 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1353 RegisterInfo dwarf_reg; 1354 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1355 context.SetRegisterPlusOffset(dwarf_reg, 0); 1356 1357 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 1358 return false; 1359 } 1360 return true; 1361 } 1362 1363 // Move (immediate) writes an immediate value to the destination register. It 1364 // can optionally update the condition flags based on the value. 1365 // MOV (immediate) 1366 bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode, 1367 const ARMEncoding encoding) { 1368 #if 0 1369 // ARM pseudo code... 1370 if (ConditionPassed()) 1371 { 1372 EncodingSpecificOperations(); 1373 result = imm32; 1374 if d == 15 then // Can only occur for ARM encoding 1375 ALUWritePC(result); // setflags is always FALSE here 1376 else 1377 R[d] = result; 1378 if setflags then 1379 APSR.N = result<31>; 1380 APSR.Z = IsZeroBit(result); 1381 APSR.C = carry; 1382 // APSR.V unchanged 1383 } 1384 #endif 1385 1386 if (ConditionPassed(opcode)) { 1387 uint32_t Rd; // the destination register 1388 uint32_t imm32; // the immediate value to be written to Rd 1389 uint32_t carry = 1390 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 1391 // for setflags == false, this value is a don't care initialized to 1392 // 0 to silence the static analyzer 1393 bool setflags; 1394 switch (encoding) { 1395 case eEncodingT1: 1396 Rd = Bits32(opcode, 10, 8); 1397 setflags = !InITBlock(); 1398 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 1399 carry = APSR_C; 1400 1401 break; 1402 1403 case eEncodingT2: 1404 Rd = Bits32(opcode, 11, 8); 1405 setflags = BitIsSet(opcode, 20); 1406 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1407 if (BadReg(Rd)) 1408 return false; 1409 1410 break; 1411 1412 case eEncodingT3: { 1413 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 1414 // 32); 1415 Rd = Bits32(opcode, 11, 8); 1416 setflags = false; 1417 uint32_t imm4 = Bits32(opcode, 19, 16); 1418 uint32_t imm3 = Bits32(opcode, 14, 12); 1419 uint32_t i = Bit32(opcode, 26); 1420 uint32_t imm8 = Bits32(opcode, 7, 0); 1421 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 1422 1423 // if BadReg(d) then UNPREDICTABLE; 1424 if (BadReg(Rd)) 1425 return false; 1426 } break; 1427 1428 case eEncodingA1: 1429 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = 1430 // ARMExpandImm_C(imm12, APSR.C); 1431 Rd = Bits32(opcode, 15, 12); 1432 setflags = BitIsSet(opcode, 20); 1433 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1434 1435 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1436 // instructions; 1437 if ((Rd == 15) && setflags) 1438 return EmulateSUBSPcLrEtc(opcode, encoding); 1439 1440 break; 1441 1442 case eEncodingA2: { 1443 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 1444 Rd = Bits32(opcode, 15, 12); 1445 setflags = false; 1446 uint32_t imm4 = Bits32(opcode, 19, 16); 1447 uint32_t imm12 = Bits32(opcode, 11, 0); 1448 imm32 = (imm4 << 12) | imm12; 1449 1450 // if d == 15 then UNPREDICTABLE; 1451 if (Rd == 15) 1452 return false; 1453 } break; 1454 1455 default: 1456 return false; 1457 } 1458 uint32_t result = imm32; 1459 1460 // The context specifies that an immediate is to be moved into Rd. 1461 EmulateInstruction::Context context; 1462 context.type = EmulateInstruction::eContextImmediate; 1463 context.SetNoArgs(); 1464 1465 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1466 return false; 1467 } 1468 return true; 1469 } 1470 1471 // MUL multiplies two register values. The least significant 32 bits of the 1472 // result are written to the destination 1473 // register. These 32 bits do not depend on whether the source register values 1474 // are considered to be signed values or unsigned values. 1475 // 1476 // Optionally, it can update the condition flags based on the result. In the 1477 // Thumb instruction set, this option is limited to only a few forms of the 1478 // instruction. 1479 bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode, 1480 const ARMEncoding encoding) { 1481 #if 0 1482 if ConditionPassed() then 1483 EncodingSpecificOperations(); 1484 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1485 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1486 result = operand1 * operand2; 1487 R[d] = result<31:0>; 1488 if setflags then 1489 APSR.N = result<31>; 1490 APSR.Z = IsZeroBit(result); 1491 if ArchVersion() == 4 then 1492 APSR.C = bit UNKNOWN; 1493 // else APSR.C unchanged 1494 // APSR.V always unchanged 1495 #endif 1496 1497 if (ConditionPassed(opcode)) { 1498 uint32_t d; 1499 uint32_t n; 1500 uint32_t m; 1501 bool setflags; 1502 1503 // EncodingSpecificOperations(); 1504 switch (encoding) { 1505 case eEncodingT1: 1506 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 1507 d = Bits32(opcode, 2, 0); 1508 n = Bits32(opcode, 5, 3); 1509 m = Bits32(opcode, 2, 0); 1510 setflags = !InITBlock(); 1511 1512 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1513 if ((ArchVersion() < ARMv6) && (d == n)) 1514 return false; 1515 1516 break; 1517 1518 case eEncodingT2: 1519 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 1520 d = Bits32(opcode, 11, 8); 1521 n = Bits32(opcode, 19, 16); 1522 m = Bits32(opcode, 3, 0); 1523 setflags = false; 1524 1525 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 1526 if (BadReg(d) || BadReg(n) || BadReg(m)) 1527 return false; 1528 1529 break; 1530 1531 case eEncodingA1: 1532 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 1533 d = Bits32(opcode, 19, 16); 1534 n = Bits32(opcode, 3, 0); 1535 m = Bits32(opcode, 11, 8); 1536 setflags = BitIsSet(opcode, 20); 1537 1538 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1539 if ((d == 15) || (n == 15) || (m == 15)) 1540 return false; 1541 1542 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1543 if ((ArchVersion() < ARMv6) && (d == n)) 1544 return false; 1545 1546 break; 1547 1548 default: 1549 return false; 1550 } 1551 1552 bool success = false; 1553 1554 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final 1555 // results 1556 uint64_t operand1 = 1557 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1558 if (!success) 1559 return false; 1560 1561 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final 1562 // results 1563 uint64_t operand2 = 1564 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1565 if (!success) 1566 return false; 1567 1568 // result = operand1 * operand2; 1569 uint64_t result = operand1 * operand2; 1570 1571 // R[d] = result<31:0>; 1572 RegisterInfo op1_reg; 1573 RegisterInfo op2_reg; 1574 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1575 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1576 1577 EmulateInstruction::Context context; 1578 context.type = eContextArithmetic; 1579 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 1580 1581 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 1582 (0x0000ffff & result))) 1583 return false; 1584 1585 // if setflags then 1586 if (setflags) { 1587 // APSR.N = result<31>; 1588 // APSR.Z = IsZeroBit(result); 1589 m_new_inst_cpsr = m_opcode_cpsr; 1590 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31)); 1591 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1592 if (m_new_inst_cpsr != m_opcode_cpsr) { 1593 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1594 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1595 return false; 1596 } 1597 1598 // if ArchVersion() == 4 then 1599 // APSR.C = bit UNKNOWN; 1600 } 1601 } 1602 return true; 1603 } 1604 1605 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to 1606 // the destination register. It can optionally update the condition flags based 1607 // on the value. 1608 bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode, 1609 const ARMEncoding encoding) { 1610 #if 0 1611 // ARM pseudo code... 1612 if (ConditionPassed()) 1613 { 1614 EncodingSpecificOperations(); 1615 result = NOT(imm32); 1616 if d == 15 then // Can only occur for ARM encoding 1617 ALUWritePC(result); // setflags is always FALSE here 1618 else 1619 R[d] = result; 1620 if setflags then 1621 APSR.N = result<31>; 1622 APSR.Z = IsZeroBit(result); 1623 APSR.C = carry; 1624 // APSR.V unchanged 1625 } 1626 #endif 1627 1628 if (ConditionPassed(opcode)) { 1629 uint32_t Rd; // the destination register 1630 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1631 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1632 bool setflags; 1633 switch (encoding) { 1634 case eEncodingT1: 1635 Rd = Bits32(opcode, 11, 8); 1636 setflags = BitIsSet(opcode, 20); 1637 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1638 break; 1639 case eEncodingA1: 1640 Rd = Bits32(opcode, 15, 12); 1641 setflags = BitIsSet(opcode, 20); 1642 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1643 1644 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1645 // instructions; 1646 if (Rd == 15 && setflags) 1647 return EmulateSUBSPcLrEtc(opcode, encoding); 1648 break; 1649 default: 1650 return false; 1651 } 1652 uint32_t result = ~imm32; 1653 1654 // The context specifies that an immediate is to be moved into Rd. 1655 EmulateInstruction::Context context; 1656 context.type = EmulateInstruction::eContextImmediate; 1657 context.SetNoArgs(); 1658 1659 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1660 return false; 1661 } 1662 return true; 1663 } 1664 1665 // Bitwise NOT (register) writes the bitwise inverse of a register value to the 1666 // destination register. It can optionally update the condition flags based on 1667 // the result. 1668 bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode, 1669 const ARMEncoding encoding) { 1670 #if 0 1671 // ARM pseudo code... 1672 if (ConditionPassed()) 1673 { 1674 EncodingSpecificOperations(); 1675 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1676 result = NOT(shifted); 1677 if d == 15 then // Can only occur for ARM encoding 1678 ALUWritePC(result); // setflags is always FALSE here 1679 else 1680 R[d] = result; 1681 if setflags then 1682 APSR.N = result<31>; 1683 APSR.Z = IsZeroBit(result); 1684 APSR.C = carry; 1685 // APSR.V unchanged 1686 } 1687 #endif 1688 1689 if (ConditionPassed(opcode)) { 1690 uint32_t Rm; // the source register 1691 uint32_t Rd; // the destination register 1692 ARM_ShifterType shift_t; 1693 uint32_t shift_n; // the shift applied to the value read from Rm 1694 bool setflags; 1695 uint32_t carry; // the carry bit after the shift operation 1696 switch (encoding) { 1697 case eEncodingT1: 1698 Rd = Bits32(opcode, 2, 0); 1699 Rm = Bits32(opcode, 5, 3); 1700 setflags = !InITBlock(); 1701 shift_t = SRType_LSL; 1702 shift_n = 0; 1703 if (InITBlock()) 1704 return false; 1705 break; 1706 case eEncodingT2: 1707 Rd = Bits32(opcode, 11, 8); 1708 Rm = Bits32(opcode, 3, 0); 1709 setflags = BitIsSet(opcode, 20); 1710 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1711 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1712 if (BadReg(Rd) || BadReg(Rm)) 1713 return false; 1714 break; 1715 case eEncodingA1: 1716 Rd = Bits32(opcode, 15, 12); 1717 Rm = Bits32(opcode, 3, 0); 1718 setflags = BitIsSet(opcode, 20); 1719 shift_n = DecodeImmShiftARM(opcode, shift_t); 1720 break; 1721 default: 1722 return false; 1723 } 1724 bool success = false; 1725 uint32_t value = ReadCoreReg(Rm, &success); 1726 if (!success) 1727 return false; 1728 1729 uint32_t shifted = 1730 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1731 if (!success) 1732 return false; 1733 uint32_t result = ~shifted; 1734 1735 // The context specifies that an immediate is to be moved into Rd. 1736 EmulateInstruction::Context context; 1737 context.type = EmulateInstruction::eContextImmediate; 1738 context.SetNoArgs(); 1739 1740 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1741 return false; 1742 } 1743 return true; 1744 } 1745 1746 // PC relative immediate load into register, possibly followed by ADD (SP plus 1747 // register). 1748 // LDR (literal) 1749 bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode, 1750 const ARMEncoding encoding) { 1751 #if 0 1752 // ARM pseudo code... 1753 if (ConditionPassed()) 1754 { 1755 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1756 base = Align(PC,4); 1757 address = if add then (base + imm32) else (base - imm32); 1758 data = MemU[address,4]; 1759 if t == 15 then 1760 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1761 elsif UnalignedSupport() || address<1:0> = '00' then 1762 R[t] = data; 1763 else // Can only apply before ARMv7 1764 if CurrentInstrSet() == InstrSet_ARM then 1765 R[t] = ROR(data, 8*UInt(address<1:0>)); 1766 else 1767 R[t] = bits(32) UNKNOWN; 1768 } 1769 #endif 1770 1771 if (ConditionPassed(opcode)) { 1772 bool success = false; 1773 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1774 if (!success) 1775 return false; 1776 1777 // PC relative immediate load context 1778 EmulateInstruction::Context context; 1779 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1780 RegisterInfo pc_reg; 1781 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 1782 context.SetRegisterPlusOffset(pc_reg, 0); 1783 1784 uint32_t Rt; // the destination register 1785 uint32_t imm32; // immediate offset from the PC 1786 bool add; // +imm32 or -imm32? 1787 addr_t base; // the base address 1788 addr_t address; // the PC relative address 1789 uint32_t data; // the literal data value from the PC relative load 1790 switch (encoding) { 1791 case eEncodingT1: 1792 Rt = Bits32(opcode, 10, 8); 1793 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1794 add = true; 1795 break; 1796 case eEncodingT2: 1797 Rt = Bits32(opcode, 15, 12); 1798 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1799 add = BitIsSet(opcode, 23); 1800 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1801 return false; 1802 break; 1803 default: 1804 return false; 1805 } 1806 1807 base = Align(pc, 4); 1808 if (add) 1809 address = base + imm32; 1810 else 1811 address = base - imm32; 1812 1813 context.SetRegisterPlusOffset(pc_reg, address - base); 1814 data = MemURead(context, address, 4, 0, &success); 1815 if (!success) 1816 return false; 1817 1818 if (Rt == 15) { 1819 if (Bits32(address, 1, 0) == 0) { 1820 // In ARMv5T and above, this is an interworking branch. 1821 if (!LoadWritePC(context, data)) 1822 return false; 1823 } else 1824 return false; 1825 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 1826 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 1827 data)) 1828 return false; 1829 } else // We don't handle ARM for now. 1830 return false; 1831 } 1832 return true; 1833 } 1834 1835 // An add operation to adjust the SP. 1836 // ADD (SP plus immediate) 1837 bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode, 1838 const ARMEncoding encoding) { 1839 #if 0 1840 // ARM pseudo code... 1841 if (ConditionPassed()) 1842 { 1843 EncodingSpecificOperations(); 1844 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1845 if d == 15 then // Can only occur for ARM encoding 1846 ALUWritePC(result); // setflags is always FALSE here 1847 else 1848 R[d] = result; 1849 if setflags then 1850 APSR.N = result<31>; 1851 APSR.Z = IsZeroBit(result); 1852 APSR.C = carry; 1853 APSR.V = overflow; 1854 } 1855 #endif 1856 1857 bool success = false; 1858 1859 if (ConditionPassed(opcode)) { 1860 const addr_t sp = ReadCoreReg(SP_REG, &success); 1861 if (!success) 1862 return false; 1863 uint32_t imm32; // the immediate operand 1864 uint32_t d; 1865 bool setflags; 1866 switch (encoding) { 1867 case eEncodingT1: 1868 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1869 d = Bits32(opcode, 10, 8); 1870 imm32 = (Bits32(opcode, 7, 0) << 2); 1871 setflags = false; 1872 break; 1873 1874 case eEncodingT2: 1875 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1876 d = 13; 1877 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1878 setflags = false; 1879 break; 1880 1881 case eEncodingT3: 1882 // d = UInt(Rd); setflags = (S == "1"); imm32 = 1883 // ThumbExpandImm(i:imm3:imm8); 1884 d = Bits32(opcode, 11, 8); 1885 imm32 = ThumbExpandImm(opcode); 1886 setflags = Bit32(opcode, 20); 1887 1888 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 1889 if (d == 15 && setflags == 1) 1890 return false; // CMN (immediate) not yet supported 1891 1892 // if d == 15 && S == "0" then UNPREDICTABLE; 1893 if (d == 15 && setflags == 0) 1894 return false; 1895 break; 1896 1897 case eEncodingT4: { 1898 // if Rn == '1111' then SEE ADR; 1899 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 1900 d = Bits32(opcode, 11, 8); 1901 setflags = false; 1902 uint32_t i = Bit32(opcode, 26); 1903 uint32_t imm3 = Bits32(opcode, 14, 12); 1904 uint32_t imm8 = Bits32(opcode, 7, 0); 1905 imm32 = (i << 11) | (imm3 << 8) | imm8; 1906 1907 // if d == 15 then UNPREDICTABLE; 1908 if (d == 15) 1909 return false; 1910 } break; 1911 1912 default: 1913 return false; 1914 } 1915 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 1916 AddWithCarryResult res = AddWithCarry(sp, imm32, 0); 1917 1918 EmulateInstruction::Context context; 1919 if (d == 13) 1920 context.type = EmulateInstruction::eContextAdjustStackPointer; 1921 else 1922 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1923 1924 RegisterInfo sp_reg; 1925 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1926 context.SetRegisterPlusOffset(sp_reg, res.result - sp); 1927 1928 if (d == 15) { 1929 if (!ALUWritePC(context, res.result)) 1930 return false; 1931 } else { 1932 // R[d] = result; 1933 // if setflags then 1934 // APSR.N = result<31>; 1935 // APSR.Z = IsZeroBit(result); 1936 // APSR.C = carry; 1937 // APSR.V = overflow; 1938 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 1939 res.carry_out, res.overflow)) 1940 return false; 1941 } 1942 } 1943 return true; 1944 } 1945 1946 // An add operation to adjust the SP. 1947 // ADD (SP plus register) 1948 bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode, 1949 const ARMEncoding encoding) { 1950 #if 0 1951 // ARM pseudo code... 1952 if (ConditionPassed()) 1953 { 1954 EncodingSpecificOperations(); 1955 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1956 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1957 if d == 15 then 1958 ALUWritePC(result); // setflags is always FALSE here 1959 else 1960 R[d] = result; 1961 if setflags then 1962 APSR.N = result<31>; 1963 APSR.Z = IsZeroBit(result); 1964 APSR.C = carry; 1965 APSR.V = overflow; 1966 } 1967 #endif 1968 1969 bool success = false; 1970 1971 if (ConditionPassed(opcode)) { 1972 const addr_t sp = ReadCoreReg(SP_REG, &success); 1973 if (!success) 1974 return false; 1975 uint32_t Rm; // the second operand 1976 switch (encoding) { 1977 case eEncodingT2: 1978 Rm = Bits32(opcode, 6, 3); 1979 break; 1980 default: 1981 return false; 1982 } 1983 int32_t reg_value = ReadCoreReg(Rm, &success); 1984 if (!success) 1985 return false; 1986 1987 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1988 1989 EmulateInstruction::Context context; 1990 context.type = eContextArithmetic; 1991 RegisterInfo sp_reg; 1992 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1993 1994 RegisterInfo other_reg; 1995 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1996 context.SetRegisterRegisterOperands(sp_reg, other_reg); 1997 1998 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1999 LLDB_REGNUM_GENERIC_SP, addr)) 2000 return false; 2001 } 2002 return true; 2003 } 2004 2005 // Branch with Link and Exchange Instruction Sets (immediate) calls a 2006 // subroutine at a PC-relative address, and changes instruction set from ARM to 2007 // Thumb, or from Thumb to ARM. 2008 // BLX (immediate) 2009 bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode, 2010 const ARMEncoding encoding) { 2011 #if 0 2012 // ARM pseudo code... 2013 if (ConditionPassed()) 2014 { 2015 EncodingSpecificOperations(); 2016 if CurrentInstrSet() == InstrSet_ARM then 2017 LR = PC - 4; 2018 else 2019 LR = PC<31:1> : '1'; 2020 if targetInstrSet == InstrSet_ARM then 2021 targetAddress = Align(PC,4) + imm32; 2022 else 2023 targetAddress = PC + imm32; 2024 SelectInstrSet(targetInstrSet); 2025 BranchWritePC(targetAddress); 2026 } 2027 #endif 2028 2029 bool success = true; 2030 2031 if (ConditionPassed(opcode)) { 2032 EmulateInstruction::Context context; 2033 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2034 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2035 if (!success) 2036 return false; 2037 addr_t lr; // next instruction address 2038 addr_t target; // target address 2039 int32_t imm32; // PC-relative offset 2040 switch (encoding) { 2041 case eEncodingT1: { 2042 lr = pc | 1u; // return address 2043 uint32_t S = Bit32(opcode, 26); 2044 uint32_t imm10 = Bits32(opcode, 25, 16); 2045 uint32_t J1 = Bit32(opcode, 13); 2046 uint32_t J2 = Bit32(opcode, 11); 2047 uint32_t imm11 = Bits32(opcode, 10, 0); 2048 uint32_t I1 = !(J1 ^ S); 2049 uint32_t I2 = !(J2 ^ S); 2050 uint32_t imm25 = 2051 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2052 imm32 = llvm::SignExtend32<25>(imm25); 2053 target = pc + imm32; 2054 SelectInstrSet(eModeThumb); 2055 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2056 if (InITBlock() && !LastInITBlock()) 2057 return false; 2058 break; 2059 } 2060 case eEncodingT2: { 2061 lr = pc | 1u; // return address 2062 uint32_t S = Bit32(opcode, 26); 2063 uint32_t imm10H = Bits32(opcode, 25, 16); 2064 uint32_t J1 = Bit32(opcode, 13); 2065 uint32_t J2 = Bit32(opcode, 11); 2066 uint32_t imm10L = Bits32(opcode, 10, 1); 2067 uint32_t I1 = !(J1 ^ S); 2068 uint32_t I2 = !(J2 ^ S); 2069 uint32_t imm25 = 2070 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 2071 imm32 = llvm::SignExtend32<25>(imm25); 2072 target = Align(pc, 4) + imm32; 2073 SelectInstrSet(eModeARM); 2074 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32); 2075 if (InITBlock() && !LastInITBlock()) 2076 return false; 2077 break; 2078 } 2079 case eEncodingA1: 2080 lr = pc - 4; // return address 2081 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2082 target = Align(pc, 4) + imm32; 2083 SelectInstrSet(eModeARM); 2084 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2085 break; 2086 case eEncodingA2: 2087 lr = pc - 4; // return address 2088 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | 2089 Bits32(opcode, 24, 24) << 1); 2090 target = pc + imm32; 2091 SelectInstrSet(eModeThumb); 2092 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32); 2093 break; 2094 default: 2095 return false; 2096 } 2097 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2098 LLDB_REGNUM_GENERIC_RA, lr)) 2099 return false; 2100 if (!BranchWritePC(context, target)) 2101 return false; 2102 if (m_opcode_cpsr != m_new_inst_cpsr) 2103 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2104 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2105 return false; 2106 } 2107 return true; 2108 } 2109 2110 // Branch with Link and Exchange (register) calls a subroutine at an address 2111 // and instruction set specified by a register. 2112 // BLX (register) 2113 bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode, 2114 const ARMEncoding encoding) { 2115 #if 0 2116 // ARM pseudo code... 2117 if (ConditionPassed()) 2118 { 2119 EncodingSpecificOperations(); 2120 target = R[m]; 2121 if CurrentInstrSet() == InstrSet_ARM then 2122 next_instr_addr = PC - 4; 2123 LR = next_instr_addr; 2124 else 2125 next_instr_addr = PC - 2; 2126 LR = next_instr_addr<31:1> : '1'; 2127 BXWritePC(target); 2128 } 2129 #endif 2130 2131 bool success = false; 2132 2133 if (ConditionPassed(opcode)) { 2134 EmulateInstruction::Context context; 2135 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2136 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2137 addr_t lr; // next instruction address 2138 if (!success) 2139 return false; 2140 uint32_t Rm; // the register with the target address 2141 switch (encoding) { 2142 case eEncodingT1: 2143 lr = (pc - 2) | 1u; // return address 2144 Rm = Bits32(opcode, 6, 3); 2145 // if m == 15 then UNPREDICTABLE; 2146 if (Rm == 15) 2147 return false; 2148 if (InITBlock() && !LastInITBlock()) 2149 return false; 2150 break; 2151 case eEncodingA1: 2152 lr = pc - 4; // return address 2153 Rm = Bits32(opcode, 3, 0); 2154 // if m == 15 then UNPREDICTABLE; 2155 if (Rm == 15) 2156 return false; 2157 break; 2158 default: 2159 return false; 2160 } 2161 addr_t target = ReadCoreReg(Rm, &success); 2162 if (!success) 2163 return false; 2164 RegisterInfo dwarf_reg; 2165 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2166 context.SetRegister(dwarf_reg); 2167 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2168 LLDB_REGNUM_GENERIC_RA, lr)) 2169 return false; 2170 if (!BXWritePC(context, target)) 2171 return false; 2172 } 2173 return true; 2174 } 2175 2176 // Branch and Exchange causes a branch to an address and instruction set 2177 // specified by a register. 2178 bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode, 2179 const ARMEncoding encoding) { 2180 #if 0 2181 // ARM pseudo code... 2182 if (ConditionPassed()) 2183 { 2184 EncodingSpecificOperations(); 2185 BXWritePC(R[m]); 2186 } 2187 #endif 2188 2189 if (ConditionPassed(opcode)) { 2190 EmulateInstruction::Context context; 2191 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2192 uint32_t Rm; // the register with the target address 2193 switch (encoding) { 2194 case eEncodingT1: 2195 Rm = Bits32(opcode, 6, 3); 2196 if (InITBlock() && !LastInITBlock()) 2197 return false; 2198 break; 2199 case eEncodingA1: 2200 Rm = Bits32(opcode, 3, 0); 2201 break; 2202 default: 2203 return false; 2204 } 2205 bool success = false; 2206 addr_t target = ReadCoreReg(Rm, &success); 2207 if (!success) 2208 return false; 2209 2210 RegisterInfo dwarf_reg; 2211 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2212 context.SetRegister(dwarf_reg); 2213 if (!BXWritePC(context, target)) 2214 return false; 2215 } 2216 return true; 2217 } 2218 2219 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the 2220 // attempt fails, it branches to an address and instruction set specified by a 2221 // register as though it were a BX instruction. 2222 // 2223 // TODO: Emulate Jazelle architecture? 2224 // We currently assume that switching to Jazelle state fails, thus 2225 // treating BXJ as a BX operation. 2226 bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode, 2227 const ARMEncoding encoding) { 2228 #if 0 2229 // ARM pseudo code... 2230 if (ConditionPassed()) 2231 { 2232 EncodingSpecificOperations(); 2233 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 2234 BXWritePC(R[m]); 2235 else 2236 if JazelleAcceptsExecution() then 2237 SwitchToJazelleExecution(); 2238 else 2239 SUBARCHITECTURE_DEFINED handler call; 2240 } 2241 #endif 2242 2243 if (ConditionPassed(opcode)) { 2244 EmulateInstruction::Context context; 2245 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2246 uint32_t Rm; // the register with the target address 2247 switch (encoding) { 2248 case eEncodingT1: 2249 Rm = Bits32(opcode, 19, 16); 2250 if (BadReg(Rm)) 2251 return false; 2252 if (InITBlock() && !LastInITBlock()) 2253 return false; 2254 break; 2255 case eEncodingA1: 2256 Rm = Bits32(opcode, 3, 0); 2257 if (Rm == 15) 2258 return false; 2259 break; 2260 default: 2261 return false; 2262 } 2263 bool success = false; 2264 addr_t target = ReadCoreReg(Rm, &success); 2265 if (!success) 2266 return false; 2267 2268 RegisterInfo dwarf_reg; 2269 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2270 context.SetRegister(dwarf_reg); 2271 if (!BXWritePC(context, target)) 2272 return false; 2273 } 2274 return true; 2275 } 2276 2277 // Set r7 to point to some ip offset. 2278 // SUB (immediate) 2279 bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode, 2280 const ARMEncoding encoding) { 2281 #if 0 2282 // ARM pseudo code... 2283 if (ConditionPassed()) 2284 { 2285 EncodingSpecificOperations(); 2286 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2287 if d == 15 then // Can only occur for ARM encoding 2288 ALUWritePC(result); // setflags is always FALSE here 2289 else 2290 R[d] = result; 2291 if setflags then 2292 APSR.N = result<31>; 2293 APSR.Z = IsZeroBit(result); 2294 APSR.C = carry; 2295 APSR.V = overflow; 2296 } 2297 #endif 2298 2299 if (ConditionPassed(opcode)) { 2300 bool success = false; 2301 const addr_t ip = ReadCoreReg(12, &success); 2302 if (!success) 2303 return false; 2304 uint32_t imm32; 2305 switch (encoding) { 2306 case eEncodingA1: 2307 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2308 break; 2309 default: 2310 return false; 2311 } 2312 addr_t ip_offset = imm32; 2313 addr_t addr = ip - ip_offset; // the adjusted ip value 2314 2315 EmulateInstruction::Context context; 2316 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2317 RegisterInfo dwarf_reg; 2318 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg); 2319 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset); 2320 2321 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr)) 2322 return false; 2323 } 2324 return true; 2325 } 2326 2327 // Set ip to point to some stack offset. 2328 // SUB (SP minus immediate) 2329 bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode, 2330 const ARMEncoding encoding) { 2331 #if 0 2332 // ARM pseudo code... 2333 if (ConditionPassed()) 2334 { 2335 EncodingSpecificOperations(); 2336 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2337 if d == 15 then // Can only occur for ARM encoding 2338 ALUWritePC(result); // setflags is always FALSE here 2339 else 2340 R[d] = result; 2341 if setflags then 2342 APSR.N = result<31>; 2343 APSR.Z = IsZeroBit(result); 2344 APSR.C = carry; 2345 APSR.V = overflow; 2346 } 2347 #endif 2348 2349 if (ConditionPassed(opcode)) { 2350 bool success = false; 2351 const addr_t sp = ReadCoreReg(SP_REG, &success); 2352 if (!success) 2353 return false; 2354 uint32_t imm32; 2355 switch (encoding) { 2356 case eEncodingA1: 2357 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2358 break; 2359 default: 2360 return false; 2361 } 2362 addr_t sp_offset = imm32; 2363 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 2364 2365 EmulateInstruction::Context context; 2366 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2367 RegisterInfo dwarf_reg; 2368 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 2369 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset); 2370 2371 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr)) 2372 return false; 2373 } 2374 return true; 2375 } 2376 2377 // This instruction subtracts an immediate value from the SP value, and writes 2378 // the result to the destination register. 2379 // 2380 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local 2381 // storage. 2382 bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode, 2383 const ARMEncoding encoding) { 2384 #if 0 2385 // ARM pseudo code... 2386 if (ConditionPassed()) 2387 { 2388 EncodingSpecificOperations(); 2389 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2390 if d == 15 then // Can only occur for ARM encoding 2391 ALUWritePC(result); // setflags is always FALSE here 2392 else 2393 R[d] = result; 2394 if setflags then 2395 APSR.N = result<31>; 2396 APSR.Z = IsZeroBit(result); 2397 APSR.C = carry; 2398 APSR.V = overflow; 2399 } 2400 #endif 2401 2402 bool success = false; 2403 if (ConditionPassed(opcode)) { 2404 const addr_t sp = ReadCoreReg(SP_REG, &success); 2405 if (!success) 2406 return false; 2407 2408 uint32_t Rd; 2409 bool setflags; 2410 uint32_t imm32; 2411 switch (encoding) { 2412 case eEncodingT1: 2413 Rd = 13; 2414 setflags = false; 2415 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 2416 break; 2417 case eEncodingT2: 2418 Rd = Bits32(opcode, 11, 8); 2419 setflags = BitIsSet(opcode, 20); 2420 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2421 if (Rd == 15 && setflags) 2422 return EmulateCMPImm(opcode, eEncodingT2); 2423 if (Rd == 15 && !setflags) 2424 return false; 2425 break; 2426 case eEncodingT3: 2427 Rd = Bits32(opcode, 11, 8); 2428 setflags = false; 2429 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 2430 if (Rd == 15) 2431 return false; 2432 break; 2433 case eEncodingA1: 2434 Rd = Bits32(opcode, 15, 12); 2435 setflags = BitIsSet(opcode, 20); 2436 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2437 2438 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 2439 // instructions; 2440 if (Rd == 15 && setflags) 2441 return EmulateSUBSPcLrEtc(opcode, encoding); 2442 break; 2443 default: 2444 return false; 2445 } 2446 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 2447 2448 EmulateInstruction::Context context; 2449 if (Rd == 13) { 2450 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting 2451 // to negate it, or the wrong 2452 // value gets passed down to context.SetImmediateSigned. 2453 context.type = EmulateInstruction::eContextAdjustStackPointer; 2454 context.SetImmediateSigned(-imm64); // the stack pointer offset 2455 } else { 2456 context.type = EmulateInstruction::eContextImmediate; 2457 context.SetNoArgs(); 2458 } 2459 2460 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 2461 res.carry_out, res.overflow)) 2462 return false; 2463 } 2464 return true; 2465 } 2466 2467 // A store operation to the stack that also updates the SP. 2468 bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode, 2469 const ARMEncoding encoding) { 2470 #if 0 2471 // ARM pseudo code... 2472 if (ConditionPassed()) 2473 { 2474 EncodingSpecificOperations(); 2475 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2476 address = if index then offset_addr else R[n]; 2477 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 2478 if wback then R[n] = offset_addr; 2479 } 2480 #endif 2481 2482 bool success = false; 2483 if (ConditionPassed(opcode)) { 2484 const uint32_t addr_byte_size = GetAddressByteSize(); 2485 const addr_t sp = ReadCoreReg(SP_REG, &success); 2486 if (!success) 2487 return false; 2488 uint32_t Rt; // the source register 2489 uint32_t imm12; 2490 uint32_t 2491 Rn; // This function assumes Rn is the SP, but we should verify that. 2492 2493 bool index; 2494 bool add; 2495 bool wback; 2496 switch (encoding) { 2497 case eEncodingA1: 2498 Rt = Bits32(opcode, 15, 12); 2499 imm12 = Bits32(opcode, 11, 0); 2500 Rn = Bits32(opcode, 19, 16); 2501 2502 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 2503 return false; 2504 2505 index = BitIsSet(opcode, 24); 2506 add = BitIsSet(opcode, 23); 2507 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 2508 2509 if (wback && ((Rn == 15) || (Rn == Rt))) 2510 return false; 2511 break; 2512 default: 2513 return false; 2514 } 2515 addr_t offset_addr; 2516 if (add) 2517 offset_addr = sp + imm12; 2518 else 2519 offset_addr = sp - imm12; 2520 2521 addr_t addr; 2522 if (index) 2523 addr = offset_addr; 2524 else 2525 addr = sp; 2526 2527 EmulateInstruction::Context context; 2528 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2529 RegisterInfo sp_reg; 2530 RegisterInfo dwarf_reg; 2531 2532 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2533 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2534 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2535 if (Rt != 15) { 2536 uint32_t reg_value = ReadCoreReg(Rt, &success); 2537 if (!success) 2538 return false; 2539 if (!MemUWrite(context, addr, reg_value, addr_byte_size)) 2540 return false; 2541 } else { 2542 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2543 if (!success) 2544 return false; 2545 if (!MemUWrite(context, addr, pc, addr_byte_size)) 2546 return false; 2547 } 2548 2549 if (wback) { 2550 context.type = EmulateInstruction::eContextAdjustStackPointer; 2551 context.SetImmediateSigned(addr - sp); 2552 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2553 LLDB_REGNUM_GENERIC_SP, offset_addr)) 2554 return false; 2555 } 2556 } 2557 return true; 2558 } 2559 2560 // Vector Push stores multiple extension registers to the stack. It also 2561 // updates SP to point to the start of the stored data. 2562 bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode, 2563 const ARMEncoding encoding) { 2564 #if 0 2565 // ARM pseudo code... 2566 if (ConditionPassed()) 2567 { 2568 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2569 address = SP - imm32; 2570 SP = SP - imm32; 2571 if single_regs then 2572 for r = 0 to regs-1 2573 MemA[address,4] = S[d+r]; address = address+4; 2574 else 2575 for r = 0 to regs-1 2576 // Store as two word-aligned words in the correct order for 2577 // current endianness. 2578 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2579 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2580 address = address+8; 2581 } 2582 #endif 2583 2584 bool success = false; 2585 if (ConditionPassed(opcode)) { 2586 const uint32_t addr_byte_size = GetAddressByteSize(); 2587 const addr_t sp = ReadCoreReg(SP_REG, &success); 2588 if (!success) 2589 return false; 2590 bool single_regs; 2591 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2592 uint32_t imm32; // stack offset 2593 uint32_t regs; // number of registers 2594 switch (encoding) { 2595 case eEncodingT1: 2596 case eEncodingA1: 2597 single_regs = false; 2598 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2599 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2600 // If UInt(imm8) is odd, see "FSTMX". 2601 regs = Bits32(opcode, 7, 0) / 2; 2602 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2603 if (regs == 0 || regs > 16 || (d + regs) > 32) 2604 return false; 2605 break; 2606 case eEncodingT2: 2607 case eEncodingA2: 2608 single_regs = true; 2609 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2610 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2611 regs = Bits32(opcode, 7, 0); 2612 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2613 if (regs == 0 || regs > 16 || (d + regs) > 32) 2614 return false; 2615 break; 2616 default: 2617 return false; 2618 } 2619 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2620 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2621 addr_t sp_offset = imm32; 2622 addr_t addr = sp - sp_offset; 2623 uint32_t i; 2624 2625 EmulateInstruction::Context context; 2626 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2627 2628 RegisterInfo dwarf_reg; 2629 RegisterInfo sp_reg; 2630 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2631 for (i = 0; i < regs; ++i) { 2632 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2633 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2634 // uint64_t to accommodate 64-bit registers. 2635 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success); 2636 if (!success) 2637 return false; 2638 if (!MemAWrite(context, addr, reg_value, reg_byte_size)) 2639 return false; 2640 addr += reg_byte_size; 2641 } 2642 2643 context.type = EmulateInstruction::eContextAdjustStackPointer; 2644 context.SetImmediateSigned(-sp_offset); 2645 2646 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2647 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2648 return false; 2649 } 2650 return true; 2651 } 2652 2653 // Vector Pop loads multiple extension registers from the stack. It also 2654 // updates SP to point just above the loaded data. 2655 bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode, 2656 const ARMEncoding encoding) { 2657 #if 0 2658 // ARM pseudo code... 2659 if (ConditionPassed()) 2660 { 2661 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2662 address = SP; 2663 SP = SP + imm32; 2664 if single_regs then 2665 for r = 0 to regs-1 2666 S[d+r] = MemA[address,4]; address = address+4; 2667 else 2668 for r = 0 to regs-1 2669 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2670 // Combine the word-aligned words in the correct order for 2671 // current endianness. 2672 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2673 } 2674 #endif 2675 2676 bool success = false; 2677 if (ConditionPassed(opcode)) { 2678 const uint32_t addr_byte_size = GetAddressByteSize(); 2679 const addr_t sp = ReadCoreReg(SP_REG, &success); 2680 if (!success) 2681 return false; 2682 bool single_regs; 2683 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2684 uint32_t imm32; // stack offset 2685 uint32_t regs; // number of registers 2686 switch (encoding) { 2687 case eEncodingT1: 2688 case eEncodingA1: 2689 single_regs = false; 2690 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2691 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2692 // If UInt(imm8) is odd, see "FLDMX". 2693 regs = Bits32(opcode, 7, 0) / 2; 2694 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2695 if (regs == 0 || regs > 16 || (d + regs) > 32) 2696 return false; 2697 break; 2698 case eEncodingT2: 2699 case eEncodingA2: 2700 single_regs = true; 2701 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2702 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2703 regs = Bits32(opcode, 7, 0); 2704 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2705 if (regs == 0 || regs > 16 || (d + regs) > 32) 2706 return false; 2707 break; 2708 default: 2709 return false; 2710 } 2711 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2712 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2713 addr_t sp_offset = imm32; 2714 addr_t addr = sp; 2715 uint32_t i; 2716 uint64_t data; // uint64_t to accommodate 64-bit registers. 2717 2718 EmulateInstruction::Context context; 2719 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2720 2721 RegisterInfo dwarf_reg; 2722 RegisterInfo sp_reg; 2723 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2724 for (i = 0; i < regs; ++i) { 2725 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2726 context.SetAddress(addr); 2727 data = MemARead(context, addr, reg_byte_size, 0, &success); 2728 if (!success) 2729 return false; 2730 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2731 return false; 2732 addr += reg_byte_size; 2733 } 2734 2735 context.type = EmulateInstruction::eContextAdjustStackPointer; 2736 context.SetImmediateSigned(sp_offset); 2737 2738 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2739 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2740 return false; 2741 } 2742 return true; 2743 } 2744 2745 // SVC (previously SWI) 2746 bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode, 2747 const ARMEncoding encoding) { 2748 #if 0 2749 // ARM pseudo code... 2750 if (ConditionPassed()) 2751 { 2752 EncodingSpecificOperations(); 2753 CallSupervisor(); 2754 } 2755 #endif 2756 2757 bool success = false; 2758 2759 if (ConditionPassed(opcode)) { 2760 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2761 addr_t lr; // next instruction address 2762 if (!success) 2763 return false; 2764 uint32_t imm32; // the immediate constant 2765 uint32_t mode; // ARM or Thumb mode 2766 switch (encoding) { 2767 case eEncodingT1: 2768 lr = (pc + 2) | 1u; // return address 2769 imm32 = Bits32(opcode, 7, 0); 2770 mode = eModeThumb; 2771 break; 2772 case eEncodingA1: 2773 lr = pc + 4; // return address 2774 imm32 = Bits32(opcode, 23, 0); 2775 mode = eModeARM; 2776 break; 2777 default: 2778 return false; 2779 } 2780 2781 EmulateInstruction::Context context; 2782 context.type = EmulateInstruction::eContextSupervisorCall; 2783 context.SetISAAndImmediate(mode, imm32); 2784 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2785 LLDB_REGNUM_GENERIC_RA, lr)) 2786 return false; 2787 } 2788 return true; 2789 } 2790 2791 // If Then makes up to four following instructions (the IT block) conditional. 2792 bool EmulateInstructionARM::EmulateIT(const uint32_t opcode, 2793 const ARMEncoding encoding) { 2794 #if 0 2795 // ARM pseudo code... 2796 EncodingSpecificOperations(); 2797 ITSTATE.IT<7:0> = firstcond:mask; 2798 #endif 2799 2800 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2801 return true; 2802 } 2803 2804 bool EmulateInstructionARM::EmulateNop(const uint32_t opcode, 2805 const ARMEncoding encoding) { 2806 // NOP, nothing to do... 2807 return true; 2808 } 2809 2810 // Branch causes a branch to a target address. 2811 bool EmulateInstructionARM::EmulateB(const uint32_t opcode, 2812 const ARMEncoding encoding) { 2813 #if 0 2814 // ARM pseudo code... 2815 if (ConditionPassed()) 2816 { 2817 EncodingSpecificOperations(); 2818 BranchWritePC(PC + imm32); 2819 } 2820 #endif 2821 2822 bool success = false; 2823 2824 if (ConditionPassed(opcode)) { 2825 EmulateInstruction::Context context; 2826 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2827 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2828 if (!success) 2829 return false; 2830 addr_t target; // target address 2831 int32_t imm32; // PC-relative offset 2832 switch (encoding) { 2833 case eEncodingT1: 2834 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2835 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2836 target = pc + imm32; 2837 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2838 break; 2839 case eEncodingT2: 2840 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2841 target = pc + imm32; 2842 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2843 break; 2844 case eEncodingT3: 2845 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2846 { 2847 if (Bits32(opcode, 25, 23) == 7) 2848 return false; // See Branches and miscellaneous control on page 2849 // A6-235. 2850 2851 uint32_t S = Bit32(opcode, 26); 2852 uint32_t imm6 = Bits32(opcode, 21, 16); 2853 uint32_t J1 = Bit32(opcode, 13); 2854 uint32_t J2 = Bit32(opcode, 11); 2855 uint32_t imm11 = Bits32(opcode, 10, 0); 2856 uint32_t imm21 = 2857 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2858 imm32 = llvm::SignExtend32<21>(imm21); 2859 target = pc + imm32; 2860 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2861 break; 2862 } 2863 case eEncodingT4: { 2864 uint32_t S = Bit32(opcode, 26); 2865 uint32_t imm10 = Bits32(opcode, 25, 16); 2866 uint32_t J1 = Bit32(opcode, 13); 2867 uint32_t J2 = Bit32(opcode, 11); 2868 uint32_t imm11 = Bits32(opcode, 10, 0); 2869 uint32_t I1 = !(J1 ^ S); 2870 uint32_t I2 = !(J2 ^ S); 2871 uint32_t imm25 = 2872 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2873 imm32 = llvm::SignExtend32<25>(imm25); 2874 target = pc + imm32; 2875 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2876 break; 2877 } 2878 case eEncodingA1: 2879 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2880 target = pc + imm32; 2881 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2882 break; 2883 default: 2884 return false; 2885 } 2886 if (!BranchWritePC(context, target)) 2887 return false; 2888 } 2889 return true; 2890 } 2891 2892 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the 2893 // value in a register with zero and conditionally branch forward a constant 2894 // value. They do not affect the condition flags. CBNZ, CBZ 2895 bool EmulateInstructionARM::EmulateCB(const uint32_t opcode, 2896 const ARMEncoding encoding) { 2897 #if 0 2898 // ARM pseudo code... 2899 EncodingSpecificOperations(); 2900 if nonzero ^ IsZero(R[n]) then 2901 BranchWritePC(PC + imm32); 2902 #endif 2903 2904 bool success = false; 2905 2906 // Read the register value from the operand register Rn. 2907 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2908 if (!success) 2909 return false; 2910 2911 EmulateInstruction::Context context; 2912 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2913 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2914 if (!success) 2915 return false; 2916 2917 addr_t target; // target address 2918 uint32_t imm32; // PC-relative offset to branch forward 2919 bool nonzero; 2920 switch (encoding) { 2921 case eEncodingT1: 2922 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2923 nonzero = BitIsSet(opcode, 11); 2924 target = pc + imm32; 2925 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2926 break; 2927 default: 2928 return false; 2929 } 2930 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2931 if (!BranchWritePC(context, target)) 2932 return false; 2933 2934 return true; 2935 } 2936 2937 // Table Branch Byte causes a PC-relative forward branch using a table of 2938 // single byte offsets. 2939 // A base register provides a pointer to the table, and a second register 2940 // supplies an index into the table. 2941 // The branch length is twice the value of the byte returned from the table. 2942 // 2943 // Table Branch Halfword causes a PC-relative forward branch using a table of 2944 // single halfword offsets. 2945 // A base register provides a pointer to the table, and a second register 2946 // supplies an index into the table. 2947 // The branch length is twice the value of the halfword returned from the 2948 // table. TBB, TBH 2949 bool EmulateInstructionARM::EmulateTB(const uint32_t opcode, 2950 const ARMEncoding encoding) { 2951 #if 0 2952 // ARM pseudo code... 2953 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2954 if is_tbh then 2955 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2956 else 2957 halfwords = UInt(MemU[R[n]+R[m], 1]); 2958 BranchWritePC(PC + 2*halfwords); 2959 #endif 2960 2961 bool success = false; 2962 2963 if (ConditionPassed(opcode)) { 2964 uint32_t Rn; // the base register which contains the address of the table of 2965 // branch lengths 2966 uint32_t Rm; // the index register which contains an integer pointing to a 2967 // byte/halfword in the table 2968 bool is_tbh; // true if table branch halfword 2969 switch (encoding) { 2970 case eEncodingT1: 2971 Rn = Bits32(opcode, 19, 16); 2972 Rm = Bits32(opcode, 3, 0); 2973 is_tbh = BitIsSet(opcode, 4); 2974 if (Rn == 13 || BadReg(Rm)) 2975 return false; 2976 if (InITBlock() && !LastInITBlock()) 2977 return false; 2978 break; 2979 default: 2980 return false; 2981 } 2982 2983 // Read the address of the table from the operand register Rn. The PC can 2984 // be used, in which case the table immediately follows this instruction. 2985 uint32_t base = ReadCoreReg(Rn, &success); 2986 if (!success) 2987 return false; 2988 2989 // the table index 2990 uint32_t index = ReadCoreReg(Rm, &success); 2991 if (!success) 2992 return false; 2993 2994 // the offsetted table address 2995 addr_t addr = base + (is_tbh ? index * 2 : index); 2996 2997 // PC-relative offset to branch forward 2998 EmulateInstruction::Context context; 2999 context.type = EmulateInstruction::eContextTableBranchReadMemory; 3000 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 3001 if (!success) 3002 return false; 3003 3004 const uint32_t pc = ReadCoreReg(PC_REG, &success); 3005 if (!success) 3006 return false; 3007 3008 // target address 3009 addr_t target = pc + offset; 3010 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 3011 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset); 3012 3013 if (!BranchWritePC(context, target)) 3014 return false; 3015 } 3016 3017 return true; 3018 } 3019 3020 // This instruction adds an immediate value to a register value, and writes the 3021 // result to the destination register. It can optionally update the condition 3022 // flags based on the result. 3023 bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode, 3024 const ARMEncoding encoding) { 3025 #if 0 3026 if ConditionPassed() then 3027 EncodingSpecificOperations(); 3028 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3029 R[d] = result; 3030 if setflags then 3031 APSR.N = result<31>; 3032 APSR.Z = IsZeroBit(result); 3033 APSR.C = carry; 3034 APSR.V = overflow; 3035 #endif 3036 3037 bool success = false; 3038 3039 if (ConditionPassed(opcode)) { 3040 uint32_t d; 3041 uint32_t n; 3042 bool setflags; 3043 uint32_t imm32; 3044 uint32_t carry_out; 3045 3046 // EncodingSpecificOperations(); 3047 switch (encoding) { 3048 case eEncodingT1: 3049 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = 3050 // ZeroExtend(imm3, 32); 3051 d = Bits32(opcode, 2, 0); 3052 n = Bits32(opcode, 5, 3); 3053 setflags = !InITBlock(); 3054 imm32 = Bits32(opcode, 8, 6); 3055 3056 break; 3057 3058 case eEncodingT2: 3059 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = 3060 // ZeroExtend(imm8, 32); 3061 d = Bits32(opcode, 10, 8); 3062 n = Bits32(opcode, 10, 8); 3063 setflags = !InITBlock(); 3064 imm32 = Bits32(opcode, 7, 0); 3065 3066 break; 3067 3068 case eEncodingT3: 3069 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 3070 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = 3071 // ThumbExpandImm(i:imm3:imm8); 3072 d = Bits32(opcode, 11, 8); 3073 n = Bits32(opcode, 19, 16); 3074 setflags = BitIsSet(opcode, 20); 3075 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out); 3076 3077 // if Rn == '1101' then SEE ADD (SP plus immediate); 3078 if (n == 13) 3079 return EmulateADDSPImm(opcode, eEncodingT3); 3080 3081 // if BadReg(d) || n == 15 then UNPREDICTABLE; 3082 if (BadReg(d) || (n == 15)) 3083 return false; 3084 3085 break; 3086 3087 case eEncodingT4: { 3088 // if Rn == '1111' then SEE ADR; 3089 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = 3090 // ZeroExtend(i:imm3:imm8, 32); 3091 d = Bits32(opcode, 11, 8); 3092 n = Bits32(opcode, 19, 16); 3093 setflags = false; 3094 uint32_t i = Bit32(opcode, 26); 3095 uint32_t imm3 = Bits32(opcode, 14, 12); 3096 uint32_t imm8 = Bits32(opcode, 7, 0); 3097 imm32 = (i << 11) | (imm3 << 8) | imm8; 3098 3099 // if Rn == '1101' then SEE ADD (SP plus immediate); 3100 if (n == 13) 3101 return EmulateADDSPImm(opcode, eEncodingT4); 3102 3103 // if BadReg(d) then UNPREDICTABLE; 3104 if (BadReg(d)) 3105 return false; 3106 3107 break; 3108 } 3109 3110 default: 3111 return false; 3112 } 3113 3114 uint64_t Rn = 3115 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3116 if (!success) 3117 return false; 3118 3119 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3120 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0); 3121 3122 RegisterInfo reg_n; 3123 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 3124 3125 EmulateInstruction::Context context; 3126 context.type = eContextArithmetic; 3127 context.SetRegisterPlusOffset(reg_n, imm32); 3128 3129 // R[d] = result; 3130 // if setflags then 3131 // APSR.N = result<31>; 3132 // APSR.Z = IsZeroBit(result); 3133 // APSR.C = carry; 3134 // APSR.V = overflow; 3135 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 3136 res.carry_out, res.overflow)) 3137 return false; 3138 } 3139 return true; 3140 } 3141 3142 // This instruction adds an immediate value to a register value, and writes the 3143 // result to the destination register. It can optionally update the condition 3144 // flags based on the result. 3145 bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode, 3146 const ARMEncoding encoding) { 3147 #if 0 3148 // ARM pseudo code... 3149 if ConditionPassed() then 3150 EncodingSpecificOperations(); 3151 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3152 if d == 15 then 3153 ALUWritePC(result); // setflags is always FALSE here 3154 else 3155 R[d] = result; 3156 if setflags then 3157 APSR.N = result<31>; 3158 APSR.Z = IsZeroBit(result); 3159 APSR.C = carry; 3160 APSR.V = overflow; 3161 #endif 3162 3163 bool success = false; 3164 3165 if (ConditionPassed(opcode)) { 3166 uint32_t Rd, Rn; 3167 uint32_t 3168 imm32; // the immediate value to be added to the value obtained from Rn 3169 bool setflags; 3170 switch (encoding) { 3171 case eEncodingA1: 3172 Rd = Bits32(opcode, 15, 12); 3173 Rn = Bits32(opcode, 19, 16); 3174 setflags = BitIsSet(opcode, 20); 3175 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3176 break; 3177 default: 3178 return false; 3179 } 3180 3181 // Read the first operand. 3182 uint32_t val1 = ReadCoreReg(Rn, &success); 3183 if (!success) 3184 return false; 3185 3186 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 3187 3188 EmulateInstruction::Context context; 3189 if (Rd == 13) 3190 context.type = EmulateInstruction::eContextAdjustStackPointer; 3191 else if (Rd == GetFramePointerRegisterNumber()) 3192 context.type = EmulateInstruction::eContextSetFramePointer; 3193 else 3194 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3195 3196 RegisterInfo dwarf_reg; 3197 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 3198 context.SetRegisterPlusOffset(dwarf_reg, imm32); 3199 3200 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3201 res.carry_out, res.overflow)) 3202 return false; 3203 } 3204 return true; 3205 } 3206 3207 // This instruction adds a register value and an optionally-shifted register 3208 // value, and writes the result to the destination register. It can optionally 3209 // update the condition flags based on the result. 3210 bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode, 3211 const ARMEncoding encoding) { 3212 #if 0 3213 // ARM pseudo code... 3214 if ConditionPassed() then 3215 EncodingSpecificOperations(); 3216 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3217 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3218 if d == 15 then 3219 ALUWritePC(result); // setflags is always FALSE here 3220 else 3221 R[d] = result; 3222 if setflags then 3223 APSR.N = result<31>; 3224 APSR.Z = IsZeroBit(result); 3225 APSR.C = carry; 3226 APSR.V = overflow; 3227 #endif 3228 3229 bool success = false; 3230 3231 if (ConditionPassed(opcode)) { 3232 uint32_t Rd, Rn, Rm; 3233 ARM_ShifterType shift_t; 3234 uint32_t shift_n; // the shift applied to the value read from Rm 3235 bool setflags; 3236 switch (encoding) { 3237 case eEncodingT1: 3238 Rd = Bits32(opcode, 2, 0); 3239 Rn = Bits32(opcode, 5, 3); 3240 Rm = Bits32(opcode, 8, 6); 3241 setflags = !InITBlock(); 3242 shift_t = SRType_LSL; 3243 shift_n = 0; 3244 break; 3245 case eEncodingT2: 3246 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3247 Rm = Bits32(opcode, 6, 3); 3248 setflags = false; 3249 shift_t = SRType_LSL; 3250 shift_n = 0; 3251 if (Rn == 15 && Rm == 15) 3252 return false; 3253 if (Rd == 15 && InITBlock() && !LastInITBlock()) 3254 return false; 3255 break; 3256 case eEncodingA1: 3257 Rd = Bits32(opcode, 15, 12); 3258 Rn = Bits32(opcode, 19, 16); 3259 Rm = Bits32(opcode, 3, 0); 3260 setflags = BitIsSet(opcode, 20); 3261 shift_n = DecodeImmShiftARM(opcode, shift_t); 3262 break; 3263 default: 3264 return false; 3265 } 3266 3267 // Read the first operand. 3268 uint32_t val1 = ReadCoreReg(Rn, &success); 3269 if (!success) 3270 return false; 3271 3272 // Read the second operand. 3273 uint32_t val2 = ReadCoreReg(Rm, &success); 3274 if (!success) 3275 return false; 3276 3277 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3278 if (!success) 3279 return false; 3280 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3281 3282 EmulateInstruction::Context context; 3283 context.type = eContextArithmetic; 3284 RegisterInfo op1_reg; 3285 RegisterInfo op2_reg; 3286 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 3287 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 3288 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 3289 3290 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3291 res.carry_out, res.overflow)) 3292 return false; 3293 } 3294 return true; 3295 } 3296 3297 // Compare Negative (immediate) adds a register value and an immediate value. 3298 // It updates the condition flags based on the result, and discards the result. 3299 bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode, 3300 const ARMEncoding encoding) { 3301 #if 0 3302 // ARM pseudo code... 3303 if ConditionPassed() then 3304 EncodingSpecificOperations(); 3305 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3306 APSR.N = result<31>; 3307 APSR.Z = IsZeroBit(result); 3308 APSR.C = carry; 3309 APSR.V = overflow; 3310 #endif 3311 3312 bool success = false; 3313 3314 uint32_t Rn; // the first operand 3315 uint32_t imm32; // the immediate value to be compared with 3316 switch (encoding) { 3317 case eEncodingT1: 3318 Rn = Bits32(opcode, 19, 16); 3319 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3320 if (Rn == 15) 3321 return false; 3322 break; 3323 case eEncodingA1: 3324 Rn = Bits32(opcode, 19, 16); 3325 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3326 break; 3327 default: 3328 return false; 3329 } 3330 // Read the register value from the operand register Rn. 3331 uint32_t reg_val = ReadCoreReg(Rn, &success); 3332 if (!success) 3333 return false; 3334 3335 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 3336 3337 EmulateInstruction::Context context; 3338 context.type = EmulateInstruction::eContextImmediate; 3339 context.SetNoArgs(); 3340 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3341 } 3342 3343 // Compare Negative (register) adds a register value and an optionally-shifted 3344 // register value. It updates the condition flags based on the result, and 3345 // discards the result. 3346 bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode, 3347 const ARMEncoding encoding) { 3348 #if 0 3349 // ARM pseudo code... 3350 if ConditionPassed() then 3351 EncodingSpecificOperations(); 3352 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3353 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3354 APSR.N = result<31>; 3355 APSR.Z = IsZeroBit(result); 3356 APSR.C = carry; 3357 APSR.V = overflow; 3358 #endif 3359 3360 bool success = false; 3361 3362 uint32_t Rn; // the first operand 3363 uint32_t Rm; // the second operand 3364 ARM_ShifterType shift_t; 3365 uint32_t shift_n; // the shift applied to the value read from Rm 3366 switch (encoding) { 3367 case eEncodingT1: 3368 Rn = Bits32(opcode, 2, 0); 3369 Rm = Bits32(opcode, 5, 3); 3370 shift_t = SRType_LSL; 3371 shift_n = 0; 3372 break; 3373 case eEncodingT2: 3374 Rn = Bits32(opcode, 19, 16); 3375 Rm = Bits32(opcode, 3, 0); 3376 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3377 // if n == 15 || BadReg(m) then UNPREDICTABLE; 3378 if (Rn == 15 || BadReg(Rm)) 3379 return false; 3380 break; 3381 case eEncodingA1: 3382 Rn = Bits32(opcode, 19, 16); 3383 Rm = Bits32(opcode, 3, 0); 3384 shift_n = DecodeImmShiftARM(opcode, shift_t); 3385 break; 3386 default: 3387 return false; 3388 } 3389 // Read the register value from register Rn. 3390 uint32_t val1 = ReadCoreReg(Rn, &success); 3391 if (!success) 3392 return false; 3393 3394 // Read the register value from register Rm. 3395 uint32_t val2 = ReadCoreReg(Rm, &success); 3396 if (!success) 3397 return false; 3398 3399 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3400 if (!success) 3401 return false; 3402 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3403 3404 EmulateInstruction::Context context; 3405 context.type = EmulateInstruction::eContextImmediate; 3406 context.SetNoArgs(); 3407 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3408 } 3409 3410 // Compare (immediate) subtracts an immediate value from a register value. It 3411 // updates the condition flags based on the result, and discards the result. 3412 bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode, 3413 const ARMEncoding encoding) { 3414 #if 0 3415 // ARM pseudo code... 3416 if ConditionPassed() then 3417 EncodingSpecificOperations(); 3418 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 3419 APSR.N = result<31>; 3420 APSR.Z = IsZeroBit(result); 3421 APSR.C = carry; 3422 APSR.V = overflow; 3423 #endif 3424 3425 bool success = false; 3426 3427 uint32_t Rn; // the first operand 3428 uint32_t imm32; // the immediate value to be compared with 3429 switch (encoding) { 3430 case eEncodingT1: 3431 Rn = Bits32(opcode, 10, 8); 3432 imm32 = Bits32(opcode, 7, 0); 3433 break; 3434 case eEncodingT2: 3435 Rn = Bits32(opcode, 19, 16); 3436 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3437 if (Rn == 15) 3438 return false; 3439 break; 3440 case eEncodingA1: 3441 Rn = Bits32(opcode, 19, 16); 3442 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3443 break; 3444 default: 3445 return false; 3446 } 3447 // Read the register value from the operand register Rn. 3448 uint32_t reg_val = ReadCoreReg(Rn, &success); 3449 if (!success) 3450 return false; 3451 3452 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 3453 3454 EmulateInstruction::Context context; 3455 context.type = EmulateInstruction::eContextImmediate; 3456 context.SetNoArgs(); 3457 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3458 } 3459 3460 // Compare (register) subtracts an optionally-shifted register value from a 3461 // register value. It updates the condition flags based on the result, and 3462 // discards the result. 3463 bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode, 3464 const ARMEncoding encoding) { 3465 #if 0 3466 // ARM pseudo code... 3467 if ConditionPassed() then 3468 EncodingSpecificOperations(); 3469 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3470 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 3471 APSR.N = result<31>; 3472 APSR.Z = IsZeroBit(result); 3473 APSR.C = carry; 3474 APSR.V = overflow; 3475 #endif 3476 3477 bool success = false; 3478 3479 uint32_t Rn; // the first operand 3480 uint32_t Rm; // the second operand 3481 ARM_ShifterType shift_t; 3482 uint32_t shift_n; // the shift applied to the value read from Rm 3483 switch (encoding) { 3484 case eEncodingT1: 3485 Rn = Bits32(opcode, 2, 0); 3486 Rm = Bits32(opcode, 5, 3); 3487 shift_t = SRType_LSL; 3488 shift_n = 0; 3489 break; 3490 case eEncodingT2: 3491 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3492 Rm = Bits32(opcode, 6, 3); 3493 shift_t = SRType_LSL; 3494 shift_n = 0; 3495 if (Rn < 8 && Rm < 8) 3496 return false; 3497 if (Rn == 15 || Rm == 15) 3498 return false; 3499 break; 3500 case eEncodingT3: 3501 Rn = Bits32(opcode, 19, 16); 3502 Rm = Bits32(opcode, 3, 0); 3503 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3504 if (Rn == 15 || BadReg(Rm)) 3505 return false; 3506 break; 3507 case eEncodingA1: 3508 Rn = Bits32(opcode, 19, 16); 3509 Rm = Bits32(opcode, 3, 0); 3510 shift_n = DecodeImmShiftARM(opcode, shift_t); 3511 break; 3512 default: 3513 return false; 3514 } 3515 // Read the register value from register Rn. 3516 uint32_t val1 = ReadCoreReg(Rn, &success); 3517 if (!success) 3518 return false; 3519 3520 // Read the register value from register Rm. 3521 uint32_t val2 = ReadCoreReg(Rm, &success); 3522 if (!success) 3523 return false; 3524 3525 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3526 if (!success) 3527 return false; 3528 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3529 3530 EmulateInstruction::Context context; 3531 context.type = EmulateInstruction::eContextImmediate; 3532 context.SetNoArgs(); 3533 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3534 } 3535 3536 // Arithmetic Shift Right (immediate) shifts a register value right by an 3537 // immediate number of bits, shifting in copies of its sign bit, and writes the 3538 // result to the destination register. It can optionally update the condition 3539 // flags based on the result. 3540 bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode, 3541 const ARMEncoding encoding) { 3542 #if 0 3543 // ARM pseudo code... 3544 if ConditionPassed() then 3545 EncodingSpecificOperations(); 3546 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3547 if d == 15 then // Can only occur for ARM encoding 3548 ALUWritePC(result); // setflags is always FALSE here 3549 else 3550 R[d] = result; 3551 if setflags then 3552 APSR.N = result<31>; 3553 APSR.Z = IsZeroBit(result); 3554 APSR.C = carry; 3555 // APSR.V unchanged 3556 #endif 3557 3558 return EmulateShiftImm(opcode, encoding, SRType_ASR); 3559 } 3560 3561 // Arithmetic Shift Right (register) shifts a register value right by a 3562 // variable number of bits, shifting in copies of its sign bit, and writes the 3563 // result to the destination register. The variable number of bits is read from 3564 // the bottom byte of a register. It can optionally update the condition flags 3565 // based on the result. 3566 bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode, 3567 const ARMEncoding encoding) { 3568 #if 0 3569 // ARM pseudo code... 3570 if ConditionPassed() then 3571 EncodingSpecificOperations(); 3572 shift_n = UInt(R[m]<7:0>); 3573 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3574 R[d] = result; 3575 if setflags then 3576 APSR.N = result<31>; 3577 APSR.Z = IsZeroBit(result); 3578 APSR.C = carry; 3579 // APSR.V unchanged 3580 #endif 3581 3582 return EmulateShiftReg(opcode, encoding, SRType_ASR); 3583 } 3584 3585 // Logical Shift Left (immediate) shifts a register value left by an immediate 3586 // number of bits, shifting in zeros, and writes the result to the destination 3587 // register. It can optionally update the condition flags based on the result. 3588 bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode, 3589 const ARMEncoding encoding) { 3590 #if 0 3591 // ARM pseudo code... 3592 if ConditionPassed() then 3593 EncodingSpecificOperations(); 3594 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3595 if d == 15 then // Can only occur for ARM encoding 3596 ALUWritePC(result); // setflags is always FALSE here 3597 else 3598 R[d] = result; 3599 if setflags then 3600 APSR.N = result<31>; 3601 APSR.Z = IsZeroBit(result); 3602 APSR.C = carry; 3603 // APSR.V unchanged 3604 #endif 3605 3606 return EmulateShiftImm(opcode, encoding, SRType_LSL); 3607 } 3608 3609 // Logical Shift Left (register) shifts a register value left by a variable 3610 // number of bits, shifting in zeros, and writes the result to the destination 3611 // register. The variable number of bits is read from the bottom byte of a 3612 // register. It can optionally update the condition flags based on the result. 3613 bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode, 3614 const ARMEncoding encoding) { 3615 #if 0 3616 // ARM pseudo code... 3617 if ConditionPassed() then 3618 EncodingSpecificOperations(); 3619 shift_n = UInt(R[m]<7:0>); 3620 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3621 R[d] = result; 3622 if setflags then 3623 APSR.N = result<31>; 3624 APSR.Z = IsZeroBit(result); 3625 APSR.C = carry; 3626 // APSR.V unchanged 3627 #endif 3628 3629 return EmulateShiftReg(opcode, encoding, SRType_LSL); 3630 } 3631 3632 // Logical Shift Right (immediate) shifts a register value right by an 3633 // immediate number of bits, shifting in zeros, and writes the result to the 3634 // destination register. It can optionally update the condition flags based on 3635 // the result. 3636 bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode, 3637 const ARMEncoding encoding) { 3638 #if 0 3639 // ARM pseudo code... 3640 if ConditionPassed() then 3641 EncodingSpecificOperations(); 3642 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3643 if d == 15 then // Can only occur for ARM encoding 3644 ALUWritePC(result); // setflags is always FALSE here 3645 else 3646 R[d] = result; 3647 if setflags then 3648 APSR.N = result<31>; 3649 APSR.Z = IsZeroBit(result); 3650 APSR.C = carry; 3651 // APSR.V unchanged 3652 #endif 3653 3654 return EmulateShiftImm(opcode, encoding, SRType_LSR); 3655 } 3656 3657 // Logical Shift Right (register) shifts a register value right by a variable 3658 // number of bits, shifting in zeros, and writes the result to the destination 3659 // register. The variable number of bits is read from the bottom byte of a 3660 // register. It can optionally update the condition flags based on the result. 3661 bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode, 3662 const ARMEncoding encoding) { 3663 #if 0 3664 // ARM pseudo code... 3665 if ConditionPassed() then 3666 EncodingSpecificOperations(); 3667 shift_n = UInt(R[m]<7:0>); 3668 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3669 R[d] = result; 3670 if setflags then 3671 APSR.N = result<31>; 3672 APSR.Z = IsZeroBit(result); 3673 APSR.C = carry; 3674 // APSR.V unchanged 3675 #endif 3676 3677 return EmulateShiftReg(opcode, encoding, SRType_LSR); 3678 } 3679 3680 // Rotate Right (immediate) provides the value of the contents of a register 3681 // rotated by a constant value. The bits that are rotated off the right end are 3682 // inserted into the vacated bit positions on the left. It can optionally 3683 // update the condition flags based on the result. 3684 bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode, 3685 const ARMEncoding encoding) { 3686 #if 0 3687 // ARM pseudo code... 3688 if ConditionPassed() then 3689 EncodingSpecificOperations(); 3690 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3691 if d == 15 then // Can only occur for ARM encoding 3692 ALUWritePC(result); // setflags is always FALSE here 3693 else 3694 R[d] = result; 3695 if setflags then 3696 APSR.N = result<31>; 3697 APSR.Z = IsZeroBit(result); 3698 APSR.C = carry; 3699 // APSR.V unchanged 3700 #endif 3701 3702 return EmulateShiftImm(opcode, encoding, SRType_ROR); 3703 } 3704 3705 // Rotate Right (register) provides the value of the contents of a register 3706 // rotated by a variable number of bits. The bits that are rotated off the 3707 // right end are inserted into the vacated bit positions on the left. The 3708 // variable number of bits is read from the bottom byte of a register. It can 3709 // optionally update the condition flags based on the result. 3710 bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode, 3711 const ARMEncoding encoding) { 3712 #if 0 3713 // ARM pseudo code... 3714 if ConditionPassed() then 3715 EncodingSpecificOperations(); 3716 shift_n = UInt(R[m]<7:0>); 3717 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3718 R[d] = result; 3719 if setflags then 3720 APSR.N = result<31>; 3721 APSR.Z = IsZeroBit(result); 3722 APSR.C = carry; 3723 // APSR.V unchanged 3724 #endif 3725 3726 return EmulateShiftReg(opcode, encoding, SRType_ROR); 3727 } 3728 3729 // Rotate Right with Extend provides the value of the contents of a register 3730 // shifted right by one place, with the carry flag shifted into bit [31]. 3731 // 3732 // RRX can optionally update the condition flags based on the result. 3733 // In that case, bit [0] is shifted into the carry flag. 3734 bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode, 3735 const ARMEncoding encoding) { 3736 #if 0 3737 // ARM pseudo code... 3738 if ConditionPassed() then 3739 EncodingSpecificOperations(); 3740 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3741 if d == 15 then // Can only occur for ARM encoding 3742 ALUWritePC(result); // setflags is always FALSE here 3743 else 3744 R[d] = result; 3745 if setflags then 3746 APSR.N = result<31>; 3747 APSR.Z = IsZeroBit(result); 3748 APSR.C = carry; 3749 // APSR.V unchanged 3750 #endif 3751 3752 return EmulateShiftImm(opcode, encoding, SRType_RRX); 3753 } 3754 3755 bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode, 3756 const ARMEncoding encoding, 3757 ARM_ShifterType shift_type) { 3758 // assert(shift_type == SRType_ASR 3759 // || shift_type == SRType_LSL 3760 // || shift_type == SRType_LSR 3761 // || shift_type == SRType_ROR 3762 // || shift_type == SRType_RRX); 3763 3764 bool success = false; 3765 3766 if (ConditionPassed(opcode)) { 3767 uint32_t Rd; // the destination register 3768 uint32_t Rm; // the first operand register 3769 uint32_t imm5; // encoding for the shift amount 3770 uint32_t carry; // the carry bit after the shift operation 3771 bool setflags; 3772 3773 // Special case handling! 3774 // A8.6.139 ROR (immediate) -- Encoding T1 3775 ARMEncoding use_encoding = encoding; 3776 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) { 3777 // Morph the T1 encoding from the ARM Architecture Manual into T2 3778 // encoding to have the same decoding of bit fields as the other Thumb2 3779 // shift operations. 3780 use_encoding = eEncodingT2; 3781 } 3782 3783 switch (use_encoding) { 3784 case eEncodingT1: 3785 // Due to the above special case handling! 3786 if (shift_type == SRType_ROR) 3787 return false; 3788 3789 Rd = Bits32(opcode, 2, 0); 3790 Rm = Bits32(opcode, 5, 3); 3791 setflags = !InITBlock(); 3792 imm5 = Bits32(opcode, 10, 6); 3793 break; 3794 case eEncodingT2: 3795 // A8.6.141 RRX 3796 // There's no imm form of RRX instructions. 3797 if (shift_type == SRType_RRX) 3798 return false; 3799 3800 Rd = Bits32(opcode, 11, 8); 3801 Rm = Bits32(opcode, 3, 0); 3802 setflags = BitIsSet(opcode, 20); 3803 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3804 if (BadReg(Rd) || BadReg(Rm)) 3805 return false; 3806 break; 3807 case eEncodingA1: 3808 Rd = Bits32(opcode, 15, 12); 3809 Rm = Bits32(opcode, 3, 0); 3810 setflags = BitIsSet(opcode, 20); 3811 imm5 = Bits32(opcode, 11, 7); 3812 break; 3813 default: 3814 return false; 3815 } 3816 3817 // A8.6.139 ROR (immediate) 3818 if (shift_type == SRType_ROR && imm5 == 0) 3819 shift_type = SRType_RRX; 3820 3821 // Get the first operand. 3822 uint32_t value = ReadCoreReg(Rm, &success); 3823 if (!success) 3824 return false; 3825 3826 // Decode the shift amount if not RRX. 3827 uint32_t amt = 3828 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3829 3830 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3831 if (!success) 3832 return false; 3833 3834 // The context specifies that an immediate is to be moved into Rd. 3835 EmulateInstruction::Context context; 3836 context.type = EmulateInstruction::eContextImmediate; 3837 context.SetNoArgs(); 3838 3839 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3840 return false; 3841 } 3842 return true; 3843 } 3844 3845 bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode, 3846 const ARMEncoding encoding, 3847 ARM_ShifterType shift_type) { 3848 // assert(shift_type == SRType_ASR 3849 // || shift_type == SRType_LSL 3850 // || shift_type == SRType_LSR 3851 // || shift_type == SRType_ROR); 3852 3853 bool success = false; 3854 3855 if (ConditionPassed(opcode)) { 3856 uint32_t Rd; // the destination register 3857 uint32_t Rn; // the first operand register 3858 uint32_t 3859 Rm; // the register whose bottom byte contains the amount to shift by 3860 uint32_t carry; // the carry bit after the shift operation 3861 bool setflags; 3862 switch (encoding) { 3863 case eEncodingT1: 3864 Rd = Bits32(opcode, 2, 0); 3865 Rn = Rd; 3866 Rm = Bits32(opcode, 5, 3); 3867 setflags = !InITBlock(); 3868 break; 3869 case eEncodingT2: 3870 Rd = Bits32(opcode, 11, 8); 3871 Rn = Bits32(opcode, 19, 16); 3872 Rm = Bits32(opcode, 3, 0); 3873 setflags = BitIsSet(opcode, 20); 3874 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3875 return false; 3876 break; 3877 case eEncodingA1: 3878 Rd = Bits32(opcode, 15, 12); 3879 Rn = Bits32(opcode, 3, 0); 3880 Rm = Bits32(opcode, 11, 8); 3881 setflags = BitIsSet(opcode, 20); 3882 if (Rd == 15 || Rn == 15 || Rm == 15) 3883 return false; 3884 break; 3885 default: 3886 return false; 3887 } 3888 3889 // Get the first operand. 3890 uint32_t value = ReadCoreReg(Rn, &success); 3891 if (!success) 3892 return false; 3893 // Get the Rm register content. 3894 uint32_t val = ReadCoreReg(Rm, &success); 3895 if (!success) 3896 return false; 3897 3898 // Get the shift amount. 3899 uint32_t amt = Bits32(val, 7, 0); 3900 3901 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3902 if (!success) 3903 return false; 3904 3905 // The context specifies that an immediate is to be moved into Rd. 3906 EmulateInstruction::Context context; 3907 context.type = EmulateInstruction::eContextImmediate; 3908 context.SetNoArgs(); 3909 3910 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3911 return false; 3912 } 3913 return true; 3914 } 3915 3916 // LDM loads multiple registers from consecutive memory locations, using an 3917 // address from a base register. Optionally the address just above the highest 3918 // of those locations can be written back to the base register. 3919 bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode, 3920 const ARMEncoding encoding) { 3921 #if 0 3922 // ARM pseudo code... 3923 if ConditionPassed() 3924 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3925 address = R[n]; 3926 3927 for i = 0 to 14 3928 if registers<i> == '1' then 3929 R[i] = MemA[address, 4]; address = address + 4; 3930 if registers<15> == '1' then 3931 LoadWritePC (MemA[address, 4]); 3932 3933 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3934 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3935 3936 #endif 3937 3938 bool success = false; 3939 if (ConditionPassed(opcode)) { 3940 uint32_t n; 3941 uint32_t registers = 0; 3942 bool wback; 3943 const uint32_t addr_byte_size = GetAddressByteSize(); 3944 switch (encoding) { 3945 case eEncodingT1: 3946 // n = UInt(Rn); registers = '00000000':register_list; wback = 3947 // (registers<n> == '0'); 3948 n = Bits32(opcode, 10, 8); 3949 registers = Bits32(opcode, 7, 0); 3950 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3951 wback = BitIsClear(registers, n); 3952 // if BitCount(registers) < 1 then UNPREDICTABLE; 3953 if (BitCount(registers) < 1) 3954 return false; 3955 break; 3956 case eEncodingT2: 3957 // if W == '1' && Rn == '1101' then SEE POP; 3958 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3959 n = Bits32(opcode, 19, 16); 3960 registers = Bits32(opcode, 15, 0); 3961 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3962 wback = BitIsSet(opcode, 21); 3963 3964 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 3965 // UNPREDICTABLE; 3966 if ((n == 15) || (BitCount(registers) < 2) || 3967 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 3968 return false; 3969 3970 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 3971 // UNPREDICTABLE; 3972 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 3973 return false; 3974 3975 // if wback && registers<n> == '1' then UNPREDICTABLE; 3976 if (wback && BitIsSet(registers, n)) 3977 return false; 3978 break; 3979 3980 case eEncodingA1: 3981 n = Bits32(opcode, 19, 16); 3982 registers = Bits32(opcode, 15, 0); 3983 wback = BitIsSet(opcode, 21); 3984 if ((n == 15) || (BitCount(registers) < 1)) 3985 return false; 3986 break; 3987 default: 3988 return false; 3989 } 3990 3991 int32_t offset = 0; 3992 const addr_t base_address = 3993 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3994 if (!success) 3995 return false; 3996 3997 EmulateInstruction::Context context; 3998 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3999 RegisterInfo dwarf_reg; 4000 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4001 context.SetRegisterPlusOffset(dwarf_reg, offset); 4002 4003 for (int i = 0; i < 14; ++i) { 4004 if (BitIsSet(registers, i)) { 4005 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4006 context.SetRegisterPlusOffset(dwarf_reg, offset); 4007 if (wback && (n == 13)) // Pop Instruction 4008 { 4009 context.type = EmulateInstruction::eContextPopRegisterOffStack; 4010 context.SetAddress(base_address + offset); 4011 } 4012 4013 // R[i] = MemA [address, 4]; address = address + 4; 4014 uint32_t data = MemARead(context, base_address + offset, addr_byte_size, 4015 0, &success); 4016 if (!success) 4017 return false; 4018 4019 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4020 data)) 4021 return false; 4022 4023 offset += addr_byte_size; 4024 } 4025 } 4026 4027 if (BitIsSet(registers, 15)) { 4028 // LoadWritePC (MemA [address, 4]); 4029 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4030 context.SetRegisterPlusOffset(dwarf_reg, offset); 4031 uint32_t data = 4032 MemARead(context, base_address + offset, addr_byte_size, 0, &success); 4033 if (!success) 4034 return false; 4035 // In ARMv5T and above, this is an interworking branch. 4036 if (!LoadWritePC(context, data)) 4037 return false; 4038 } 4039 4040 if (wback && BitIsClear(registers, n)) { 4041 // R[n] = R[n] + 4 * BitCount (registers) 4042 int32_t offset = addr_byte_size * BitCount(registers); 4043 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4044 context.SetRegisterPlusOffset(dwarf_reg, offset); 4045 4046 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4047 base_address + offset)) 4048 return false; 4049 } 4050 if (wback && BitIsSet(registers, n)) 4051 // R[n] bits(32) UNKNOWN; 4052 return WriteBits32Unknown(n); 4053 } 4054 return true; 4055 } 4056 4057 // LDMDA loads multiple registers from consecutive memory locations using an 4058 // address from a base register. 4059 // The consecutive memory locations end at this address and the address just 4060 // below the lowest of those locations can optionally be written back to the 4061 // base register. 4062 bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode, 4063 const ARMEncoding encoding) { 4064 #if 0 4065 // ARM pseudo code... 4066 if ConditionPassed() then 4067 EncodingSpecificOperations(); 4068 address = R[n] - 4*BitCount(registers) + 4; 4069 4070 for i = 0 to 14 4071 if registers<i> == '1' then 4072 R[i] = MemA[address,4]; address = address + 4; 4073 4074 if registers<15> == '1' then 4075 LoadWritePC(MemA[address,4]); 4076 4077 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4078 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4079 #endif 4080 4081 bool success = false; 4082 4083 if (ConditionPassed(opcode)) { 4084 uint32_t n; 4085 uint32_t registers = 0; 4086 bool wback; 4087 const uint32_t addr_byte_size = GetAddressByteSize(); 4088 4089 // EncodingSpecificOperations(); 4090 switch (encoding) { 4091 case eEncodingA1: 4092 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4093 n = Bits32(opcode, 19, 16); 4094 registers = Bits32(opcode, 15, 0); 4095 wback = BitIsSet(opcode, 21); 4096 4097 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4098 if ((n == 15) || (BitCount(registers) < 1)) 4099 return false; 4100 4101 break; 4102 4103 default: 4104 return false; 4105 } 4106 // address = R[n] - 4*BitCount(registers) + 4; 4107 4108 int32_t offset = 0; 4109 addr_t Rn = ReadCoreReg(n, &success); 4110 4111 if (!success) 4112 return false; 4113 4114 addr_t address = 4115 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size; 4116 4117 EmulateInstruction::Context context; 4118 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4119 RegisterInfo dwarf_reg; 4120 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4121 context.SetRegisterPlusOffset(dwarf_reg, offset); 4122 4123 // for i = 0 to 14 4124 for (int i = 0; i < 14; ++i) { 4125 // if registers<i> == '1' then 4126 if (BitIsSet(registers, i)) { 4127 // R[i] = MemA[address,4]; address = address + 4; 4128 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4129 uint32_t data = 4130 MemARead(context, address + offset, addr_byte_size, 0, &success); 4131 if (!success) 4132 return false; 4133 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4134 data)) 4135 return false; 4136 offset += addr_byte_size; 4137 } 4138 } 4139 4140 // if registers<15> == '1' then 4141 // LoadWritePC(MemA[address,4]); 4142 if (BitIsSet(registers, 15)) { 4143 context.SetRegisterPlusOffset(dwarf_reg, offset); 4144 uint32_t data = 4145 MemARead(context, address + offset, addr_byte_size, 0, &success); 4146 if (!success) 4147 return false; 4148 // In ARMv5T and above, this is an interworking branch. 4149 if (!LoadWritePC(context, data)) 4150 return false; 4151 } 4152 4153 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4154 if (wback && BitIsClear(registers, n)) { 4155 if (!success) 4156 return false; 4157 4158 offset = (addr_byte_size * BitCount(registers)) * -1; 4159 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4160 context.SetImmediateSigned(offset); 4161 addr_t addr = Rn + offset; 4162 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4163 addr)) 4164 return false; 4165 } 4166 4167 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4168 if (wback && BitIsSet(registers, n)) 4169 return WriteBits32Unknown(n); 4170 } 4171 return true; 4172 } 4173 4174 // LDMDB loads multiple registers from consecutive memory locations using an 4175 // address from a base register. The 4176 // consecutive memory locations end just below this address, and the address of 4177 // the lowest of those locations can be optionally written back to the base 4178 // register. 4179 bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode, 4180 const ARMEncoding encoding) { 4181 #if 0 4182 // ARM pseudo code... 4183 if ConditionPassed() then 4184 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4185 address = R[n] - 4*BitCount(registers); 4186 4187 for i = 0 to 14 4188 if registers<i> == '1' then 4189 R[i] = MemA[address,4]; address = address + 4; 4190 if registers<15> == '1' then 4191 LoadWritePC(MemA[address,4]); 4192 4193 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4194 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 4195 #endif 4196 4197 bool success = false; 4198 4199 if (ConditionPassed(opcode)) { 4200 uint32_t n; 4201 uint32_t registers = 0; 4202 bool wback; 4203 const uint32_t addr_byte_size = GetAddressByteSize(); 4204 switch (encoding) { 4205 case eEncodingT1: 4206 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 4207 n = Bits32(opcode, 19, 16); 4208 registers = Bits32(opcode, 15, 0); 4209 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 4210 wback = BitIsSet(opcode, 21); 4211 4212 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 4213 // UNPREDICTABLE; 4214 if ((n == 15) || (BitCount(registers) < 2) || 4215 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 4216 return false; 4217 4218 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 4219 // UNPREDICTABLE; 4220 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 4221 return false; 4222 4223 // if wback && registers<n> == '1' then UNPREDICTABLE; 4224 if (wback && BitIsSet(registers, n)) 4225 return false; 4226 4227 break; 4228 4229 case eEncodingA1: 4230 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4231 n = Bits32(opcode, 19, 16); 4232 registers = Bits32(opcode, 15, 0); 4233 wback = BitIsSet(opcode, 21); 4234 4235 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4236 if ((n == 15) || (BitCount(registers) < 1)) 4237 return false; 4238 4239 break; 4240 4241 default: 4242 return false; 4243 } 4244 4245 // address = R[n] - 4*BitCount(registers); 4246 4247 int32_t offset = 0; 4248 addr_t Rn = 4249 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4250 4251 if (!success) 4252 return false; 4253 4254 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4255 EmulateInstruction::Context context; 4256 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4257 RegisterInfo dwarf_reg; 4258 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4259 context.SetRegisterPlusOffset(dwarf_reg, Rn - address); 4260 4261 for (int i = 0; i < 14; ++i) { 4262 if (BitIsSet(registers, i)) { 4263 // R[i] = MemA[address,4]; address = address + 4; 4264 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4265 uint32_t data = 4266 MemARead(context, address + offset, addr_byte_size, 0, &success); 4267 if (!success) 4268 return false; 4269 4270 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4271 data)) 4272 return false; 4273 4274 offset += addr_byte_size; 4275 } 4276 } 4277 4278 // if registers<15> == '1' then 4279 // LoadWritePC(MemA[address,4]); 4280 if (BitIsSet(registers, 15)) { 4281 context.SetRegisterPlusOffset(dwarf_reg, offset); 4282 uint32_t data = 4283 MemARead(context, address + offset, addr_byte_size, 0, &success); 4284 if (!success) 4285 return false; 4286 // In ARMv5T and above, this is an interworking branch. 4287 if (!LoadWritePC(context, data)) 4288 return false; 4289 } 4290 4291 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4292 if (wback && BitIsClear(registers, n)) { 4293 if (!success) 4294 return false; 4295 4296 offset = (addr_byte_size * BitCount(registers)) * -1; 4297 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4298 context.SetImmediateSigned(offset); 4299 addr_t addr = Rn + offset; 4300 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4301 addr)) 4302 return false; 4303 } 4304 4305 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4306 // possible for encoding A1 4307 if (wback && BitIsSet(registers, n)) 4308 return WriteBits32Unknown(n); 4309 } 4310 return true; 4311 } 4312 4313 // LDMIB loads multiple registers from consecutive memory locations using an 4314 // address from a base register. The 4315 // consecutive memory locations start just above this address, and thea ddress 4316 // of the last of those locations can optinoally be written back to the base 4317 // register. 4318 bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode, 4319 const ARMEncoding encoding) { 4320 #if 0 4321 if ConditionPassed() then 4322 EncodingSpecificOperations(); 4323 address = R[n] + 4; 4324 4325 for i = 0 to 14 4326 if registers<i> == '1' then 4327 R[i] = MemA[address,4]; address = address + 4; 4328 if registers<15> == '1' then 4329 LoadWritePC(MemA[address,4]); 4330 4331 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4332 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4333 #endif 4334 4335 bool success = false; 4336 4337 if (ConditionPassed(opcode)) { 4338 uint32_t n; 4339 uint32_t registers = 0; 4340 bool wback; 4341 const uint32_t addr_byte_size = GetAddressByteSize(); 4342 switch (encoding) { 4343 case eEncodingA1: 4344 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4345 n = Bits32(opcode, 19, 16); 4346 registers = Bits32(opcode, 15, 0); 4347 wback = BitIsSet(opcode, 21); 4348 4349 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4350 if ((n == 15) || (BitCount(registers) < 1)) 4351 return false; 4352 4353 break; 4354 default: 4355 return false; 4356 } 4357 // address = R[n] + 4; 4358 4359 int32_t offset = 0; 4360 addr_t Rn = 4361 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4362 4363 if (!success) 4364 return false; 4365 4366 addr_t address = Rn + addr_byte_size; 4367 4368 EmulateInstruction::Context context; 4369 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4370 RegisterInfo dwarf_reg; 4371 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4372 context.SetRegisterPlusOffset(dwarf_reg, offset); 4373 4374 for (int i = 0; i < 14; ++i) { 4375 if (BitIsSet(registers, i)) { 4376 // R[i] = MemA[address,4]; address = address + 4; 4377 4378 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size); 4379 uint32_t data = 4380 MemARead(context, address + offset, addr_byte_size, 0, &success); 4381 if (!success) 4382 return false; 4383 4384 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4385 data)) 4386 return false; 4387 4388 offset += addr_byte_size; 4389 } 4390 } 4391 4392 // if registers<15> == '1' then 4393 // LoadWritePC(MemA[address,4]); 4394 if (BitIsSet(registers, 15)) { 4395 context.SetRegisterPlusOffset(dwarf_reg, offset); 4396 uint32_t data = 4397 MemARead(context, address + offset, addr_byte_size, 0, &success); 4398 if (!success) 4399 return false; 4400 // In ARMv5T and above, this is an interworking branch. 4401 if (!LoadWritePC(context, data)) 4402 return false; 4403 } 4404 4405 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4406 if (wback && BitIsClear(registers, n)) { 4407 if (!success) 4408 return false; 4409 4410 offset = addr_byte_size * BitCount(registers); 4411 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4412 context.SetImmediateSigned(offset); 4413 addr_t addr = Rn + offset; 4414 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4415 addr)) 4416 return false; 4417 } 4418 4419 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4420 // possible for encoding A1 4421 if (wback && BitIsSet(registers, n)) 4422 return WriteBits32Unknown(n); 4423 } 4424 return true; 4425 } 4426 4427 // Load Register (immediate) calculates an address from a base register value 4428 // and an immediate offset, loads a word from memory, and writes to a register. 4429 // LDR (immediate, Thumb) 4430 bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode, 4431 const ARMEncoding encoding) { 4432 #if 0 4433 // ARM pseudo code... 4434 if (ConditionPassed()) 4435 { 4436 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 4437 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4438 address = if index then offset_addr else R[n]; 4439 data = MemU[address,4]; 4440 if wback then R[n] = offset_addr; 4441 if t == 15 then 4442 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 4443 elsif UnalignedSupport() || address<1:0> = '00' then 4444 R[t] = data; 4445 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 4446 } 4447 #endif 4448 4449 bool success = false; 4450 4451 if (ConditionPassed(opcode)) { 4452 uint32_t Rt; // the destination register 4453 uint32_t Rn; // the base register 4454 uint32_t imm32; // the immediate offset used to form the address 4455 addr_t offset_addr; // the offset address 4456 addr_t address; // the calculated address 4457 uint32_t data; // the literal data value from memory load 4458 bool add, index, wback; 4459 switch (encoding) { 4460 case eEncodingT1: 4461 Rt = Bits32(opcode, 2, 0); 4462 Rn = Bits32(opcode, 5, 3); 4463 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 4464 // index = TRUE; add = TRUE; wback = FALSE 4465 add = true; 4466 index = true; 4467 wback = false; 4468 4469 break; 4470 4471 case eEncodingT2: 4472 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4473 Rt = Bits32(opcode, 10, 8); 4474 Rn = 13; 4475 imm32 = Bits32(opcode, 7, 0) << 2; 4476 4477 // index = TRUE; add = TRUE; wback = FALSE; 4478 index = true; 4479 add = true; 4480 wback = false; 4481 4482 break; 4483 4484 case eEncodingT3: 4485 // if Rn == '1111' then SEE LDR (literal); 4486 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4487 Rt = Bits32(opcode, 15, 12); 4488 Rn = Bits32(opcode, 19, 16); 4489 imm32 = Bits32(opcode, 11, 0); 4490 4491 // index = TRUE; add = TRUE; wback = FALSE; 4492 index = true; 4493 add = true; 4494 wback = false; 4495 4496 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4497 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4498 return false; 4499 4500 break; 4501 4502 case eEncodingT4: 4503 // if Rn == '1111' then SEE LDR (literal); 4504 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4505 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == 4506 // '00000100' then SEE POP; 4507 // if P == '0' && W == '0' then UNDEFINED; 4508 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 4509 return false; 4510 4511 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4512 Rt = Bits32(opcode, 15, 12); 4513 Rn = Bits32(opcode, 19, 16); 4514 imm32 = Bits32(opcode, 7, 0); 4515 4516 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4517 index = BitIsSet(opcode, 10); 4518 add = BitIsSet(opcode, 9); 4519 wback = BitIsSet(opcode, 8); 4520 4521 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) 4522 // then UNPREDICTABLE; 4523 if ((wback && (Rn == Rt)) || 4524 ((Rt == 15) && InITBlock() && !LastInITBlock())) 4525 return false; 4526 4527 break; 4528 4529 default: 4530 return false; 4531 } 4532 uint32_t base = ReadCoreReg(Rn, &success); 4533 if (!success) 4534 return false; 4535 if (add) 4536 offset_addr = base + imm32; 4537 else 4538 offset_addr = base - imm32; 4539 4540 address = (index ? offset_addr : base); 4541 4542 RegisterInfo base_reg; 4543 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4544 if (wback) { 4545 EmulateInstruction::Context ctx; 4546 if (Rn == 13) { 4547 ctx.type = eContextAdjustStackPointer; 4548 ctx.SetImmediateSigned((int32_t)(offset_addr - base)); 4549 } else if (Rn == GetFramePointerRegisterNumber()) { 4550 ctx.type = eContextSetFramePointer; 4551 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4552 } else { 4553 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4554 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4555 } 4556 4557 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn, 4558 offset_addr)) 4559 return false; 4560 } 4561 4562 // Prepare to write to the Rt register. 4563 EmulateInstruction::Context context; 4564 context.type = EmulateInstruction::eContextRegisterLoad; 4565 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4566 4567 // Read memory from the address. 4568 data = MemURead(context, address, 4, 0, &success); 4569 if (!success) 4570 return false; 4571 4572 if (Rt == 15) { 4573 if (Bits32(address, 1, 0) == 0) { 4574 if (!LoadWritePC(context, data)) 4575 return false; 4576 } else 4577 return false; 4578 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 4579 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 4580 data)) 4581 return false; 4582 } else 4583 WriteBits32Unknown(Rt); 4584 } 4585 return true; 4586 } 4587 4588 // STM (Store Multiple Increment After) stores multiple registers to consecutive 4589 // memory locations using an address 4590 // from a base register. The consecutive memory locations start at this 4591 // address, and the address just above the last of those locations can 4592 // optionally be written back to the base register. 4593 bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode, 4594 const ARMEncoding encoding) { 4595 #if 0 4596 if ConditionPassed() then 4597 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4598 address = R[n]; 4599 4600 for i = 0 to 14 4601 if registers<i> == '1' then 4602 if i == n && wback && i != LowestSetBit(registers) then 4603 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4604 else 4605 MemA[address,4] = R[i]; 4606 address = address + 4; 4607 4608 if registers<15> == '1' then // Only possible for encoding A1 4609 MemA[address,4] = PCStoreValue(); 4610 if wback then R[n] = R[n] + 4*BitCount(registers); 4611 #endif 4612 4613 bool success = false; 4614 4615 if (ConditionPassed(opcode)) { 4616 uint32_t n; 4617 uint32_t registers = 0; 4618 bool wback; 4619 const uint32_t addr_byte_size = GetAddressByteSize(); 4620 4621 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4622 switch (encoding) { 4623 case eEncodingT1: 4624 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4625 n = Bits32(opcode, 10, 8); 4626 registers = Bits32(opcode, 7, 0); 4627 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4628 wback = true; 4629 4630 // if BitCount(registers) < 1 then UNPREDICTABLE; 4631 if (BitCount(registers) < 1) 4632 return false; 4633 4634 break; 4635 4636 case eEncodingT2: 4637 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4638 n = Bits32(opcode, 19, 16); 4639 registers = Bits32(opcode, 15, 0); 4640 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4641 wback = BitIsSet(opcode, 21); 4642 4643 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4644 if ((n == 15) || (BitCount(registers) < 2)) 4645 return false; 4646 4647 // if wback && registers<n> == '1' then UNPREDICTABLE; 4648 if (wback && BitIsSet(registers, n)) 4649 return false; 4650 4651 break; 4652 4653 case eEncodingA1: 4654 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4655 n = Bits32(opcode, 19, 16); 4656 registers = Bits32(opcode, 15, 0); 4657 wback = BitIsSet(opcode, 21); 4658 4659 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4660 if ((n == 15) || (BitCount(registers) < 1)) 4661 return false; 4662 4663 break; 4664 4665 default: 4666 return false; 4667 } 4668 4669 // address = R[n]; 4670 int32_t offset = 0; 4671 const addr_t address = 4672 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4673 if (!success) 4674 return false; 4675 4676 EmulateInstruction::Context context; 4677 context.type = EmulateInstruction::eContextRegisterStore; 4678 RegisterInfo base_reg; 4679 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4680 4681 // for i = 0 to 14 4682 uint32_t lowest_set_bit = 14; 4683 for (uint32_t i = 0; i < 14; ++i) { 4684 // if registers<i> == '1' then 4685 if (BitIsSet(registers, i)) { 4686 if (i < lowest_set_bit) 4687 lowest_set_bit = i; 4688 // if i == n && wback && i != LowestSetBit(registers) then 4689 if ((i == n) && wback && (i != lowest_set_bit)) 4690 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings 4691 // T1 and A1 4692 WriteBits32UnknownToMemory(address + offset); 4693 else { 4694 // MemA[address,4] = R[i]; 4695 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4696 0, &success); 4697 if (!success) 4698 return false; 4699 4700 RegisterInfo data_reg; 4701 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4702 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 4703 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4704 return false; 4705 } 4706 4707 // address = address + 4; 4708 offset += addr_byte_size; 4709 } 4710 } 4711 4712 // if registers<15> == '1' then // Only possible for encoding A1 4713 // MemA[address,4] = PCStoreValue(); 4714 if (BitIsSet(registers, 15)) { 4715 RegisterInfo pc_reg; 4716 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4717 context.SetRegisterPlusOffset(pc_reg, 8); 4718 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4719 if (!success) 4720 return false; 4721 4722 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4723 return false; 4724 } 4725 4726 // if wback then R[n] = R[n] + 4*BitCount(registers); 4727 if (wback) { 4728 offset = addr_byte_size * BitCount(registers); 4729 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4730 context.SetImmediateSigned(offset); 4731 addr_t data = address + offset; 4732 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4733 data)) 4734 return false; 4735 } 4736 } 4737 return true; 4738 } 4739 4740 // STMDA (Store Multiple Decrement After) stores multiple registers to 4741 // consecutive memory locations using an address from a base register. The 4742 // consecutive memory locations end at this address, and the address just below 4743 // the lowest of those locations can optionally be written back to the base 4744 // register. 4745 bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode, 4746 const ARMEncoding encoding) { 4747 #if 0 4748 if ConditionPassed() then 4749 EncodingSpecificOperations(); 4750 address = R[n] - 4*BitCount(registers) + 4; 4751 4752 for i = 0 to 14 4753 if registers<i> == '1' then 4754 if i == n && wback && i != LowestSetBit(registers) then 4755 MemA[address,4] = bits(32) UNKNOWN; 4756 else 4757 MemA[address,4] = R[i]; 4758 address = address + 4; 4759 4760 if registers<15> == '1' then 4761 MemA[address,4] = PCStoreValue(); 4762 4763 if wback then R[n] = R[n] - 4*BitCount(registers); 4764 #endif 4765 4766 bool success = false; 4767 4768 if (ConditionPassed(opcode)) { 4769 uint32_t n; 4770 uint32_t registers = 0; 4771 bool wback; 4772 const uint32_t addr_byte_size = GetAddressByteSize(); 4773 4774 // EncodingSpecificOperations(); 4775 switch (encoding) { 4776 case eEncodingA1: 4777 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4778 n = Bits32(opcode, 19, 16); 4779 registers = Bits32(opcode, 15, 0); 4780 wback = BitIsSet(opcode, 21); 4781 4782 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4783 if ((n == 15) || (BitCount(registers) < 1)) 4784 return false; 4785 break; 4786 default: 4787 return false; 4788 } 4789 4790 // address = R[n] - 4*BitCount(registers) + 4; 4791 int32_t offset = 0; 4792 addr_t Rn = ReadCoreReg(n, &success); 4793 if (!success) 4794 return false; 4795 4796 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4; 4797 4798 EmulateInstruction::Context context; 4799 context.type = EmulateInstruction::eContextRegisterStore; 4800 RegisterInfo base_reg; 4801 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4802 4803 // for i = 0 to 14 4804 uint32_t lowest_bit_set = 14; 4805 for (uint32_t i = 0; i < 14; ++i) { 4806 // if registers<i> == '1' then 4807 if (BitIsSet(registers, i)) { 4808 if (i < lowest_bit_set) 4809 lowest_bit_set = i; 4810 // if i == n && wback && i != LowestSetBit(registers) then 4811 if ((i == n) && wback && (i != lowest_bit_set)) 4812 // MemA[address,4] = bits(32) UNKNOWN; 4813 WriteBits32UnknownToMemory(address + offset); 4814 else { 4815 // MemA[address,4] = R[i]; 4816 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4817 0, &success); 4818 if (!success) 4819 return false; 4820 4821 RegisterInfo data_reg; 4822 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4823 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4824 Rn - (address + offset)); 4825 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4826 return false; 4827 } 4828 4829 // address = address + 4; 4830 offset += addr_byte_size; 4831 } 4832 } 4833 4834 // if registers<15> == '1' then 4835 // MemA[address,4] = PCStoreValue(); 4836 if (BitIsSet(registers, 15)) { 4837 RegisterInfo pc_reg; 4838 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4839 context.SetRegisterPlusOffset(pc_reg, 8); 4840 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4841 if (!success) 4842 return false; 4843 4844 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4845 return false; 4846 } 4847 4848 // if wback then R[n] = R[n] - 4*BitCount(registers); 4849 if (wback) { 4850 offset = (addr_byte_size * BitCount(registers)) * -1; 4851 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4852 context.SetImmediateSigned(offset); 4853 addr_t data = Rn + offset; 4854 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4855 data)) 4856 return false; 4857 } 4858 } 4859 return true; 4860 } 4861 4862 // STMDB (Store Multiple Decrement Before) stores multiple registers to 4863 // consecutive memory locations using an address from a base register. The 4864 // consecutive memory locations end just below this address, and the address of 4865 // the first of those locations can optionally be written back to the base 4866 // register. 4867 bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode, 4868 const ARMEncoding encoding) { 4869 #if 0 4870 if ConditionPassed() then 4871 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4872 address = R[n] - 4*BitCount(registers); 4873 4874 for i = 0 to 14 4875 if registers<i> == '1' then 4876 if i == n && wback && i != LowestSetBit(registers) then 4877 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4878 else 4879 MemA[address,4] = R[i]; 4880 address = address + 4; 4881 4882 if registers<15> == '1' then // Only possible for encoding A1 4883 MemA[address,4] = PCStoreValue(); 4884 4885 if wback then R[n] = R[n] - 4*BitCount(registers); 4886 #endif 4887 4888 bool success = false; 4889 4890 if (ConditionPassed(opcode)) { 4891 uint32_t n; 4892 uint32_t registers = 0; 4893 bool wback; 4894 const uint32_t addr_byte_size = GetAddressByteSize(); 4895 4896 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4897 switch (encoding) { 4898 case eEncodingT1: 4899 // if W == '1' && Rn == '1101' then SEE PUSH; 4900 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) { 4901 // See PUSH 4902 } 4903 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4904 n = Bits32(opcode, 19, 16); 4905 registers = Bits32(opcode, 15, 0); 4906 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4907 wback = BitIsSet(opcode, 21); 4908 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4909 if ((n == 15) || BitCount(registers) < 2) 4910 return false; 4911 // if wback && registers<n> == '1' then UNPREDICTABLE; 4912 if (wback && BitIsSet(registers, n)) 4913 return false; 4914 break; 4915 4916 case eEncodingA1: 4917 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE 4918 // PUSH; 4919 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) && 4920 BitCount(Bits32(opcode, 15, 0)) >= 2) { 4921 // See Push 4922 } 4923 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4924 n = Bits32(opcode, 19, 16); 4925 registers = Bits32(opcode, 15, 0); 4926 wback = BitIsSet(opcode, 21); 4927 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4928 if ((n == 15) || BitCount(registers) < 1) 4929 return false; 4930 break; 4931 4932 default: 4933 return false; 4934 } 4935 4936 // address = R[n] - 4*BitCount(registers); 4937 4938 int32_t offset = 0; 4939 addr_t Rn = 4940 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4941 if (!success) 4942 return false; 4943 4944 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4945 4946 EmulateInstruction::Context context; 4947 context.type = EmulateInstruction::eContextRegisterStore; 4948 RegisterInfo base_reg; 4949 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4950 4951 // for i = 0 to 14 4952 uint32_t lowest_set_bit = 14; 4953 for (uint32_t i = 0; i < 14; ++i) { 4954 // if registers<i> == '1' then 4955 if (BitIsSet(registers, i)) { 4956 if (i < lowest_set_bit) 4957 lowest_set_bit = i; 4958 // if i == n && wback && i != LowestSetBit(registers) then 4959 if ((i == n) && wback && (i != lowest_set_bit)) 4960 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding 4961 // A1 4962 WriteBits32UnknownToMemory(address + offset); 4963 else { 4964 // MemA[address,4] = R[i]; 4965 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4966 0, &success); 4967 if (!success) 4968 return false; 4969 4970 RegisterInfo data_reg; 4971 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4972 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4973 Rn - (address + offset)); 4974 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4975 return false; 4976 } 4977 4978 // address = address + 4; 4979 offset += addr_byte_size; 4980 } 4981 } 4982 4983 // if registers<15> == '1' then // Only possible for encoding A1 4984 // MemA[address,4] = PCStoreValue(); 4985 if (BitIsSet(registers, 15)) { 4986 RegisterInfo pc_reg; 4987 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4988 context.SetRegisterPlusOffset(pc_reg, 8); 4989 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4990 if (!success) 4991 return false; 4992 4993 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4994 return false; 4995 } 4996 4997 // if wback then R[n] = R[n] - 4*BitCount(registers); 4998 if (wback) { 4999 offset = (addr_byte_size * BitCount(registers)) * -1; 5000 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5001 context.SetImmediateSigned(offset); 5002 addr_t data = Rn + offset; 5003 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5004 data)) 5005 return false; 5006 } 5007 } 5008 return true; 5009 } 5010 5011 // STMIB (Store Multiple Increment Before) stores multiple registers to 5012 // consecutive memory locations using an address from a base register. The 5013 // consecutive memory locations start just above this address, and the address 5014 // of the last of those locations can optionally be written back to the base 5015 // register. 5016 bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode, 5017 const ARMEncoding encoding) { 5018 #if 0 5019 if ConditionPassed() then 5020 EncodingSpecificOperations(); 5021 address = R[n] + 4; 5022 5023 for i = 0 to 14 5024 if registers<i> == '1' then 5025 if i == n && wback && i != LowestSetBit(registers) then 5026 MemA[address,4] = bits(32) UNKNOWN; 5027 else 5028 MemA[address,4] = R[i]; 5029 address = address + 4; 5030 5031 if registers<15> == '1' then 5032 MemA[address,4] = PCStoreValue(); 5033 5034 if wback then R[n] = R[n] + 4*BitCount(registers); 5035 #endif 5036 5037 bool success = false; 5038 5039 if (ConditionPassed(opcode)) { 5040 uint32_t n; 5041 uint32_t registers = 0; 5042 bool wback; 5043 const uint32_t addr_byte_size = GetAddressByteSize(); 5044 5045 // EncodingSpecificOperations(); 5046 switch (encoding) { 5047 case eEncodingA1: 5048 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 5049 n = Bits32(opcode, 19, 16); 5050 registers = Bits32(opcode, 15, 0); 5051 wback = BitIsSet(opcode, 21); 5052 5053 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 5054 if ((n == 15) && (BitCount(registers) < 1)) 5055 return false; 5056 break; 5057 default: 5058 return false; 5059 } 5060 // address = R[n] + 4; 5061 5062 int32_t offset = 0; 5063 addr_t Rn = ReadCoreReg(n, &success); 5064 if (!success) 5065 return false; 5066 5067 addr_t address = Rn + addr_byte_size; 5068 5069 EmulateInstruction::Context context; 5070 context.type = EmulateInstruction::eContextRegisterStore; 5071 RegisterInfo base_reg; 5072 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5073 5074 uint32_t lowest_set_bit = 14; 5075 // for i = 0 to 14 5076 for (uint32_t i = 0; i < 14; ++i) { 5077 // if registers<i> == '1' then 5078 if (BitIsSet(registers, i)) { 5079 if (i < lowest_set_bit) 5080 lowest_set_bit = i; 5081 // if i == n && wback && i != LowestSetBit(registers) then 5082 if ((i == n) && wback && (i != lowest_set_bit)) 5083 // MemA[address,4] = bits(32) UNKNOWN; 5084 WriteBits32UnknownToMemory(address + offset); 5085 // else 5086 else { 5087 // MemA[address,4] = R[i]; 5088 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5089 0, &success); 5090 if (!success) 5091 return false; 5092 5093 RegisterInfo data_reg; 5094 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5095 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5096 offset + addr_byte_size); 5097 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5098 return false; 5099 } 5100 5101 // address = address + 4; 5102 offset += addr_byte_size; 5103 } 5104 } 5105 5106 // if registers<15> == '1' then 5107 // MemA[address,4] = PCStoreValue(); 5108 if (BitIsSet(registers, 15)) { 5109 RegisterInfo pc_reg; 5110 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5111 context.SetRegisterPlusOffset(pc_reg, 8); 5112 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5113 if (!success) 5114 return false; 5115 5116 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5117 return false; 5118 } 5119 5120 // if wback then R[n] = R[n] + 4*BitCount(registers); 5121 if (wback) { 5122 offset = addr_byte_size * BitCount(registers); 5123 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5124 context.SetImmediateSigned(offset); 5125 addr_t data = Rn + offset; 5126 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5127 data)) 5128 return false; 5129 } 5130 } 5131 return true; 5132 } 5133 5134 // STR (store immediate) calculates an address from a base register value and an 5135 // immediate offset, and stores a word 5136 // from a register to memory. It can use offset, post-indexed, or pre-indexed 5137 // addressing. 5138 bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode, 5139 const ARMEncoding encoding) { 5140 #if 0 5141 if ConditionPassed() then 5142 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5143 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5144 address = if index then offset_addr else R[n]; 5145 if UnalignedSupport() || address<1:0> == '00' then 5146 MemU[address,4] = R[t]; 5147 else // Can only occur before ARMv7 5148 MemU[address,4] = bits(32) UNKNOWN; 5149 if wback then R[n] = offset_addr; 5150 #endif 5151 5152 bool success = false; 5153 5154 if (ConditionPassed(opcode)) { 5155 const uint32_t addr_byte_size = GetAddressByteSize(); 5156 5157 uint32_t t; 5158 uint32_t n; 5159 uint32_t imm32; 5160 bool index; 5161 bool add; 5162 bool wback; 5163 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5164 switch (encoding) { 5165 case eEncodingT1: 5166 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 5167 t = Bits32(opcode, 2, 0); 5168 n = Bits32(opcode, 5, 3); 5169 imm32 = Bits32(opcode, 10, 6) << 2; 5170 5171 // index = TRUE; add = TRUE; wback = FALSE; 5172 index = true; 5173 add = false; 5174 wback = false; 5175 break; 5176 5177 case eEncodingT2: 5178 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 5179 t = Bits32(opcode, 10, 8); 5180 n = 13; 5181 imm32 = Bits32(opcode, 7, 0) << 2; 5182 5183 // index = TRUE; add = TRUE; wback = FALSE; 5184 index = true; 5185 add = true; 5186 wback = false; 5187 break; 5188 5189 case eEncodingT3: 5190 // if Rn == '1111' then UNDEFINED; 5191 if (Bits32(opcode, 19, 16) == 15) 5192 return false; 5193 5194 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5195 t = Bits32(opcode, 15, 12); 5196 n = Bits32(opcode, 19, 16); 5197 imm32 = Bits32(opcode, 11, 0); 5198 5199 // index = TRUE; add = TRUE; wback = FALSE; 5200 index = true; 5201 add = true; 5202 wback = false; 5203 5204 // if t == 15 then UNPREDICTABLE; 5205 if (t == 15) 5206 return false; 5207 break; 5208 5209 case eEncodingT4: 5210 // if P == '1' && U == '1' && W == '0' then SEE STRT; 5211 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == 5212 // '00000100' then SEE PUSH; 5213 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5214 if ((Bits32(opcode, 19, 16) == 15) || 5215 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))) 5216 return false; 5217 5218 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5219 t = Bits32(opcode, 15, 12); 5220 n = Bits32(opcode, 19, 16); 5221 imm32 = Bits32(opcode, 7, 0); 5222 5223 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5224 index = BitIsSet(opcode, 10); 5225 add = BitIsSet(opcode, 9); 5226 wback = BitIsSet(opcode, 8); 5227 5228 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 5229 if ((t == 15) || (wback && (n == t))) 5230 return false; 5231 break; 5232 5233 default: 5234 return false; 5235 } 5236 5237 addr_t offset_addr; 5238 addr_t address; 5239 5240 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5241 uint32_t base_address = ReadCoreReg(n, &success); 5242 if (!success) 5243 return false; 5244 5245 if (add) 5246 offset_addr = base_address + imm32; 5247 else 5248 offset_addr = base_address - imm32; 5249 5250 // address = if index then offset_addr else R[n]; 5251 if (index) 5252 address = offset_addr; 5253 else 5254 address = base_address; 5255 5256 EmulateInstruction::Context context; 5257 if (n == 13) 5258 context.type = eContextPushRegisterOnStack; 5259 else 5260 context.type = eContextRegisterStore; 5261 5262 RegisterInfo base_reg; 5263 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5264 5265 // if UnalignedSupport() || address<1:0> == '00' then 5266 if (UnalignedSupport() || 5267 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 5268 // MemU[address,4] = R[t]; 5269 uint32_t data = 5270 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5271 if (!success) 5272 return false; 5273 5274 RegisterInfo data_reg; 5275 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5276 int32_t offset = address - base_address; 5277 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 5278 if (!MemUWrite(context, address, data, addr_byte_size)) 5279 return false; 5280 } else { 5281 // MemU[address,4] = bits(32) UNKNOWN; 5282 WriteBits32UnknownToMemory(address); 5283 } 5284 5285 // if wback then R[n] = offset_addr; 5286 if (wback) { 5287 if (n == 13) 5288 context.type = eContextAdjustStackPointer; 5289 else 5290 context.type = eContextAdjustBaseRegister; 5291 context.SetAddress(offset_addr); 5292 5293 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5294 offset_addr)) 5295 return false; 5296 } 5297 } 5298 return true; 5299 } 5300 5301 // STR (Store Register) calculates an address from a base register value and an 5302 // offset register value, stores a 5303 // word from a register to memory. The offset register value can optionally 5304 // be shifted. 5305 bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode, 5306 const ARMEncoding encoding) { 5307 #if 0 5308 if ConditionPassed() then 5309 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5310 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5311 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5312 address = if index then offset_addr else R[n]; 5313 if t == 15 then // Only possible for encoding A1 5314 data = PCStoreValue(); 5315 else 5316 data = R[t]; 5317 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 5318 MemU[address,4] = data; 5319 else // Can only occur before ARMv7 5320 MemU[address,4] = bits(32) UNKNOWN; 5321 if wback then R[n] = offset_addr; 5322 #endif 5323 5324 bool success = false; 5325 5326 if (ConditionPassed(opcode)) { 5327 const uint32_t addr_byte_size = GetAddressByteSize(); 5328 5329 uint32_t t; 5330 uint32_t n; 5331 uint32_t m; 5332 ARM_ShifterType shift_t; 5333 uint32_t shift_n; 5334 bool index; 5335 bool add; 5336 bool wback; 5337 5338 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5339 switch (encoding) { 5340 case eEncodingT1: 5341 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5342 // in ThumbEE"; 5343 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5344 t = Bits32(opcode, 2, 0); 5345 n = Bits32(opcode, 5, 3); 5346 m = Bits32(opcode, 8, 6); 5347 5348 // index = TRUE; add = TRUE; wback = FALSE; 5349 index = true; 5350 add = true; 5351 wback = false; 5352 5353 // (shift_t, shift_n) = (SRType_LSL, 0); 5354 shift_t = SRType_LSL; 5355 shift_n = 0; 5356 break; 5357 5358 case eEncodingT2: 5359 // if Rn == '1111' then UNDEFINED; 5360 if (Bits32(opcode, 19, 16) == 15) 5361 return false; 5362 5363 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5364 t = Bits32(opcode, 15, 12); 5365 n = Bits32(opcode, 19, 16); 5366 m = Bits32(opcode, 3, 0); 5367 5368 // index = TRUE; add = TRUE; wback = FALSE; 5369 index = true; 5370 add = true; 5371 wback = false; 5372 5373 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5374 shift_t = SRType_LSL; 5375 shift_n = Bits32(opcode, 5, 4); 5376 5377 // if t == 15 || BadReg(m) then UNPREDICTABLE; 5378 if ((t == 15) || (BadReg(m))) 5379 return false; 5380 break; 5381 5382 case eEncodingA1: { 5383 // if P == '0' && W == '1' then SEE STRT; 5384 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5385 t = Bits32(opcode, 15, 12); 5386 n = Bits32(opcode, 19, 16); 5387 m = Bits32(opcode, 3, 0); 5388 5389 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5390 // (W == '1'); 5391 index = BitIsSet(opcode, 24); 5392 add = BitIsSet(opcode, 23); 5393 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5394 5395 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5396 uint32_t typ = Bits32(opcode, 6, 5); 5397 uint32_t imm5 = Bits32(opcode, 11, 7); 5398 shift_n = DecodeImmShift(typ, imm5, shift_t); 5399 5400 // if m == 15 then UNPREDICTABLE; 5401 if (m == 15) 5402 return false; 5403 5404 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5405 if (wback && ((n == 15) || (n == t))) 5406 return false; 5407 5408 break; 5409 } 5410 default: 5411 return false; 5412 } 5413 5414 addr_t offset_addr; 5415 addr_t address; 5416 int32_t offset = 0; 5417 5418 addr_t base_address = 5419 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5420 if (!success) 5421 return false; 5422 5423 uint32_t Rm_data = 5424 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5425 if (!success) 5426 return false; 5427 5428 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5429 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success); 5430 if (!success) 5431 return false; 5432 5433 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5434 if (add) 5435 offset_addr = base_address + offset; 5436 else 5437 offset_addr = base_address - offset; 5438 5439 // address = if index then offset_addr else R[n]; 5440 if (index) 5441 address = offset_addr; 5442 else 5443 address = base_address; 5444 5445 uint32_t data; 5446 // if t == 15 then // Only possible for encoding A1 5447 if (t == 15) 5448 // data = PCStoreValue(); 5449 data = ReadCoreReg(PC_REG, &success); 5450 else 5451 // data = R[t]; 5452 data = 5453 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5454 5455 if (!success) 5456 return false; 5457 5458 EmulateInstruction::Context context; 5459 context.type = eContextRegisterStore; 5460 5461 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == 5462 // InstrSet_ARM then 5463 if (UnalignedSupport() || 5464 (BitIsClear(address, 1) && BitIsClear(address, 0)) || 5465 CurrentInstrSet() == eModeARM) { 5466 // MemU[address,4] = data; 5467 5468 RegisterInfo base_reg; 5469 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5470 5471 RegisterInfo data_reg; 5472 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5473 5474 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5475 address - base_address); 5476 if (!MemUWrite(context, address, data, addr_byte_size)) 5477 return false; 5478 5479 } else 5480 // MemU[address,4] = bits(32) UNKNOWN; 5481 WriteBits32UnknownToMemory(address); 5482 5483 // if wback then R[n] = offset_addr; 5484 if (wback) { 5485 context.type = eContextRegisterLoad; 5486 context.SetAddress(offset_addr); 5487 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5488 offset_addr)) 5489 return false; 5490 } 5491 } 5492 return true; 5493 } 5494 5495 bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode, 5496 const ARMEncoding encoding) { 5497 #if 0 5498 if ConditionPassed() then 5499 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5500 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5501 address = if index then offset_addr else R[n]; 5502 MemU[address,1] = R[t]<7:0>; 5503 if wback then R[n] = offset_addr; 5504 #endif 5505 5506 bool success = false; 5507 5508 if (ConditionPassed(opcode)) { 5509 uint32_t t; 5510 uint32_t n; 5511 uint32_t imm32; 5512 bool index; 5513 bool add; 5514 bool wback; 5515 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5516 switch (encoding) { 5517 case eEncodingT1: 5518 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5519 t = Bits32(opcode, 2, 0); 5520 n = Bits32(opcode, 5, 3); 5521 imm32 = Bits32(opcode, 10, 6); 5522 5523 // index = TRUE; add = TRUE; wback = FALSE; 5524 index = true; 5525 add = true; 5526 wback = false; 5527 break; 5528 5529 case eEncodingT2: 5530 // if Rn == '1111' then UNDEFINED; 5531 if (Bits32(opcode, 19, 16) == 15) 5532 return false; 5533 5534 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5535 t = Bits32(opcode, 15, 12); 5536 n = Bits32(opcode, 19, 16); 5537 imm32 = Bits32(opcode, 11, 0); 5538 5539 // index = TRUE; add = TRUE; wback = FALSE; 5540 index = true; 5541 add = true; 5542 wback = false; 5543 5544 // if BadReg(t) then UNPREDICTABLE; 5545 if (BadReg(t)) 5546 return false; 5547 break; 5548 5549 case eEncodingT3: 5550 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5551 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5552 if (Bits32(opcode, 19, 16) == 15) 5553 return false; 5554 5555 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5556 t = Bits32(opcode, 15, 12); 5557 n = Bits32(opcode, 19, 16); 5558 imm32 = Bits32(opcode, 7, 0); 5559 5560 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5561 index = BitIsSet(opcode, 10); 5562 add = BitIsSet(opcode, 9); 5563 wback = BitIsSet(opcode, 8); 5564 5565 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5566 if ((BadReg(t)) || (wback && (n == t))) 5567 return false; 5568 break; 5569 5570 default: 5571 return false; 5572 } 5573 5574 addr_t offset_addr; 5575 addr_t address; 5576 addr_t base_address = 5577 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5578 if (!success) 5579 return false; 5580 5581 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5582 if (add) 5583 offset_addr = base_address + imm32; 5584 else 5585 offset_addr = base_address - imm32; 5586 5587 // address = if index then offset_addr else R[n]; 5588 if (index) 5589 address = offset_addr; 5590 else 5591 address = base_address; 5592 5593 // MemU[address,1] = R[t]<7:0> 5594 RegisterInfo base_reg; 5595 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5596 5597 RegisterInfo data_reg; 5598 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5599 5600 EmulateInstruction::Context context; 5601 context.type = eContextRegisterStore; 5602 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5603 address - base_address); 5604 5605 uint32_t data = 5606 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5607 if (!success) 5608 return false; 5609 5610 data = Bits32(data, 7, 0); 5611 5612 if (!MemUWrite(context, address, data, 1)) 5613 return false; 5614 5615 // if wback then R[n] = offset_addr; 5616 if (wback) { 5617 context.type = eContextRegisterLoad; 5618 context.SetAddress(offset_addr); 5619 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5620 offset_addr)) 5621 return false; 5622 } 5623 } 5624 5625 return true; 5626 } 5627 5628 // STRH (register) calculates an address from a base register value and an 5629 // offset register value, and stores a 5630 // halfword from a register to memory. The offset register value can be 5631 // shifted left by 0, 1, 2, or 3 bits. 5632 bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode, 5633 const ARMEncoding encoding) { 5634 #if 0 5635 if ConditionPassed() then 5636 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5637 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5638 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5639 address = if index then offset_addr else R[n]; 5640 if UnalignedSupport() || address<0> == '0' then 5641 MemU[address,2] = R[t]<15:0>; 5642 else // Can only occur before ARMv7 5643 MemU[address,2] = bits(16) UNKNOWN; 5644 if wback then R[n] = offset_addr; 5645 #endif 5646 5647 bool success = false; 5648 5649 if (ConditionPassed(opcode)) { 5650 uint32_t t; 5651 uint32_t n; 5652 uint32_t m; 5653 bool index; 5654 bool add; 5655 bool wback; 5656 ARM_ShifterType shift_t; 5657 uint32_t shift_n; 5658 5659 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5660 switch (encoding) { 5661 case eEncodingT1: 5662 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5663 // in ThumbEE"; 5664 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5665 t = Bits32(opcode, 2, 0); 5666 n = Bits32(opcode, 5, 3); 5667 m = Bits32(opcode, 8, 6); 5668 5669 // index = TRUE; add = TRUE; wback = FALSE; 5670 index = true; 5671 add = true; 5672 wback = false; 5673 5674 // (shift_t, shift_n) = (SRType_LSL, 0); 5675 shift_t = SRType_LSL; 5676 shift_n = 0; 5677 5678 break; 5679 5680 case eEncodingT2: 5681 // if Rn == '1111' then UNDEFINED; 5682 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5683 t = Bits32(opcode, 15, 12); 5684 n = Bits32(opcode, 19, 16); 5685 m = Bits32(opcode, 3, 0); 5686 if (n == 15) 5687 return false; 5688 5689 // index = TRUE; add = TRUE; wback = FALSE; 5690 index = true; 5691 add = true; 5692 wback = false; 5693 5694 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5695 shift_t = SRType_LSL; 5696 shift_n = Bits32(opcode, 5, 4); 5697 5698 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5699 if (BadReg(t) || BadReg(m)) 5700 return false; 5701 5702 break; 5703 5704 case eEncodingA1: 5705 // if P == '0' && W == '1' then SEE STRHT; 5706 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5707 t = Bits32(opcode, 15, 12); 5708 n = Bits32(opcode, 19, 16); 5709 m = Bits32(opcode, 3, 0); 5710 5711 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5712 // (W == '1'); 5713 index = BitIsSet(opcode, 24); 5714 add = BitIsSet(opcode, 23); 5715 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5716 5717 // (shift_t, shift_n) = (SRType_LSL, 0); 5718 shift_t = SRType_LSL; 5719 shift_n = 0; 5720 5721 // if t == 15 || m == 15 then UNPREDICTABLE; 5722 if ((t == 15) || (m == 15)) 5723 return false; 5724 5725 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5726 if (wback && ((n == 15) || (n == t))) 5727 return false; 5728 5729 break; 5730 5731 default: 5732 return false; 5733 } 5734 5735 uint32_t Rm = ReadCoreReg(m, &success); 5736 if (!success) 5737 return false; 5738 5739 uint32_t Rn = ReadCoreReg(n, &success); 5740 if (!success) 5741 return false; 5742 5743 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5744 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 5745 if (!success) 5746 return false; 5747 5748 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5749 addr_t offset_addr; 5750 if (add) 5751 offset_addr = Rn + offset; 5752 else 5753 offset_addr = Rn - offset; 5754 5755 // address = if index then offset_addr else R[n]; 5756 addr_t address; 5757 if (index) 5758 address = offset_addr; 5759 else 5760 address = Rn; 5761 5762 EmulateInstruction::Context context; 5763 context.type = eContextRegisterStore; 5764 RegisterInfo base_reg; 5765 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5766 RegisterInfo offset_reg; 5767 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5768 5769 // if UnalignedSupport() || address<0> == '0' then 5770 if (UnalignedSupport() || BitIsClear(address, 0)) { 5771 // MemU[address,2] = R[t]<15:0>; 5772 uint32_t Rt = ReadCoreReg(t, &success); 5773 if (!success) 5774 return false; 5775 5776 EmulateInstruction::Context context; 5777 context.type = eContextRegisterStore; 5778 RegisterInfo base_reg; 5779 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5780 RegisterInfo offset_reg; 5781 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5782 RegisterInfo data_reg; 5783 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5784 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 5785 data_reg); 5786 5787 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2)) 5788 return false; 5789 } else // Can only occur before ARMv7 5790 { 5791 // MemU[address,2] = bits(16) UNKNOWN; 5792 } 5793 5794 // if wback then R[n] = offset_addr; 5795 if (wback) { 5796 context.type = eContextAdjustBaseRegister; 5797 context.SetAddress(offset_addr); 5798 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5799 offset_addr)) 5800 return false; 5801 } 5802 } 5803 5804 return true; 5805 } 5806 5807 // Add with Carry (immediate) adds an immediate value and the carry flag value 5808 // to a register value, and writes the result to the destination register. It 5809 // can optionally update the condition flags based on the result. 5810 bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode, 5811 const ARMEncoding encoding) { 5812 #if 0 5813 // ARM pseudo code... 5814 if ConditionPassed() then 5815 EncodingSpecificOperations(); 5816 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5817 if d == 15 then // Can only occur for ARM encoding 5818 ALUWritePC(result); // setflags is always FALSE here 5819 else 5820 R[d] = result; 5821 if setflags then 5822 APSR.N = result<31>; 5823 APSR.Z = IsZeroBit(result); 5824 APSR.C = carry; 5825 APSR.V = overflow; 5826 #endif 5827 5828 bool success = false; 5829 5830 if (ConditionPassed(opcode)) { 5831 uint32_t Rd, Rn; 5832 uint32_t 5833 imm32; // the immediate value to be added to the value obtained from Rn 5834 bool setflags; 5835 switch (encoding) { 5836 case eEncodingT1: 5837 Rd = Bits32(opcode, 11, 8); 5838 Rn = Bits32(opcode, 19, 16); 5839 setflags = BitIsSet(opcode, 20); 5840 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5841 if (BadReg(Rd) || BadReg(Rn)) 5842 return false; 5843 break; 5844 case eEncodingA1: 5845 Rd = Bits32(opcode, 15, 12); 5846 Rn = Bits32(opcode, 19, 16); 5847 setflags = BitIsSet(opcode, 20); 5848 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5849 5850 if (Rd == 15 && setflags) 5851 return EmulateSUBSPcLrEtc(opcode, encoding); 5852 break; 5853 default: 5854 return false; 5855 } 5856 5857 // Read the first operand. 5858 int32_t val1 = ReadCoreReg(Rn, &success); 5859 if (!success) 5860 return false; 5861 5862 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5863 5864 EmulateInstruction::Context context; 5865 context.type = EmulateInstruction::eContextImmediate; 5866 context.SetNoArgs(); 5867 5868 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5869 res.carry_out, res.overflow)) 5870 return false; 5871 } 5872 return true; 5873 } 5874 5875 // Add with Carry (register) adds a register value, the carry flag value, and 5876 // an optionally-shifted register value, and writes the result to the 5877 // destination register. It can optionally update the condition flags based on 5878 // the result. 5879 bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode, 5880 const ARMEncoding encoding) { 5881 #if 0 5882 // ARM pseudo code... 5883 if ConditionPassed() then 5884 EncodingSpecificOperations(); 5885 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5886 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5887 if d == 15 then // Can only occur for ARM encoding 5888 ALUWritePC(result); // setflags is always FALSE here 5889 else 5890 R[d] = result; 5891 if setflags then 5892 APSR.N = result<31>; 5893 APSR.Z = IsZeroBit(result); 5894 APSR.C = carry; 5895 APSR.V = overflow; 5896 #endif 5897 5898 bool success = false; 5899 5900 if (ConditionPassed(opcode)) { 5901 uint32_t Rd, Rn, Rm; 5902 ARM_ShifterType shift_t; 5903 uint32_t shift_n; // the shift applied to the value read from Rm 5904 bool setflags; 5905 switch (encoding) { 5906 case eEncodingT1: 5907 Rd = Rn = Bits32(opcode, 2, 0); 5908 Rm = Bits32(opcode, 5, 3); 5909 setflags = !InITBlock(); 5910 shift_t = SRType_LSL; 5911 shift_n = 0; 5912 break; 5913 case eEncodingT2: 5914 Rd = Bits32(opcode, 11, 8); 5915 Rn = Bits32(opcode, 19, 16); 5916 Rm = Bits32(opcode, 3, 0); 5917 setflags = BitIsSet(opcode, 20); 5918 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5919 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5920 return false; 5921 break; 5922 case eEncodingA1: 5923 Rd = Bits32(opcode, 15, 12); 5924 Rn = Bits32(opcode, 19, 16); 5925 Rm = Bits32(opcode, 3, 0); 5926 setflags = BitIsSet(opcode, 20); 5927 shift_n = DecodeImmShiftARM(opcode, shift_t); 5928 5929 if (Rd == 15 && setflags) 5930 return EmulateSUBSPcLrEtc(opcode, encoding); 5931 break; 5932 default: 5933 return false; 5934 } 5935 5936 // Read the first operand. 5937 int32_t val1 = ReadCoreReg(Rn, &success); 5938 if (!success) 5939 return false; 5940 5941 // Read the second operand. 5942 int32_t val2 = ReadCoreReg(Rm, &success); 5943 if (!success) 5944 return false; 5945 5946 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5947 if (!success) 5948 return false; 5949 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5950 5951 EmulateInstruction::Context context; 5952 context.type = EmulateInstruction::eContextImmediate; 5953 context.SetNoArgs(); 5954 5955 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5956 res.carry_out, res.overflow)) 5957 return false; 5958 } 5959 return true; 5960 } 5961 5962 // This instruction adds an immediate value to the PC value to form a PC- 5963 // relative address, and writes the result to the destination register. 5964 bool EmulateInstructionARM::EmulateADR(const uint32_t opcode, 5965 const ARMEncoding encoding) { 5966 #if 0 5967 // ARM pseudo code... 5968 if ConditionPassed() then 5969 EncodingSpecificOperations(); 5970 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5971 if d == 15 then // Can only occur for ARM encodings 5972 ALUWritePC(result); 5973 else 5974 R[d] = result; 5975 #endif 5976 5977 bool success = false; 5978 5979 if (ConditionPassed(opcode)) { 5980 uint32_t Rd; 5981 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5982 bool add; 5983 switch (encoding) { 5984 case eEncodingT1: 5985 Rd = Bits32(opcode, 10, 8); 5986 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5987 add = true; 5988 break; 5989 case eEncodingT2: 5990 case eEncodingT3: 5991 Rd = Bits32(opcode, 11, 8); 5992 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5993 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5994 if (BadReg(Rd)) 5995 return false; 5996 break; 5997 case eEncodingA1: 5998 case eEncodingA2: 5999 Rd = Bits32(opcode, 15, 12); 6000 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 6001 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 6002 break; 6003 default: 6004 return false; 6005 } 6006 6007 // Read the PC value. 6008 uint32_t pc = ReadCoreReg(PC_REG, &success); 6009 if (!success) 6010 return false; 6011 6012 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 6013 6014 EmulateInstruction::Context context; 6015 context.type = EmulateInstruction::eContextImmediate; 6016 context.SetNoArgs(); 6017 6018 if (!WriteCoreReg(context, result, Rd)) 6019 return false; 6020 } 6021 return true; 6022 } 6023 6024 // This instruction performs a bitwise AND of a register value and an immediate 6025 // value, and writes the result to the destination register. It can optionally 6026 // update the condition flags based on the result. 6027 bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode, 6028 const ARMEncoding encoding) { 6029 #if 0 6030 // ARM pseudo code... 6031 if ConditionPassed() then 6032 EncodingSpecificOperations(); 6033 result = R[n] AND imm32; 6034 if d == 15 then // Can only occur for ARM encoding 6035 ALUWritePC(result); // setflags is always FALSE here 6036 else 6037 R[d] = result; 6038 if setflags then 6039 APSR.N = result<31>; 6040 APSR.Z = IsZeroBit(result); 6041 APSR.C = carry; 6042 // APSR.V unchanged 6043 #endif 6044 6045 bool success = false; 6046 6047 if (ConditionPassed(opcode)) { 6048 uint32_t Rd, Rn; 6049 uint32_t 6050 imm32; // the immediate value to be ANDed to the value obtained from Rn 6051 bool setflags; 6052 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6053 switch (encoding) { 6054 case eEncodingT1: 6055 Rd = Bits32(opcode, 11, 8); 6056 Rn = Bits32(opcode, 19, 16); 6057 setflags = BitIsSet(opcode, 20); 6058 imm32 = ThumbExpandImm_C( 6059 opcode, APSR_C, 6060 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6061 // if Rd == '1111' && S == '1' then SEE TST (immediate); 6062 if (Rd == 15 && setflags) 6063 return EmulateTSTImm(opcode, eEncodingT1); 6064 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 6065 return false; 6066 break; 6067 case eEncodingA1: 6068 Rd = Bits32(opcode, 15, 12); 6069 Rn = Bits32(opcode, 19, 16); 6070 setflags = BitIsSet(opcode, 20); 6071 imm32 = 6072 ARMExpandImm_C(opcode, APSR_C, 6073 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6074 6075 if (Rd == 15 && setflags) 6076 return EmulateSUBSPcLrEtc(opcode, encoding); 6077 break; 6078 default: 6079 return false; 6080 } 6081 6082 // Read the first operand. 6083 uint32_t val1 = ReadCoreReg(Rn, &success); 6084 if (!success) 6085 return false; 6086 6087 uint32_t result = val1 & imm32; 6088 6089 EmulateInstruction::Context context; 6090 context.type = EmulateInstruction::eContextImmediate; 6091 context.SetNoArgs(); 6092 6093 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6094 return false; 6095 } 6096 return true; 6097 } 6098 6099 // This instruction performs a bitwise AND of a register value and an 6100 // optionally-shifted register value, and writes the result to the destination 6101 // register. It can optionally update the condition flags based on the result. 6102 bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode, 6103 const ARMEncoding encoding) { 6104 #if 0 6105 // ARM pseudo code... 6106 if ConditionPassed() then 6107 EncodingSpecificOperations(); 6108 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6109 result = R[n] AND shifted; 6110 if d == 15 then // Can only occur for ARM encoding 6111 ALUWritePC(result); // setflags is always FALSE here 6112 else 6113 R[d] = result; 6114 if setflags then 6115 APSR.N = result<31>; 6116 APSR.Z = IsZeroBit(result); 6117 APSR.C = carry; 6118 // APSR.V unchanged 6119 #endif 6120 6121 bool success = false; 6122 6123 if (ConditionPassed(opcode)) { 6124 uint32_t Rd, Rn, Rm; 6125 ARM_ShifterType shift_t; 6126 uint32_t shift_n; // the shift applied to the value read from Rm 6127 bool setflags; 6128 uint32_t carry; 6129 switch (encoding) { 6130 case eEncodingT1: 6131 Rd = Rn = Bits32(opcode, 2, 0); 6132 Rm = Bits32(opcode, 5, 3); 6133 setflags = !InITBlock(); 6134 shift_t = SRType_LSL; 6135 shift_n = 0; 6136 break; 6137 case eEncodingT2: 6138 Rd = Bits32(opcode, 11, 8); 6139 Rn = Bits32(opcode, 19, 16); 6140 Rm = Bits32(opcode, 3, 0); 6141 setflags = BitIsSet(opcode, 20); 6142 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6143 // if Rd == '1111' && S == '1' then SEE TST (register); 6144 if (Rd == 15 && setflags) 6145 return EmulateTSTReg(opcode, eEncodingT2); 6146 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 6147 return false; 6148 break; 6149 case eEncodingA1: 6150 Rd = Bits32(opcode, 15, 12); 6151 Rn = Bits32(opcode, 19, 16); 6152 Rm = Bits32(opcode, 3, 0); 6153 setflags = BitIsSet(opcode, 20); 6154 shift_n = DecodeImmShiftARM(opcode, shift_t); 6155 6156 if (Rd == 15 && setflags) 6157 return EmulateSUBSPcLrEtc(opcode, encoding); 6158 break; 6159 default: 6160 return false; 6161 } 6162 6163 // Read the first operand. 6164 uint32_t val1 = ReadCoreReg(Rn, &success); 6165 if (!success) 6166 return false; 6167 6168 // Read the second operand. 6169 uint32_t val2 = ReadCoreReg(Rm, &success); 6170 if (!success) 6171 return false; 6172 6173 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6174 if (!success) 6175 return false; 6176 uint32_t result = val1 & shifted; 6177 6178 EmulateInstruction::Context context; 6179 context.type = EmulateInstruction::eContextImmediate; 6180 context.SetNoArgs(); 6181 6182 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6183 return false; 6184 } 6185 return true; 6186 } 6187 6188 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and 6189 // the complement of an immediate value, and writes the result to the 6190 // destination register. It can optionally update the condition flags based on 6191 // the result. 6192 bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode, 6193 const ARMEncoding encoding) { 6194 #if 0 6195 // ARM pseudo code... 6196 if ConditionPassed() then 6197 EncodingSpecificOperations(); 6198 result = R[n] AND NOT(imm32); 6199 if d == 15 then // Can only occur for ARM encoding 6200 ALUWritePC(result); // setflags is always FALSE here 6201 else 6202 R[d] = result; 6203 if setflags then 6204 APSR.N = result<31>; 6205 APSR.Z = IsZeroBit(result); 6206 APSR.C = carry; 6207 // APSR.V unchanged 6208 #endif 6209 6210 bool success = false; 6211 6212 if (ConditionPassed(opcode)) { 6213 uint32_t Rd, Rn; 6214 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to 6215 // the value obtained from Rn 6216 bool setflags; 6217 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6218 switch (encoding) { 6219 case eEncodingT1: 6220 Rd = Bits32(opcode, 11, 8); 6221 Rn = Bits32(opcode, 19, 16); 6222 setflags = BitIsSet(opcode, 20); 6223 imm32 = ThumbExpandImm_C( 6224 opcode, APSR_C, 6225 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6226 if (BadReg(Rd) || BadReg(Rn)) 6227 return false; 6228 break; 6229 case eEncodingA1: 6230 Rd = Bits32(opcode, 15, 12); 6231 Rn = Bits32(opcode, 19, 16); 6232 setflags = BitIsSet(opcode, 20); 6233 imm32 = 6234 ARMExpandImm_C(opcode, APSR_C, 6235 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6236 6237 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6238 // instructions; 6239 if (Rd == 15 && setflags) 6240 return EmulateSUBSPcLrEtc(opcode, encoding); 6241 break; 6242 default: 6243 return false; 6244 } 6245 6246 // Read the first operand. 6247 uint32_t val1 = ReadCoreReg(Rn, &success); 6248 if (!success) 6249 return false; 6250 6251 uint32_t result = val1 & ~imm32; 6252 6253 EmulateInstruction::Context context; 6254 context.type = EmulateInstruction::eContextImmediate; 6255 context.SetNoArgs(); 6256 6257 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6258 return false; 6259 } 6260 return true; 6261 } 6262 6263 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and 6264 // the complement of an optionally-shifted register value, and writes the 6265 // result to the destination register. It can optionally update the condition 6266 // flags based on the result. 6267 bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode, 6268 const ARMEncoding encoding) { 6269 #if 0 6270 // ARM pseudo code... 6271 if ConditionPassed() then 6272 EncodingSpecificOperations(); 6273 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6274 result = R[n] AND NOT(shifted); 6275 if d == 15 then // Can only occur for ARM encoding 6276 ALUWritePC(result); // setflags is always FALSE here 6277 else 6278 R[d] = result; 6279 if setflags then 6280 APSR.N = result<31>; 6281 APSR.Z = IsZeroBit(result); 6282 APSR.C = carry; 6283 // APSR.V unchanged 6284 #endif 6285 6286 bool success = false; 6287 6288 if (ConditionPassed(opcode)) { 6289 uint32_t Rd, Rn, Rm; 6290 ARM_ShifterType shift_t; 6291 uint32_t shift_n; // the shift applied to the value read from Rm 6292 bool setflags; 6293 uint32_t carry; 6294 switch (encoding) { 6295 case eEncodingT1: 6296 Rd = Rn = Bits32(opcode, 2, 0); 6297 Rm = Bits32(opcode, 5, 3); 6298 setflags = !InITBlock(); 6299 shift_t = SRType_LSL; 6300 shift_n = 0; 6301 break; 6302 case eEncodingT2: 6303 Rd = Bits32(opcode, 11, 8); 6304 Rn = Bits32(opcode, 19, 16); 6305 Rm = Bits32(opcode, 3, 0); 6306 setflags = BitIsSet(opcode, 20); 6307 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6308 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 6309 return false; 6310 break; 6311 case eEncodingA1: 6312 Rd = Bits32(opcode, 15, 12); 6313 Rn = Bits32(opcode, 19, 16); 6314 Rm = Bits32(opcode, 3, 0); 6315 setflags = BitIsSet(opcode, 20); 6316 shift_n = DecodeImmShiftARM(opcode, shift_t); 6317 6318 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6319 // instructions; 6320 if (Rd == 15 && setflags) 6321 return EmulateSUBSPcLrEtc(opcode, encoding); 6322 break; 6323 default: 6324 return false; 6325 } 6326 6327 // Read the first operand. 6328 uint32_t val1 = ReadCoreReg(Rn, &success); 6329 if (!success) 6330 return false; 6331 6332 // Read the second operand. 6333 uint32_t val2 = ReadCoreReg(Rm, &success); 6334 if (!success) 6335 return false; 6336 6337 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6338 if (!success) 6339 return false; 6340 uint32_t result = val1 & ~shifted; 6341 6342 EmulateInstruction::Context context; 6343 context.type = EmulateInstruction::eContextImmediate; 6344 context.SetNoArgs(); 6345 6346 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6347 return false; 6348 } 6349 return true; 6350 } 6351 6352 // LDR (immediate, ARM) calculates an address from a base register value and an 6353 // immediate offset, loads a word 6354 // from memory, and writes it to a register. It can use offset, post-indexed, 6355 // or pre-indexed addressing. 6356 bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode, 6357 const ARMEncoding encoding) { 6358 #if 0 6359 if ConditionPassed() then 6360 EncodingSpecificOperations(); 6361 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6362 address = if index then offset_addr else R[n]; 6363 data = MemU[address,4]; 6364 if wback then R[n] = offset_addr; 6365 if t == 15 then 6366 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6367 elsif UnalignedSupport() || address<1:0> = '00' then 6368 R[t] = data; 6369 else // Can only apply before ARMv7 6370 R[t] = ROR(data, 8*UInt(address<1:0>)); 6371 #endif 6372 6373 bool success = false; 6374 6375 if (ConditionPassed(opcode)) { 6376 const uint32_t addr_byte_size = GetAddressByteSize(); 6377 6378 uint32_t t; 6379 uint32_t n; 6380 uint32_t imm32; 6381 bool index; 6382 bool add; 6383 bool wback; 6384 6385 switch (encoding) { 6386 case eEncodingA1: 6387 // if Rn == '1111' then SEE LDR (literal); 6388 // if P == '0' && W == '1' then SEE LDRT; 6389 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == 6390 // '000000000100' then SEE POP; 6391 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6392 t = Bits32(opcode, 15, 12); 6393 n = Bits32(opcode, 19, 16); 6394 imm32 = Bits32(opcode, 11, 0); 6395 6396 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6397 // (W == '1'); 6398 index = BitIsSet(opcode, 24); 6399 add = BitIsSet(opcode, 23); 6400 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6401 6402 // if wback && n == t then UNPREDICTABLE; 6403 if (wback && (n == t)) 6404 return false; 6405 6406 break; 6407 6408 default: 6409 return false; 6410 } 6411 6412 addr_t address; 6413 addr_t offset_addr; 6414 addr_t base_address = ReadCoreReg(n, &success); 6415 if (!success) 6416 return false; 6417 6418 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6419 if (add) 6420 offset_addr = base_address + imm32; 6421 else 6422 offset_addr = base_address - imm32; 6423 6424 // address = if index then offset_addr else R[n]; 6425 if (index) 6426 address = offset_addr; 6427 else 6428 address = base_address; 6429 6430 // data = MemU[address,4]; 6431 6432 RegisterInfo base_reg; 6433 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6434 6435 EmulateInstruction::Context context; 6436 context.type = eContextRegisterLoad; 6437 context.SetRegisterPlusOffset(base_reg, address - base_address); 6438 6439 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6440 if (!success) 6441 return false; 6442 6443 // if wback then R[n] = offset_addr; 6444 if (wback) { 6445 context.type = eContextAdjustBaseRegister; 6446 context.SetAddress(offset_addr); 6447 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6448 offset_addr)) 6449 return false; 6450 } 6451 6452 // if t == 15 then 6453 if (t == 15) { 6454 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6455 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6456 // LoadWritePC (data); 6457 context.type = eContextRegisterLoad; 6458 context.SetRegisterPlusOffset(base_reg, address - base_address); 6459 LoadWritePC(context, data); 6460 } else 6461 return false; 6462 } 6463 // elsif UnalignedSupport() || address<1:0> = '00' then 6464 else if (UnalignedSupport() || 6465 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6466 // R[t] = data; 6467 context.type = eContextRegisterLoad; 6468 context.SetRegisterPlusOffset(base_reg, address - base_address); 6469 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6470 data)) 6471 return false; 6472 } 6473 // else // Can only apply before ARMv7 6474 else { 6475 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6476 data = ROR(data, Bits32(address, 1, 0), &success); 6477 if (!success) 6478 return false; 6479 context.type = eContextRegisterLoad; 6480 context.SetImmediate(data); 6481 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6482 data)) 6483 return false; 6484 } 6485 } 6486 return true; 6487 } 6488 6489 // LDR (register) calculates an address from a base register value and an offset 6490 // register value, loads a word 6491 // from memory, and writes it to a register. The offset register value can 6492 // optionally be shifted. 6493 bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode, 6494 const ARMEncoding encoding) { 6495 #if 0 6496 if ConditionPassed() then 6497 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6498 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6499 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6500 address = if index then offset_addr else R[n]; 6501 data = MemU[address,4]; 6502 if wback then R[n] = offset_addr; 6503 if t == 15 then 6504 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6505 elsif UnalignedSupport() || address<1:0> = '00' then 6506 R[t] = data; 6507 else // Can only apply before ARMv7 6508 if CurrentInstrSet() == InstrSet_ARM then 6509 R[t] = ROR(data, 8*UInt(address<1:0>)); 6510 else 6511 R[t] = bits(32) UNKNOWN; 6512 #endif 6513 6514 bool success = false; 6515 6516 if (ConditionPassed(opcode)) { 6517 const uint32_t addr_byte_size = GetAddressByteSize(); 6518 6519 uint32_t t; 6520 uint32_t n; 6521 uint32_t m; 6522 bool index; 6523 bool add; 6524 bool wback; 6525 ARM_ShifterType shift_t; 6526 uint32_t shift_n; 6527 6528 switch (encoding) { 6529 case eEncodingT1: 6530 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 6531 // in ThumbEE"; 6532 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6533 t = Bits32(opcode, 2, 0); 6534 n = Bits32(opcode, 5, 3); 6535 m = Bits32(opcode, 8, 6); 6536 6537 // index = TRUE; add = TRUE; wback = FALSE; 6538 index = true; 6539 add = true; 6540 wback = false; 6541 6542 // (shift_t, shift_n) = (SRType_LSL, 0); 6543 shift_t = SRType_LSL; 6544 shift_n = 0; 6545 6546 break; 6547 6548 case eEncodingT2: 6549 // if Rn == '1111' then SEE LDR (literal); 6550 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6551 t = Bits32(opcode, 15, 12); 6552 n = Bits32(opcode, 19, 16); 6553 m = Bits32(opcode, 3, 0); 6554 6555 // index = TRUE; add = TRUE; wback = FALSE; 6556 index = true; 6557 add = true; 6558 wback = false; 6559 6560 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6561 shift_t = SRType_LSL; 6562 shift_n = Bits32(opcode, 5, 4); 6563 6564 // if BadReg(m) then UNPREDICTABLE; 6565 if (BadReg(m)) 6566 return false; 6567 6568 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6569 if ((t == 15) && InITBlock() && !LastInITBlock()) 6570 return false; 6571 6572 break; 6573 6574 case eEncodingA1: { 6575 // if P == '0' && W == '1' then SEE LDRT; 6576 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6577 t = Bits32(opcode, 15, 12); 6578 n = Bits32(opcode, 19, 16); 6579 m = Bits32(opcode, 3, 0); 6580 6581 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6582 // (W == '1'); 6583 index = BitIsSet(opcode, 24); 6584 add = BitIsSet(opcode, 23); 6585 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6586 6587 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6588 uint32_t type = Bits32(opcode, 6, 5); 6589 uint32_t imm5 = Bits32(opcode, 11, 7); 6590 shift_n = DecodeImmShift(type, imm5, shift_t); 6591 6592 // if m == 15 then UNPREDICTABLE; 6593 if (m == 15) 6594 return false; 6595 6596 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6597 if (wback && ((n == 15) || (n == t))) 6598 return false; 6599 } break; 6600 6601 default: 6602 return false; 6603 } 6604 6605 uint32_t Rm = 6606 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6607 if (!success) 6608 return false; 6609 6610 uint32_t Rn = 6611 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6612 if (!success) 6613 return false; 6614 6615 addr_t offset_addr; 6616 addr_t address; 6617 6618 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is 6619 // an application level alias for the CPSR". 6620 addr_t offset = 6621 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success); 6622 if (!success) 6623 return false; 6624 6625 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6626 if (add) 6627 offset_addr = Rn + offset; 6628 else 6629 offset_addr = Rn - offset; 6630 6631 // address = if index then offset_addr else R[n]; 6632 if (index) 6633 address = offset_addr; 6634 else 6635 address = Rn; 6636 6637 // data = MemU[address,4]; 6638 RegisterInfo base_reg; 6639 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6640 6641 EmulateInstruction::Context context; 6642 context.type = eContextRegisterLoad; 6643 context.SetRegisterPlusOffset(base_reg, address - Rn); 6644 6645 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6646 if (!success) 6647 return false; 6648 6649 // if wback then R[n] = offset_addr; 6650 if (wback) { 6651 context.type = eContextAdjustBaseRegister; 6652 context.SetAddress(offset_addr); 6653 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6654 offset_addr)) 6655 return false; 6656 } 6657 6658 // if t == 15 then 6659 if (t == 15) { 6660 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6661 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6662 context.type = eContextRegisterLoad; 6663 context.SetRegisterPlusOffset(base_reg, address - Rn); 6664 LoadWritePC(context, data); 6665 } else 6666 return false; 6667 } 6668 // elsif UnalignedSupport() || address<1:0> = '00' then 6669 else if (UnalignedSupport() || 6670 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6671 // R[t] = data; 6672 context.type = eContextRegisterLoad; 6673 context.SetRegisterPlusOffset(base_reg, address - Rn); 6674 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6675 data)) 6676 return false; 6677 } else // Can only apply before ARMv7 6678 { 6679 // if CurrentInstrSet() == InstrSet_ARM then 6680 if (CurrentInstrSet() == eModeARM) { 6681 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6682 data = ROR(data, Bits32(address, 1, 0), &success); 6683 if (!success) 6684 return false; 6685 context.type = eContextRegisterLoad; 6686 context.SetImmediate(data); 6687 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6688 data)) 6689 return false; 6690 } else { 6691 // R[t] = bits(32) UNKNOWN; 6692 WriteBits32Unknown(t); 6693 } 6694 } 6695 } 6696 return true; 6697 } 6698 6699 // LDRB (immediate, Thumb) 6700 bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode, 6701 const ARMEncoding encoding) { 6702 #if 0 6703 if ConditionPassed() then 6704 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6705 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6706 address = if index then offset_addr else R[n]; 6707 R[t] = ZeroExtend(MemU[address,1], 32); 6708 if wback then R[n] = offset_addr; 6709 #endif 6710 6711 bool success = false; 6712 6713 if (ConditionPassed(opcode)) { 6714 uint32_t t; 6715 uint32_t n; 6716 uint32_t imm32; 6717 bool index; 6718 bool add; 6719 bool wback; 6720 6721 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6722 switch (encoding) { 6723 case eEncodingT1: 6724 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6725 t = Bits32(opcode, 2, 0); 6726 n = Bits32(opcode, 5, 3); 6727 imm32 = Bits32(opcode, 10, 6); 6728 6729 // index = TRUE; add = TRUE; wback = FALSE; 6730 index = true; 6731 add = true; 6732 wback = false; 6733 6734 break; 6735 6736 case eEncodingT2: 6737 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6738 t = Bits32(opcode, 15, 12); 6739 n = Bits32(opcode, 19, 16); 6740 imm32 = Bits32(opcode, 11, 0); 6741 6742 // index = TRUE; add = TRUE; wback = FALSE; 6743 index = true; 6744 add = true; 6745 wback = false; 6746 6747 // if Rt == '1111' then SEE PLD; 6748 if (t == 15) 6749 return false; // PLD is not implemented yet 6750 6751 // if Rn == '1111' then SEE LDRB (literal); 6752 if (n == 15) 6753 return EmulateLDRBLiteral(opcode, eEncodingT1); 6754 6755 // if t == 13 then UNPREDICTABLE; 6756 if (t == 13) 6757 return false; 6758 6759 break; 6760 6761 case eEncodingT3: 6762 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6763 // if P == '0' && W == '0' then UNDEFINED; 6764 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 6765 return false; 6766 6767 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6768 t = Bits32(opcode, 15, 12); 6769 n = Bits32(opcode, 19, 16); 6770 imm32 = Bits32(opcode, 7, 0); 6771 6772 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6773 index = BitIsSet(opcode, 10); 6774 add = BitIsSet(opcode, 9); 6775 wback = BitIsSet(opcode, 8); 6776 6777 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6778 if (t == 15) 6779 return false; // PLD is not implemented yet 6780 6781 // if Rn == '1111' then SEE LDRB (literal); 6782 if (n == 15) 6783 return EmulateLDRBLiteral(opcode, eEncodingT1); 6784 6785 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6786 if (BadReg(t) || (wback && (n == t))) 6787 return false; 6788 6789 break; 6790 6791 default: 6792 return false; 6793 } 6794 6795 uint32_t Rn = 6796 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6797 if (!success) 6798 return false; 6799 6800 addr_t address; 6801 addr_t offset_addr; 6802 6803 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6804 if (add) 6805 offset_addr = Rn + imm32; 6806 else 6807 offset_addr = Rn - imm32; 6808 6809 // address = if index then offset_addr else R[n]; 6810 if (index) 6811 address = offset_addr; 6812 else 6813 address = Rn; 6814 6815 // R[t] = ZeroExtend(MemU[address,1], 32); 6816 RegisterInfo base_reg; 6817 RegisterInfo data_reg; 6818 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6819 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6820 6821 EmulateInstruction::Context context; 6822 context.type = eContextRegisterLoad; 6823 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 6824 6825 uint64_t data = MemURead(context, address, 1, 0, &success); 6826 if (!success) 6827 return false; 6828 6829 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6830 return false; 6831 6832 // if wback then R[n] = offset_addr; 6833 if (wback) { 6834 context.type = eContextAdjustBaseRegister; 6835 context.SetAddress(offset_addr); 6836 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6837 offset_addr)) 6838 return false; 6839 } 6840 } 6841 return true; 6842 } 6843 6844 // LDRB (literal) calculates an address from the PC value and an immediate 6845 // offset, loads a byte from memory, 6846 // zero-extends it to form a 32-bit word and writes it to a register. 6847 bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode, 6848 const ARMEncoding encoding) { 6849 #if 0 6850 if ConditionPassed() then 6851 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6852 base = Align(PC,4); 6853 address = if add then (base + imm32) else (base - imm32); 6854 R[t] = ZeroExtend(MemU[address,1], 32); 6855 #endif 6856 6857 bool success = false; 6858 6859 if (ConditionPassed(opcode)) { 6860 uint32_t t; 6861 uint32_t imm32; 6862 bool add; 6863 switch (encoding) { 6864 case eEncodingT1: 6865 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6866 t = Bits32(opcode, 15, 12); 6867 imm32 = Bits32(opcode, 11, 0); 6868 add = BitIsSet(opcode, 23); 6869 6870 // if Rt == '1111' then SEE PLD; 6871 if (t == 15) 6872 return false; // PLD is not implemented yet 6873 6874 // if t == 13 then UNPREDICTABLE; 6875 if (t == 13) 6876 return false; 6877 6878 break; 6879 6880 case eEncodingA1: 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 t == 15 then UNPREDICTABLE; 6887 if (t == 15) 6888 return false; 6889 break; 6890 6891 default: 6892 return false; 6893 } 6894 6895 // base = Align(PC,4); 6896 uint32_t pc_val = ReadCoreReg(PC_REG, &success); 6897 if (!success) 6898 return false; 6899 6900 uint32_t base = AlignPC(pc_val); 6901 6902 addr_t address; 6903 // address = if add then (base + imm32) else (base - imm32); 6904 if (add) 6905 address = base + imm32; 6906 else 6907 address = base - imm32; 6908 6909 // R[t] = ZeroExtend(MemU[address,1], 32); 6910 EmulateInstruction::Context context; 6911 context.type = eContextRelativeBranchImmediate; 6912 context.SetImmediate(address - base); 6913 6914 uint64_t data = MemURead(context, address, 1, 0, &success); 6915 if (!success) 6916 return false; 6917 6918 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6919 return false; 6920 } 6921 return true; 6922 } 6923 6924 // LDRB (register) calculates an address from a base register value and an 6925 // offset rigister value, loads a byte from memory, zero-extends it to form a 6926 // 32-bit word, and writes it to a register. The offset register value can 6927 // optionally be shifted. 6928 bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode, 6929 const ARMEncoding encoding) { 6930 #if 0 6931 if ConditionPassed() then 6932 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6933 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6934 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6935 address = if index then offset_addr else R[n]; 6936 R[t] = ZeroExtend(MemU[address,1],32); 6937 if wback then R[n] = offset_addr; 6938 #endif 6939 6940 bool success = false; 6941 6942 if (ConditionPassed(opcode)) { 6943 uint32_t t; 6944 uint32_t n; 6945 uint32_t m; 6946 bool index; 6947 bool add; 6948 bool wback; 6949 ARM_ShifterType shift_t; 6950 uint32_t shift_n; 6951 6952 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6953 switch (encoding) { 6954 case eEncodingT1: 6955 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6956 t = Bits32(opcode, 2, 0); 6957 n = Bits32(opcode, 5, 3); 6958 m = Bits32(opcode, 8, 6); 6959 6960 // index = TRUE; add = TRUE; wback = FALSE; 6961 index = true; 6962 add = true; 6963 wback = false; 6964 6965 // (shift_t, shift_n) = (SRType_LSL, 0); 6966 shift_t = SRType_LSL; 6967 shift_n = 0; 6968 break; 6969 6970 case eEncodingT2: 6971 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6972 t = Bits32(opcode, 15, 12); 6973 n = Bits32(opcode, 19, 16); 6974 m = Bits32(opcode, 3, 0); 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, UInt(imm2)); 6982 shift_t = SRType_LSL; 6983 shift_n = Bits32(opcode, 5, 4); 6984 6985 // if Rt == '1111' then SEE PLD; 6986 if (t == 15) 6987 return false; // PLD is not implemented yet 6988 6989 // if Rn == '1111' then SEE LDRB (literal); 6990 if (n == 15) 6991 return EmulateLDRBLiteral(opcode, eEncodingT1); 6992 6993 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6994 if ((t == 13) || BadReg(m)) 6995 return false; 6996 break; 6997 6998 case eEncodingA1: { 6999 // if P == '0' && W == '1' then SEE LDRBT; 7000 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7001 t = Bits32(opcode, 15, 12); 7002 n = Bits32(opcode, 19, 16); 7003 m = Bits32(opcode, 3, 0); 7004 7005 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7006 // (W == '1'); 7007 index = BitIsSet(opcode, 24); 7008 add = BitIsSet(opcode, 23); 7009 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7010 7011 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 7012 uint32_t type = Bits32(opcode, 6, 5); 7013 uint32_t imm5 = Bits32(opcode, 11, 7); 7014 shift_n = DecodeImmShift(type, imm5, shift_t); 7015 7016 // if t == 15 || m == 15 then UNPREDICTABLE; 7017 if ((t == 15) || (m == 15)) 7018 return false; 7019 7020 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7021 if (wback && ((n == 15) || (n == t))) 7022 return false; 7023 } break; 7024 7025 default: 7026 return false; 7027 } 7028 7029 addr_t offset_addr; 7030 addr_t address; 7031 7032 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7033 uint32_t Rm = 7034 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7035 if (!success) 7036 return false; 7037 7038 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7039 if (!success) 7040 return false; 7041 7042 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7043 uint32_t Rn = 7044 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7045 if (!success) 7046 return false; 7047 7048 if (add) 7049 offset_addr = Rn + offset; 7050 else 7051 offset_addr = Rn - offset; 7052 7053 // address = if index then offset_addr else R[n]; 7054 if (index) 7055 address = offset_addr; 7056 else 7057 address = Rn; 7058 7059 // R[t] = ZeroExtend(MemU[address,1],32); 7060 RegisterInfo base_reg; 7061 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7062 7063 EmulateInstruction::Context context; 7064 context.type = eContextRegisterLoad; 7065 context.SetRegisterPlusOffset(base_reg, address - Rn); 7066 7067 uint64_t data = MemURead(context, address, 1, 0, &success); 7068 if (!success) 7069 return false; 7070 7071 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7072 return false; 7073 7074 // if wback then R[n] = offset_addr; 7075 if (wback) { 7076 context.type = eContextAdjustBaseRegister; 7077 context.SetAddress(offset_addr); 7078 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7079 offset_addr)) 7080 return false; 7081 } 7082 } 7083 return true; 7084 } 7085 7086 // LDRH (immediate, Thumb) calculates an address from a base register value and 7087 // an immediate offset, loads a 7088 // halfword from memory, zero-extends it to form a 32-bit word, and writes it 7089 // to a register. It can use offset, post-indexed, or pre-indexed addressing. 7090 bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode, 7091 const ARMEncoding encoding) { 7092 #if 0 7093 if ConditionPassed() then 7094 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7095 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7096 address = if index then offset_addr else R[n]; 7097 data = MemU[address,2]; 7098 if wback then R[n] = offset_addr; 7099 if UnalignedSupport() || address<0> = '0' then 7100 R[t] = ZeroExtend(data, 32); 7101 else // Can only apply before ARMv7 7102 R[t] = bits(32) UNKNOWN; 7103 #endif 7104 7105 bool success = false; 7106 7107 if (ConditionPassed(opcode)) { 7108 uint32_t t; 7109 uint32_t n; 7110 uint32_t imm32; 7111 bool index; 7112 bool add; 7113 bool wback; 7114 7115 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7116 switch (encoding) { 7117 case eEncodingT1: 7118 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 7119 t = Bits32(opcode, 2, 0); 7120 n = Bits32(opcode, 5, 3); 7121 imm32 = Bits32(opcode, 10, 6) << 1; 7122 7123 // index = TRUE; add = TRUE; wback = FALSE; 7124 index = true; 7125 add = true; 7126 wback = false; 7127 7128 break; 7129 7130 case eEncodingT2: 7131 // if Rt == '1111' then SEE "Unallocated memory hints"; 7132 // if Rn == '1111' then SEE LDRH (literal); 7133 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7134 t = Bits32(opcode, 15, 12); 7135 n = Bits32(opcode, 19, 16); 7136 imm32 = Bits32(opcode, 11, 0); 7137 7138 // index = TRUE; add = TRUE; wback = FALSE; 7139 index = true; 7140 add = true; 7141 wback = false; 7142 7143 // if t == 13 then UNPREDICTABLE; 7144 if (t == 13) 7145 return false; 7146 break; 7147 7148 case eEncodingT3: 7149 // if Rn == '1111' then SEE LDRH (literal); 7150 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7151 // "Unallocated memory hints"; 7152 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 7153 // if P == '0' && W == '0' then UNDEFINED; 7154 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7155 return false; 7156 7157 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7158 t = Bits32(opcode, 15, 12); 7159 n = Bits32(opcode, 19, 16); 7160 imm32 = Bits32(opcode, 7, 0); 7161 7162 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7163 index = BitIsSet(opcode, 10); 7164 add = BitIsSet(opcode, 9); 7165 wback = BitIsSet(opcode, 8); 7166 7167 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7168 if (BadReg(t) || (wback && (n == t))) 7169 return false; 7170 break; 7171 7172 default: 7173 return false; 7174 } 7175 7176 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7177 uint32_t Rn = 7178 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7179 if (!success) 7180 return false; 7181 7182 addr_t offset_addr; 7183 addr_t address; 7184 7185 if (add) 7186 offset_addr = Rn + imm32; 7187 else 7188 offset_addr = Rn - imm32; 7189 7190 // address = if index then offset_addr else R[n]; 7191 if (index) 7192 address = offset_addr; 7193 else 7194 address = Rn; 7195 7196 // data = MemU[address,2]; 7197 RegisterInfo base_reg; 7198 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7199 7200 EmulateInstruction::Context context; 7201 context.type = eContextRegisterLoad; 7202 context.SetRegisterPlusOffset(base_reg, address - Rn); 7203 7204 uint64_t data = MemURead(context, address, 2, 0, &success); 7205 if (!success) 7206 return false; 7207 7208 // if wback then R[n] = offset_addr; 7209 if (wback) { 7210 context.type = eContextAdjustBaseRegister; 7211 context.SetAddress(offset_addr); 7212 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7213 offset_addr)) 7214 return false; 7215 } 7216 7217 // if UnalignedSupport() || address<0> = '0' then 7218 if (UnalignedSupport() || BitIsClear(address, 0)) { 7219 // R[t] = ZeroExtend(data, 32); 7220 context.type = eContextRegisterLoad; 7221 context.SetRegisterPlusOffset(base_reg, address - Rn); 7222 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7223 data)) 7224 return false; 7225 } else // Can only apply before ARMv7 7226 { 7227 // R[t] = bits(32) UNKNOWN; 7228 WriteBits32Unknown(t); 7229 } 7230 } 7231 return true; 7232 } 7233 7234 // LDRH (literal) caculates an address from the PC value and an immediate 7235 // offset, loads a halfword from memory, 7236 // zero-extends it to form a 32-bit word, and writes it to a register. 7237 bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode, 7238 const ARMEncoding encoding) { 7239 #if 0 7240 if ConditionPassed() then 7241 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7242 base = Align(PC,4); 7243 address = if add then (base + imm32) else (base - imm32); 7244 data = MemU[address,2]; 7245 if UnalignedSupport() || address<0> = '0' then 7246 R[t] = ZeroExtend(data, 32); 7247 else // Can only apply before ARMv7 7248 R[t] = bits(32) UNKNOWN; 7249 #endif 7250 7251 bool success = false; 7252 7253 if (ConditionPassed(opcode)) { 7254 uint32_t t; 7255 uint32_t imm32; 7256 bool add; 7257 7258 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7259 switch (encoding) { 7260 case eEncodingT1: 7261 // if Rt == '1111' then SEE "Unallocated memory hints"; 7262 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7263 t = Bits32(opcode, 15, 12); 7264 imm32 = Bits32(opcode, 11, 0); 7265 add = BitIsSet(opcode, 23); 7266 7267 // if t == 13 then UNPREDICTABLE; 7268 if (t == 13) 7269 return false; 7270 7271 break; 7272 7273 case eEncodingA1: { 7274 uint32_t imm4H = Bits32(opcode, 11, 8); 7275 uint32_t imm4L = Bits32(opcode, 3, 0); 7276 7277 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7278 t = Bits32(opcode, 15, 12); 7279 imm32 = (imm4H << 4) | imm4L; 7280 add = BitIsSet(opcode, 23); 7281 7282 // if t == 15 then UNPREDICTABLE; 7283 if (t == 15) 7284 return false; 7285 break; 7286 } 7287 7288 default: 7289 return false; 7290 } 7291 7292 // base = Align(PC,4); 7293 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7294 if (!success) 7295 return false; 7296 7297 addr_t base = AlignPC(pc_value); 7298 addr_t address; 7299 7300 // address = if add then (base + imm32) else (base - imm32); 7301 if (add) 7302 address = base + imm32; 7303 else 7304 address = base - imm32; 7305 7306 // data = MemU[address,2]; 7307 RegisterInfo base_reg; 7308 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7309 7310 EmulateInstruction::Context context; 7311 context.type = eContextRegisterLoad; 7312 context.SetRegisterPlusOffset(base_reg, address - base); 7313 7314 uint64_t data = MemURead(context, address, 2, 0, &success); 7315 if (!success) 7316 return false; 7317 7318 // if UnalignedSupport() || address<0> = '0' then 7319 if (UnalignedSupport() || BitIsClear(address, 0)) { 7320 // R[t] = ZeroExtend(data, 32); 7321 context.type = eContextRegisterLoad; 7322 context.SetRegisterPlusOffset(base_reg, address - base); 7323 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7324 data)) 7325 return false; 7326 7327 } else // Can only apply before ARMv7 7328 { 7329 // R[t] = bits(32) UNKNOWN; 7330 WriteBits32Unknown(t); 7331 } 7332 } 7333 return true; 7334 } 7335 7336 // LDRH (literal) calculates an address from a base register value and an offset 7337 // register value, loads a halfword 7338 // from memory, zero-extends it to form a 32-bit word, and writes it to a 7339 // register. The offset register value can be shifted left by 0, 1, 2, or 3 7340 // bits. 7341 bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode, 7342 const ARMEncoding encoding) { 7343 #if 0 7344 if ConditionPassed() then 7345 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7346 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7347 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7348 address = if index then offset_addr else R[n]; 7349 data = MemU[address,2]; 7350 if wback then R[n] = offset_addr; 7351 if UnalignedSupport() || address<0> = '0' then 7352 R[t] = ZeroExtend(data, 32); 7353 else // Can only apply before ARMv7 7354 R[t] = bits(32) UNKNOWN; 7355 #endif 7356 7357 bool success = false; 7358 7359 if (ConditionPassed(opcode)) { 7360 uint32_t t; 7361 uint32_t n; 7362 uint32_t m; 7363 bool index; 7364 bool add; 7365 bool wback; 7366 ARM_ShifterType shift_t; 7367 uint32_t shift_n; 7368 7369 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7370 switch (encoding) { 7371 case eEncodingT1: 7372 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 7373 // in ThumbEE"; 7374 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7375 t = Bits32(opcode, 2, 0); 7376 n = Bits32(opcode, 5, 3); 7377 m = Bits32(opcode, 8, 6); 7378 7379 // index = TRUE; add = TRUE; wback = FALSE; 7380 index = true; 7381 add = true; 7382 wback = false; 7383 7384 // (shift_t, shift_n) = (SRType_LSL, 0); 7385 shift_t = SRType_LSL; 7386 shift_n = 0; 7387 7388 break; 7389 7390 case eEncodingT2: 7391 // if Rn == '1111' then SEE LDRH (literal); 7392 // if Rt == '1111' then SEE "Unallocated memory hints"; 7393 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7394 t = Bits32(opcode, 15, 12); 7395 n = Bits32(opcode, 19, 16); 7396 m = Bits32(opcode, 3, 0); 7397 7398 // index = TRUE; add = TRUE; wback = FALSE; 7399 index = true; 7400 add = true; 7401 wback = false; 7402 7403 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7404 shift_t = SRType_LSL; 7405 shift_n = Bits32(opcode, 5, 4); 7406 7407 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7408 if ((t == 13) || BadReg(m)) 7409 return false; 7410 break; 7411 7412 case eEncodingA1: 7413 // if P == '0' && W == '1' then SEE LDRHT; 7414 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7415 t = Bits32(opcode, 15, 12); 7416 n = Bits32(opcode, 19, 16); 7417 m = Bits32(opcode, 3, 0); 7418 7419 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7420 // (W == '1'); 7421 index = BitIsSet(opcode, 24); 7422 add = BitIsSet(opcode, 23); 7423 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7424 7425 // (shift_t, shift_n) = (SRType_LSL, 0); 7426 shift_t = SRType_LSL; 7427 shift_n = 0; 7428 7429 // if t == 15 || m == 15 then UNPREDICTABLE; 7430 if ((t == 15) || (m == 15)) 7431 return false; 7432 7433 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7434 if (wback && ((n == 15) || (n == t))) 7435 return false; 7436 7437 break; 7438 7439 default: 7440 return false; 7441 } 7442 7443 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7444 7445 uint64_t Rm = 7446 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7447 if (!success) 7448 return false; 7449 7450 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7451 if (!success) 7452 return false; 7453 7454 addr_t offset_addr; 7455 addr_t address; 7456 7457 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7458 uint64_t Rn = 7459 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7460 if (!success) 7461 return false; 7462 7463 if (add) 7464 offset_addr = Rn + offset; 7465 else 7466 offset_addr = Rn - offset; 7467 7468 // address = if index then offset_addr else R[n]; 7469 if (index) 7470 address = offset_addr; 7471 else 7472 address = Rn; 7473 7474 // data = MemU[address,2]; 7475 RegisterInfo base_reg; 7476 RegisterInfo offset_reg; 7477 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7478 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7479 7480 EmulateInstruction::Context context; 7481 context.type = eContextRegisterLoad; 7482 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7483 uint64_t data = MemURead(context, address, 2, 0, &success); 7484 if (!success) 7485 return false; 7486 7487 // if wback then R[n] = offset_addr; 7488 if (wback) { 7489 context.type = eContextAdjustBaseRegister; 7490 context.SetAddress(offset_addr); 7491 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7492 offset_addr)) 7493 return false; 7494 } 7495 7496 // if UnalignedSupport() || address<0> = '0' then 7497 if (UnalignedSupport() || BitIsClear(address, 0)) { 7498 // R[t] = ZeroExtend(data, 32); 7499 context.type = eContextRegisterLoad; 7500 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7501 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7502 data)) 7503 return false; 7504 } else // Can only apply before ARMv7 7505 { 7506 // R[t] = bits(32) UNKNOWN; 7507 WriteBits32Unknown(t); 7508 } 7509 } 7510 return true; 7511 } 7512 7513 // LDRSB (immediate) calculates an address from a base register value and an 7514 // immediate offset, loads a byte from 7515 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7516 // It can use offset, post-indexed, or pre-indexed addressing. 7517 bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode, 7518 const ARMEncoding encoding) { 7519 #if 0 7520 if ConditionPassed() then 7521 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7522 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7523 address = if index then offset_addr else R[n]; 7524 R[t] = SignExtend(MemU[address,1], 32); 7525 if wback then R[n] = offset_addr; 7526 #endif 7527 7528 bool success = false; 7529 7530 if (ConditionPassed(opcode)) { 7531 uint32_t t; 7532 uint32_t n; 7533 uint32_t imm32; 7534 bool index; 7535 bool add; 7536 bool wback; 7537 7538 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7539 switch (encoding) { 7540 case eEncodingT1: 7541 // if Rt == '1111' then SEE PLI; 7542 // if Rn == '1111' then SEE LDRSB (literal); 7543 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7544 t = Bits32(opcode, 15, 12); 7545 n = Bits32(opcode, 19, 16); 7546 imm32 = Bits32(opcode, 11, 0); 7547 7548 // index = TRUE; add = TRUE; wback = FALSE; 7549 index = true; 7550 add = true; 7551 wback = false; 7552 7553 // if t == 13 then UNPREDICTABLE; 7554 if (t == 13) 7555 return false; 7556 7557 break; 7558 7559 case eEncodingT2: 7560 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7561 // if Rn == '1111' then SEE LDRSB (literal); 7562 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7563 // if P == '0' && W == '0' then UNDEFINED; 7564 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7565 return false; 7566 7567 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7568 t = Bits32(opcode, 15, 12); 7569 n = Bits32(opcode, 19, 16); 7570 imm32 = Bits32(opcode, 7, 0); 7571 7572 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7573 index = BitIsSet(opcode, 10); 7574 add = BitIsSet(opcode, 9); 7575 wback = BitIsSet(opcode, 8); 7576 7577 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7578 if (((t == 13) || 7579 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) || 7580 BitIsSet(opcode, 8)))) || 7581 (wback && (n == t))) 7582 return false; 7583 7584 break; 7585 7586 case eEncodingA1: { 7587 // if Rn == '1111' then SEE LDRSB (literal); 7588 // if P == '0' && W == '1' then SEE LDRSBT; 7589 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7590 t = Bits32(opcode, 15, 12); 7591 n = Bits32(opcode, 19, 16); 7592 7593 uint32_t imm4H = Bits32(opcode, 11, 8); 7594 uint32_t imm4L = Bits32(opcode, 3, 0); 7595 imm32 = (imm4H << 4) | imm4L; 7596 7597 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7598 // (W == '1'); 7599 index = BitIsSet(opcode, 24); 7600 add = BitIsSet(opcode, 23); 7601 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7602 7603 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7604 if ((t == 15) || (wback && (n == t))) 7605 return false; 7606 7607 break; 7608 } 7609 7610 default: 7611 return false; 7612 } 7613 7614 uint64_t Rn = ReadCoreReg(n, &success); 7615 if (!success) 7616 return false; 7617 7618 addr_t offset_addr; 7619 addr_t address; 7620 7621 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7622 if (add) 7623 offset_addr = Rn + imm32; 7624 else 7625 offset_addr = Rn - imm32; 7626 7627 // address = if index then offset_addr else R[n]; 7628 if (index) 7629 address = offset_addr; 7630 else 7631 address = Rn; 7632 7633 // R[t] = SignExtend(MemU[address,1], 32); 7634 RegisterInfo base_reg; 7635 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7636 7637 EmulateInstruction::Context context; 7638 context.type = eContextRegisterLoad; 7639 context.SetRegisterPlusOffset(base_reg, address - Rn); 7640 7641 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7642 if (!success) 7643 return false; 7644 7645 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7646 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7647 (uint64_t)signed_data)) 7648 return false; 7649 7650 // if wback then R[n] = offset_addr; 7651 if (wback) { 7652 context.type = eContextAdjustBaseRegister; 7653 context.SetAddress(offset_addr); 7654 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7655 offset_addr)) 7656 return false; 7657 } 7658 } 7659 7660 return true; 7661 } 7662 7663 // LDRSB (literal) calculates an address from the PC value and an immediate 7664 // offset, loads a byte from memory, 7665 // sign-extends it to form a 32-bit word, and writes tit to a register. 7666 bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode, 7667 const ARMEncoding encoding) { 7668 #if 0 7669 if ConditionPassed() then 7670 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7671 base = Align(PC,4); 7672 address = if add then (base + imm32) else (base - imm32); 7673 R[t] = SignExtend(MemU[address,1], 32); 7674 #endif 7675 7676 bool success = false; 7677 7678 if (ConditionPassed(opcode)) { 7679 uint32_t t; 7680 uint32_t imm32; 7681 bool add; 7682 7683 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7684 switch (encoding) { 7685 case eEncodingT1: 7686 // if Rt == '1111' then SEE PLI; 7687 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7688 t = Bits32(opcode, 15, 12); 7689 imm32 = Bits32(opcode, 11, 0); 7690 add = BitIsSet(opcode, 23); 7691 7692 // if t == 13 then UNPREDICTABLE; 7693 if (t == 13) 7694 return false; 7695 7696 break; 7697 7698 case eEncodingA1: { 7699 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7700 t = Bits32(opcode, 15, 12); 7701 uint32_t imm4H = Bits32(opcode, 11, 8); 7702 uint32_t imm4L = Bits32(opcode, 3, 0); 7703 imm32 = (imm4H << 4) | imm4L; 7704 add = BitIsSet(opcode, 23); 7705 7706 // if t == 15 then UNPREDICTABLE; 7707 if (t == 15) 7708 return false; 7709 7710 break; 7711 } 7712 7713 default: 7714 return false; 7715 } 7716 7717 // base = Align(PC,4); 7718 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7719 if (!success) 7720 return false; 7721 uint64_t base = AlignPC(pc_value); 7722 7723 // address = if add then (base + imm32) else (base - imm32); 7724 addr_t address; 7725 if (add) 7726 address = base + imm32; 7727 else 7728 address = base - imm32; 7729 7730 // R[t] = SignExtend(MemU[address,1], 32); 7731 RegisterInfo base_reg; 7732 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7733 7734 EmulateInstruction::Context context; 7735 context.type = eContextRegisterLoad; 7736 context.SetRegisterPlusOffset(base_reg, address - base); 7737 7738 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7739 if (!success) 7740 return false; 7741 7742 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7743 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7744 (uint64_t)signed_data)) 7745 return false; 7746 } 7747 return true; 7748 } 7749 7750 // LDRSB (register) calculates an address from a base register value and an 7751 // offset register value, loadsa byte from 7752 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7753 // The offset register value can be shifted left by 0, 1, 2, or 3 bits. 7754 bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode, 7755 const ARMEncoding encoding) { 7756 #if 0 7757 if ConditionPassed() then 7758 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7759 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7760 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7761 address = if index then offset_addr else R[n]; 7762 R[t] = SignExtend(MemU[address,1], 32); 7763 if wback then R[n] = offset_addr; 7764 #endif 7765 7766 bool success = false; 7767 7768 if (ConditionPassed(opcode)) { 7769 uint32_t t; 7770 uint32_t n; 7771 uint32_t m; 7772 bool index; 7773 bool add; 7774 bool wback; 7775 ARM_ShifterType shift_t; 7776 uint32_t shift_n; 7777 7778 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7779 switch (encoding) { 7780 case eEncodingT1: 7781 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7782 t = Bits32(opcode, 2, 0); 7783 n = Bits32(opcode, 5, 3); 7784 m = Bits32(opcode, 8, 6); 7785 7786 // index = TRUE; add = TRUE; wback = FALSE; 7787 index = true; 7788 add = true; 7789 wback = false; 7790 7791 // (shift_t, shift_n) = (SRType_LSL, 0); 7792 shift_t = SRType_LSL; 7793 shift_n = 0; 7794 7795 break; 7796 7797 case eEncodingT2: 7798 // if Rt == '1111' then SEE PLI; 7799 // if Rn == '1111' then SEE LDRSB (literal); 7800 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7801 t = Bits32(opcode, 15, 12); 7802 n = Bits32(opcode, 19, 16); 7803 m = Bits32(opcode, 3, 0); 7804 7805 // index = TRUE; add = TRUE; wback = FALSE; 7806 index = true; 7807 add = true; 7808 wback = false; 7809 7810 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7811 shift_t = SRType_LSL; 7812 shift_n = Bits32(opcode, 5, 4); 7813 7814 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7815 if ((t == 13) || BadReg(m)) 7816 return false; 7817 break; 7818 7819 case eEncodingA1: 7820 // if P == '0' && W == '1' then SEE LDRSBT; 7821 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7822 t = Bits32(opcode, 15, 12); 7823 n = Bits32(opcode, 19, 16); 7824 m = Bits32(opcode, 3, 0); 7825 7826 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7827 // (W == '1'); 7828 index = BitIsSet(opcode, 24); 7829 add = BitIsSet(opcode, 23); 7830 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7831 7832 // (shift_t, shift_n) = (SRType_LSL, 0); 7833 shift_t = SRType_LSL; 7834 shift_n = 0; 7835 7836 // if t == 15 || m == 15 then UNPREDICTABLE; 7837 if ((t == 15) || (m == 15)) 7838 return false; 7839 7840 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7841 if (wback && ((n == 15) || (n == t))) 7842 return false; 7843 break; 7844 7845 default: 7846 return false; 7847 } 7848 7849 uint64_t Rm = 7850 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7851 if (!success) 7852 return false; 7853 7854 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7855 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7856 if (!success) 7857 return false; 7858 7859 addr_t offset_addr; 7860 addr_t address; 7861 7862 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7863 uint64_t Rn = 7864 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7865 if (!success) 7866 return false; 7867 7868 if (add) 7869 offset_addr = Rn + offset; 7870 else 7871 offset_addr = Rn - offset; 7872 7873 // address = if index then offset_addr else R[n]; 7874 if (index) 7875 address = offset_addr; 7876 else 7877 address = Rn; 7878 7879 // R[t] = SignExtend(MemU[address,1], 32); 7880 RegisterInfo base_reg; 7881 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7882 RegisterInfo offset_reg; 7883 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7884 7885 EmulateInstruction::Context context; 7886 context.type = eContextRegisterLoad; 7887 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7888 7889 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7890 if (!success) 7891 return false; 7892 7893 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7894 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7895 (uint64_t)signed_data)) 7896 return false; 7897 7898 // if wback then R[n] = offset_addr; 7899 if (wback) { 7900 context.type = eContextAdjustBaseRegister; 7901 context.SetAddress(offset_addr); 7902 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7903 offset_addr)) 7904 return false; 7905 } 7906 } 7907 return true; 7908 } 7909 7910 // LDRSH (immediate) calculates an address from a base register value and an 7911 // immediate offset, loads a halfword from 7912 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7913 // It can use offset, post-indexed, or pre-indexed addressing. 7914 bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode, 7915 const ARMEncoding encoding) { 7916 #if 0 7917 if ConditionPassed() then 7918 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7919 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7920 address = if index then offset_addr else R[n]; 7921 data = MemU[address,2]; 7922 if wback then R[n] = offset_addr; 7923 if UnalignedSupport() || address<0> = '0' then 7924 R[t] = SignExtend(data, 32); 7925 else // Can only apply before ARMv7 7926 R[t] = bits(32) UNKNOWN; 7927 #endif 7928 7929 bool success = false; 7930 7931 if (ConditionPassed(opcode)) { 7932 uint32_t t; 7933 uint32_t n; 7934 uint32_t imm32; 7935 bool index; 7936 bool add; 7937 bool wback; 7938 7939 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7940 switch (encoding) { 7941 case eEncodingT1: 7942 // if Rn == '1111' then SEE LDRSH (literal); 7943 // if Rt == '1111' then SEE "Unallocated memory hints"; 7944 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7945 t = Bits32(opcode, 15, 12); 7946 n = Bits32(opcode, 19, 16); 7947 imm32 = Bits32(opcode, 11, 0); 7948 7949 // index = TRUE; add = TRUE; wback = FALSE; 7950 index = true; 7951 add = true; 7952 wback = false; 7953 7954 // if t == 13 then UNPREDICTABLE; 7955 if (t == 13) 7956 return false; 7957 7958 break; 7959 7960 case eEncodingT2: 7961 // if Rn == '1111' then SEE LDRSH (literal); 7962 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7963 // "Unallocated memory hints"; 7964 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7965 // if P == '0' && W == '0' then UNDEFINED; 7966 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7967 return false; 7968 7969 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7970 t = Bits32(opcode, 15, 12); 7971 n = Bits32(opcode, 19, 16); 7972 imm32 = Bits32(opcode, 7, 0); 7973 7974 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7975 index = BitIsSet(opcode, 10); 7976 add = BitIsSet(opcode, 9); 7977 wback = BitIsSet(opcode, 8); 7978 7979 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7980 if (BadReg(t) || (wback && (n == t))) 7981 return false; 7982 7983 break; 7984 7985 case eEncodingA1: { 7986 // if Rn == '1111' then SEE LDRSH (literal); 7987 // if P == '0' && W == '1' then SEE LDRSHT; 7988 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7989 t = Bits32(opcode, 15, 12); 7990 n = Bits32(opcode, 19, 16); 7991 uint32_t imm4H = Bits32(opcode, 11, 8); 7992 uint32_t imm4L = Bits32(opcode, 3, 0); 7993 imm32 = (imm4H << 4) | imm4L; 7994 7995 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7996 // (W == '1'); 7997 index = BitIsSet(opcode, 24); 7998 add = BitIsSet(opcode, 23); 7999 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8000 8001 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 8002 if ((t == 15) || (wback && (n == t))) 8003 return false; 8004 8005 break; 8006 } 8007 8008 default: 8009 return false; 8010 } 8011 8012 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 8013 uint64_t Rn = 8014 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8015 if (!success) 8016 return false; 8017 8018 addr_t offset_addr; 8019 if (add) 8020 offset_addr = Rn + imm32; 8021 else 8022 offset_addr = Rn - imm32; 8023 8024 // address = if index then offset_addr else R[n]; 8025 addr_t address; 8026 if (index) 8027 address = offset_addr; 8028 else 8029 address = Rn; 8030 8031 // data = MemU[address,2]; 8032 RegisterInfo base_reg; 8033 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8034 8035 EmulateInstruction::Context context; 8036 context.type = eContextRegisterLoad; 8037 context.SetRegisterPlusOffset(base_reg, address - Rn); 8038 8039 uint64_t data = MemURead(context, address, 2, 0, &success); 8040 if (!success) 8041 return false; 8042 8043 // if wback then R[n] = offset_addr; 8044 if (wback) { 8045 context.type = eContextAdjustBaseRegister; 8046 context.SetAddress(offset_addr); 8047 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8048 offset_addr)) 8049 return false; 8050 } 8051 8052 // if UnalignedSupport() || address<0> = '0' then 8053 if (UnalignedSupport() || BitIsClear(address, 0)) { 8054 // R[t] = SignExtend(data, 32); 8055 int64_t signed_data = llvm::SignExtend64<16>(data); 8056 context.type = eContextRegisterLoad; 8057 context.SetRegisterPlusOffset(base_reg, address - Rn); 8058 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8059 (uint64_t)signed_data)) 8060 return false; 8061 } else // Can only apply before ARMv7 8062 { 8063 // R[t] = bits(32) UNKNOWN; 8064 WriteBits32Unknown(t); 8065 } 8066 } 8067 return true; 8068 } 8069 8070 // LDRSH (literal) calculates an address from the PC value and an immediate 8071 // offset, loads a halfword from memory, 8072 // sign-extends it to from a 32-bit word, and writes it to a register. 8073 bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode, 8074 const ARMEncoding encoding) { 8075 #if 0 8076 if ConditionPassed() then 8077 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8078 base = Align(PC,4); 8079 address = if add then (base + imm32) else (base - imm32); 8080 data = MemU[address,2]; 8081 if UnalignedSupport() || address<0> = '0' then 8082 R[t] = SignExtend(data, 32); 8083 else // Can only apply before ARMv7 8084 R[t] = bits(32) UNKNOWN; 8085 #endif 8086 8087 bool success = false; 8088 8089 if (ConditionPassed(opcode)) { 8090 uint32_t t; 8091 uint32_t imm32; 8092 bool add; 8093 8094 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8095 switch (encoding) { 8096 case eEncodingT1: 8097 // if Rt == '1111' then SEE "Unallocated memory hints"; 8098 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 8099 t = Bits32(opcode, 15, 12); 8100 imm32 = Bits32(opcode, 11, 0); 8101 add = BitIsSet(opcode, 23); 8102 8103 // if t == 13 then UNPREDICTABLE; 8104 if (t == 13) 8105 return false; 8106 8107 break; 8108 8109 case eEncodingA1: { 8110 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 8111 t = Bits32(opcode, 15, 12); 8112 uint32_t imm4H = Bits32(opcode, 11, 8); 8113 uint32_t imm4L = Bits32(opcode, 3, 0); 8114 imm32 = (imm4H << 4) | imm4L; 8115 add = BitIsSet(opcode, 23); 8116 8117 // if t == 15 then UNPREDICTABLE; 8118 if (t == 15) 8119 return false; 8120 8121 break; 8122 } 8123 default: 8124 return false; 8125 } 8126 8127 // base = Align(PC,4); 8128 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 8129 if (!success) 8130 return false; 8131 8132 uint64_t base = AlignPC(pc_value); 8133 8134 addr_t address; 8135 // address = if add then (base + imm32) else (base - imm32); 8136 if (add) 8137 address = base + imm32; 8138 else 8139 address = base - imm32; 8140 8141 // data = MemU[address,2]; 8142 RegisterInfo base_reg; 8143 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 8144 8145 EmulateInstruction::Context context; 8146 context.type = eContextRegisterLoad; 8147 context.SetRegisterPlusOffset(base_reg, imm32); 8148 8149 uint64_t data = MemURead(context, address, 2, 0, &success); 8150 if (!success) 8151 return false; 8152 8153 // if UnalignedSupport() || address<0> = '0' then 8154 if (UnalignedSupport() || BitIsClear(address, 0)) { 8155 // R[t] = SignExtend(data, 32); 8156 int64_t signed_data = llvm::SignExtend64<16>(data); 8157 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8158 (uint64_t)signed_data)) 8159 return false; 8160 } else // Can only apply before ARMv7 8161 { 8162 // R[t] = bits(32) UNKNOWN; 8163 WriteBits32Unknown(t); 8164 } 8165 } 8166 return true; 8167 } 8168 8169 // LDRSH (register) calculates an address from a base register value and an 8170 // offset register value, loads a halfword 8171 // from memory, sign-extends it to form a 32-bit word, and writes it to a 8172 // register. The offset register value can be shifted left by 0, 1, 2, or 3 8173 // bits. 8174 bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode, 8175 const ARMEncoding encoding) { 8176 #if 0 8177 if ConditionPassed() then 8178 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8179 offset = Shift(R[m], shift_t, shift_n, APSR.C); 8180 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8181 address = if index then offset_addr else R[n]; 8182 data = MemU[address,2]; 8183 if wback then R[n] = offset_addr; 8184 if UnalignedSupport() || address<0> = '0' then 8185 R[t] = SignExtend(data, 32); 8186 else // Can only apply before ARMv7 8187 R[t] = bits(32) UNKNOWN; 8188 #endif 8189 8190 bool success = false; 8191 8192 if (ConditionPassed(opcode)) { 8193 uint32_t t; 8194 uint32_t n; 8195 uint32_t m; 8196 bool index; 8197 bool add; 8198 bool wback; 8199 ARM_ShifterType shift_t; 8200 uint32_t shift_n; 8201 8202 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8203 switch (encoding) { 8204 case eEncodingT1: 8205 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 8206 // in ThumbEE"; 8207 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8208 t = Bits32(opcode, 2, 0); 8209 n = Bits32(opcode, 5, 3); 8210 m = Bits32(opcode, 8, 6); 8211 8212 // index = TRUE; add = TRUE; wback = FALSE; 8213 index = true; 8214 add = true; 8215 wback = false; 8216 8217 // (shift_t, shift_n) = (SRType_LSL, 0); 8218 shift_t = SRType_LSL; 8219 shift_n = 0; 8220 8221 break; 8222 8223 case eEncodingT2: 8224 // if Rn == '1111' then SEE LDRSH (literal); 8225 // if Rt == '1111' then SEE "Unallocated memory hints"; 8226 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8227 t = Bits32(opcode, 15, 12); 8228 n = Bits32(opcode, 19, 16); 8229 m = Bits32(opcode, 3, 0); 8230 8231 // index = TRUE; add = TRUE; wback = FALSE; 8232 index = true; 8233 add = true; 8234 wback = false; 8235 8236 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 8237 shift_t = SRType_LSL; 8238 shift_n = Bits32(opcode, 5, 4); 8239 8240 // if t == 13 || BadReg(m) then UNPREDICTABLE; 8241 if ((t == 13) || BadReg(m)) 8242 return false; 8243 8244 break; 8245 8246 case eEncodingA1: 8247 // if P == '0' && W == '1' then SEE LDRSHT; 8248 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8249 t = Bits32(opcode, 15, 12); 8250 n = Bits32(opcode, 19, 16); 8251 m = Bits32(opcode, 3, 0); 8252 8253 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8254 // (W == '1'); 8255 index = BitIsSet(opcode, 24); 8256 add = BitIsSet(opcode, 23); 8257 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8258 8259 // (shift_t, shift_n) = (SRType_LSL, 0); 8260 shift_t = SRType_LSL; 8261 shift_n = 0; 8262 8263 // if t == 15 || m == 15 then UNPREDICTABLE; 8264 if ((t == 15) || (m == 15)) 8265 return false; 8266 8267 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 8268 if (wback && ((n == 15) || (n == t))) 8269 return false; 8270 8271 break; 8272 8273 default: 8274 return false; 8275 } 8276 8277 uint64_t Rm = 8278 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8279 if (!success) 8280 return false; 8281 8282 uint64_t Rn = 8283 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8284 if (!success) 8285 return false; 8286 8287 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 8288 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 8289 if (!success) 8290 return false; 8291 8292 addr_t offset_addr; 8293 addr_t address; 8294 8295 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8296 if (add) 8297 offset_addr = Rn + offset; 8298 else 8299 offset_addr = Rn - offset; 8300 8301 // address = if index then offset_addr else R[n]; 8302 if (index) 8303 address = offset_addr; 8304 else 8305 address = Rn; 8306 8307 // data = MemU[address,2]; 8308 RegisterInfo base_reg; 8309 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8310 8311 RegisterInfo offset_reg; 8312 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 8313 8314 EmulateInstruction::Context context; 8315 context.type = eContextRegisterLoad; 8316 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8317 8318 uint64_t data = MemURead(context, address, 2, 0, &success); 8319 if (!success) 8320 return false; 8321 8322 // if wback then R[n] = offset_addr; 8323 if (wback) { 8324 context.type = eContextAdjustBaseRegister; 8325 context.SetAddress(offset_addr); 8326 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8327 offset_addr)) 8328 return false; 8329 } 8330 8331 // if UnalignedSupport() || address<0> = '0' then 8332 if (UnalignedSupport() || BitIsClear(address, 0)) { 8333 // R[t] = SignExtend(data, 32); 8334 context.type = eContextRegisterLoad; 8335 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8336 8337 int64_t signed_data = llvm::SignExtend64<16>(data); 8338 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8339 (uint64_t)signed_data)) 8340 return false; 8341 } else // Can only apply before ARMv7 8342 { 8343 // R[t] = bits(32) UNKNOWN; 8344 WriteBits32Unknown(t); 8345 } 8346 } 8347 return true; 8348 } 8349 8350 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and 8351 // writes the result to the destination 8352 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before 8353 // extracting the 8-bit value. 8354 bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode, 8355 const ARMEncoding encoding) { 8356 #if 0 8357 if ConditionPassed() then 8358 EncodingSpecificOperations(); 8359 rotated = ROR(R[m], rotation); 8360 R[d] = SignExtend(rotated<7:0>, 32); 8361 #endif 8362 8363 bool success = false; 8364 8365 if (ConditionPassed(opcode)) { 8366 uint32_t d; 8367 uint32_t m; 8368 uint32_t rotation; 8369 8370 // EncodingSpecificOperations(); 8371 switch (encoding) { 8372 case eEncodingT1: 8373 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8374 d = Bits32(opcode, 2, 0); 8375 m = Bits32(opcode, 5, 3); 8376 rotation = 0; 8377 8378 break; 8379 8380 case eEncodingT2: 8381 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8382 d = Bits32(opcode, 11, 8); 8383 m = Bits32(opcode, 3, 0); 8384 rotation = Bits32(opcode, 5, 4) << 3; 8385 8386 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8387 if (BadReg(d) || BadReg(m)) 8388 return false; 8389 8390 break; 8391 8392 case eEncodingA1: 8393 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8394 d = Bits32(opcode, 15, 12); 8395 m = Bits32(opcode, 3, 0); 8396 rotation = Bits32(opcode, 11, 10) << 3; 8397 8398 // if d == 15 || m == 15 then UNPREDICTABLE; 8399 if ((d == 15) || (m == 15)) 8400 return false; 8401 8402 break; 8403 8404 default: 8405 return false; 8406 } 8407 8408 uint64_t Rm = 8409 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8410 if (!success) 8411 return false; 8412 8413 // rotated = ROR(R[m], rotation); 8414 uint64_t rotated = ROR(Rm, rotation, &success); 8415 if (!success) 8416 return false; 8417 8418 // R[d] = SignExtend(rotated<7:0>, 32); 8419 int64_t data = llvm::SignExtend64<8>(rotated); 8420 8421 RegisterInfo source_reg; 8422 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8423 8424 EmulateInstruction::Context context; 8425 context.type = eContextRegisterLoad; 8426 context.SetRegister(source_reg); 8427 8428 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8429 (uint64_t)data)) 8430 return false; 8431 } 8432 return true; 8433 } 8434 8435 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and 8436 // writes the result to the destination 8437 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8438 // extracting the 16-bit value. 8439 bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode, 8440 const ARMEncoding encoding) { 8441 #if 0 8442 if ConditionPassed() then 8443 EncodingSpecificOperations(); 8444 rotated = ROR(R[m], rotation); 8445 R[d] = SignExtend(rotated<15:0>, 32); 8446 #endif 8447 8448 bool success = false; 8449 8450 if (ConditionPassed(opcode)) { 8451 uint32_t d; 8452 uint32_t m; 8453 uint32_t rotation; 8454 8455 // EncodingSpecificOperations(); 8456 switch (encoding) { 8457 case eEncodingT1: 8458 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8459 d = Bits32(opcode, 2, 0); 8460 m = Bits32(opcode, 5, 3); 8461 rotation = 0; 8462 8463 break; 8464 8465 case eEncodingT2: 8466 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8467 d = Bits32(opcode, 11, 8); 8468 m = Bits32(opcode, 3, 0); 8469 rotation = Bits32(opcode, 5, 4) << 3; 8470 8471 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8472 if (BadReg(d) || BadReg(m)) 8473 return false; 8474 8475 break; 8476 8477 case eEncodingA1: 8478 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8479 d = Bits32(opcode, 15, 12); 8480 m = Bits32(opcode, 3, 0); 8481 rotation = Bits32(opcode, 11, 10) << 3; 8482 8483 // if d == 15 || m == 15 then UNPREDICTABLE; 8484 if ((d == 15) || (m == 15)) 8485 return false; 8486 8487 break; 8488 8489 default: 8490 return false; 8491 } 8492 8493 uint64_t Rm = 8494 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8495 if (!success) 8496 return false; 8497 8498 // rotated = ROR(R[m], rotation); 8499 uint64_t rotated = ROR(Rm, rotation, &success); 8500 if (!success) 8501 return false; 8502 8503 // R[d] = SignExtend(rotated<15:0>, 32); 8504 RegisterInfo source_reg; 8505 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8506 8507 EmulateInstruction::Context context; 8508 context.type = eContextRegisterLoad; 8509 context.SetRegister(source_reg); 8510 8511 int64_t data = llvm::SignExtend64<16>(rotated); 8512 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8513 (uint64_t)data)) 8514 return false; 8515 } 8516 8517 return true; 8518 } 8519 8520 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and 8521 // writes the result to the destination 8522 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8523 // extracting the 8-bit value. 8524 bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode, 8525 const ARMEncoding encoding) { 8526 #if 0 8527 if ConditionPassed() then 8528 EncodingSpecificOperations(); 8529 rotated = ROR(R[m], rotation); 8530 R[d] = ZeroExtend(rotated<7:0>, 32); 8531 #endif 8532 8533 bool success = false; 8534 8535 if (ConditionPassed(opcode)) { 8536 uint32_t d; 8537 uint32_t m; 8538 uint32_t rotation; 8539 8540 // EncodingSpecificOperations(); 8541 switch (encoding) { 8542 case eEncodingT1: 8543 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8544 d = Bits32(opcode, 2, 0); 8545 m = Bits32(opcode, 5, 3); 8546 rotation = 0; 8547 8548 break; 8549 8550 case eEncodingT2: 8551 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8552 d = Bits32(opcode, 11, 8); 8553 m = Bits32(opcode, 3, 0); 8554 rotation = Bits32(opcode, 5, 4) << 3; 8555 8556 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8557 if (BadReg(d) || BadReg(m)) 8558 return false; 8559 8560 break; 8561 8562 case eEncodingA1: 8563 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8564 d = Bits32(opcode, 15, 12); 8565 m = Bits32(opcode, 3, 0); 8566 rotation = Bits32(opcode, 11, 10) << 3; 8567 8568 // if d == 15 || m == 15 then UNPREDICTABLE; 8569 if ((d == 15) || (m == 15)) 8570 return false; 8571 8572 break; 8573 8574 default: 8575 return false; 8576 } 8577 8578 uint64_t Rm = 8579 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8580 if (!success) 8581 return false; 8582 8583 // rotated = ROR(R[m], rotation); 8584 uint64_t rotated = ROR(Rm, rotation, &success); 8585 if (!success) 8586 return false; 8587 8588 // R[d] = ZeroExtend(rotated<7:0>, 32); 8589 RegisterInfo source_reg; 8590 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8591 8592 EmulateInstruction::Context context; 8593 context.type = eContextRegisterLoad; 8594 context.SetRegister(source_reg); 8595 8596 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8597 Bits32(rotated, 7, 0))) 8598 return false; 8599 } 8600 return true; 8601 } 8602 8603 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and 8604 // writes the result to the destination 8605 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8606 // extracting the 16-bit value. 8607 bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode, 8608 const ARMEncoding encoding) { 8609 #if 0 8610 if ConditionPassed() then 8611 EncodingSpecificOperations(); 8612 rotated = ROR(R[m], rotation); 8613 R[d] = ZeroExtend(rotated<15:0>, 32); 8614 #endif 8615 8616 bool success = false; 8617 8618 if (ConditionPassed(opcode)) { 8619 uint32_t d; 8620 uint32_t m; 8621 uint32_t rotation; 8622 8623 switch (encoding) { 8624 case eEncodingT1: 8625 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8626 d = Bits32(opcode, 2, 0); 8627 m = Bits32(opcode, 5, 3); 8628 rotation = 0; 8629 8630 break; 8631 8632 case eEncodingT2: 8633 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8634 d = Bits32(opcode, 11, 8); 8635 m = Bits32(opcode, 3, 0); 8636 rotation = Bits32(opcode, 5, 4) << 3; 8637 8638 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8639 if (BadReg(d) || BadReg(m)) 8640 return false; 8641 8642 break; 8643 8644 case eEncodingA1: 8645 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8646 d = Bits32(opcode, 15, 12); 8647 m = Bits32(opcode, 3, 0); 8648 rotation = Bits32(opcode, 11, 10) << 3; 8649 8650 // if d == 15 || m == 15 then UNPREDICTABLE; 8651 if ((d == 15) || (m == 15)) 8652 return false; 8653 8654 break; 8655 8656 default: 8657 return false; 8658 } 8659 8660 uint64_t Rm = 8661 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8662 if (!success) 8663 return false; 8664 8665 // rotated = ROR(R[m], rotation); 8666 uint64_t rotated = ROR(Rm, rotation, &success); 8667 if (!success) 8668 return false; 8669 8670 // R[d] = ZeroExtend(rotated<15:0>, 32); 8671 RegisterInfo source_reg; 8672 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8673 8674 EmulateInstruction::Context context; 8675 context.type = eContextRegisterLoad; 8676 context.SetRegister(source_reg); 8677 8678 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8679 Bits32(rotated, 15, 0))) 8680 return false; 8681 } 8682 return true; 8683 } 8684 8685 // RFE (Return From Exception) loads the PC and the CPSR from the word at the 8686 // specified address and the following 8687 // word respectively. 8688 bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode, 8689 const ARMEncoding encoding) { 8690 #if 0 8691 if ConditionPassed() then 8692 EncodingSpecificOperations(); 8693 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8694 UNPREDICTABLE; 8695 else 8696 address = if increment then R[n] else R[n]-8; 8697 if wordhigher then address = address+4; 8698 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8699 BranchWritePC(MemA[address,4]); 8700 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8701 #endif 8702 8703 bool success = false; 8704 8705 if (ConditionPassed(opcode)) { 8706 uint32_t n; 8707 bool wback; 8708 bool increment; 8709 bool wordhigher; 8710 8711 // EncodingSpecificOperations(); 8712 switch (encoding) { 8713 case eEncodingT1: 8714 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = 8715 // FALSE; 8716 n = Bits32(opcode, 19, 16); 8717 wback = BitIsSet(opcode, 21); 8718 increment = false; 8719 wordhigher = false; 8720 8721 // if n == 15 then UNPREDICTABLE; 8722 if (n == 15) 8723 return false; 8724 8725 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8726 if (InITBlock() && !LastInITBlock()) 8727 return false; 8728 8729 break; 8730 8731 case eEncodingT2: 8732 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8733 n = Bits32(opcode, 19, 16); 8734 wback = BitIsSet(opcode, 21); 8735 increment = true; 8736 wordhigher = false; 8737 8738 // if n == 15 then UNPREDICTABLE; 8739 if (n == 15) 8740 return false; 8741 8742 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8743 if (InITBlock() && !LastInITBlock()) 8744 return false; 8745 8746 break; 8747 8748 case eEncodingA1: 8749 // n = UInt(Rn); 8750 n = Bits32(opcode, 19, 16); 8751 8752 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8753 wback = BitIsSet(opcode, 21); 8754 increment = BitIsSet(opcode, 23); 8755 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23)); 8756 8757 // if n == 15 then UNPREDICTABLE; 8758 if (n == 15) 8759 return false; 8760 8761 break; 8762 8763 default: 8764 return false; 8765 } 8766 8767 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE 8768 // then 8769 if (!CurrentModeIsPrivileged()) 8770 // UNPREDICTABLE; 8771 return false; 8772 else { 8773 uint64_t Rn = 8774 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8775 if (!success) 8776 return false; 8777 8778 addr_t address; 8779 // address = if increment then R[n] else R[n]-8; 8780 if (increment) 8781 address = Rn; 8782 else 8783 address = Rn - 8; 8784 8785 // if wordhigher then address = address+4; 8786 if (wordhigher) 8787 address = address + 4; 8788 8789 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8790 RegisterInfo base_reg; 8791 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8792 8793 EmulateInstruction::Context context; 8794 context.type = eContextReturnFromException; 8795 context.SetRegisterPlusOffset(base_reg, address - Rn); 8796 8797 uint64_t data = MemARead(context, address + 4, 4, 0, &success); 8798 if (!success) 8799 return false; 8800 8801 CPSRWriteByInstr(data, 15, true); 8802 8803 // BranchWritePC(MemA[address,4]); 8804 uint64_t data2 = MemARead(context, address, 4, 0, &success); 8805 if (!success) 8806 return false; 8807 8808 BranchWritePC(context, data2); 8809 8810 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8811 if (wback) { 8812 context.type = eContextAdjustBaseRegister; 8813 if (increment) { 8814 context.SetOffset(8); 8815 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8816 Rn + 8)) 8817 return false; 8818 } else { 8819 context.SetOffset(-8); 8820 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8821 Rn - 8)) 8822 return false; 8823 } 8824 } // if wback 8825 } 8826 } // if ConditionPassed() 8827 return true; 8828 } 8829 8830 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a 8831 // register value and an immediate value, and writes the result to the 8832 // destination register. It can optionally update the condition flags based on 8833 // the result. 8834 bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode, 8835 const ARMEncoding encoding) { 8836 #if 0 8837 // ARM pseudo code... 8838 if ConditionPassed() then 8839 EncodingSpecificOperations(); 8840 result = R[n] EOR imm32; 8841 if d == 15 then // Can only occur for ARM encoding 8842 ALUWritePC(result); // setflags is always FALSE here 8843 else 8844 R[d] = result; 8845 if setflags then 8846 APSR.N = result<31>; 8847 APSR.Z = IsZeroBit(result); 8848 APSR.C = carry; 8849 // APSR.V unchanged 8850 #endif 8851 8852 bool success = false; 8853 8854 if (ConditionPassed(opcode)) { 8855 uint32_t Rd, Rn; 8856 uint32_t 8857 imm32; // the immediate value to be ORed to the value obtained from Rn 8858 bool setflags; 8859 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8860 switch (encoding) { 8861 case eEncodingT1: 8862 Rd = Bits32(opcode, 11, 8); 8863 Rn = Bits32(opcode, 19, 16); 8864 setflags = BitIsSet(opcode, 20); 8865 imm32 = ThumbExpandImm_C( 8866 opcode, APSR_C, 8867 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8868 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8869 if (Rd == 15 && setflags) 8870 return EmulateTEQImm(opcode, eEncodingT1); 8871 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8872 return false; 8873 break; 8874 case eEncodingA1: 8875 Rd = Bits32(opcode, 15, 12); 8876 Rn = Bits32(opcode, 19, 16); 8877 setflags = BitIsSet(opcode, 20); 8878 imm32 = 8879 ARMExpandImm_C(opcode, APSR_C, 8880 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8881 8882 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8883 // instructions; 8884 if (Rd == 15 && setflags) 8885 return EmulateSUBSPcLrEtc(opcode, encoding); 8886 break; 8887 default: 8888 return false; 8889 } 8890 8891 // Read the first operand. 8892 uint32_t val1 = ReadCoreReg(Rn, &success); 8893 if (!success) 8894 return false; 8895 8896 uint32_t result = val1 ^ imm32; 8897 8898 EmulateInstruction::Context context; 8899 context.type = EmulateInstruction::eContextImmediate; 8900 context.SetNoArgs(); 8901 8902 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8903 return false; 8904 } 8905 return true; 8906 } 8907 8908 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a 8909 // register value and an optionally-shifted register value, and writes the 8910 // result to the destination register. It can optionally update the condition 8911 // flags based on the result. 8912 bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode, 8913 const ARMEncoding encoding) { 8914 #if 0 8915 // ARM pseudo code... 8916 if ConditionPassed() then 8917 EncodingSpecificOperations(); 8918 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8919 result = R[n] EOR shifted; 8920 if d == 15 then // Can only occur for ARM encoding 8921 ALUWritePC(result); // setflags is always FALSE here 8922 else 8923 R[d] = result; 8924 if setflags then 8925 APSR.N = result<31>; 8926 APSR.Z = IsZeroBit(result); 8927 APSR.C = carry; 8928 // APSR.V unchanged 8929 #endif 8930 8931 bool success = false; 8932 8933 if (ConditionPassed(opcode)) { 8934 uint32_t Rd, Rn, Rm; 8935 ARM_ShifterType shift_t; 8936 uint32_t shift_n; // the shift applied to the value read from Rm 8937 bool setflags; 8938 uint32_t carry; 8939 switch (encoding) { 8940 case eEncodingT1: 8941 Rd = Rn = Bits32(opcode, 2, 0); 8942 Rm = Bits32(opcode, 5, 3); 8943 setflags = !InITBlock(); 8944 shift_t = SRType_LSL; 8945 shift_n = 0; 8946 break; 8947 case eEncodingT2: 8948 Rd = Bits32(opcode, 11, 8); 8949 Rn = Bits32(opcode, 19, 16); 8950 Rm = Bits32(opcode, 3, 0); 8951 setflags = BitIsSet(opcode, 20); 8952 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8953 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8954 if (Rd == 15 && setflags) 8955 return EmulateTEQReg(opcode, eEncodingT1); 8956 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8957 return false; 8958 break; 8959 case eEncodingA1: 8960 Rd = Bits32(opcode, 15, 12); 8961 Rn = Bits32(opcode, 19, 16); 8962 Rm = Bits32(opcode, 3, 0); 8963 setflags = BitIsSet(opcode, 20); 8964 shift_n = DecodeImmShiftARM(opcode, shift_t); 8965 8966 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8967 // instructions; 8968 if (Rd == 15 && setflags) 8969 return EmulateSUBSPcLrEtc(opcode, encoding); 8970 break; 8971 default: 8972 return false; 8973 } 8974 8975 // Read the first operand. 8976 uint32_t val1 = ReadCoreReg(Rn, &success); 8977 if (!success) 8978 return false; 8979 8980 // Read the second operand. 8981 uint32_t val2 = ReadCoreReg(Rm, &success); 8982 if (!success) 8983 return false; 8984 8985 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8986 if (!success) 8987 return false; 8988 uint32_t result = val1 ^ shifted; 8989 8990 EmulateInstruction::Context context; 8991 context.type = EmulateInstruction::eContextImmediate; 8992 context.SetNoArgs(); 8993 8994 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8995 return false; 8996 } 8997 return true; 8998 } 8999 9000 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value 9001 // and an immediate value, and writes the result to the destination register. 9002 // It can optionally update the condition flags based on the result. 9003 bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode, 9004 const ARMEncoding encoding) { 9005 #if 0 9006 // ARM pseudo code... 9007 if ConditionPassed() then 9008 EncodingSpecificOperations(); 9009 result = R[n] OR imm32; 9010 if d == 15 then // Can only occur for ARM encoding 9011 ALUWritePC(result); // setflags is always FALSE here 9012 else 9013 R[d] = result; 9014 if setflags then 9015 APSR.N = result<31>; 9016 APSR.Z = IsZeroBit(result); 9017 APSR.C = carry; 9018 // APSR.V unchanged 9019 #endif 9020 9021 bool success = false; 9022 9023 if (ConditionPassed(opcode)) { 9024 uint32_t Rd, Rn; 9025 uint32_t 9026 imm32; // the immediate value to be ORed to the value obtained from Rn 9027 bool setflags; 9028 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9029 switch (encoding) { 9030 case eEncodingT1: 9031 Rd = Bits32(opcode, 11, 8); 9032 Rn = Bits32(opcode, 19, 16); 9033 setflags = BitIsSet(opcode, 20); 9034 imm32 = ThumbExpandImm_C( 9035 opcode, APSR_C, 9036 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9037 // if Rn == '1111' then SEE MOV (immediate); 9038 if (Rn == 15) 9039 return EmulateMOVRdImm(opcode, eEncodingT2); 9040 if (BadReg(Rd) || Rn == 13) 9041 return false; 9042 break; 9043 case eEncodingA1: 9044 Rd = Bits32(opcode, 15, 12); 9045 Rn = Bits32(opcode, 19, 16); 9046 setflags = BitIsSet(opcode, 20); 9047 imm32 = 9048 ARMExpandImm_C(opcode, APSR_C, 9049 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9050 9051 if (Rd == 15 && setflags) 9052 return EmulateSUBSPcLrEtc(opcode, encoding); 9053 break; 9054 default: 9055 return false; 9056 } 9057 9058 // Read the first operand. 9059 uint32_t val1 = ReadCoreReg(Rn, &success); 9060 if (!success) 9061 return false; 9062 9063 uint32_t result = val1 | imm32; 9064 9065 EmulateInstruction::Context context; 9066 context.type = EmulateInstruction::eContextImmediate; 9067 context.SetNoArgs(); 9068 9069 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9070 return false; 9071 } 9072 return true; 9073 } 9074 9075 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value 9076 // and an optionally-shifted register value, and writes the result to the 9077 // destination register. It can optionally update the condition flags based on 9078 // the result. 9079 bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode, 9080 const ARMEncoding encoding) { 9081 #if 0 9082 // ARM pseudo code... 9083 if ConditionPassed() then 9084 EncodingSpecificOperations(); 9085 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9086 result = R[n] OR shifted; 9087 if d == 15 then // Can only occur for ARM encoding 9088 ALUWritePC(result); // setflags is always FALSE here 9089 else 9090 R[d] = result; 9091 if setflags then 9092 APSR.N = result<31>; 9093 APSR.Z = IsZeroBit(result); 9094 APSR.C = carry; 9095 // APSR.V unchanged 9096 #endif 9097 9098 bool success = false; 9099 9100 if (ConditionPassed(opcode)) { 9101 uint32_t Rd, Rn, Rm; 9102 ARM_ShifterType shift_t; 9103 uint32_t shift_n; // the shift applied to the value read from Rm 9104 bool setflags; 9105 uint32_t carry; 9106 switch (encoding) { 9107 case eEncodingT1: 9108 Rd = Rn = Bits32(opcode, 2, 0); 9109 Rm = Bits32(opcode, 5, 3); 9110 setflags = !InITBlock(); 9111 shift_t = SRType_LSL; 9112 shift_n = 0; 9113 break; 9114 case eEncodingT2: 9115 Rd = Bits32(opcode, 11, 8); 9116 Rn = Bits32(opcode, 19, 16); 9117 Rm = Bits32(opcode, 3, 0); 9118 setflags = BitIsSet(opcode, 20); 9119 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9120 // if Rn == '1111' then SEE MOV (register); 9121 if (Rn == 15) 9122 return EmulateMOVRdRm(opcode, eEncodingT3); 9123 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 9124 return false; 9125 break; 9126 case eEncodingA1: 9127 Rd = Bits32(opcode, 15, 12); 9128 Rn = Bits32(opcode, 19, 16); 9129 Rm = Bits32(opcode, 3, 0); 9130 setflags = BitIsSet(opcode, 20); 9131 shift_n = DecodeImmShiftARM(opcode, shift_t); 9132 9133 if (Rd == 15 && setflags) 9134 return EmulateSUBSPcLrEtc(opcode, encoding); 9135 break; 9136 default: 9137 return false; 9138 } 9139 9140 // Read the first operand. 9141 uint32_t val1 = ReadCoreReg(Rn, &success); 9142 if (!success) 9143 return false; 9144 9145 // Read the second operand. 9146 uint32_t val2 = ReadCoreReg(Rm, &success); 9147 if (!success) 9148 return false; 9149 9150 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9151 if (!success) 9152 return false; 9153 uint32_t result = val1 | shifted; 9154 9155 EmulateInstruction::Context context; 9156 context.type = EmulateInstruction::eContextImmediate; 9157 context.SetNoArgs(); 9158 9159 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9160 return false; 9161 } 9162 return true; 9163 } 9164 9165 // Reverse Subtract (immediate) subtracts a register value from an immediate 9166 // value, and writes the result to the destination register. It can optionally 9167 // update the condition flags based on the result. 9168 bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode, 9169 const ARMEncoding encoding) { 9170 #if 0 9171 // ARM pseudo code... 9172 if ConditionPassed() then 9173 EncodingSpecificOperations(); 9174 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 9175 if d == 15 then // Can only occur for ARM encoding 9176 ALUWritePC(result); // setflags is always FALSE here 9177 else 9178 R[d] = result; 9179 if setflags then 9180 APSR.N = result<31>; 9181 APSR.Z = IsZeroBit(result); 9182 APSR.C = carry; 9183 APSR.V = overflow; 9184 #endif 9185 9186 bool success = false; 9187 9188 uint32_t Rd; // the destination register 9189 uint32_t Rn; // the first operand 9190 bool setflags; 9191 uint32_t 9192 imm32; // the immediate value to be added to the value obtained from Rn 9193 switch (encoding) { 9194 case eEncodingT1: 9195 Rd = Bits32(opcode, 2, 0); 9196 Rn = Bits32(opcode, 5, 3); 9197 setflags = !InITBlock(); 9198 imm32 = 0; 9199 break; 9200 case eEncodingT2: 9201 Rd = Bits32(opcode, 11, 8); 9202 Rn = Bits32(opcode, 19, 16); 9203 setflags = BitIsSet(opcode, 20); 9204 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9205 if (BadReg(Rd) || BadReg(Rn)) 9206 return false; 9207 break; 9208 case eEncodingA1: 9209 Rd = Bits32(opcode, 15, 12); 9210 Rn = Bits32(opcode, 19, 16); 9211 setflags = BitIsSet(opcode, 20); 9212 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9213 9214 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9215 // instructions; 9216 if (Rd == 15 && setflags) 9217 return EmulateSUBSPcLrEtc(opcode, encoding); 9218 break; 9219 default: 9220 return false; 9221 } 9222 // Read the register value from the operand register Rn. 9223 uint32_t reg_val = ReadCoreReg(Rn, &success); 9224 if (!success) 9225 return false; 9226 9227 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 9228 9229 EmulateInstruction::Context context; 9230 context.type = EmulateInstruction::eContextImmediate; 9231 context.SetNoArgs(); 9232 9233 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9234 res.carry_out, res.overflow); 9235 } 9236 9237 // Reverse Subtract (register) subtracts a register value from an optionally- 9238 // shifted register value, and writes the result to the destination register. 9239 // It can optionally update the condition flags based on the result. 9240 bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode, 9241 const ARMEncoding encoding) { 9242 #if 0 9243 // ARM pseudo code... 9244 if ConditionPassed() then 9245 EncodingSpecificOperations(); 9246 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9247 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 9248 if d == 15 then // Can only occur for ARM encoding 9249 ALUWritePC(result); // setflags is always FALSE here 9250 else 9251 R[d] = result; 9252 if setflags then 9253 APSR.N = result<31>; 9254 APSR.Z = IsZeroBit(result); 9255 APSR.C = carry; 9256 APSR.V = overflow; 9257 #endif 9258 9259 bool success = false; 9260 9261 uint32_t Rd; // the destination register 9262 uint32_t Rn; // the first operand 9263 uint32_t Rm; // the second operand 9264 bool setflags; 9265 ARM_ShifterType shift_t; 9266 uint32_t shift_n; // the shift applied to the value read from Rm 9267 switch (encoding) { 9268 case eEncodingT1: 9269 Rd = Bits32(opcode, 11, 8); 9270 Rn = Bits32(opcode, 19, 16); 9271 Rm = Bits32(opcode, 3, 0); 9272 setflags = BitIsSet(opcode, 20); 9273 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9274 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 9275 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9276 return false; 9277 break; 9278 case eEncodingA1: 9279 Rd = Bits32(opcode, 15, 12); 9280 Rn = Bits32(opcode, 19, 16); 9281 Rm = Bits32(opcode, 3, 0); 9282 setflags = BitIsSet(opcode, 20); 9283 shift_n = DecodeImmShiftARM(opcode, shift_t); 9284 9285 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9286 // instructions; 9287 if (Rd == 15 && setflags) 9288 return EmulateSUBSPcLrEtc(opcode, encoding); 9289 break; 9290 default: 9291 return false; 9292 } 9293 // Read the register value from register Rn. 9294 uint32_t val1 = ReadCoreReg(Rn, &success); 9295 if (!success) 9296 return false; 9297 9298 // Read the register value from register Rm. 9299 uint32_t val2 = ReadCoreReg(Rm, &success); 9300 if (!success) 9301 return false; 9302 9303 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9304 if (!success) 9305 return false; 9306 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 9307 9308 EmulateInstruction::Context context; 9309 context.type = EmulateInstruction::eContextImmediate; 9310 context.SetNoArgs(); 9311 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9312 res.carry_out, res.overflow); 9313 } 9314 9315 // Reverse Subtract with Carry (immediate) subtracts a register value and the 9316 // value of NOT (Carry flag) from an immediate value, and writes the result to 9317 // the destination register. It can optionally update the condition flags based 9318 // on the result. 9319 bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode, 9320 const ARMEncoding encoding) { 9321 #if 0 9322 // ARM pseudo code... 9323 if ConditionPassed() then 9324 EncodingSpecificOperations(); 9325 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 9326 if d == 15 then 9327 ALUWritePC(result); // setflags is always FALSE here 9328 else 9329 R[d] = result; 9330 if setflags then 9331 APSR.N = result<31>; 9332 APSR.Z = IsZeroBit(result); 9333 APSR.C = carry; 9334 APSR.V = overflow; 9335 #endif 9336 9337 bool success = false; 9338 9339 uint32_t Rd; // the destination register 9340 uint32_t Rn; // the first operand 9341 bool setflags; 9342 uint32_t 9343 imm32; // the immediate value to be added to the value obtained from Rn 9344 switch (encoding) { 9345 case eEncodingA1: 9346 Rd = Bits32(opcode, 15, 12); 9347 Rn = Bits32(opcode, 19, 16); 9348 setflags = BitIsSet(opcode, 20); 9349 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9350 9351 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9352 // instructions; 9353 if (Rd == 15 && setflags) 9354 return EmulateSUBSPcLrEtc(opcode, encoding); 9355 break; 9356 default: 9357 return false; 9358 } 9359 // Read the register value from the operand register Rn. 9360 uint32_t reg_val = ReadCoreReg(Rn, &success); 9361 if (!success) 9362 return false; 9363 9364 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 9365 9366 EmulateInstruction::Context context; 9367 context.type = EmulateInstruction::eContextImmediate; 9368 context.SetNoArgs(); 9369 9370 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9371 res.carry_out, res.overflow); 9372 } 9373 9374 // Reverse Subtract with Carry (register) subtracts a register value and the 9375 // value of NOT (Carry flag) from an optionally-shifted register value, and 9376 // writes the result to the destination register. It can optionally update the 9377 // condition flags based on the result. 9378 bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode, 9379 const ARMEncoding encoding) { 9380 #if 0 9381 // ARM pseudo code... 9382 if ConditionPassed() then 9383 EncodingSpecificOperations(); 9384 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9385 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 9386 if d == 15 then 9387 ALUWritePC(result); // setflags is always FALSE here 9388 else 9389 R[d] = result; 9390 if setflags then 9391 APSR.N = result<31>; 9392 APSR.Z = IsZeroBit(result); 9393 APSR.C = carry; 9394 APSR.V = overflow; 9395 #endif 9396 9397 bool success = false; 9398 9399 uint32_t Rd; // the destination register 9400 uint32_t Rn; // the first operand 9401 uint32_t Rm; // the second operand 9402 bool setflags; 9403 ARM_ShifterType shift_t; 9404 uint32_t shift_n; // the shift applied to the value read from Rm 9405 switch (encoding) { 9406 case eEncodingA1: 9407 Rd = Bits32(opcode, 15, 12); 9408 Rn = Bits32(opcode, 19, 16); 9409 Rm = Bits32(opcode, 3, 0); 9410 setflags = BitIsSet(opcode, 20); 9411 shift_n = DecodeImmShiftARM(opcode, shift_t); 9412 9413 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9414 // instructions; 9415 if (Rd == 15 && setflags) 9416 return EmulateSUBSPcLrEtc(opcode, encoding); 9417 break; 9418 default: 9419 return false; 9420 } 9421 // Read the register value from register Rn. 9422 uint32_t val1 = ReadCoreReg(Rn, &success); 9423 if (!success) 9424 return false; 9425 9426 // Read the register value from register Rm. 9427 uint32_t val2 = ReadCoreReg(Rm, &success); 9428 if (!success) 9429 return false; 9430 9431 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9432 if (!success) 9433 return false; 9434 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 9435 9436 EmulateInstruction::Context context; 9437 context.type = EmulateInstruction::eContextImmediate; 9438 context.SetNoArgs(); 9439 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9440 res.carry_out, res.overflow); 9441 } 9442 9443 // Subtract with Carry (immediate) subtracts an immediate value and the value 9444 // of 9445 // NOT (Carry flag) from a register value, and writes the result to the 9446 // destination register. 9447 // It can optionally update the condition flags based on the result. 9448 bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode, 9449 const ARMEncoding encoding) { 9450 #if 0 9451 // ARM pseudo code... 9452 if ConditionPassed() then 9453 EncodingSpecificOperations(); 9454 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 9455 if d == 15 then // Can only occur for ARM encoding 9456 ALUWritePC(result); // setflags is always FALSE here 9457 else 9458 R[d] = result; 9459 if setflags then 9460 APSR.N = result<31>; 9461 APSR.Z = IsZeroBit(result); 9462 APSR.C = carry; 9463 APSR.V = overflow; 9464 #endif 9465 9466 bool success = false; 9467 9468 uint32_t Rd; // the destination register 9469 uint32_t Rn; // the first operand 9470 bool setflags; 9471 uint32_t 9472 imm32; // the immediate value to be added to the value obtained from Rn 9473 switch (encoding) { 9474 case eEncodingT1: 9475 Rd = Bits32(opcode, 11, 8); 9476 Rn = Bits32(opcode, 19, 16); 9477 setflags = BitIsSet(opcode, 20); 9478 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9479 if (BadReg(Rd) || BadReg(Rn)) 9480 return false; 9481 break; 9482 case eEncodingA1: 9483 Rd = Bits32(opcode, 15, 12); 9484 Rn = Bits32(opcode, 19, 16); 9485 setflags = BitIsSet(opcode, 20); 9486 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9487 9488 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9489 // instructions; 9490 if (Rd == 15 && setflags) 9491 return EmulateSUBSPcLrEtc(opcode, encoding); 9492 break; 9493 default: 9494 return false; 9495 } 9496 // Read the register value from the operand register Rn. 9497 uint32_t reg_val = ReadCoreReg(Rn, &success); 9498 if (!success) 9499 return false; 9500 9501 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9502 9503 EmulateInstruction::Context context; 9504 context.type = EmulateInstruction::eContextImmediate; 9505 context.SetNoArgs(); 9506 9507 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9508 res.carry_out, res.overflow); 9509 } 9510 9511 // Subtract with Carry (register) subtracts an optionally-shifted register 9512 // value and the value of 9513 // NOT (Carry flag) from a register value, and writes the result to the 9514 // destination register. 9515 // It can optionally update the condition flags based on the result. 9516 bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode, 9517 const ARMEncoding encoding) { 9518 #if 0 9519 // ARM pseudo code... 9520 if ConditionPassed() then 9521 EncodingSpecificOperations(); 9522 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9523 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9524 if d == 15 then // Can only occur for ARM encoding 9525 ALUWritePC(result); // setflags is always FALSE here 9526 else 9527 R[d] = result; 9528 if setflags then 9529 APSR.N = result<31>; 9530 APSR.Z = IsZeroBit(result); 9531 APSR.C = carry; 9532 APSR.V = overflow; 9533 #endif 9534 9535 bool success = false; 9536 9537 uint32_t Rd; // the destination register 9538 uint32_t Rn; // the first operand 9539 uint32_t Rm; // the second operand 9540 bool setflags; 9541 ARM_ShifterType shift_t; 9542 uint32_t shift_n; // the shift applied to the value read from Rm 9543 switch (encoding) { 9544 case eEncodingT1: 9545 Rd = Rn = Bits32(opcode, 2, 0); 9546 Rm = Bits32(opcode, 5, 3); 9547 setflags = !InITBlock(); 9548 shift_t = SRType_LSL; 9549 shift_n = 0; 9550 break; 9551 case eEncodingT2: 9552 Rd = Bits32(opcode, 11, 8); 9553 Rn = Bits32(opcode, 19, 16); 9554 Rm = Bits32(opcode, 3, 0); 9555 setflags = BitIsSet(opcode, 20); 9556 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9557 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9558 return false; 9559 break; 9560 case eEncodingA1: 9561 Rd = Bits32(opcode, 15, 12); 9562 Rn = Bits32(opcode, 19, 16); 9563 Rm = Bits32(opcode, 3, 0); 9564 setflags = BitIsSet(opcode, 20); 9565 shift_n = DecodeImmShiftARM(opcode, shift_t); 9566 9567 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9568 // instructions; 9569 if (Rd == 15 && setflags) 9570 return EmulateSUBSPcLrEtc(opcode, encoding); 9571 break; 9572 default: 9573 return false; 9574 } 9575 // Read the register value from register Rn. 9576 uint32_t val1 = ReadCoreReg(Rn, &success); 9577 if (!success) 9578 return false; 9579 9580 // Read the register value from register Rm. 9581 uint32_t val2 = ReadCoreReg(Rm, &success); 9582 if (!success) 9583 return false; 9584 9585 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9586 if (!success) 9587 return false; 9588 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9589 9590 EmulateInstruction::Context context; 9591 context.type = EmulateInstruction::eContextImmediate; 9592 context.SetNoArgs(); 9593 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9594 res.carry_out, res.overflow); 9595 } 9596 9597 // This instruction subtracts an immediate value from a register value, and 9598 // writes the result to the destination register. It can optionally update the 9599 // condition flags based on the result. 9600 bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode, 9601 const ARMEncoding encoding) { 9602 #if 0 9603 // ARM pseudo code... 9604 if ConditionPassed() then 9605 EncodingSpecificOperations(); 9606 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9607 R[d] = result; 9608 if setflags then 9609 APSR.N = result<31>; 9610 APSR.Z = IsZeroBit(result); 9611 APSR.C = carry; 9612 APSR.V = overflow; 9613 #endif 9614 9615 bool success = false; 9616 9617 uint32_t Rd; // the destination register 9618 uint32_t Rn; // the first operand 9619 bool setflags; 9620 uint32_t imm32; // the immediate value to be subtracted from the value 9621 // obtained from Rn 9622 switch (encoding) { 9623 case eEncodingT1: 9624 Rd = Bits32(opcode, 2, 0); 9625 Rn = Bits32(opcode, 5, 3); 9626 setflags = !InITBlock(); 9627 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9628 break; 9629 case eEncodingT2: 9630 Rd = Rn = Bits32(opcode, 10, 8); 9631 setflags = !InITBlock(); 9632 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9633 break; 9634 case eEncodingT3: 9635 Rd = Bits32(opcode, 11, 8); 9636 Rn = Bits32(opcode, 19, 16); 9637 setflags = BitIsSet(opcode, 20); 9638 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9639 9640 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9641 if (Rd == 15 && setflags) 9642 return EmulateCMPImm(opcode, eEncodingT2); 9643 9644 // if Rn == '1101' then SEE SUB (SP minus immediate); 9645 if (Rn == 13) 9646 return EmulateSUBSPImm(opcode, eEncodingT2); 9647 9648 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9649 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9650 return false; 9651 break; 9652 case eEncodingT4: 9653 Rd = Bits32(opcode, 11, 8); 9654 Rn = Bits32(opcode, 19, 16); 9655 setflags = BitIsSet(opcode, 20); 9656 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9657 9658 // if Rn == '1111' then SEE ADR; 9659 if (Rn == 15) 9660 return EmulateADR(opcode, eEncodingT2); 9661 9662 // if Rn == '1101' then SEE SUB (SP minus immediate); 9663 if (Rn == 13) 9664 return EmulateSUBSPImm(opcode, eEncodingT3); 9665 9666 if (BadReg(Rd)) 9667 return false; 9668 break; 9669 default: 9670 return false; 9671 } 9672 // Read the register value from the operand register Rn. 9673 uint32_t reg_val = ReadCoreReg(Rn, &success); 9674 if (!success) 9675 return false; 9676 9677 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9678 9679 EmulateInstruction::Context context; 9680 context.type = EmulateInstruction::eContextImmediate; 9681 context.SetNoArgs(); 9682 9683 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9684 res.carry_out, res.overflow); 9685 } 9686 9687 // This instruction subtracts an immediate value from a register value, and 9688 // writes the result to the destination register. It can optionally update the 9689 // condition flags based on the result. 9690 bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode, 9691 const ARMEncoding encoding) { 9692 #if 0 9693 // ARM pseudo code... 9694 if ConditionPassed() then 9695 EncodingSpecificOperations(); 9696 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9697 if d == 15 then 9698 ALUWritePC(result); // setflags is always FALSE here 9699 else 9700 R[d] = result; 9701 if setflags then 9702 APSR.N = result<31>; 9703 APSR.Z = IsZeroBit(result); 9704 APSR.C = carry; 9705 APSR.V = overflow; 9706 #endif 9707 9708 bool success = false; 9709 9710 if (ConditionPassed(opcode)) { 9711 uint32_t Rd; // the destination register 9712 uint32_t Rn; // the first operand 9713 bool setflags; 9714 uint32_t imm32; // the immediate value to be subtracted from the value 9715 // obtained from Rn 9716 switch (encoding) { 9717 case eEncodingA1: 9718 Rd = Bits32(opcode, 15, 12); 9719 Rn = Bits32(opcode, 19, 16); 9720 setflags = BitIsSet(opcode, 20); 9721 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9722 9723 // if Rn == '1111' && S == '0' then SEE ADR; 9724 if (Rn == 15 && !setflags) 9725 return EmulateADR(opcode, eEncodingA2); 9726 9727 // if Rn == '1101' then SEE SUB (SP minus immediate); 9728 if (Rn == 13) 9729 return EmulateSUBSPImm(opcode, eEncodingA1); 9730 9731 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9732 // instructions; 9733 if (Rd == 15 && setflags) 9734 return EmulateSUBSPcLrEtc(opcode, encoding); 9735 break; 9736 default: 9737 return false; 9738 } 9739 // Read the register value from the operand register Rn. 9740 uint32_t reg_val = ReadCoreReg(Rn, &success); 9741 if (!success) 9742 return false; 9743 9744 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9745 9746 EmulateInstruction::Context context; 9747 if (Rd == 13) 9748 context.type = EmulateInstruction::eContextAdjustStackPointer; 9749 else 9750 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9751 9752 RegisterInfo dwarf_reg; 9753 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 9754 int64_t imm32_signed = imm32; 9755 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed); 9756 9757 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9758 res.carry_out, res.overflow)) 9759 return false; 9760 } 9761 return true; 9762 } 9763 9764 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a 9765 // register value and an immediate value. It updates the condition flags based 9766 // on the result, and discards the result. 9767 bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode, 9768 const ARMEncoding encoding) { 9769 #if 0 9770 // ARM pseudo code... 9771 if ConditionPassed() then 9772 EncodingSpecificOperations(); 9773 result = R[n] EOR imm32; 9774 APSR.N = result<31>; 9775 APSR.Z = IsZeroBit(result); 9776 APSR.C = carry; 9777 // APSR.V unchanged 9778 #endif 9779 9780 bool success = false; 9781 9782 if (ConditionPassed(opcode)) { 9783 uint32_t Rn; 9784 uint32_t 9785 imm32; // the immediate value to be ANDed to the value obtained from Rn 9786 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9787 switch (encoding) { 9788 case eEncodingT1: 9789 Rn = Bits32(opcode, 19, 16); 9790 imm32 = ThumbExpandImm_C( 9791 opcode, APSR_C, 9792 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9793 if (BadReg(Rn)) 9794 return false; 9795 break; 9796 case eEncodingA1: 9797 Rn = Bits32(opcode, 19, 16); 9798 imm32 = 9799 ARMExpandImm_C(opcode, APSR_C, 9800 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9801 break; 9802 default: 9803 return false; 9804 } 9805 9806 // Read the first operand. 9807 uint32_t val1 = ReadCoreReg(Rn, &success); 9808 if (!success) 9809 return false; 9810 9811 uint32_t result = val1 ^ imm32; 9812 9813 EmulateInstruction::Context context; 9814 context.type = EmulateInstruction::eContextImmediate; 9815 context.SetNoArgs(); 9816 9817 if (!WriteFlags(context, result, carry)) 9818 return false; 9819 } 9820 return true; 9821 } 9822 9823 // Test Equivalence (register) performs a bitwise exclusive OR operation on a 9824 // register value and an optionally-shifted register value. It updates the 9825 // condition flags based on the result, and discards the result. 9826 bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode, 9827 const ARMEncoding encoding) { 9828 #if 0 9829 // ARM pseudo code... 9830 if ConditionPassed() then 9831 EncodingSpecificOperations(); 9832 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9833 result = R[n] EOR shifted; 9834 APSR.N = result<31>; 9835 APSR.Z = IsZeroBit(result); 9836 APSR.C = carry; 9837 // APSR.V unchanged 9838 #endif 9839 9840 bool success = false; 9841 9842 if (ConditionPassed(opcode)) { 9843 uint32_t Rn, Rm; 9844 ARM_ShifterType shift_t; 9845 uint32_t shift_n; // the shift applied to the value read from Rm 9846 uint32_t carry; 9847 switch (encoding) { 9848 case eEncodingT1: 9849 Rn = Bits32(opcode, 19, 16); 9850 Rm = Bits32(opcode, 3, 0); 9851 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9852 if (BadReg(Rn) || BadReg(Rm)) 9853 return false; 9854 break; 9855 case eEncodingA1: 9856 Rn = Bits32(opcode, 19, 16); 9857 Rm = Bits32(opcode, 3, 0); 9858 shift_n = DecodeImmShiftARM(opcode, shift_t); 9859 break; 9860 default: 9861 return false; 9862 } 9863 9864 // Read the first operand. 9865 uint32_t val1 = ReadCoreReg(Rn, &success); 9866 if (!success) 9867 return false; 9868 9869 // Read the second operand. 9870 uint32_t val2 = ReadCoreReg(Rm, &success); 9871 if (!success) 9872 return false; 9873 9874 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9875 if (!success) 9876 return false; 9877 uint32_t result = val1 ^ shifted; 9878 9879 EmulateInstruction::Context context; 9880 context.type = EmulateInstruction::eContextImmediate; 9881 context.SetNoArgs(); 9882 9883 if (!WriteFlags(context, result, carry)) 9884 return false; 9885 } 9886 return true; 9887 } 9888 9889 // Test (immediate) performs a bitwise AND operation on a register value and an 9890 // immediate value. It updates the condition flags based on the result, and 9891 // discards the result. 9892 bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode, 9893 const ARMEncoding encoding) { 9894 #if 0 9895 // ARM pseudo code... 9896 if ConditionPassed() then 9897 EncodingSpecificOperations(); 9898 result = R[n] AND imm32; 9899 APSR.N = result<31>; 9900 APSR.Z = IsZeroBit(result); 9901 APSR.C = carry; 9902 // APSR.V unchanged 9903 #endif 9904 9905 bool success = false; 9906 9907 if (ConditionPassed(opcode)) { 9908 uint32_t Rn; 9909 uint32_t 9910 imm32; // the immediate value to be ANDed to the value obtained from Rn 9911 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9912 switch (encoding) { 9913 case eEncodingT1: 9914 Rn = Bits32(opcode, 19, 16); 9915 imm32 = ThumbExpandImm_C( 9916 opcode, APSR_C, 9917 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9918 if (BadReg(Rn)) 9919 return false; 9920 break; 9921 case eEncodingA1: 9922 Rn = Bits32(opcode, 19, 16); 9923 imm32 = 9924 ARMExpandImm_C(opcode, APSR_C, 9925 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9926 break; 9927 default: 9928 return false; 9929 } 9930 9931 // Read the first operand. 9932 uint32_t val1 = ReadCoreReg(Rn, &success); 9933 if (!success) 9934 return false; 9935 9936 uint32_t result = val1 & imm32; 9937 9938 EmulateInstruction::Context context; 9939 context.type = EmulateInstruction::eContextImmediate; 9940 context.SetNoArgs(); 9941 9942 if (!WriteFlags(context, result, carry)) 9943 return false; 9944 } 9945 return true; 9946 } 9947 9948 // Test (register) performs a bitwise AND operation on a register value and an 9949 // optionally-shifted register value. It updates the condition flags based on 9950 // the result, and discards the result. 9951 bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode, 9952 const ARMEncoding encoding) { 9953 #if 0 9954 // ARM pseudo code... 9955 if ConditionPassed() then 9956 EncodingSpecificOperations(); 9957 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9958 result = R[n] AND shifted; 9959 APSR.N = result<31>; 9960 APSR.Z = IsZeroBit(result); 9961 APSR.C = carry; 9962 // APSR.V unchanged 9963 #endif 9964 9965 bool success = false; 9966 9967 if (ConditionPassed(opcode)) { 9968 uint32_t Rn, Rm; 9969 ARM_ShifterType shift_t; 9970 uint32_t shift_n; // the shift applied to the value read from Rm 9971 uint32_t carry; 9972 switch (encoding) { 9973 case eEncodingT1: 9974 Rn = Bits32(opcode, 2, 0); 9975 Rm = Bits32(opcode, 5, 3); 9976 shift_t = SRType_LSL; 9977 shift_n = 0; 9978 break; 9979 case eEncodingT2: 9980 Rn = Bits32(opcode, 19, 16); 9981 Rm = Bits32(opcode, 3, 0); 9982 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9983 if (BadReg(Rn) || BadReg(Rm)) 9984 return false; 9985 break; 9986 case eEncodingA1: 9987 Rn = Bits32(opcode, 19, 16); 9988 Rm = Bits32(opcode, 3, 0); 9989 shift_n = DecodeImmShiftARM(opcode, shift_t); 9990 break; 9991 default: 9992 return false; 9993 } 9994 9995 // Read the first operand. 9996 uint32_t val1 = ReadCoreReg(Rn, &success); 9997 if (!success) 9998 return false; 9999 10000 // Read the second operand. 10001 uint32_t val2 = ReadCoreReg(Rm, &success); 10002 if (!success) 10003 return false; 10004 10005 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 10006 if (!success) 10007 return false; 10008 uint32_t result = val1 & shifted; 10009 10010 EmulateInstruction::Context context; 10011 context.type = EmulateInstruction::eContextImmediate; 10012 context.SetNoArgs(); 10013 10014 if (!WriteFlags(context, result, carry)) 10015 return false; 10016 } 10017 return true; 10018 } 10019 10020 // A8.6.216 SUB (SP minus register) 10021 bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode, 10022 const ARMEncoding encoding) { 10023 #if 0 10024 if ConditionPassed() then 10025 EncodingSpecificOperations(); 10026 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10027 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10028 if d == 15 then // Can only occur for ARM encoding 10029 ALUWritePC(result); // setflags is always FALSE here 10030 else 10031 R[d] = result; 10032 if setflags then 10033 APSR.N = result<31>; 10034 APSR.Z = IsZeroBit(result); 10035 APSR.C = carry; 10036 APSR.V = overflow; 10037 #endif 10038 10039 bool success = false; 10040 10041 if (ConditionPassed(opcode)) { 10042 uint32_t d; 10043 uint32_t m; 10044 bool setflags; 10045 ARM_ShifterType shift_t; 10046 uint32_t shift_n; 10047 10048 switch (encoding) { 10049 case eEncodingT1: 10050 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10051 d = Bits32(opcode, 11, 8); 10052 m = Bits32(opcode, 3, 0); 10053 setflags = BitIsSet(opcode, 20); 10054 10055 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10056 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10057 10058 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then 10059 // UNPREDICTABLE; 10060 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 10061 return false; 10062 10063 // if d == 15 || BadReg(m) then UNPREDICTABLE; 10064 if ((d == 15) || BadReg(m)) 10065 return false; 10066 break; 10067 10068 case eEncodingA1: 10069 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10070 d = Bits32(opcode, 15, 12); 10071 m = Bits32(opcode, 3, 0); 10072 setflags = BitIsSet(opcode, 20); 10073 10074 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10075 // instructions; 10076 if (d == 15 && setflags) 10077 EmulateSUBSPcLrEtc(opcode, encoding); 10078 10079 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10080 shift_n = DecodeImmShiftARM(opcode, shift_t); 10081 break; 10082 10083 default: 10084 return false; 10085 } 10086 10087 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10088 uint32_t Rm = ReadCoreReg(m, &success); 10089 if (!success) 10090 return false; 10091 10092 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10093 if (!success) 10094 return false; 10095 10096 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10097 uint32_t sp_val = ReadCoreReg(SP_REG, &success); 10098 if (!success) 10099 return false; 10100 10101 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1); 10102 10103 EmulateInstruction::Context context; 10104 context.type = eContextArithmetic; 10105 RegisterInfo sp_reg; 10106 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 10107 RegisterInfo dwarf_reg; 10108 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 10109 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg); 10110 10111 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10112 res.carry_out, res.overflow)) 10113 return false; 10114 } 10115 return true; 10116 } 10117 10118 // A8.6.7 ADD (register-shifted register) 10119 bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode, 10120 const ARMEncoding encoding) { 10121 #if 0 10122 if ConditionPassed() then 10123 EncodingSpecificOperations(); 10124 shift_n = UInt(R[s]<7:0>); 10125 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10126 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10127 R[d] = result; 10128 if setflags then 10129 APSR.N = result<31>; 10130 APSR.Z = IsZeroBit(result); 10131 APSR.C = carry; 10132 APSR.V = overflow; 10133 #endif 10134 10135 bool success = false; 10136 10137 if (ConditionPassed(opcode)) { 10138 uint32_t d; 10139 uint32_t n; 10140 uint32_t m; 10141 uint32_t s; 10142 bool setflags; 10143 ARM_ShifterType shift_t; 10144 10145 switch (encoding) { 10146 case eEncodingA1: 10147 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 10148 d = Bits32(opcode, 15, 12); 10149 n = Bits32(opcode, 19, 16); 10150 m = Bits32(opcode, 3, 0); 10151 s = Bits32(opcode, 11, 8); 10152 10153 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 10154 setflags = BitIsSet(opcode, 20); 10155 shift_t = DecodeRegShift(Bits32(opcode, 6, 5)); 10156 10157 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 10158 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 10159 return false; 10160 break; 10161 10162 default: 10163 return false; 10164 } 10165 10166 // shift_n = UInt(R[s]<7:0>); 10167 uint32_t Rs = ReadCoreReg(s, &success); 10168 if (!success) 10169 return false; 10170 10171 uint32_t shift_n = Bits32(Rs, 7, 0); 10172 10173 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10174 uint32_t Rm = ReadCoreReg(m, &success); 10175 if (!success) 10176 return false; 10177 10178 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10179 if (!success) 10180 return false; 10181 10182 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10183 uint32_t Rn = ReadCoreReg(n, &success); 10184 if (!success) 10185 return false; 10186 10187 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0); 10188 10189 // R[d] = result; 10190 EmulateInstruction::Context context; 10191 context.type = eContextArithmetic; 10192 RegisterInfo reg_n; 10193 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10194 RegisterInfo reg_m; 10195 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10196 10197 context.SetRegisterRegisterOperands(reg_n, reg_m); 10198 10199 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 10200 res.result)) 10201 return false; 10202 10203 // if setflags then 10204 // APSR.N = result<31>; 10205 // APSR.Z = IsZeroBit(result); 10206 // APSR.C = carry; 10207 // APSR.V = overflow; 10208 if (setflags) 10209 return WriteFlags(context, res.result, res.carry_out, res.overflow); 10210 } 10211 return true; 10212 } 10213 10214 // A8.6.213 SUB (register) 10215 bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode, 10216 const ARMEncoding encoding) { 10217 #if 0 10218 if ConditionPassed() then 10219 EncodingSpecificOperations(); 10220 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10221 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10222 if d == 15 then // Can only occur for ARM encoding 10223 ALUWritePC(result); // setflags is always FALSE here 10224 else 10225 R[d] = result; 10226 if setflags then 10227 APSR.N = result<31>; 10228 APSR.Z = IsZeroBit(result); 10229 APSR.C = carry; 10230 APSR.V = overflow; 10231 #endif 10232 10233 bool success = false; 10234 10235 if (ConditionPassed(opcode)) { 10236 uint32_t d; 10237 uint32_t n; 10238 uint32_t m; 10239 bool setflags; 10240 ARM_ShifterType shift_t; 10241 uint32_t shift_n; 10242 10243 switch (encoding) { 10244 case eEncodingT1: 10245 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 10246 d = Bits32(opcode, 2, 0); 10247 n = Bits32(opcode, 5, 3); 10248 m = Bits32(opcode, 8, 6); 10249 setflags = !InITBlock(); 10250 10251 // (shift_t, shift_n) = (SRType_LSL, 0); 10252 shift_t = SRType_LSL; 10253 shift_n = 0; 10254 10255 break; 10256 10257 case eEncodingT2: 10258 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 10259 d = Bits32(opcode, 11, 8); 10260 n = Bits32(opcode, 19, 16); 10261 m = Bits32(opcode, 3, 0); 10262 setflags = BitIsSet(opcode, 20); 10263 10264 // if Rd == "1111" && S == "1" then SEE CMP (register); 10265 if (d == 15 && setflags == 1) 10266 return EmulateCMPImm(opcode, eEncodingT3); 10267 10268 // if Rn == "1101" then SEE SUB (SP minus register); 10269 if (n == 13) 10270 return EmulateSUBSPReg(opcode, eEncodingT1); 10271 10272 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10273 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10274 10275 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then 10276 // UNPREDICTABLE; 10277 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) || 10278 BadReg(m)) 10279 return false; 10280 10281 break; 10282 10283 case eEncodingA1: 10284 // if Rn == '1101' then SEE SUB (SP minus register); 10285 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 10286 d = Bits32(opcode, 15, 12); 10287 n = Bits32(opcode, 19, 16); 10288 m = Bits32(opcode, 3, 0); 10289 setflags = BitIsSet(opcode, 20); 10290 10291 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10292 // instructions; 10293 if ((d == 15) && setflags) 10294 EmulateSUBSPcLrEtc(opcode, encoding); 10295 10296 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10297 shift_n = DecodeImmShiftARM(opcode, shift_t); 10298 10299 break; 10300 10301 default: 10302 return false; 10303 } 10304 10305 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10306 uint32_t Rm = ReadCoreReg(m, &success); 10307 if (!success) 10308 return false; 10309 10310 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10311 if (!success) 10312 return false; 10313 10314 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10315 uint32_t Rn = ReadCoreReg(n, &success); 10316 if (!success) 10317 return false; 10318 10319 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1); 10320 10321 // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result); 10322 // // setflags is always FALSE here else 10323 // R[d] = result; 10324 // if setflags then 10325 // APSR.N = result<31>; 10326 // APSR.Z = IsZeroBit(result); 10327 // APSR.C = carry; 10328 // APSR.V = overflow; 10329 10330 EmulateInstruction::Context context; 10331 context.type = eContextArithmetic; 10332 RegisterInfo reg_n; 10333 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10334 RegisterInfo reg_m; 10335 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10336 context.SetRegisterRegisterOperands(reg_n, reg_m); 10337 10338 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10339 res.carry_out, res.overflow)) 10340 return false; 10341 } 10342 return true; 10343 } 10344 10345 // A8.6.202 STREX 10346 // Store Register Exclusive calculates an address from a base register value 10347 // and an immediate offset, and stores a word from a register to memory if the 10348 // executing processor has exclusive access to the memory addressed. 10349 bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode, 10350 const ARMEncoding encoding) { 10351 #if 0 10352 if ConditionPassed() then 10353 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10354 address = R[n] + imm32; 10355 if ExclusiveMonitorsPass(address,4) then 10356 MemA[address,4] = R[t]; 10357 R[d] = 0; 10358 else 10359 R[d] = 1; 10360 #endif 10361 10362 bool success = false; 10363 10364 if (ConditionPassed(opcode)) { 10365 uint32_t d; 10366 uint32_t t; 10367 uint32_t n; 10368 uint32_t imm32; 10369 const uint32_t addr_byte_size = GetAddressByteSize(); 10370 10371 switch (encoding) { 10372 case eEncodingT1: 10373 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = 10374 // ZeroExtend(imm8:'00', 10375 // 32); 10376 d = Bits32(opcode, 11, 8); 10377 t = Bits32(opcode, 15, 12); 10378 n = Bits32(opcode, 19, 16); 10379 imm32 = Bits32(opcode, 7, 0) << 2; 10380 10381 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 10382 if (BadReg(d) || BadReg(t) || (n == 15)) 10383 return false; 10384 10385 // if d == n || d == t then UNPREDICTABLE; 10386 if ((d == n) || (d == t)) 10387 return false; 10388 10389 break; 10390 10391 case eEncodingA1: 10392 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero 10393 // offset 10394 d = Bits32(opcode, 15, 12); 10395 t = Bits32(opcode, 3, 0); 10396 n = Bits32(opcode, 19, 16); 10397 imm32 = 0; 10398 10399 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 10400 if ((d == 15) || (t == 15) || (n == 15)) 10401 return false; 10402 10403 // if d == n || d == t then UNPREDICTABLE; 10404 if ((d == n) || (d == t)) 10405 return false; 10406 10407 break; 10408 10409 default: 10410 return false; 10411 } 10412 10413 // address = R[n] + imm32; 10414 uint32_t Rn = ReadCoreReg(n, &success); 10415 if (!success) 10416 return false; 10417 10418 addr_t address = Rn + imm32; 10419 10420 RegisterInfo base_reg; 10421 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10422 RegisterInfo data_reg; 10423 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10424 EmulateInstruction::Context context; 10425 context.type = eContextRegisterStore; 10426 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32); 10427 10428 // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass 10429 // (address, addr_byte_size)) -- For now, for the sake of emulation, we 10430 // will say this 10431 // always return 10432 // true. 10433 if (true) { 10434 // MemA[address,4] = R[t]; 10435 uint32_t Rt = 10436 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 10437 if (!success) 10438 return false; 10439 10440 if (!MemAWrite(context, address, Rt, addr_byte_size)) 10441 return false; 10442 10443 // R[d] = 0; 10444 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 10445 return false; 10446 } 10447 #if 0 // unreachable because if true 10448 else 10449 { 10450 // R[d] = 1; 10451 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 10452 return false; 10453 } 10454 #endif // unreachable because if true 10455 } 10456 return true; 10457 } 10458 10459 // A8.6.197 STRB (immediate, ARM) 10460 bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode, 10461 const ARMEncoding encoding) { 10462 #if 0 10463 if ConditionPassed() then 10464 EncodingSpecificOperations(); 10465 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10466 address = if index then offset_addr else R[n]; 10467 MemU[address,1] = R[t]<7:0>; 10468 if wback then R[n] = offset_addr; 10469 #endif 10470 10471 bool success = false; 10472 10473 if (ConditionPassed(opcode)) { 10474 uint32_t t; 10475 uint32_t n; 10476 uint32_t imm32; 10477 bool index; 10478 bool add; 10479 bool wback; 10480 10481 switch (encoding) { 10482 case eEncodingA1: 10483 // if P == '0' && W == '1' then SEE STRBT; 10484 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10485 t = Bits32(opcode, 15, 12); 10486 n = Bits32(opcode, 19, 16); 10487 imm32 = Bits32(opcode, 11, 0); 10488 10489 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10490 index = BitIsSet(opcode, 24); 10491 add = BitIsSet(opcode, 23); 10492 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10493 10494 // if t == 15 then UNPREDICTABLE; 10495 if (t == 15) 10496 return false; 10497 10498 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10499 if (wback && ((n == 15) || (n == t))) 10500 return false; 10501 10502 break; 10503 10504 default: 10505 return false; 10506 } 10507 10508 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10509 uint32_t Rn = ReadCoreReg(n, &success); 10510 if (!success) 10511 return false; 10512 10513 addr_t offset_addr; 10514 if (add) 10515 offset_addr = Rn + imm32; 10516 else 10517 offset_addr = Rn - imm32; 10518 10519 // address = if index then offset_addr else R[n]; 10520 addr_t address; 10521 if (index) 10522 address = offset_addr; 10523 else 10524 address = Rn; 10525 10526 // MemU[address,1] = R[t]<7:0>; 10527 uint32_t Rt = ReadCoreReg(t, &success); 10528 if (!success) 10529 return false; 10530 10531 RegisterInfo base_reg; 10532 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10533 RegisterInfo data_reg; 10534 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10535 EmulateInstruction::Context context; 10536 context.type = eContextRegisterStore; 10537 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10538 10539 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1)) 10540 return false; 10541 10542 // if wback then R[n] = offset_addr; 10543 if (wback) { 10544 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10545 offset_addr)) 10546 return false; 10547 } 10548 } 10549 return true; 10550 } 10551 10552 // A8.6.194 STR (immediate, ARM) 10553 bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode, 10554 const ARMEncoding encoding) { 10555 #if 0 10556 if ConditionPassed() then 10557 EncodingSpecificOperations(); 10558 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10559 address = if index then offset_addr else R[n]; 10560 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10561 if wback then R[n] = offset_addr; 10562 #endif 10563 10564 bool success = false; 10565 10566 if (ConditionPassed(opcode)) { 10567 uint32_t t; 10568 uint32_t n; 10569 uint32_t imm32; 10570 bool index; 10571 bool add; 10572 bool wback; 10573 10574 const uint32_t addr_byte_size = GetAddressByteSize(); 10575 10576 switch (encoding) { 10577 case eEncodingA1: 10578 // if P == '0' && W == '1' then SEE STRT; 10579 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == 10580 // '000000000100' then SEE PUSH; 10581 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10582 t = Bits32(opcode, 15, 12); 10583 n = Bits32(opcode, 19, 16); 10584 imm32 = Bits32(opcode, 11, 0); 10585 10586 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10587 index = BitIsSet(opcode, 24); 10588 add = BitIsSet(opcode, 23); 10589 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10590 10591 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10592 if (wback && ((n == 15) || (n == t))) 10593 return false; 10594 10595 break; 10596 10597 default: 10598 return false; 10599 } 10600 10601 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10602 uint32_t Rn = ReadCoreReg(n, &success); 10603 if (!success) 10604 return false; 10605 10606 addr_t offset_addr; 10607 if (add) 10608 offset_addr = Rn + imm32; 10609 else 10610 offset_addr = Rn - imm32; 10611 10612 // address = if index then offset_addr else R[n]; 10613 addr_t address; 10614 if (index) 10615 address = offset_addr; 10616 else 10617 address = Rn; 10618 10619 RegisterInfo base_reg; 10620 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10621 RegisterInfo data_reg; 10622 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10623 EmulateInstruction::Context context; 10624 context.type = eContextRegisterStore; 10625 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10626 10627 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10628 uint32_t Rt = ReadCoreReg(t, &success); 10629 if (!success) 10630 return false; 10631 10632 if (t == 15) { 10633 uint32_t pc_value = ReadCoreReg(PC_REG, &success); 10634 if (!success) 10635 return false; 10636 10637 if (!MemUWrite(context, address, pc_value, addr_byte_size)) 10638 return false; 10639 } else { 10640 if (!MemUWrite(context, address, Rt, addr_byte_size)) 10641 return false; 10642 } 10643 10644 // if wback then R[n] = offset_addr; 10645 if (wback) { 10646 context.type = eContextAdjustBaseRegister; 10647 context.SetImmediate(offset_addr); 10648 10649 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10650 offset_addr)) 10651 return false; 10652 } 10653 } 10654 return true; 10655 } 10656 10657 // A8.6.66 LDRD (immediate) 10658 // Load Register Dual (immediate) calculates an address from a base register 10659 // value and an immediate offset, loads two words from memory, and writes them 10660 // to two registers. It can use offset, post-indexed, or pre-indexed 10661 // addressing. 10662 bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode, 10663 const ARMEncoding encoding) { 10664 #if 0 10665 if ConditionPassed() then 10666 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10667 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10668 address = if index then offset_addr else R[n]; 10669 R[t] = MemA[address,4]; 10670 R[t2] = MemA[address+4,4]; 10671 if wback then R[n] = offset_addr; 10672 #endif 10673 10674 bool success = false; 10675 10676 if (ConditionPassed(opcode)) { 10677 uint32_t t; 10678 uint32_t t2; 10679 uint32_t n; 10680 uint32_t imm32; 10681 bool index; 10682 bool add; 10683 bool wback; 10684 10685 switch (encoding) { 10686 case eEncodingT1: 10687 // if P == '0' && W == '0' then SEE 'Related encodings'; 10688 // if Rn == '1111' then SEE LDRD (literal); 10689 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10690 // ZeroExtend(imm8:'00', 32); 10691 t = Bits32(opcode, 15, 12); 10692 t2 = Bits32(opcode, 11, 8); 10693 n = Bits32(opcode, 19, 16); 10694 imm32 = Bits32(opcode, 7, 0) << 2; 10695 10696 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10697 index = BitIsSet(opcode, 24); 10698 add = BitIsSet(opcode, 23); 10699 wback = BitIsSet(opcode, 21); 10700 10701 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10702 if (wback && ((n == t) || (n == t2))) 10703 return false; 10704 10705 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10706 if (BadReg(t) || BadReg(t2) || (t == t2)) 10707 return false; 10708 10709 break; 10710 10711 case eEncodingA1: 10712 // if Rn == '1111' then SEE LDRD (literal); 10713 // if Rt<0> == '1' then UNPREDICTABLE; 10714 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10715 // 32); 10716 t = Bits32(opcode, 15, 12); 10717 if (BitIsSet(t, 0)) 10718 return false; 10719 t2 = t + 1; 10720 n = Bits32(opcode, 19, 16); 10721 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10722 10723 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10724 index = BitIsSet(opcode, 24); 10725 add = BitIsSet(opcode, 23); 10726 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10727 10728 // if P == '0' && W == '1' then UNPREDICTABLE; 10729 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10730 return false; 10731 10732 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10733 if (wback && ((n == t) || (n == t2))) 10734 return false; 10735 10736 // if t2 == 15 then UNPREDICTABLE; 10737 if (t2 == 15) 10738 return false; 10739 10740 break; 10741 10742 default: 10743 return false; 10744 } 10745 10746 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10747 uint32_t Rn = ReadCoreReg(n, &success); 10748 if (!success) 10749 return false; 10750 10751 addr_t offset_addr; 10752 if (add) 10753 offset_addr = Rn + imm32; 10754 else 10755 offset_addr = Rn - imm32; 10756 10757 // address = if index then offset_addr else R[n]; 10758 addr_t address; 10759 if (index) 10760 address = offset_addr; 10761 else 10762 address = Rn; 10763 10764 // R[t] = MemA[address,4]; 10765 RegisterInfo base_reg; 10766 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10767 10768 EmulateInstruction::Context context; 10769 if (n == 13) 10770 context.type = eContextPopRegisterOffStack; 10771 else 10772 context.type = eContextRegisterLoad; 10773 context.SetAddress(address); 10774 10775 const uint32_t addr_byte_size = GetAddressByteSize(); 10776 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10777 if (!success) 10778 return false; 10779 10780 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10781 return false; 10782 10783 // R[t2] = MemA[address+4,4]; 10784 context.SetAddress(address + 4); 10785 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10786 if (!success) 10787 return false; 10788 10789 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10790 data)) 10791 return false; 10792 10793 // if wback then R[n] = offset_addr; 10794 if (wback) { 10795 context.type = eContextAdjustBaseRegister; 10796 context.SetAddress(offset_addr); 10797 10798 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10799 offset_addr)) 10800 return false; 10801 } 10802 } 10803 return true; 10804 } 10805 10806 // A8.6.68 LDRD (register) 10807 // Load Register Dual (register) calculates an address from a base register 10808 // value and a register offset, loads two words from memory, and writes them to 10809 // two registers. It can use offset, post-indexed or pre-indexed addressing. 10810 bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode, 10811 const ARMEncoding encoding) { 10812 #if 0 10813 if ConditionPassed() then 10814 EncodingSpecificOperations(); 10815 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10816 address = if index then offset_addr else R[n]; 10817 R[t] = MemA[address,4]; 10818 R[t2] = MemA[address+4,4]; 10819 if wback then R[n] = offset_addr; 10820 #endif 10821 10822 bool success = false; 10823 10824 if (ConditionPassed(opcode)) { 10825 uint32_t t; 10826 uint32_t t2; 10827 uint32_t n; 10828 uint32_t m; 10829 bool index; 10830 bool add; 10831 bool wback; 10832 10833 switch (encoding) { 10834 case eEncodingA1: 10835 // if Rt<0> == '1' then UNPREDICTABLE; 10836 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10837 t = Bits32(opcode, 15, 12); 10838 if (BitIsSet(t, 0)) 10839 return false; 10840 t2 = t + 1; 10841 n = Bits32(opcode, 19, 16); 10842 m = Bits32(opcode, 3, 0); 10843 10844 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10845 index = BitIsSet(opcode, 24); 10846 add = BitIsSet(opcode, 23); 10847 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10848 10849 // if P == '0' && W == '1' then UNPREDICTABLE; 10850 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10851 return false; 10852 10853 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10854 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10855 return false; 10856 10857 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10858 if (wback && ((n == 15) || (n == t) || (n == t2))) 10859 return false; 10860 10861 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10862 if ((ArchVersion() < 6) && wback && (m == n)) 10863 return false; 10864 break; 10865 10866 default: 10867 return false; 10868 } 10869 10870 uint32_t Rn = ReadCoreReg(n, &success); 10871 if (!success) 10872 return false; 10873 RegisterInfo base_reg; 10874 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10875 10876 uint32_t Rm = ReadCoreReg(m, &success); 10877 if (!success) 10878 return false; 10879 RegisterInfo offset_reg; 10880 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10881 10882 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10883 addr_t offset_addr; 10884 if (add) 10885 offset_addr = Rn + Rm; 10886 else 10887 offset_addr = Rn - Rm; 10888 10889 // address = if index then offset_addr else R[n]; 10890 addr_t address; 10891 if (index) 10892 address = offset_addr; 10893 else 10894 address = Rn; 10895 10896 EmulateInstruction::Context context; 10897 if (n == 13) 10898 context.type = eContextPopRegisterOffStack; 10899 else 10900 context.type = eContextRegisterLoad; 10901 context.SetAddress(address); 10902 10903 // R[t] = MemA[address,4]; 10904 const uint32_t addr_byte_size = GetAddressByteSize(); 10905 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10906 if (!success) 10907 return false; 10908 10909 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10910 return false; 10911 10912 // R[t2] = MemA[address+4,4]; 10913 10914 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10915 if (!success) 10916 return false; 10917 10918 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10919 data)) 10920 return false; 10921 10922 // if wback then R[n] = offset_addr; 10923 if (wback) { 10924 context.type = eContextAdjustBaseRegister; 10925 context.SetAddress(offset_addr); 10926 10927 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10928 offset_addr)) 10929 return false; 10930 } 10931 } 10932 return true; 10933 } 10934 10935 // A8.6.200 STRD (immediate) 10936 // Store Register Dual (immediate) calculates an address from a base register 10937 // value and an immediate offset, and stores two words from two registers to 10938 // memory. It can use offset, post-indexed, or pre-indexed addressing. 10939 bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode, 10940 const ARMEncoding encoding) { 10941 #if 0 10942 if ConditionPassed() then 10943 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10944 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10945 address = if index then offset_addr else R[n]; 10946 MemA[address,4] = R[t]; 10947 MemA[address+4,4] = R[t2]; 10948 if wback then R[n] = offset_addr; 10949 #endif 10950 10951 bool success = false; 10952 10953 if (ConditionPassed(opcode)) { 10954 uint32_t t; 10955 uint32_t t2; 10956 uint32_t n; 10957 uint32_t imm32; 10958 bool index; 10959 bool add; 10960 bool wback; 10961 10962 switch (encoding) { 10963 case eEncodingT1: 10964 // if P == '0' && W == '0' then SEE 'Related encodings'; 10965 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10966 // ZeroExtend(imm8:'00', 32); 10967 t = Bits32(opcode, 15, 12); 10968 t2 = Bits32(opcode, 11, 8); 10969 n = Bits32(opcode, 19, 16); 10970 imm32 = Bits32(opcode, 7, 0) << 2; 10971 10972 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10973 index = BitIsSet(opcode, 24); 10974 add = BitIsSet(opcode, 23); 10975 wback = BitIsSet(opcode, 21); 10976 10977 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10978 if (wback && ((n == t) || (n == t2))) 10979 return false; 10980 10981 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10982 if ((n == 15) || BadReg(t) || BadReg(t2)) 10983 return false; 10984 10985 break; 10986 10987 case eEncodingA1: 10988 // if Rt<0> == '1' then UNPREDICTABLE; 10989 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10990 // 32); 10991 t = Bits32(opcode, 15, 12); 10992 if (BitIsSet(t, 0)) 10993 return false; 10994 10995 t2 = t + 1; 10996 n = Bits32(opcode, 19, 16); 10997 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10998 10999 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11000 index = BitIsSet(opcode, 24); 11001 add = BitIsSet(opcode, 23); 11002 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11003 11004 // if P == '0' && W == '1' then UNPREDICTABLE; 11005 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11006 return false; 11007 11008 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11009 if (wback && ((n == 15) || (n == t) || (n == t2))) 11010 return false; 11011 11012 // if t2 == 15 then UNPREDICTABLE; 11013 if (t2 == 15) 11014 return false; 11015 11016 break; 11017 11018 default: 11019 return false; 11020 } 11021 11022 RegisterInfo base_reg; 11023 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11024 11025 uint32_t Rn = ReadCoreReg(n, &success); 11026 if (!success) 11027 return false; 11028 11029 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11030 addr_t offset_addr; 11031 if (add) 11032 offset_addr = Rn + imm32; 11033 else 11034 offset_addr = Rn - imm32; 11035 11036 // address = if index then offset_addr else R[n]; 11037 addr_t address; 11038 if (index) 11039 address = offset_addr; 11040 else 11041 address = Rn; 11042 11043 // MemA[address,4] = R[t]; 11044 RegisterInfo data_reg; 11045 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11046 11047 uint32_t data = ReadCoreReg(t, &success); 11048 if (!success) 11049 return false; 11050 11051 EmulateInstruction::Context context; 11052 if (n == 13) 11053 context.type = eContextPushRegisterOnStack; 11054 else 11055 context.type = eContextRegisterStore; 11056 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11057 11058 const uint32_t addr_byte_size = GetAddressByteSize(); 11059 11060 if (!MemAWrite(context, address, data, addr_byte_size)) 11061 return false; 11062 11063 // MemA[address+4,4] = R[t2]; 11064 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11065 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11066 (address + 4) - Rn); 11067 11068 data = ReadCoreReg(t2, &success); 11069 if (!success) 11070 return false; 11071 11072 if (!MemAWrite(context, address + 4, data, addr_byte_size)) 11073 return false; 11074 11075 // if wback then R[n] = offset_addr; 11076 if (wback) { 11077 if (n == 13) 11078 context.type = eContextAdjustStackPointer; 11079 else 11080 context.type = eContextAdjustBaseRegister; 11081 context.SetAddress(offset_addr); 11082 11083 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11084 offset_addr)) 11085 return false; 11086 } 11087 } 11088 return true; 11089 } 11090 11091 // A8.6.201 STRD (register) 11092 bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode, 11093 const ARMEncoding encoding) { 11094 #if 0 11095 if ConditionPassed() then 11096 EncodingSpecificOperations(); 11097 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11098 address = if index then offset_addr else R[n]; 11099 MemA[address,4] = R[t]; 11100 MemA[address+4,4] = R[t2]; 11101 if wback then R[n] = offset_addr; 11102 #endif 11103 11104 bool success = false; 11105 11106 if (ConditionPassed(opcode)) { 11107 uint32_t t; 11108 uint32_t t2; 11109 uint32_t n; 11110 uint32_t m; 11111 bool index; 11112 bool add; 11113 bool wback; 11114 11115 switch (encoding) { 11116 case eEncodingA1: 11117 // if Rt<0> == '1' then UNPREDICTABLE; 11118 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 11119 t = Bits32(opcode, 15, 12); 11120 if (BitIsSet(t, 0)) 11121 return false; 11122 11123 t2 = t + 1; 11124 n = Bits32(opcode, 19, 16); 11125 m = Bits32(opcode, 3, 0); 11126 11127 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11128 index = BitIsSet(opcode, 24); 11129 add = BitIsSet(opcode, 23); 11130 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11131 11132 // if P == '0' && W == '1' then UNPREDICTABLE; 11133 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11134 return false; 11135 11136 // if t2 == 15 || m == 15 then UNPREDICTABLE; 11137 if ((t2 == 15) || (m == 15)) 11138 return false; 11139 11140 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11141 if (wback && ((n == 15) || (n == t) || (n == t2))) 11142 return false; 11143 11144 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 11145 if ((ArchVersion() < 6) && wback && (m == n)) 11146 return false; 11147 11148 break; 11149 11150 default: 11151 return false; 11152 } 11153 11154 RegisterInfo base_reg; 11155 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11156 RegisterInfo offset_reg; 11157 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 11158 RegisterInfo data_reg; 11159 11160 uint32_t Rn = ReadCoreReg(n, &success); 11161 if (!success) 11162 return false; 11163 11164 uint32_t Rm = ReadCoreReg(m, &success); 11165 if (!success) 11166 return false; 11167 11168 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11169 addr_t offset_addr; 11170 if (add) 11171 offset_addr = Rn + Rm; 11172 else 11173 offset_addr = Rn - Rm; 11174 11175 // address = if index then offset_addr else R[n]; 11176 addr_t address; 11177 if (index) 11178 address = offset_addr; 11179 else 11180 address = Rn; 11181 // MemA[address,4] = R[t]; 11182 uint32_t Rt = ReadCoreReg(t, &success); 11183 if (!success) 11184 return false; 11185 11186 EmulateInstruction::Context context; 11187 if (t == 13) 11188 context.type = eContextPushRegisterOnStack; 11189 else 11190 context.type = eContextRegisterStore; 11191 11192 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11193 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11194 data_reg); 11195 11196 const uint32_t addr_byte_size = GetAddressByteSize(); 11197 11198 if (!MemAWrite(context, address, Rt, addr_byte_size)) 11199 return false; 11200 11201 // MemA[address+4,4] = R[t2]; 11202 uint32_t Rt2 = ReadCoreReg(t2, &success); 11203 if (!success) 11204 return false; 11205 11206 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11207 11208 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11209 data_reg); 11210 11211 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size)) 11212 return false; 11213 11214 // if wback then R[n] = offset_addr; 11215 if (wback) { 11216 context.type = eContextAdjustBaseRegister; 11217 context.SetAddress(offset_addr); 11218 11219 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11220 offset_addr)) 11221 return false; 11222 } 11223 } 11224 return true; 11225 } 11226 11227 // A8.6.319 VLDM 11228 // Vector Load Multiple loads multiple extension registers from consecutive 11229 // memory locations using an address from an ARM core register. 11230 bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode, 11231 const ARMEncoding encoding) { 11232 #if 0 11233 if ConditionPassed() then 11234 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11235 address = if add then R[n] else R[n]-imm32; 11236 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11237 for r = 0 to regs-1 11238 if single_regs then 11239 S[d+r] = MemA[address,4]; address = address+4; 11240 else 11241 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 11242 // Combine the word-aligned words in the correct order for 11243 // current endianness. 11244 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11245 #endif 11246 11247 bool success = false; 11248 11249 if (ConditionPassed(opcode)) { 11250 bool single_regs; 11251 bool add; 11252 bool wback; 11253 uint32_t d; 11254 uint32_t n; 11255 uint32_t imm32; 11256 uint32_t regs; 11257 11258 switch (encoding) { 11259 case eEncodingT1: 11260 case eEncodingA1: 11261 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11262 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11263 // if P == '1' && W == '0' then SEE VLDR; 11264 // if P == U && W == '1' then UNDEFINED; 11265 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11266 return false; 11267 11268 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11269 // !), 101 (DB with !) 11270 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11271 single_regs = false; 11272 add = BitIsSet(opcode, 23); 11273 wback = BitIsSet(opcode, 21); 11274 11275 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11276 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11277 n = Bits32(opcode, 19, 16); 11278 imm32 = Bits32(opcode, 7, 0) << 2; 11279 11280 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 11281 regs = Bits32(opcode, 7, 0) / 2; 11282 11283 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11284 // UNPREDICTABLE; 11285 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 11286 return false; 11287 11288 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11289 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11290 return false; 11291 11292 break; 11293 11294 case eEncodingT2: 11295 case eEncodingA2: 11296 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11297 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11298 // if P == '1' && W == '0' then SEE VLDR; 11299 // if P == U && W == '1' then UNDEFINED; 11300 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11301 return false; 11302 11303 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11304 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11305 // == '1'); d = 11306 // UInt(Vd:D); n = UInt(Rn); 11307 single_regs = true; 11308 add = BitIsSet(opcode, 23); 11309 wback = BitIsSet(opcode, 21); 11310 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11311 n = Bits32(opcode, 19, 16); 11312 11313 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11314 imm32 = Bits32(opcode, 7, 0) << 2; 11315 regs = Bits32(opcode, 7, 0); 11316 11317 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11318 // UNPREDICTABLE; 11319 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11320 return false; 11321 11322 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11323 if ((regs == 0) || ((d + regs) > 32)) 11324 return false; 11325 break; 11326 11327 default: 11328 return false; 11329 } 11330 11331 RegisterInfo base_reg; 11332 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11333 11334 uint32_t Rn = ReadCoreReg(n, &success); 11335 if (!success) 11336 return false; 11337 11338 // address = if add then R[n] else R[n]-imm32; 11339 addr_t address; 11340 if (add) 11341 address = Rn; 11342 else 11343 address = Rn - imm32; 11344 11345 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11346 EmulateInstruction::Context context; 11347 11348 if (wback) { 11349 uint32_t value; 11350 if (add) 11351 value = Rn + imm32; 11352 else 11353 value = Rn - imm32; 11354 11355 context.type = eContextAdjustBaseRegister; 11356 context.SetImmediateSigned(value - Rn); 11357 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11358 value)) 11359 return false; 11360 } 11361 11362 const uint32_t addr_byte_size = GetAddressByteSize(); 11363 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11364 11365 context.type = eContextRegisterLoad; 11366 11367 // for r = 0 to regs-1 11368 for (uint32_t r = 0; r < regs; ++r) { 11369 if (single_regs) { 11370 // S[d+r] = MemA[address,4]; address = address+4; 11371 context.SetRegisterPlusOffset(base_reg, address - Rn); 11372 11373 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11374 if (!success) 11375 return false; 11376 11377 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11378 start_reg + d + r, data)) 11379 return false; 11380 11381 address = address + 4; 11382 } else { 11383 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = 11384 // address+8; 11385 context.SetRegisterPlusOffset(base_reg, address - Rn); 11386 uint32_t word1 = 11387 MemARead(context, address, addr_byte_size, 0, &success); 11388 if (!success) 11389 return false; 11390 11391 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn); 11392 uint32_t word2 = 11393 MemARead(context, address + 4, addr_byte_size, 0, &success); 11394 if (!success) 11395 return false; 11396 11397 address = address + 8; 11398 // // Combine the word-aligned words in the correct order for current 11399 // endianness. 11400 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11401 uint64_t data; 11402 if (GetByteOrder() == eByteOrderBig) { 11403 data = word1; 11404 data = (data << 32) | word2; 11405 } else { 11406 data = word2; 11407 data = (data << 32) | word1; 11408 } 11409 11410 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11411 start_reg + d + r, data)) 11412 return false; 11413 } 11414 } 11415 } 11416 return true; 11417 } 11418 11419 // A8.6.399 VSTM 11420 // Vector Store Multiple stores multiple extension registers to consecutive 11421 // memory locations using an address from an 11422 // ARM core register. 11423 bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode, 11424 const ARMEncoding encoding) { 11425 #if 0 11426 if ConditionPassed() then 11427 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11428 address = if add then R[n] else R[n]-imm32; 11429 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11430 for r = 0 to regs-1 11431 if single_regs then 11432 MemA[address,4] = S[d+r]; address = address+4; 11433 else 11434 // Store as two word-aligned words in the correct order for 11435 // current endianness. 11436 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11437 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11438 address = address+8; 11439 #endif 11440 11441 bool success = false; 11442 11443 if (ConditionPassed(opcode)) { 11444 bool single_regs; 11445 bool add; 11446 bool wback; 11447 uint32_t d; 11448 uint32_t n; 11449 uint32_t imm32; 11450 uint32_t regs; 11451 11452 switch (encoding) { 11453 case eEncodingT1: 11454 case eEncodingA1: 11455 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11456 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11457 // if P == '1' && W == '0' then SEE VSTR; 11458 // if P == U && W == '1' then UNDEFINED; 11459 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11460 return false; 11461 11462 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11463 // !), 101 (DB with !) 11464 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11465 single_regs = false; 11466 add = BitIsSet(opcode, 23); 11467 wback = BitIsSet(opcode, 21); 11468 11469 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11470 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11471 n = Bits32(opcode, 19, 16); 11472 imm32 = Bits32(opcode, 7, 0) << 2; 11473 11474 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11475 regs = Bits32(opcode, 7, 0) / 2; 11476 11477 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11478 // UNPREDICTABLE; 11479 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11480 return false; 11481 11482 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11483 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11484 return false; 11485 11486 break; 11487 11488 case eEncodingT2: 11489 case eEncodingA2: 11490 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11491 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11492 // if P == '1' && W == '0' then SEE VSTR; 11493 // if P == U && W == '1' then UNDEFINED; 11494 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11495 return false; 11496 11497 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11498 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11499 // == '1'); d = 11500 // UInt(Vd:D); n = UInt(Rn); 11501 single_regs = true; 11502 add = BitIsSet(opcode, 23); 11503 wback = BitIsSet(opcode, 21); 11504 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11505 n = Bits32(opcode, 19, 16); 11506 11507 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11508 imm32 = Bits32(opcode, 7, 0) << 2; 11509 regs = Bits32(opcode, 7, 0); 11510 11511 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11512 // UNPREDICTABLE; 11513 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11514 return false; 11515 11516 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11517 if ((regs == 0) || ((d + regs) > 32)) 11518 return false; 11519 11520 break; 11521 11522 default: 11523 return false; 11524 } 11525 11526 RegisterInfo base_reg; 11527 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11528 11529 uint32_t Rn = ReadCoreReg(n, &success); 11530 if (!success) 11531 return false; 11532 11533 // address = if add then R[n] else R[n]-imm32; 11534 addr_t address; 11535 if (add) 11536 address = Rn; 11537 else 11538 address = Rn - imm32; 11539 11540 EmulateInstruction::Context context; 11541 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11542 if (wback) { 11543 uint32_t value; 11544 if (add) 11545 value = Rn + imm32; 11546 else 11547 value = Rn - imm32; 11548 11549 context.type = eContextAdjustBaseRegister; 11550 context.SetRegisterPlusOffset(base_reg, value - Rn); 11551 11552 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11553 value)) 11554 return false; 11555 } 11556 11557 const uint32_t addr_byte_size = GetAddressByteSize(); 11558 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11559 11560 context.type = eContextRegisterStore; 11561 // for r = 0 to regs-1 11562 for (uint32_t r = 0; r < regs; ++r) { 11563 11564 if (single_regs) { 11565 // MemA[address,4] = S[d+r]; address = address+4; 11566 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11567 start_reg + d + r, 0, &success); 11568 if (!success) 11569 return false; 11570 11571 RegisterInfo data_reg; 11572 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11573 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11574 address - Rn); 11575 if (!MemAWrite(context, address, data, addr_byte_size)) 11576 return false; 11577 11578 address = address + 4; 11579 } else { 11580 // // Store as two word-aligned words in the correct order for current 11581 // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else 11582 // D[d+r]<31:0>; 11583 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else 11584 // D[d+r]<63:32>; 11585 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11586 start_reg + d + r, 0, &success); 11587 if (!success) 11588 return false; 11589 11590 RegisterInfo data_reg; 11591 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11592 11593 if (GetByteOrder() == eByteOrderBig) { 11594 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11595 address - Rn); 11596 if (!MemAWrite(context, address, Bits64(data, 63, 32), 11597 addr_byte_size)) 11598 return false; 11599 11600 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11601 (address + 4) - Rn); 11602 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11603 addr_byte_size)) 11604 return false; 11605 } else { 11606 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11607 address - Rn); 11608 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11609 return false; 11610 11611 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11612 (address + 4) - Rn); 11613 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11614 addr_byte_size)) 11615 return false; 11616 } 11617 // address = address+8; 11618 address = address + 8; 11619 } 11620 } 11621 } 11622 return true; 11623 } 11624 11625 // A8.6.320 11626 // This instruction loads a single extension register from memory, using an 11627 // address from an ARM core register, with an optional offset. 11628 bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode, 11629 ARMEncoding encoding) { 11630 #if 0 11631 if ConditionPassed() then 11632 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11633 base = if n == 15 then Align(PC,4) else R[n]; 11634 address = if add then (base + imm32) else (base - imm32); 11635 if single_reg then 11636 S[d] = MemA[address,4]; 11637 else 11638 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11639 // Combine the word-aligned words in the correct order for current 11640 // endianness. 11641 D[d] = if BigEndian() then word1:word2 else word2:word1; 11642 #endif 11643 11644 bool success = false; 11645 11646 if (ConditionPassed(opcode)) { 11647 bool single_reg; 11648 bool add; 11649 uint32_t imm32; 11650 uint32_t d; 11651 uint32_t n; 11652 11653 switch (encoding) { 11654 case eEncodingT1: 11655 case eEncodingA1: 11656 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11657 // 32); 11658 single_reg = false; 11659 add = BitIsSet(opcode, 23); 11660 imm32 = Bits32(opcode, 7, 0) << 2; 11661 11662 // d = UInt(D:Vd); n = UInt(Rn); 11663 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11664 n = Bits32(opcode, 19, 16); 11665 11666 break; 11667 11668 case eEncodingT2: 11669 case eEncodingA2: 11670 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11671 single_reg = true; 11672 add = BitIsSet(opcode, 23); 11673 imm32 = Bits32(opcode, 7, 0) << 2; 11674 11675 // d = UInt(Vd:D); n = UInt(Rn); 11676 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11677 n = Bits32(opcode, 19, 16); 11678 11679 break; 11680 11681 default: 11682 return false; 11683 } 11684 RegisterInfo base_reg; 11685 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11686 11687 uint32_t Rn = ReadCoreReg(n, &success); 11688 if (!success) 11689 return false; 11690 11691 // base = if n == 15 then Align(PC,4) else R[n]; 11692 uint32_t base; 11693 if (n == 15) 11694 base = AlignPC(Rn); 11695 else 11696 base = Rn; 11697 11698 // address = if add then (base + imm32) else (base - imm32); 11699 addr_t address; 11700 if (add) 11701 address = base + imm32; 11702 else 11703 address = base - imm32; 11704 11705 const uint32_t addr_byte_size = GetAddressByteSize(); 11706 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11707 11708 EmulateInstruction::Context context; 11709 context.type = eContextRegisterLoad; 11710 context.SetRegisterPlusOffset(base_reg, address - base); 11711 11712 if (single_reg) { 11713 // S[d] = MemA[address,4]; 11714 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11715 if (!success) 11716 return false; 11717 11718 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11719 data)) 11720 return false; 11721 } else { 11722 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11723 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success); 11724 if (!success) 11725 return false; 11726 11727 context.SetRegisterPlusOffset(base_reg, (address + 4) - base); 11728 uint32_t word2 = 11729 MemARead(context, address + 4, addr_byte_size, 0, &success); 11730 if (!success) 11731 return false; 11732 // // Combine the word-aligned words in the correct order for current 11733 // endianness. 11734 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11735 uint64_t data64; 11736 if (GetByteOrder() == eByteOrderBig) { 11737 data64 = word1; 11738 data64 = (data64 << 32) | word2; 11739 } else { 11740 data64 = word2; 11741 data64 = (data64 << 32) | word1; 11742 } 11743 11744 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11745 data64)) 11746 return false; 11747 } 11748 } 11749 return true; 11750 } 11751 11752 // A8.6.400 VSTR 11753 // This instruction stores a signle extension register to memory, using an 11754 // address from an ARM core register, with an optional offset. 11755 bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode, 11756 ARMEncoding encoding) { 11757 #if 0 11758 if ConditionPassed() then 11759 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11760 address = if add then (R[n] + imm32) else (R[n] - imm32); 11761 if single_reg then 11762 MemA[address,4] = S[d]; 11763 else 11764 // Store as two word-aligned words in the correct order for current 11765 // endianness. 11766 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11767 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11768 #endif 11769 11770 bool success = false; 11771 11772 if (ConditionPassed(opcode)) { 11773 bool single_reg; 11774 bool add; 11775 uint32_t imm32; 11776 uint32_t d; 11777 uint32_t n; 11778 11779 switch (encoding) { 11780 case eEncodingT1: 11781 case eEncodingA1: 11782 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11783 // 32); 11784 single_reg = false; 11785 add = BitIsSet(opcode, 23); 11786 imm32 = Bits32(opcode, 7, 0) << 2; 11787 11788 // d = UInt(D:Vd); n = UInt(Rn); 11789 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11790 n = Bits32(opcode, 19, 16); 11791 11792 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11793 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11794 return false; 11795 11796 break; 11797 11798 case eEncodingT2: 11799 case eEncodingA2: 11800 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11801 single_reg = true; 11802 add = BitIsSet(opcode, 23); 11803 imm32 = Bits32(opcode, 7, 0) << 2; 11804 11805 // d = UInt(Vd:D); n = UInt(Rn); 11806 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11807 n = Bits32(opcode, 19, 16); 11808 11809 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11810 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11811 return false; 11812 11813 break; 11814 11815 default: 11816 return false; 11817 } 11818 11819 RegisterInfo base_reg; 11820 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11821 11822 uint32_t Rn = ReadCoreReg(n, &success); 11823 if (!success) 11824 return false; 11825 11826 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11827 addr_t address; 11828 if (add) 11829 address = Rn + imm32; 11830 else 11831 address = Rn - imm32; 11832 11833 const uint32_t addr_byte_size = GetAddressByteSize(); 11834 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11835 11836 RegisterInfo data_reg; 11837 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg); 11838 EmulateInstruction::Context context; 11839 context.type = eContextRegisterStore; 11840 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11841 11842 if (single_reg) { 11843 // MemA[address,4] = S[d]; 11844 uint32_t data = 11845 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11846 if (!success) 11847 return false; 11848 11849 if (!MemAWrite(context, address, data, addr_byte_size)) 11850 return false; 11851 } else { 11852 // // Store as two word-aligned words in the correct order for current 11853 // endianness. 11854 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11855 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11856 uint64_t data = 11857 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11858 if (!success) 11859 return false; 11860 11861 if (GetByteOrder() == eByteOrderBig) { 11862 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size)) 11863 return false; 11864 11865 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11866 (address + 4) - Rn); 11867 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11868 addr_byte_size)) 11869 return false; 11870 } else { 11871 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11872 return false; 11873 11874 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11875 (address + 4) - Rn); 11876 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11877 addr_byte_size)) 11878 return false; 11879 } 11880 } 11881 } 11882 return true; 11883 } 11884 11885 // A8.6.307 VLDI1 (multiple single elements) This instruction loads elements 11886 // from memory into one, two, three or four registers, without de-interleaving. 11887 // Every element of each register is loaded. 11888 bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode, 11889 ARMEncoding encoding) { 11890 #if 0 11891 if ConditionPassed() then 11892 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11893 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11894 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11895 for r = 0 to regs-1 11896 for e = 0 to elements-1 11897 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11898 address = address + ebytes; 11899 #endif 11900 11901 bool success = false; 11902 11903 if (ConditionPassed(opcode)) { 11904 uint32_t regs; 11905 uint32_t alignment; 11906 uint32_t ebytes; 11907 uint32_t esize; 11908 uint32_t elements; 11909 uint32_t d; 11910 uint32_t n; 11911 uint32_t m; 11912 bool wback; 11913 bool register_index; 11914 11915 switch (encoding) { 11916 case eEncodingT1: 11917 case eEncodingA1: { 11918 // case type of 11919 // when '0111' 11920 // regs = 1; if align<1> == '1' then UNDEFINED; 11921 // when '1010' 11922 // regs = 2; if align == '11' then UNDEFINED; 11923 // when '0110' 11924 // regs = 3; if align<1> == '1' then UNDEFINED; 11925 // when '0010' 11926 // regs = 4; 11927 // otherwise 11928 // SEE 'Related encodings'; 11929 uint32_t type = Bits32(opcode, 11, 8); 11930 uint32_t align = Bits32(opcode, 5, 4); 11931 if (type == 7) // '0111' 11932 { 11933 regs = 1; 11934 if (BitIsSet(align, 1)) 11935 return false; 11936 } else if (type == 10) // '1010' 11937 { 11938 regs = 2; 11939 if (align == 3) 11940 return false; 11941 11942 } else if (type == 6) // '0110' 11943 { 11944 regs = 3; 11945 if (BitIsSet(align, 1)) 11946 return false; 11947 } else if (type == 2) // '0010' 11948 { 11949 regs = 4; 11950 } else 11951 return false; 11952 11953 // alignment = if align == '00' then 1 else 4 << UInt(align); 11954 if (align == 0) 11955 alignment = 1; 11956 else 11957 alignment = 4 << align; 11958 11959 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11960 ebytes = 1 << Bits32(opcode, 7, 6); 11961 esize = 8 * ebytes; 11962 elements = 8 / ebytes; 11963 11964 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11965 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11966 n = Bits32(opcode, 19, 15); 11967 m = Bits32(opcode, 3, 0); 11968 11969 // wback = (m != 15); register_index = (m != 15 && m != 13); 11970 wback = (m != 15); 11971 register_index = ((m != 15) && (m != 13)); 11972 11973 // if d+regs > 32 then UNPREDICTABLE; 11974 if ((d + regs) > 32) 11975 return false; 11976 } break; 11977 11978 default: 11979 return false; 11980 } 11981 11982 RegisterInfo base_reg; 11983 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11984 11985 uint32_t Rn = ReadCoreReg(n, &success); 11986 if (!success) 11987 return false; 11988 11989 // address = R[n]; if (address MOD alignment) != 0 then 11990 // GenerateAlignmentException(); 11991 addr_t address = Rn; 11992 if ((address % alignment) != 0) 11993 return false; 11994 11995 EmulateInstruction::Context context; 11996 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11997 if (wback) { 11998 uint32_t Rm = ReadCoreReg(m, &success); 11999 if (!success) 12000 return false; 12001 12002 uint32_t offset; 12003 if (register_index) 12004 offset = Rm; 12005 else 12006 offset = 8 * regs; 12007 12008 uint32_t value = Rn + offset; 12009 context.type = eContextAdjustBaseRegister; 12010 context.SetRegisterPlusOffset(base_reg, offset); 12011 12012 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12013 value)) 12014 return false; 12015 } 12016 12017 // for r = 0 to regs-1 12018 for (uint32_t r = 0; r < regs; ++r) { 12019 // for e = 0 to elements-1 12020 uint64_t assembled_data = 0; 12021 for (uint32_t e = 0; e < elements; ++e) { 12022 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 12023 context.type = eContextRegisterLoad; 12024 context.SetRegisterPlusOffset(base_reg, address - Rn); 12025 uint64_t data = MemURead(context, address, ebytes, 0, &success); 12026 if (!success) 12027 return false; 12028 12029 assembled_data = 12030 (data << (e * esize)) | 12031 assembled_data; // New data goes to the left of existing data 12032 12033 // address = address + ebytes; 12034 address = address + ebytes; 12035 } 12036 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12037 assembled_data)) 12038 return false; 12039 } 12040 } 12041 return true; 12042 } 12043 12044 // A8.6.308 VLD1 (single element to one lane) 12045 // 12046 bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode, 12047 const ARMEncoding encoding) { 12048 #if 0 12049 if ConditionPassed() then 12050 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12051 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12052 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12053 Elem[D[d],index,esize] = MemU[address,ebytes]; 12054 #endif 12055 12056 bool success = false; 12057 12058 if (ConditionPassed(opcode)) { 12059 uint32_t ebytes; 12060 uint32_t esize; 12061 uint32_t index; 12062 uint32_t alignment; 12063 uint32_t d; 12064 uint32_t n; 12065 uint32_t m; 12066 bool wback; 12067 bool register_index; 12068 12069 switch (encoding) { 12070 case eEncodingT1: 12071 case eEncodingA1: { 12072 uint32_t size = Bits32(opcode, 11, 10); 12073 uint32_t index_align = Bits32(opcode, 7, 4); 12074 // if size == '11' then SEE VLD1 (single element to all lanes); 12075 if (size == 3) 12076 return EmulateVLD1SingleAll(opcode, encoding); 12077 // case size of 12078 if (size == 0) // when '00' 12079 { 12080 // if index_align<0> != '0' then UNDEFINED; 12081 if (BitIsClear(index_align, 0)) 12082 return false; 12083 12084 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12085 ebytes = 1; 12086 esize = 8; 12087 index = Bits32(index_align, 3, 1); 12088 alignment = 1; 12089 } else if (size == 1) // when '01' 12090 { 12091 // if index_align<1> != '0' then UNDEFINED; 12092 if (BitIsClear(index_align, 1)) 12093 return false; 12094 12095 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12096 ebytes = 2; 12097 esize = 16; 12098 index = Bits32(index_align, 3, 2); 12099 12100 // alignment = if index_align<0> == '0' then 1 else 2; 12101 if (BitIsClear(index_align, 0)) 12102 alignment = 1; 12103 else 12104 alignment = 2; 12105 } else if (size == 2) // when '10' 12106 { 12107 // if index_align<2> != '0' then UNDEFINED; 12108 if (BitIsClear(index_align, 2)) 12109 return false; 12110 12111 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12112 // UNDEFINED; 12113 if ((Bits32(index_align, 1, 0) != 0) && 12114 (Bits32(index_align, 1, 0) != 3)) 12115 return false; 12116 12117 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12118 ebytes = 4; 12119 esize = 32; 12120 index = Bit32(index_align, 3); 12121 12122 // alignment = if index_align<1:0> == '00' then 1 else 4; 12123 if (Bits32(index_align, 1, 0) == 0) 12124 alignment = 1; 12125 else 12126 alignment = 4; 12127 } else { 12128 return false; 12129 } 12130 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12131 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12132 n = Bits32(opcode, 19, 16); 12133 m = Bits32(opcode, 3, 0); 12134 12135 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12136 // then UNPREDICTABLE; 12137 wback = (m != 15); 12138 register_index = ((m != 15) && (m != 13)); 12139 12140 if (n == 15) 12141 return false; 12142 12143 } break; 12144 12145 default: 12146 return false; 12147 } 12148 12149 RegisterInfo base_reg; 12150 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12151 12152 uint32_t Rn = ReadCoreReg(n, &success); 12153 if (!success) 12154 return false; 12155 12156 // address = R[n]; if (address MOD alignment) != 0 then 12157 // GenerateAlignmentException(); 12158 addr_t address = Rn; 12159 if ((address % alignment) != 0) 12160 return false; 12161 12162 EmulateInstruction::Context context; 12163 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12164 if (wback) { 12165 uint32_t Rm = ReadCoreReg(m, &success); 12166 if (!success) 12167 return false; 12168 12169 uint32_t offset; 12170 if (register_index) 12171 offset = Rm; 12172 else 12173 offset = ebytes; 12174 12175 uint32_t value = Rn + offset; 12176 12177 context.type = eContextAdjustBaseRegister; 12178 context.SetRegisterPlusOffset(base_reg, offset); 12179 12180 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12181 value)) 12182 return false; 12183 } 12184 12185 // Elem[D[d],index,esize] = MemU[address,ebytes]; 12186 uint32_t element = MemURead(context, address, esize, 0, &success); 12187 if (!success) 12188 return false; 12189 12190 element = element << (index * esize); 12191 12192 uint64_t reg_data = 12193 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12194 if (!success) 12195 return false; 12196 12197 uint64_t all_ones = -1; 12198 uint64_t mask = all_ones 12199 << ((index + 1) * esize); // mask is all 1's to left of 12200 // where 'element' goes, & all 0's 12201 // at element & to the right of element. 12202 if (index > 0) 12203 mask = mask | Bits64(all_ones, (index * esize) - 1, 12204 0); // add 1's to the right of where 'element' goes. 12205 // now mask should be 0's where element goes & 1's everywhere else. 12206 12207 uint64_t masked_reg = 12208 reg_data & mask; // Take original reg value & zero out 'element' bits 12209 reg_data = 12210 masked_reg & element; // Put 'element' into those bits in reg_data. 12211 12212 context.type = eContextRegisterLoad; 12213 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 12214 reg_data)) 12215 return false; 12216 } 12217 return true; 12218 } 12219 12220 // A8.6.391 VST1 (multiple single elements) Vector Store (multiple single 12221 // elements) stores elements to memory from one, two, three, or four registers, 12222 // without interleaving. Every element of each register is stored. 12223 bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode, 12224 ARMEncoding encoding) { 12225 #if 0 12226 if ConditionPassed() then 12227 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12228 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12229 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12230 for r = 0 to regs-1 12231 for e = 0 to elements-1 12232 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12233 address = address + ebytes; 12234 #endif 12235 12236 bool success = false; 12237 12238 if (ConditionPassed(opcode)) { 12239 uint32_t regs; 12240 uint32_t alignment; 12241 uint32_t ebytes; 12242 uint32_t esize; 12243 uint32_t elements; 12244 uint32_t d; 12245 uint32_t n; 12246 uint32_t m; 12247 bool wback; 12248 bool register_index; 12249 12250 switch (encoding) { 12251 case eEncodingT1: 12252 case eEncodingA1: { 12253 uint32_t type = Bits32(opcode, 11, 8); 12254 uint32_t align = Bits32(opcode, 5, 4); 12255 12256 // case type of 12257 if (type == 7) // when '0111' 12258 { 12259 // regs = 1; if align<1> == '1' then UNDEFINED; 12260 regs = 1; 12261 if (BitIsSet(align, 1)) 12262 return false; 12263 } else if (type == 10) // when '1010' 12264 { 12265 // regs = 2; if align == '11' then UNDEFINED; 12266 regs = 2; 12267 if (align == 3) 12268 return false; 12269 } else if (type == 6) // when '0110' 12270 { 12271 // regs = 3; if align<1> == '1' then UNDEFINED; 12272 regs = 3; 12273 if (BitIsSet(align, 1)) 12274 return false; 12275 } else if (type == 2) // when '0010' 12276 // regs = 4; 12277 regs = 4; 12278 else // otherwise 12279 // SEE 'Related encodings'; 12280 return false; 12281 12282 // alignment = if align == '00' then 1 else 4 << UInt(align); 12283 if (align == 0) 12284 alignment = 1; 12285 else 12286 alignment = 4 << align; 12287 12288 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 12289 ebytes = 1 << Bits32(opcode, 7, 6); 12290 esize = 8 * ebytes; 12291 elements = 8 / ebytes; 12292 12293 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12294 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12295 n = Bits32(opcode, 19, 16); 12296 m = Bits32(opcode, 3, 0); 12297 12298 // wback = (m != 15); register_index = (m != 15 && m != 13); 12299 wback = (m != 15); 12300 register_index = ((m != 15) && (m != 13)); 12301 12302 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12303 if ((d + regs) > 32) 12304 return false; 12305 12306 if (n == 15) 12307 return false; 12308 12309 } break; 12310 12311 default: 12312 return false; 12313 } 12314 12315 RegisterInfo base_reg; 12316 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12317 12318 uint32_t Rn = ReadCoreReg(n, &success); 12319 if (!success) 12320 return false; 12321 12322 // address = R[n]; if (address MOD alignment) != 0 then 12323 // GenerateAlignmentException(); 12324 addr_t address = Rn; 12325 if ((address % alignment) != 0) 12326 return false; 12327 12328 EmulateInstruction::Context context; 12329 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12330 if (wback) { 12331 uint32_t Rm = ReadCoreReg(m, &success); 12332 if (!success) 12333 return false; 12334 12335 uint32_t offset; 12336 if (register_index) 12337 offset = Rm; 12338 else 12339 offset = 8 * regs; 12340 12341 context.type = eContextAdjustBaseRegister; 12342 context.SetRegisterPlusOffset(base_reg, offset); 12343 12344 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12345 Rn + offset)) 12346 return false; 12347 } 12348 12349 RegisterInfo data_reg; 12350 context.type = eContextRegisterStore; 12351 // for r = 0 to regs-1 12352 for (uint32_t r = 0; r < regs; ++r) { 12353 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 12354 uint64_t register_data = ReadRegisterUnsigned( 12355 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 12356 if (!success) 12357 return false; 12358 12359 // for e = 0 to elements-1 12360 for (uint32_t e = 0; e < elements; ++e) { 12361 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12362 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize); 12363 12364 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12365 address - Rn); 12366 if (!MemUWrite(context, address, word, ebytes)) 12367 return false; 12368 12369 // address = address + ebytes; 12370 address = address + ebytes; 12371 } 12372 } 12373 } 12374 return true; 12375 } 12376 12377 // A8.6.392 VST1 (single element from one lane) This instruction stores one 12378 // element to memory from one element of a register. 12379 bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode, 12380 ARMEncoding encoding) { 12381 #if 0 12382 if ConditionPassed() then 12383 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12384 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12385 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12386 MemU[address,ebytes] = Elem[D[d],index,esize]; 12387 #endif 12388 12389 bool success = false; 12390 12391 if (ConditionPassed(opcode)) { 12392 uint32_t ebytes; 12393 uint32_t esize; 12394 uint32_t index; 12395 uint32_t alignment; 12396 uint32_t d; 12397 uint32_t n; 12398 uint32_t m; 12399 bool wback; 12400 bool register_index; 12401 12402 switch (encoding) { 12403 case eEncodingT1: 12404 case eEncodingA1: { 12405 uint32_t size = Bits32(opcode, 11, 10); 12406 uint32_t index_align = Bits32(opcode, 7, 4); 12407 12408 // if size == '11' then UNDEFINED; 12409 if (size == 3) 12410 return false; 12411 12412 // case size of 12413 if (size == 0) // when '00' 12414 { 12415 // if index_align<0> != '0' then UNDEFINED; 12416 if (BitIsClear(index_align, 0)) 12417 return false; 12418 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12419 ebytes = 1; 12420 esize = 8; 12421 index = Bits32(index_align, 3, 1); 12422 alignment = 1; 12423 } else if (size == 1) // when '01' 12424 { 12425 // if index_align<1> != '0' then UNDEFINED; 12426 if (BitIsClear(index_align, 1)) 12427 return false; 12428 12429 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12430 ebytes = 2; 12431 esize = 16; 12432 index = Bits32(index_align, 3, 2); 12433 12434 // alignment = if index_align<0> == '0' then 1 else 2; 12435 if (BitIsClear(index_align, 0)) 12436 alignment = 1; 12437 else 12438 alignment = 2; 12439 } else if (size == 2) // when '10' 12440 { 12441 // if index_align<2> != '0' then UNDEFINED; 12442 if (BitIsClear(index_align, 2)) 12443 return false; 12444 12445 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12446 // UNDEFINED; 12447 if ((Bits32(index_align, 1, 0) != 0) && 12448 (Bits32(index_align, 1, 0) != 3)) 12449 return false; 12450 12451 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12452 ebytes = 4; 12453 esize = 32; 12454 index = Bit32(index_align, 3); 12455 12456 // alignment = if index_align<1:0> == '00' then 1 else 4; 12457 if (Bits32(index_align, 1, 0) == 0) 12458 alignment = 1; 12459 else 12460 alignment = 4; 12461 } else { 12462 return false; 12463 } 12464 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12465 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12466 n = Bits32(opcode, 19, 16); 12467 m = Bits32(opcode, 3, 0); 12468 12469 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12470 // then UNPREDICTABLE; 12471 wback = (m != 15); 12472 register_index = ((m != 15) && (m != 13)); 12473 12474 if (n == 15) 12475 return false; 12476 } break; 12477 12478 default: 12479 return false; 12480 } 12481 12482 RegisterInfo base_reg; 12483 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12484 12485 uint32_t Rn = ReadCoreReg(n, &success); 12486 if (!success) 12487 return false; 12488 12489 // address = R[n]; if (address MOD alignment) != 0 then 12490 // GenerateAlignmentException(); 12491 addr_t address = Rn; 12492 if ((address % alignment) != 0) 12493 return false; 12494 12495 EmulateInstruction::Context context; 12496 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12497 if (wback) { 12498 uint32_t Rm = ReadCoreReg(m, &success); 12499 if (!success) 12500 return false; 12501 12502 uint32_t offset; 12503 if (register_index) 12504 offset = Rm; 12505 else 12506 offset = ebytes; 12507 12508 context.type = eContextAdjustBaseRegister; 12509 context.SetRegisterPlusOffset(base_reg, offset); 12510 12511 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12512 Rn + offset)) 12513 return false; 12514 } 12515 12516 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12517 uint64_t register_data = 12518 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12519 if (!success) 12520 return false; 12521 12522 uint64_t word = 12523 Bits64(register_data, ((index + 1) * esize) - 1, index * esize); 12524 12525 RegisterInfo data_reg; 12526 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12527 context.type = eContextRegisterStore; 12528 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 12529 12530 if (!MemUWrite(context, address, word, ebytes)) 12531 return false; 12532 } 12533 return true; 12534 } 12535 12536 // A8.6.309 VLD1 (single element to all lanes) This instruction loads one 12537 // element from memory into every element of one or two vectors. 12538 bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode, 12539 const ARMEncoding encoding) { 12540 #if 0 12541 if ConditionPassed() then 12542 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12543 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12544 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12545 replicated_element = Replicate(MemU[address,ebytes], elements); 12546 for r = 0 to regs-1 12547 D[d+r] = replicated_element; 12548 #endif 12549 12550 bool success = false; 12551 12552 if (ConditionPassed(opcode)) { 12553 uint32_t ebytes; 12554 uint32_t elements; 12555 uint32_t regs; 12556 uint32_t alignment; 12557 uint32_t d; 12558 uint32_t n; 12559 uint32_t m; 12560 bool wback; 12561 bool register_index; 12562 12563 switch (encoding) { 12564 case eEncodingT1: 12565 case eEncodingA1: { 12566 // if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12567 uint32_t size = Bits32(opcode, 7, 6); 12568 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4))) 12569 return false; 12570 12571 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' 12572 // then 1 else 2; 12573 ebytes = 1 << size; 12574 elements = 8 / ebytes; 12575 if (BitIsClear(opcode, 5)) 12576 regs = 1; 12577 else 12578 regs = 2; 12579 12580 // alignment = if a == '0' then 1 else ebytes; 12581 if (BitIsClear(opcode, 4)) 12582 alignment = 1; 12583 else 12584 alignment = ebytes; 12585 12586 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12587 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12588 n = Bits32(opcode, 19, 16); 12589 m = Bits32(opcode, 3, 0); 12590 12591 // wback = (m != 15); register_index = (m != 15 && m != 13); 12592 wback = (m != 15); 12593 register_index = ((m != 15) && (m != 13)); 12594 12595 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12596 if ((d + regs) > 32) 12597 return false; 12598 12599 if (n == 15) 12600 return false; 12601 } break; 12602 12603 default: 12604 return false; 12605 } 12606 12607 RegisterInfo base_reg; 12608 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12609 12610 uint32_t Rn = ReadCoreReg(n, &success); 12611 if (!success) 12612 return false; 12613 12614 // address = R[n]; if (address MOD alignment) != 0 then 12615 // GenerateAlignmentException(); 12616 addr_t address = Rn; 12617 if ((address % alignment) != 0) 12618 return false; 12619 12620 EmulateInstruction::Context context; 12621 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12622 if (wback) { 12623 uint32_t Rm = ReadCoreReg(m, &success); 12624 if (!success) 12625 return false; 12626 12627 uint32_t offset; 12628 if (register_index) 12629 offset = Rm; 12630 else 12631 offset = ebytes; 12632 12633 context.type = eContextAdjustBaseRegister; 12634 context.SetRegisterPlusOffset(base_reg, offset); 12635 12636 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12637 Rn + offset)) 12638 return false; 12639 } 12640 12641 // replicated_element = Replicate(MemU[address,ebytes], elements); 12642 12643 context.type = eContextRegisterLoad; 12644 uint64_t word = MemURead(context, address, ebytes, 0, &success); 12645 if (!success) 12646 return false; 12647 12648 uint64_t replicated_element = 0; 12649 uint32_t esize = ebytes * 8; 12650 for (uint32_t e = 0; e < elements; ++e) 12651 replicated_element = 12652 (replicated_element << esize) | Bits64(word, esize - 1, 0); 12653 12654 // for r = 0 to regs-1 12655 for (uint32_t r = 0; r < regs; ++r) { 12656 // D[d+r] = replicated_element; 12657 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12658 replicated_element)) 12659 return false; 12660 } 12661 } 12662 return true; 12663 } 12664 12665 // B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const? 12666 // instruction provides an exception return without the use of the stack. It 12667 // subtracts the immediate constant from the LR, branches to the resulting 12668 // address, and also copies the SPSR to the CPSR. 12669 bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode, 12670 const ARMEncoding encoding) { 12671 #if 0 12672 if ConditionPassed() then 12673 EncodingSpecificOperations(); 12674 if CurrentInstrSet() == InstrSet_ThumbEE then 12675 UNPREDICTABLE; 12676 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12677 case opcode of 12678 when '0000' result = R[n] AND operand2; // AND 12679 when '0001' result = R[n] EOR operand2; // EOR 12680 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12681 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12682 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12683 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12684 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12685 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12686 when '1100' result = R[n] OR operand2; // ORR 12687 when '1101' result = operand2; // MOV 12688 when '1110' result = R[n] AND NOT(operand2); // BIC 12689 when '1111' result = NOT(operand2); // MVN 12690 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12691 BranchWritePC(result); 12692 #endif 12693 12694 bool success = false; 12695 12696 if (ConditionPassed(opcode)) { 12697 uint32_t n; 12698 uint32_t m; 12699 uint32_t imm32; 12700 bool register_form; 12701 ARM_ShifterType shift_t; 12702 uint32_t shift_n; 12703 uint32_t code; 12704 12705 switch (encoding) { 12706 case eEncodingT1: 12707 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14; 12708 // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; 12709 // // = SUB 12710 n = 14; 12711 imm32 = Bits32(opcode, 7, 0); 12712 register_form = false; 12713 code = 2; 12714 12715 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12716 if (InITBlock() && !LastInITBlock()) 12717 return false; 12718 12719 break; 12720 12721 case eEncodingA1: 12722 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12723 n = Bits32(opcode, 19, 16); 12724 imm32 = ARMExpandImm(opcode); 12725 register_form = false; 12726 code = Bits32(opcode, 24, 21); 12727 12728 break; 12729 12730 case eEncodingA2: 12731 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12732 n = Bits32(opcode, 19, 16); 12733 m = Bits32(opcode, 3, 0); 12734 register_form = true; 12735 12736 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12737 shift_n = DecodeImmShiftARM(opcode, shift_t); 12738 12739 break; 12740 12741 default: 12742 return false; 12743 } 12744 12745 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) 12746 // else imm32; 12747 uint32_t operand2; 12748 if (register_form) { 12749 uint32_t Rm = ReadCoreReg(m, &success); 12750 if (!success) 12751 return false; 12752 12753 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success); 12754 if (!success) 12755 return false; 12756 } else { 12757 operand2 = imm32; 12758 } 12759 12760 uint32_t Rn = ReadCoreReg(n, &success); 12761 if (!success) 12762 return false; 12763 12764 AddWithCarryResult result; 12765 12766 // case opcode of 12767 switch (code) { 12768 case 0: // when '0000' 12769 // result = R[n] AND operand2; // AND 12770 result.result = Rn & operand2; 12771 break; 12772 12773 case 1: // when '0001' 12774 // result = R[n] EOR operand2; // EOR 12775 result.result = Rn ^ operand2; 12776 break; 12777 12778 case 2: // when '0010' 12779 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12780 result = AddWithCarry(Rn, ~(operand2), 1); 12781 break; 12782 12783 case 3: // when '0011' 12784 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12785 result = AddWithCarry(~(Rn), operand2, 1); 12786 break; 12787 12788 case 4: // when '0100' 12789 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12790 result = AddWithCarry(Rn, operand2, 0); 12791 break; 12792 12793 case 5: // when '0101' 12794 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12795 result = AddWithCarry(Rn, operand2, APSR_C); 12796 break; 12797 12798 case 6: // when '0110' 12799 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12800 result = AddWithCarry(Rn, ~(operand2), APSR_C); 12801 break; 12802 12803 case 7: // when '0111' 12804 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12805 result = AddWithCarry(~(Rn), operand2, APSR_C); 12806 break; 12807 12808 case 10: // when '1100' 12809 // result = R[n] OR operand2; // ORR 12810 result.result = Rn | operand2; 12811 break; 12812 12813 case 11: // when '1101' 12814 // result = operand2; // MOV 12815 result.result = operand2; 12816 break; 12817 12818 case 12: // when '1110' 12819 // result = R[n] AND NOT(operand2); // BIC 12820 result.result = Rn & ~(operand2); 12821 break; 12822 12823 case 15: // when '1111' 12824 // result = NOT(operand2); // MVN 12825 result.result = ~(operand2); 12826 break; 12827 12828 default: 12829 return false; 12830 } 12831 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12832 12833 // For now, in emulation mode, we don't have access to the SPSR, so we will 12834 // use the CPSR instead, and hope for the best. 12835 uint32_t spsr = 12836 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12837 if (!success) 12838 return false; 12839 12840 CPSRWriteByInstr(spsr, 15, true); 12841 12842 // BranchWritePC(result); 12843 EmulateInstruction::Context context; 12844 context.type = eContextAdjustPC; 12845 context.SetImmediate(result.result); 12846 12847 BranchWritePC(context, result.result); 12848 } 12849 return true; 12850 } 12851 12852 EmulateInstructionARM::ARMOpcode * 12853 EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode, 12854 uint32_t arm_isa) { 12855 static ARMOpcode g_arm_opcodes[] = { 12856 //---------------------------------------------------------------------- 12857 // Prologue instructions 12858 //---------------------------------------------------------------------- 12859 12860 // push register(s) 12861 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12862 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 12863 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12864 &EmulateInstructionARM::EmulatePUSH, "push <register>"}, 12865 12866 // set r7 to point to a stack offset 12867 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12868 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"}, 12869 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12870 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12871 // copy the stack pointer to ip 12872 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, 12873 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"}, 12874 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12875 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"}, 12876 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12877 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12878 12879 // adjust the stack pointer 12880 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12881 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12882 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12883 &EmulateInstructionARM::EmulateSUBSPReg, 12884 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 12885 12886 // push one register 12887 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12888 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12889 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"}, 12890 12891 // vector push consecutive extension register(s) 12892 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12893 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12894 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12895 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12896 12897 //---------------------------------------------------------------------- 12898 // Epilogue instructions 12899 //---------------------------------------------------------------------- 12900 12901 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12902 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12903 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12904 &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12905 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12906 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12907 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12908 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12909 12910 //---------------------------------------------------------------------- 12911 // Supervisor Call (previously Software Interrupt) 12912 //---------------------------------------------------------------------- 12913 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12914 &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12915 12916 //---------------------------------------------------------------------- 12917 // Branch instructions 12918 //---------------------------------------------------------------------- 12919 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and 12920 // "bl <label>". 12921 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, 12922 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12923 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12924 &EmulateInstructionARM::EmulateB, "b #imm24"}, 12925 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12926 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12927 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, 12928 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12929 // for example, "bx lr" 12930 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, 12931 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12932 // bxj 12933 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, 12934 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12935 12936 //---------------------------------------------------------------------- 12937 // Data-processing instructions 12938 //---------------------------------------------------------------------- 12939 // adc (immediate) 12940 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12941 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12942 // adc (register) 12943 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12944 &EmulateInstructionARM::EmulateADCReg, 12945 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12946 // add (immediate) 12947 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12948 &EmulateInstructionARM::EmulateADDImmARM, 12949 "add{s}<c> <Rd>, <Rn>, #const"}, 12950 // add (register) 12951 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12952 &EmulateInstructionARM::EmulateADDReg, 12953 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12954 // add (register-shifted register) 12955 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, 12956 &EmulateInstructionARM::EmulateADDRegShift, 12957 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12958 // adr 12959 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12960 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12961 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, 12962 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12963 // and (immediate) 12964 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12965 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12966 // and (register) 12967 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12968 &EmulateInstructionARM::EmulateANDReg, 12969 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12970 // bic (immediate) 12971 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12972 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12973 // bic (register) 12974 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12975 &EmulateInstructionARM::EmulateBICReg, 12976 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12977 // eor (immediate) 12978 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12979 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12980 // eor (register) 12981 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12982 &EmulateInstructionARM::EmulateEORReg, 12983 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12984 // orr (immediate) 12985 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12986 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12987 // orr (register) 12988 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12989 &EmulateInstructionARM::EmulateORRReg, 12990 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12991 // rsb (immediate) 12992 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12993 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12994 // rsb (register) 12995 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12996 &EmulateInstructionARM::EmulateRSBReg, 12997 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12998 // rsc (immediate) 12999 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13000 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 13001 // rsc (register) 13002 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13003 &EmulateInstructionARM::EmulateRSCReg, 13004 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13005 // sbc (immediate) 13006 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13007 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13008 // sbc (register) 13009 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13010 &EmulateInstructionARM::EmulateSBCReg, 13011 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13012 // sub (immediate, ARM) 13013 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13014 &EmulateInstructionARM::EmulateSUBImmARM, 13015 "sub{s}<c> <Rd>, <Rn>, #<const>"}, 13016 // sub (sp minus immediate) 13017 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13018 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 13019 // sub (register) 13020 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13021 &EmulateInstructionARM::EmulateSUBReg, 13022 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 13023 // teq (immediate) 13024 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13025 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 13026 // teq (register) 13027 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13028 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13029 // tst (immediate) 13030 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13031 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 13032 // tst (register) 13033 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13034 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 13035 13036 // mov (immediate) 13037 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13038 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 13039 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 13040 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"}, 13041 // mov (register) 13042 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13043 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 13044 // mvn (immediate) 13045 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13046 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 13047 // mvn (register) 13048 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13049 &EmulateInstructionARM::EmulateMVNReg, 13050 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 13051 // cmn (immediate) 13052 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13053 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13054 // cmn (register) 13055 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13056 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13057 // cmp (immediate) 13058 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13059 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 13060 // cmp (register) 13061 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13062 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 13063 // asr (immediate) 13064 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, 13065 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 13066 // asr (register) 13067 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13068 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 13069 // lsl (immediate) 13070 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13071 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 13072 // lsl (register) 13073 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, 13074 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 13075 // lsr (immediate) 13076 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, 13077 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 13078 // lsr (register) 13079 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13080 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 13081 // rrx is a special case encoding of ror (immediate) 13082 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13083 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 13084 // ror (immediate) 13085 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13086 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 13087 // ror (register) 13088 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, 13089 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 13090 // mul 13091 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, 13092 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"}, 13093 13094 // subs pc, lr and related instructions 13095 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13096 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13097 "<opc>S<c> PC,#<const> | <Rn>,#<const>"}, 13098 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, 13099 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13100 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"}, 13101 13102 //---------------------------------------------------------------------- 13103 // Load instructions 13104 //---------------------------------------------------------------------- 13105 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13106 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13107 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13108 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"}, 13109 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13110 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13111 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13112 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"}, 13113 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13114 &EmulateInstructionARM::EmulateLDRImmediateARM, 13115 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"}, 13116 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13117 &EmulateInstructionARM::EmulateLDRRegister, 13118 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"}, 13119 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13120 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 13121 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13122 &EmulateInstructionARM::EmulateLDRBRegister, 13123 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"}, 13124 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13125 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13126 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13127 &EmulateInstructionARM::EmulateLDRHRegister, 13128 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13129 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13130 &EmulateInstructionARM::EmulateLDRSBImmediate, 13131 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"}, 13132 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13133 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"}, 13134 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13135 &EmulateInstructionARM::EmulateLDRSBRegister, 13136 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13137 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13138 &EmulateInstructionARM::EmulateLDRSHImmediate, 13139 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 13140 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13141 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13142 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13143 &EmulateInstructionARM::EmulateLDRSHRegister, 13144 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13145 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13146 &EmulateInstructionARM::EmulateLDRDImmediate, 13147 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 13148 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13149 &EmulateInstructionARM::EmulateLDRDRegister, 13150 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13151 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13152 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13153 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13154 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13155 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13156 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13157 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13158 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13159 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13160 &EmulateInstructionARM::EmulateVLD1Multiple, 13161 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13162 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13163 &EmulateInstructionARM::EmulateVLD1Single, 13164 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13165 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13166 &EmulateInstructionARM::EmulateVLD1SingleAll, 13167 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13168 13169 //---------------------------------------------------------------------- 13170 // Store instructions 13171 //---------------------------------------------------------------------- 13172 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13173 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13174 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13175 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"}, 13176 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13177 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13178 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13179 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"}, 13180 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13181 &EmulateInstructionARM::EmulateSTRRegister, 13182 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"}, 13183 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13184 &EmulateInstructionARM::EmulateSTRHRegister, 13185 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"}, 13186 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13187 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 13188 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13189 &EmulateInstructionARM::EmulateSTRBImmARM, 13190 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13191 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13192 &EmulateInstructionARM::EmulateSTRImmARM, 13193 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13194 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13195 &EmulateInstructionARM::EmulateSTRDImm, 13196 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 13197 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13198 &EmulateInstructionARM::EmulateSTRDReg, 13199 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13200 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13201 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13202 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13203 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13204 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13205 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 13206 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13207 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 13208 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13209 &EmulateInstructionARM::EmulateVST1Multiple, 13210 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13211 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13212 &EmulateInstructionARM::EmulateVST1Single, 13213 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13214 13215 //---------------------------------------------------------------------- 13216 // Other instructions 13217 //---------------------------------------------------------------------- 13218 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13219 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13220 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13221 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"}, 13222 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13223 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13224 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13225 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"}, 13226 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13227 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"} 13228 13229 }; 13230 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 13231 13232 for (size_t i = 0; i < k_num_arm_opcodes; ++i) { 13233 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 13234 (g_arm_opcodes[i].variants & arm_isa) != 0) 13235 return &g_arm_opcodes[i]; 13236 } 13237 return NULL; 13238 } 13239 13240 EmulateInstructionARM::ARMOpcode * 13241 EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode, 13242 uint32_t arm_isa) { 13243 13244 static ARMOpcode g_thumb_opcodes[] = { 13245 //---------------------------------------------------------------------- 13246 // Prologue instructions 13247 //---------------------------------------------------------------------- 13248 13249 // push register(s) 13250 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, 13251 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 13252 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13253 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"}, 13254 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13255 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"}, 13256 13257 // set r7 to point to a stack offset 13258 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13259 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"}, 13260 // copy the stack pointer to r7 13261 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, 13262 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"}, 13263 // move from high register to low register (comes after "mov r7, sp" to 13264 // resolve ambiguity) 13265 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, 13266 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"}, 13267 13268 // PC-relative load into register (see also EmulateADDSPRm) 13269 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13270 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 13271 13272 // adjust the stack pointer 13273 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, 13274 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 13275 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13276 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 13277 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13278 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 13279 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13280 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 13281 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13282 &EmulateInstructionARM::EmulateSUBSPReg, 13283 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 13284 13285 // vector push consecutive extension register(s) 13286 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13287 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 13288 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13289 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 13290 13291 //---------------------------------------------------------------------- 13292 // Epilogue instructions 13293 //---------------------------------------------------------------------- 13294 13295 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13296 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 13297 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13298 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 13299 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13300 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 13301 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13302 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"}, 13303 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13304 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"}, 13305 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13306 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 13307 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13308 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 13309 13310 //---------------------------------------------------------------------- 13311 // Supervisor Call (previously Software Interrupt) 13312 //---------------------------------------------------------------------- 13313 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13314 &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 13315 13316 //---------------------------------------------------------------------- 13317 // If Then makes up to four following instructions conditional. 13318 //---------------------------------------------------------------------- 13319 // The next 5 opcode _must_ come before the if then instruction 13320 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13321 &EmulateInstructionARM::EmulateNop, "nop"}, 13322 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13323 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 13324 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13325 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 13326 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13327 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 13328 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13329 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 13330 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13331 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 13332 13333 //---------------------------------------------------------------------- 13334 // Branch instructions 13335 //---------------------------------------------------------------------- 13336 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 13337 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13338 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 13339 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13340 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 13341 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13342 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 13343 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13344 &EmulateInstructionARM::EmulateB, 13345 "b<c>.w #imm8 (outside or last in IT)"}, 13346 // J1 == J2 == 1 13347 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, 13348 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 13349 // J1 == J2 == 1 13350 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, 13351 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 13352 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, 13353 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 13354 // for example, "bx lr" 13355 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, 13356 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 13357 // bxj 13358 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, 13359 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 13360 // compare and branch 13361 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13362 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 13363 // table branch byte 13364 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13365 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 13366 // table branch halfword 13367 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13368 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 13369 13370 //---------------------------------------------------------------------- 13371 // Data-processing instructions 13372 //---------------------------------------------------------------------- 13373 // adc (immediate) 13374 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13375 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 13376 // adc (register) 13377 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, 13378 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 13379 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13380 &EmulateInstructionARM::EmulateADCReg, 13381 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13382 // add (register) 13383 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13384 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 13385 // Make sure "add sp, <Rm>" comes before this instruction, so there's no 13386 // ambiguity decoding the two. 13387 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, 13388 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 13389 // adr 13390 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13391 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13392 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13393 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 13394 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13395 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13396 // and (immediate) 13397 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13398 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 13399 // and (register) 13400 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13401 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 13402 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13403 &EmulateInstructionARM::EmulateANDReg, 13404 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13405 // bic (immediate) 13406 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13407 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 13408 // bic (register) 13409 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, 13410 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 13411 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13412 &EmulateInstructionARM::EmulateBICReg, 13413 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13414 // eor (immediate) 13415 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13416 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 13417 // eor (register) 13418 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, 13419 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 13420 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13421 &EmulateInstructionARM::EmulateEORReg, 13422 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13423 // orr (immediate) 13424 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13425 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 13426 // orr (register) 13427 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, 13428 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 13429 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13430 &EmulateInstructionARM::EmulateORRReg, 13431 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13432 // rsb (immediate) 13433 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, 13434 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 13435 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13436 &EmulateInstructionARM::EmulateRSBImm, 13437 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 13438 // rsb (register) 13439 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13440 &EmulateInstructionARM::EmulateRSBReg, 13441 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13442 // sbc (immediate) 13443 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13444 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13445 // sbc (register) 13446 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, 13447 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 13448 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13449 &EmulateInstructionARM::EmulateSBCReg, 13450 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13451 // add (immediate, Thumb) 13452 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13453 &EmulateInstructionARM::EmulateADDImmThumb, 13454 "adds|add<c> <Rd>,<Rn>,#<imm3>"}, 13455 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13456 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"}, 13457 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13458 &EmulateInstructionARM::EmulateADDImmThumb, 13459 "add{s}<c>.w <Rd>,<Rn>,#<const>"}, 13460 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13461 &EmulateInstructionARM::EmulateADDImmThumb, 13462 "addw<c> <Rd>,<Rn>,#<imm12>"}, 13463 // sub (immediate, Thumb) 13464 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13465 &EmulateInstructionARM::EmulateSUBImmThumb, 13466 "subs|sub<c> <Rd>, <Rn> #imm3"}, 13467 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, 13468 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 13469 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13470 &EmulateInstructionARM::EmulateSUBImmThumb, 13471 "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 13472 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13473 &EmulateInstructionARM::EmulateSUBImmThumb, 13474 "subw<c> <Rd>, <Rn>, #imm12"}, 13475 // sub (sp minus immediate) 13476 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13477 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 13478 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13479 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 13480 // sub (register) 13481 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13482 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 13483 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13484 &EmulateInstructionARM::EmulateSUBReg, 13485 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 13486 // teq (immediate) 13487 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13488 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 13489 // teq (register) 13490 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13491 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13492 // tst (immediate) 13493 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13494 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 13495 // tst (register) 13496 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, 13497 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 13498 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13499 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 13500 13501 // move from high register to high register 13502 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, 13503 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 13504 // move from low register to low register 13505 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13506 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 13507 // mov{s}<c>.w <Rd>, <Rm> 13508 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13509 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 13510 // move immediate 13511 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13512 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 13513 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13514 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 13515 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13516 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 13517 // mvn (immediate) 13518 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13519 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 13520 // mvn (register) 13521 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13522 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 13523 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13524 &EmulateInstructionARM::EmulateMVNReg, 13525 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 13526 // cmn (immediate) 13527 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13528 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13529 // cmn (register) 13530 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13531 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 13532 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13533 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13534 // cmp (immediate) 13535 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13536 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 13537 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13538 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 13539 // cmp (register) (Rn and Rm both from r0-r7) 13540 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, 13541 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13542 // cmp (register) (Rn and Rm not both from r0-r7) 13543 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, 13544 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13545 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, 13546 &EmulateInstructionARM::EmulateCMPReg, 13547 "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 13548 // asr (immediate) 13549 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13550 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 13551 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13552 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 13553 // asr (register) 13554 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, 13555 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 13556 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13557 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13558 // lsl (immediate) 13559 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13560 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 13561 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13562 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 13563 // lsl (register) 13564 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13565 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 13566 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13567 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13568 // lsr (immediate) 13569 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13570 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 13571 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13572 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 13573 // lsr (register) 13574 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13575 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 13576 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13577 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13578 // rrx is a special case encoding of ror (immediate) 13579 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13580 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 13581 // ror (immediate) 13582 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13583 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 13584 // ror (register) 13585 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13586 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 13587 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13588 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13589 // mul 13590 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13591 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"}, 13592 // mul 13593 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13594 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"}, 13595 13596 // subs pc, lr and related instructions 13597 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13598 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"}, 13599 13600 //---------------------------------------------------------------------- 13601 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE 13602 // LDM.. Instructions in this table; 13603 // otherwise the wrong instructions will be selected. 13604 //---------------------------------------------------------------------- 13605 13606 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13607 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"}, 13608 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13609 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"}, 13610 13611 //---------------------------------------------------------------------- 13612 // Load instructions 13613 //---------------------------------------------------------------------- 13614 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13615 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13616 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13617 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"}, 13618 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13619 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13620 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13621 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 13622 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13623 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 13624 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13625 &EmulateInstructionARM::EmulateLDRRtRnImm, 13626 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 13627 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13628 &EmulateInstructionARM::EmulateLDRRtRnImm, 13629 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 13630 // Thumb2 PC-relative load into register 13631 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13632 &EmulateInstructionARM::EmulateLDRRtPCRelative, 13633 "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 13634 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13635 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"}, 13636 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13637 &EmulateInstructionARM::EmulateLDRRegister, 13638 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"}, 13639 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13640 &EmulateInstructionARM::EmulateLDRBImmediate, 13641 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"}, 13642 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13643 &EmulateInstructionARM::EmulateLDRBImmediate, 13644 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13645 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13646 &EmulateInstructionARM::EmulateLDRBImmediate, 13647 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"}, 13648 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13649 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"}, 13650 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13651 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"}, 13652 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13653 &EmulateInstructionARM::EmulateLDRBRegister, 13654 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13655 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13656 &EmulateInstructionARM::EmulateLDRHImmediate, 13657 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"}, 13658 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13659 &EmulateInstructionARM::EmulateLDRHImmediate, 13660 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13661 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13662 &EmulateInstructionARM::EmulateLDRHImmediate, 13663 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"}, 13664 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13665 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13666 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13667 &EmulateInstructionARM::EmulateLDRHRegister, 13668 "ldrh<c> <Rt>, [<Rn>,<Rm>]"}, 13669 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13670 &EmulateInstructionARM::EmulateLDRHRegister, 13671 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13672 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13673 &EmulateInstructionARM::EmulateLDRSBImmediate, 13674 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"}, 13675 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13676 &EmulateInstructionARM::EmulateLDRSBImmediate, 13677 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13678 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13679 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"}, 13680 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13681 &EmulateInstructionARM::EmulateLDRSBRegister, 13682 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"}, 13683 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13684 &EmulateInstructionARM::EmulateLDRSBRegister, 13685 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13686 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13687 &EmulateInstructionARM::EmulateLDRSHImmediate, 13688 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"}, 13689 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13690 &EmulateInstructionARM::EmulateLDRSHImmediate, 13691 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13692 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13693 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13694 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13695 &EmulateInstructionARM::EmulateLDRSHRegister, 13696 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"}, 13697 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13698 &EmulateInstructionARM::EmulateLDRSHRegister, 13699 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13700 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13701 &EmulateInstructionARM::EmulateLDRDImmediate, 13702 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 13703 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13704 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13705 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13706 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13707 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13708 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13709 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13710 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 13711 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13712 &EmulateInstructionARM::EmulateVLD1Multiple, 13713 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13714 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13715 &EmulateInstructionARM::EmulateVLD1Single, 13716 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13717 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13718 &EmulateInstructionARM::EmulateVLD1SingleAll, 13719 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13720 13721 //---------------------------------------------------------------------- 13722 // Store instructions 13723 //---------------------------------------------------------------------- 13724 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13725 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13726 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13727 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"}, 13728 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13729 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13730 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13731 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"}, 13732 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13733 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"}, 13734 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13735 &EmulateInstructionARM::EmulateSTRThumb, 13736 "str<c>.w <Rt>, [<Rn>,#<imm12>]"}, 13737 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13738 &EmulateInstructionARM::EmulateSTRThumb, 13739 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"}, 13740 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13741 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"}, 13742 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13743 &EmulateInstructionARM::EmulateSTRRegister, 13744 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"}, 13745 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13746 &EmulateInstructionARM::EmulateSTRBThumb, 13747 "strb<c> <Rt>, [<Rn>, #<imm5>]"}, 13748 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13749 &EmulateInstructionARM::EmulateSTRBThumb, 13750 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"}, 13751 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13752 &EmulateInstructionARM::EmulateSTRBThumb, 13753 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"}, 13754 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13755 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"}, 13756 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13757 &EmulateInstructionARM::EmulateSTRHRegister, 13758 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13759 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13760 &EmulateInstructionARM::EmulateSTREX, 13761 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"}, 13762 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13763 &EmulateInstructionARM::EmulateSTRDImm, 13764 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 13765 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13766 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13767 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13768 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13769 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13770 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13771 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13772 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13773 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13774 &EmulateInstructionARM::EmulateVST1Multiple, 13775 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13776 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13777 &EmulateInstructionARM::EmulateVST1Single, 13778 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13779 13780 //---------------------------------------------------------------------- 13781 // Other instructions 13782 //---------------------------------------------------------------------- 13783 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13784 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"}, 13785 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, 13786 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13787 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13788 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"}, 13789 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13790 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13791 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13792 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"}, 13793 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13794 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13795 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13796 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"}, 13797 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13798 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13799 }; 13800 13801 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 13802 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) { 13803 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 13804 (g_thumb_opcodes[i].variants & arm_isa) != 0) 13805 return &g_thumb_opcodes[i]; 13806 } 13807 return NULL; 13808 } 13809 13810 bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) { 13811 m_arch = arch; 13812 m_arm_isa = 0; 13813 const char *arch_cstr = arch.GetArchitectureName(); 13814 if (arch_cstr) { 13815 if (0 == ::strcasecmp(arch_cstr, "armv4t")) 13816 m_arm_isa = ARMv4T; 13817 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) 13818 m_arm_isa = ARMv5TEJ; 13819 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) 13820 m_arm_isa = ARMv5TE; 13821 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) 13822 m_arm_isa = ARMv5T; 13823 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) 13824 m_arm_isa = ARMv6K; 13825 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) 13826 m_arm_isa = ARMv6T2; 13827 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) 13828 m_arm_isa = ARMv7S; 13829 else if (0 == ::strcasecmp(arch_cstr, "arm")) 13830 m_arm_isa = ARMvAll; 13831 else if (0 == ::strcasecmp(arch_cstr, "thumb")) 13832 m_arm_isa = ARMvAll; 13833 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5)) 13834 m_arm_isa = ARMv4; 13835 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5)) 13836 m_arm_isa = ARMv6; 13837 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5)) 13838 m_arm_isa = ARMv7; 13839 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5)) 13840 m_arm_isa = ARMv8; 13841 } 13842 return m_arm_isa != 0; 13843 } 13844 13845 bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode, 13846 const Address &inst_addr, 13847 Target *target) { 13848 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { 13849 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || 13850 m_arch.IsAlwaysThumbInstructions()) 13851 m_opcode_mode = eModeThumb; 13852 else { 13853 AddressClass addr_class = inst_addr.GetAddressClass(); 13854 13855 if ((addr_class == AddressClass::eCode) || 13856 (addr_class == AddressClass::eUnknown)) 13857 m_opcode_mode = eModeARM; 13858 else if (addr_class == AddressClass::eCodeAlternateISA) 13859 m_opcode_mode = eModeThumb; 13860 else 13861 return false; 13862 } 13863 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions()) 13864 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13865 else 13866 m_opcode_cpsr = CPSR_MODE_USR; 13867 return true; 13868 } 13869 return false; 13870 } 13871 13872 bool EmulateInstructionARM::ReadInstruction() { 13873 bool success = false; 13874 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric, 13875 LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13876 if (success) { 13877 addr_t pc = 13878 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 13879 LLDB_INVALID_ADDRESS, &success); 13880 if (success) { 13881 Context read_inst_context; 13882 read_inst_context.type = eContextReadOpcode; 13883 read_inst_context.SetNoArgs(); 13884 13885 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) { 13886 m_opcode_mode = eModeThumb; 13887 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13888 13889 if (success) { 13890 if ((thumb_opcode & 0xe000) != 0xe000 || 13891 ((thumb_opcode & 0x1800u) == 0)) { 13892 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder()); 13893 } else { 13894 m_opcode.SetOpcode32( 13895 (thumb_opcode << 16) | 13896 MemARead(read_inst_context, pc + 2, 2, 0, &success), 13897 GetByteOrder()); 13898 } 13899 } 13900 } else { 13901 m_opcode_mode = eModeARM; 13902 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success), 13903 GetByteOrder()); 13904 } 13905 13906 if (!m_ignore_conditions) { 13907 // If we are not ignoreing the conditions then init the it session from 13908 // the current value of cpsr. 13909 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | 13910 Bits32(m_opcode_cpsr, 26, 25); 13911 if (it != 0) 13912 m_it_session.InitIT(it); 13913 } 13914 } 13915 } 13916 if (!success) { 13917 m_opcode_mode = eModeInvalid; 13918 m_addr = LLDB_INVALID_ADDRESS; 13919 } 13920 return success; 13921 } 13922 13923 uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; } 13924 13925 bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) { 13926 // If we are ignoring conditions, then always return true. this allows us to 13927 // iterate over disassembly code and still emulate an instruction even if we 13928 // don't have all the right bits set in the CPSR register... 13929 if (m_ignore_conditions) 13930 return true; 13931 13932 const uint32_t cond = CurrentCond(opcode); 13933 if (cond == UINT32_MAX) 13934 return false; 13935 13936 bool result = false; 13937 switch (UnsignedBits(cond, 3, 1)) { 13938 case 0: 13939 if (m_opcode_cpsr == 0) 13940 result = true; 13941 else 13942 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13943 break; 13944 case 1: 13945 if (m_opcode_cpsr == 0) 13946 result = true; 13947 else 13948 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13949 break; 13950 case 2: 13951 if (m_opcode_cpsr == 0) 13952 result = true; 13953 else 13954 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13955 break; 13956 case 3: 13957 if (m_opcode_cpsr == 0) 13958 result = true; 13959 else 13960 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13961 break; 13962 case 4: 13963 if (m_opcode_cpsr == 0) 13964 result = true; 13965 else 13966 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && 13967 ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13968 break; 13969 case 5: 13970 if (m_opcode_cpsr == 0) 13971 result = true; 13972 else { 13973 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13974 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13975 result = n == v; 13976 } 13977 break; 13978 case 6: 13979 if (m_opcode_cpsr == 0) 13980 result = true; 13981 else { 13982 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13983 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13984 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13985 } 13986 break; 13987 case 7: 13988 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13989 // opcodes different meanings, but always means execution happens. 13990 return true; 13991 } 13992 13993 if (cond & 1) 13994 result = !result; 13995 return result; 13996 } 13997 13998 uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) { 13999 switch (m_opcode_mode) { 14000 case eModeInvalid: 14001 break; 14002 14003 case eModeARM: 14004 return UnsignedBits(opcode, 31, 28); 14005 14006 case eModeThumb: 14007 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 14008 // 'cond' field of the encoding. 14009 { 14010 const uint32_t byte_size = m_opcode.GetByteSize(); 14011 if (byte_size == 2) { 14012 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 14013 return Bits32(opcode, 11, 8); 14014 } else if (byte_size == 4) { 14015 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 && 14016 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) { 14017 return Bits32(opcode, 25, 22); 14018 } 14019 } else 14020 // We have an invalid thumb instruction, let's bail out. 14021 break; 14022 14023 return m_it_session.GetCond(); 14024 } 14025 } 14026 return UINT32_MAX; // Return invalid value 14027 } 14028 14029 bool EmulateInstructionARM::InITBlock() { 14030 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 14031 } 14032 14033 bool EmulateInstructionARM::LastInITBlock() { 14034 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 14035 } 14036 14037 bool EmulateInstructionARM::BadMode(uint32_t mode) { 14038 14039 switch (mode) { 14040 case 16: 14041 return false; // '10000' 14042 case 17: 14043 return false; // '10001' 14044 case 18: 14045 return false; // '10010' 14046 case 19: 14047 return false; // '10011' 14048 case 22: 14049 return false; // '10110' 14050 case 23: 14051 return false; // '10111' 14052 case 27: 14053 return false; // '11011' 14054 case 31: 14055 return false; // '11111' 14056 default: 14057 return true; 14058 } 14059 return true; 14060 } 14061 14062 bool EmulateInstructionARM::CurrentModeIsPrivileged() { 14063 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0); 14064 14065 if (BadMode(mode)) 14066 return false; 14067 14068 if (mode == 16) 14069 return false; 14070 14071 return true; 14072 } 14073 14074 void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask, 14075 bool affect_execstate) { 14076 bool privileged = CurrentModeIsPrivileged(); 14077 14078 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20; 14079 14080 if (BitIsSet(bytemask, 3)) { 14081 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27); 14082 if (affect_execstate) 14083 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24); 14084 } 14085 14086 if (BitIsSet(bytemask, 2)) { 14087 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16); 14088 } 14089 14090 if (BitIsSet(bytemask, 1)) { 14091 if (affect_execstate) 14092 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10); 14093 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9); 14094 if (privileged) 14095 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8); 14096 } 14097 14098 if (BitIsSet(bytemask, 0)) { 14099 if (privileged) 14100 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6); 14101 if (affect_execstate) 14102 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5); 14103 if (privileged) 14104 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0); 14105 } 14106 14107 m_opcode_cpsr = tmp_cpsr; 14108 } 14109 14110 bool EmulateInstructionARM::BranchWritePC(const Context &context, 14111 uint32_t addr) { 14112 addr_t target; 14113 14114 // Check the current instruction set. 14115 if (CurrentInstrSet() == eModeARM) 14116 target = addr & 0xfffffffc; 14117 else 14118 target = addr & 0xfffffffe; 14119 14120 return WriteRegisterUnsigned(context, eRegisterKindGeneric, 14121 LLDB_REGNUM_GENERIC_PC, target); 14122 } 14123 14124 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by 14125 // inspecting addr. 14126 bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) { 14127 addr_t target; 14128 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 14129 // we want to record it and issue a WriteRegister callback so the clients can 14130 // track the mode changes accordingly. 14131 bool cpsr_changed = false; 14132 14133 if (BitIsSet(addr, 0)) { 14134 if (CurrentInstrSet() != eModeThumb) { 14135 SelectInstrSet(eModeThumb); 14136 cpsr_changed = true; 14137 } 14138 target = addr & 0xfffffffe; 14139 context.SetISA(eModeThumb); 14140 } else if (BitIsClear(addr, 1)) { 14141 if (CurrentInstrSet() != eModeARM) { 14142 SelectInstrSet(eModeARM); 14143 cpsr_changed = true; 14144 } 14145 target = addr & 0xfffffffc; 14146 context.SetISA(eModeARM); 14147 } else 14148 return false; // address<1:0> == '10' => UNPREDICTABLE 14149 14150 if (cpsr_changed) { 14151 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14152 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14153 return false; 14154 } 14155 return WriteRegisterUnsigned(context, eRegisterKindGeneric, 14156 LLDB_REGNUM_GENERIC_PC, target); 14157 } 14158 14159 // Dispatches to either BXWritePC or BranchWritePC based on architecture 14160 // versions. 14161 bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) { 14162 if (ArchVersion() >= ARMv5T) 14163 return BXWritePC(context, addr); 14164 else 14165 return BranchWritePC((const Context)context, addr); 14166 } 14167 14168 // Dispatches to either BXWritePC or BranchWritePC based on architecture 14169 // versions and current instruction set. 14170 bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) { 14171 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 14172 return BXWritePC(context, addr); 14173 else 14174 return BranchWritePC((const Context)context, addr); 14175 } 14176 14177 EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() { 14178 return m_opcode_mode; 14179 } 14180 14181 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 14182 // ReadInstruction() is performed. This function has a side effect of updating 14183 // the m_new_inst_cpsr member variable if necessary. 14184 bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) { 14185 m_new_inst_cpsr = m_opcode_cpsr; 14186 switch (arm_or_thumb) { 14187 default: 14188 return false; 14189 case eModeARM: 14190 // Clear the T bit. 14191 m_new_inst_cpsr &= ~MASK_CPSR_T; 14192 break; 14193 case eModeThumb: 14194 // Set the T bit. 14195 m_new_inst_cpsr |= MASK_CPSR_T; 14196 break; 14197 } 14198 return true; 14199 } 14200 14201 // This function returns TRUE if the processor currently provides support for 14202 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 14203 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 14204 bool EmulateInstructionARM::UnalignedSupport() { 14205 return (ArchVersion() >= ARMv7); 14206 } 14207 14208 // The main addition and subtraction instructions can produce status 14209 // information about both unsigned carry and signed overflow conditions. This 14210 // status information can be used to synthesize multi-word additions and 14211 // subtractions. 14212 EmulateInstructionARM::AddWithCarryResult 14213 EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) { 14214 uint32_t result; 14215 uint8_t carry_out; 14216 uint8_t overflow; 14217 14218 uint64_t unsigned_sum = x + y + carry_in; 14219 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 14220 14221 result = UnsignedBits(unsigned_sum, 31, 0); 14222 // carry_out = (result == unsigned_sum ? 0 : 1); 14223 overflow = ((int32_t)result == signed_sum ? 0 : 1); 14224 14225 if (carry_in) 14226 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0; 14227 else 14228 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0; 14229 14230 AddWithCarryResult res = {result, carry_out, overflow}; 14231 return res; 14232 } 14233 14234 uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) { 14235 lldb::RegisterKind reg_kind; 14236 uint32_t reg_num; 14237 switch (num) { 14238 case SP_REG: 14239 reg_kind = eRegisterKindGeneric; 14240 reg_num = LLDB_REGNUM_GENERIC_SP; 14241 break; 14242 case LR_REG: 14243 reg_kind = eRegisterKindGeneric; 14244 reg_num = LLDB_REGNUM_GENERIC_RA; 14245 break; 14246 case PC_REG: 14247 reg_kind = eRegisterKindGeneric; 14248 reg_num = LLDB_REGNUM_GENERIC_PC; 14249 break; 14250 default: 14251 if (num < SP_REG) { 14252 reg_kind = eRegisterKindDWARF; 14253 reg_num = dwarf_r0 + num; 14254 } else { 14255 // assert(0 && "Invalid register number"); 14256 *success = false; 14257 return UINT32_MAX; 14258 } 14259 break; 14260 } 14261 14262 // Read our register. 14263 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success); 14264 14265 // When executing an ARM instruction , PC reads as the address of the current 14266 // instruction plus 8. When executing a Thumb instruction , PC reads as the 14267 // address of the current instruction plus 4. 14268 if (num == 15) { 14269 if (CurrentInstrSet() == eModeARM) 14270 val += 8; 14271 else 14272 val += 4; 14273 } 14274 14275 return val; 14276 } 14277 14278 // Write the result to the ARM core register Rd, and optionally update the 14279 // condition flags based on the result. 14280 // 14281 // This helper method tries to encapsulate the following pseudocode from the 14282 // ARM Architecture Reference Manual: 14283 // 14284 // if d == 15 then // Can only occur for encoding A1 14285 // ALUWritePC(result); // setflags is always FALSE here 14286 // else 14287 // R[d] = result; 14288 // if setflags then 14289 // APSR.N = result<31>; 14290 // APSR.Z = IsZeroBit(result); 14291 // APSR.C = carry; 14292 // // APSR.V unchanged 14293 // 14294 // In the above case, the API client does not pass in the overflow arg, which 14295 // defaults to ~0u. 14296 bool EmulateInstructionARM::WriteCoreRegOptionalFlags( 14297 Context &context, const uint32_t result, const uint32_t Rd, bool setflags, 14298 const uint32_t carry, const uint32_t overflow) { 14299 if (Rd == 15) { 14300 if (!ALUWritePC(context, result)) 14301 return false; 14302 } else { 14303 lldb::RegisterKind reg_kind; 14304 uint32_t reg_num; 14305 switch (Rd) { 14306 case SP_REG: 14307 reg_kind = eRegisterKindGeneric; 14308 reg_num = LLDB_REGNUM_GENERIC_SP; 14309 break; 14310 case LR_REG: 14311 reg_kind = eRegisterKindGeneric; 14312 reg_num = LLDB_REGNUM_GENERIC_RA; 14313 break; 14314 default: 14315 reg_kind = eRegisterKindDWARF; 14316 reg_num = dwarf_r0 + Rd; 14317 } 14318 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result)) 14319 return false; 14320 if (setflags) 14321 return WriteFlags(context, result, carry, overflow); 14322 } 14323 return true; 14324 } 14325 14326 // This helper method tries to encapsulate the following pseudocode from the 14327 // ARM Architecture Reference Manual: 14328 // 14329 // APSR.N = result<31>; 14330 // APSR.Z = IsZeroBit(result); 14331 // APSR.C = carry; 14332 // APSR.V = overflow 14333 // 14334 // Default arguments can be specified for carry and overflow parameters, which 14335 // means not to update the respective flags. 14336 bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result, 14337 const uint32_t carry, 14338 const uint32_t overflow) { 14339 m_new_inst_cpsr = m_opcode_cpsr; 14340 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 14341 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 14342 if (carry != ~0u) 14343 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 14344 if (overflow != ~0u) 14345 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 14346 if (m_new_inst_cpsr != m_opcode_cpsr) { 14347 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14348 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14349 return false; 14350 } 14351 return true; 14352 } 14353 14354 bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) { 14355 ARMOpcode *opcode_data = NULL; 14356 14357 if (m_opcode_mode == eModeThumb) 14358 opcode_data = 14359 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14360 else if (m_opcode_mode == eModeARM) 14361 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14362 14363 const bool auto_advance_pc = 14364 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 14365 m_ignore_conditions = 14366 evaluate_options & eEmulateInstructionOptionIgnoreConditions; 14367 14368 bool success = false; 14369 if (m_opcode_cpsr == 0 || !m_ignore_conditions) { 14370 m_opcode_cpsr = 14371 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 14372 } 14373 14374 // Only return false if we are unable to read the CPSR if we care about 14375 // conditions 14376 if (!success && !m_ignore_conditions) 14377 return false; 14378 14379 uint32_t orig_pc_value = 0; 14380 if (auto_advance_pc) { 14381 orig_pc_value = 14382 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14383 if (!success) 14384 return false; 14385 } 14386 14387 // Call the Emulate... function if we managed to decode the opcode. 14388 if (opcode_data) { 14389 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(), 14390 opcode_data->encoding); 14391 if (!success) 14392 return false; 14393 } 14394 14395 // Advance the ITSTATE bits to their values for the next instruction if we 14396 // haven't just executed an IT instruction what initialized it. 14397 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() && 14398 (opcode_data == nullptr || 14399 opcode_data->callback != &EmulateInstructionARM::EmulateIT)) 14400 m_it_session.ITAdvance(); 14401 14402 if (auto_advance_pc) { 14403 uint32_t after_pc_value = 14404 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14405 if (!success) 14406 return false; 14407 14408 if (auto_advance_pc && (after_pc_value == orig_pc_value)) { 14409 after_pc_value += m_opcode.GetByteSize(); 14410 14411 EmulateInstruction::Context context; 14412 context.type = eContextAdvancePC; 14413 context.SetNoArgs(); 14414 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc, 14415 after_pc_value)) 14416 return false; 14417 } 14418 } 14419 return true; 14420 } 14421 14422 EmulateInstruction::InstructionCondition 14423 EmulateInstructionARM::GetInstructionCondition() { 14424 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32()); 14425 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX) 14426 return EmulateInstruction::UnconditionalCondition; 14427 return cond; 14428 } 14429 14430 bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, 14431 OptionValueDictionary *test_data) { 14432 if (!test_data) { 14433 out_stream->Printf("TestEmulation: Missing test data.\n"); 14434 return false; 14435 } 14436 14437 static ConstString opcode_key("opcode"); 14438 static ConstString before_key("before_state"); 14439 static ConstString after_key("after_state"); 14440 14441 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key); 14442 14443 uint32_t test_opcode; 14444 if ((value_sp.get() == NULL) || 14445 (value_sp->GetType() != OptionValue::eTypeUInt64)) { 14446 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n"); 14447 return false; 14448 } 14449 test_opcode = value_sp->GetUInt64Value(); 14450 14451 if (arch.GetTriple().getArch() == llvm::Triple::thumb || 14452 arch.IsAlwaysThumbInstructions()) { 14453 m_opcode_mode = eModeThumb; 14454 if (test_opcode < 0x10000) 14455 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder()); 14456 else 14457 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14458 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) { 14459 m_opcode_mode = eModeARM; 14460 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14461 } else { 14462 out_stream->Printf("TestEmulation: Invalid arch.\n"); 14463 return false; 14464 } 14465 14466 EmulationStateARM before_state; 14467 EmulationStateARM after_state; 14468 14469 value_sp = test_data->GetValueForKey(before_key); 14470 if ((value_sp.get() == NULL) || 14471 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14472 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n"); 14473 return false; 14474 } 14475 14476 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary(); 14477 if (!before_state.LoadStateFromDictionary(state_dictionary)) { 14478 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n"); 14479 return false; 14480 } 14481 14482 value_sp = test_data->GetValueForKey(after_key); 14483 if ((value_sp.get() == NULL) || 14484 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14485 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n"); 14486 return false; 14487 } 14488 14489 state_dictionary = value_sp->GetAsDictionary(); 14490 if (!after_state.LoadStateFromDictionary(state_dictionary)) { 14491 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n"); 14492 return false; 14493 } 14494 14495 SetBaton((void *)&before_state); 14496 SetCallbacks(&EmulationStateARM::ReadPseudoMemory, 14497 &EmulationStateARM::WritePseudoMemory, 14498 &EmulationStateARM::ReadPseudoRegister, 14499 &EmulationStateARM::WritePseudoRegister); 14500 14501 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 14502 if (!success) { 14503 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n"); 14504 return false; 14505 } 14506 14507 success = before_state.CompareState(after_state); 14508 if (!success) 14509 out_stream->Printf( 14510 "TestEmulation: 'before' and 'after' states do not match.\n"); 14511 14512 return success; 14513 } 14514 // 14515 // 14516 // const char * 14517 // EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 14518 //{ 14519 // if (reg_kind == eRegisterKindGeneric) 14520 // { 14521 // switch (reg_num) 14522 // { 14523 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 14524 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 14525 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 14526 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 14527 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 14528 // default: return NULL; 14529 // } 14530 // } 14531 // else if (reg_kind == eRegisterKindDWARF) 14532 // { 14533 // return GetARMDWARFRegisterName (reg_num); 14534 // } 14535 // return NULL; 14536 //} 14537 // 14538 bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { 14539 unwind_plan.Clear(); 14540 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 14541 14542 UnwindPlan::RowSP row(new UnwindPlan::Row); 14543 14544 // Our previous Call Frame Address is the stack pointer 14545 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0); 14546 14547 unwind_plan.AppendRow(row); 14548 unwind_plan.SetSourceName("EmulateInstructionARM"); 14549 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 14550 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 14551 unwind_plan.SetReturnAddressRegister(dwarf_lr); 14552 return true; 14553 } 14554