1 //===-- EmulateInstructionARM.cpp -----------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include <stdlib.h> 10 11 #include "EmulateInstructionARM.h" 12 #include "EmulationStateARM.h" 13 #include "lldb/Core/Address.h" 14 #include "lldb/Core/PluginManager.h" 15 #include "lldb/Host/PosixApi.h" 16 #include "lldb/Interpreter/OptionValueArray.h" 17 #include "lldb/Interpreter/OptionValueDictionary.h" 18 #include "lldb/Symbol/UnwindPlan.h" 19 #include "lldb/Utility/ArchSpec.h" 20 #include "lldb/Utility/ConstString.h" 21 #include "lldb/Utility/Stream.h" 22 23 #include "Plugins/Process/Utility/ARMDefines.h" 24 #include "Plugins/Process/Utility/ARMUtils.h" 25 #include "Utility/ARM_DWARF_Registers.h" 26 27 #include "llvm/ADT/STLExtras.h" 28 #include "llvm/Support/MathExtras.h" 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionARM, InstructionARM) 34 35 // Convenient macro definitions. 36 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 37 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 38 39 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 40 41 // 42 // ITSession implementation 43 // 44 45 static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo ®_info) { 46 ::memset(®_info, 0, sizeof(RegisterInfo)); 47 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); 48 49 if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) { 50 reg_info.byte_size = 16; 51 reg_info.format = eFormatVectorOfUInt8; 52 reg_info.encoding = eEncodingVector; 53 } 54 55 if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) { 56 reg_info.byte_size = 8; 57 reg_info.format = eFormatFloat; 58 reg_info.encoding = eEncodingIEEE754; 59 } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) { 60 reg_info.byte_size = 4; 61 reg_info.format = eFormatFloat; 62 reg_info.encoding = eEncodingIEEE754; 63 } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) { 64 reg_info.byte_size = 12; 65 reg_info.format = eFormatFloat; 66 reg_info.encoding = eEncodingIEEE754; 67 } else { 68 reg_info.byte_size = 4; 69 reg_info.format = eFormatHex; 70 reg_info.encoding = eEncodingUint; 71 } 72 73 reg_info.kinds[eRegisterKindDWARF] = reg_num; 74 75 switch (reg_num) { 76 case dwarf_r0: 77 reg_info.name = "r0"; 78 break; 79 case dwarf_r1: 80 reg_info.name = "r1"; 81 break; 82 case dwarf_r2: 83 reg_info.name = "r2"; 84 break; 85 case dwarf_r3: 86 reg_info.name = "r3"; 87 break; 88 case dwarf_r4: 89 reg_info.name = "r4"; 90 break; 91 case dwarf_r5: 92 reg_info.name = "r5"; 93 break; 94 case dwarf_r6: 95 reg_info.name = "r6"; 96 break; 97 case dwarf_r7: 98 reg_info.name = "r7"; 99 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; 100 break; 101 case dwarf_r8: 102 reg_info.name = "r8"; 103 break; 104 case dwarf_r9: 105 reg_info.name = "r9"; 106 break; 107 case dwarf_r10: 108 reg_info.name = "r10"; 109 break; 110 case dwarf_r11: 111 reg_info.name = "r11"; 112 break; 113 case dwarf_r12: 114 reg_info.name = "r12"; 115 break; 116 case dwarf_sp: 117 reg_info.name = "sp"; 118 reg_info.alt_name = "r13"; 119 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; 120 break; 121 case dwarf_lr: 122 reg_info.name = "lr"; 123 reg_info.alt_name = "r14"; 124 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; 125 break; 126 case dwarf_pc: 127 reg_info.name = "pc"; 128 reg_info.alt_name = "r15"; 129 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; 130 break; 131 case dwarf_cpsr: 132 reg_info.name = "cpsr"; 133 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; 134 break; 135 136 case dwarf_s0: 137 reg_info.name = "s0"; 138 break; 139 case dwarf_s1: 140 reg_info.name = "s1"; 141 break; 142 case dwarf_s2: 143 reg_info.name = "s2"; 144 break; 145 case dwarf_s3: 146 reg_info.name = "s3"; 147 break; 148 case dwarf_s4: 149 reg_info.name = "s4"; 150 break; 151 case dwarf_s5: 152 reg_info.name = "s5"; 153 break; 154 case dwarf_s6: 155 reg_info.name = "s6"; 156 break; 157 case dwarf_s7: 158 reg_info.name = "s7"; 159 break; 160 case dwarf_s8: 161 reg_info.name = "s8"; 162 break; 163 case dwarf_s9: 164 reg_info.name = "s9"; 165 break; 166 case dwarf_s10: 167 reg_info.name = "s10"; 168 break; 169 case dwarf_s11: 170 reg_info.name = "s11"; 171 break; 172 case dwarf_s12: 173 reg_info.name = "s12"; 174 break; 175 case dwarf_s13: 176 reg_info.name = "s13"; 177 break; 178 case dwarf_s14: 179 reg_info.name = "s14"; 180 break; 181 case dwarf_s15: 182 reg_info.name = "s15"; 183 break; 184 case dwarf_s16: 185 reg_info.name = "s16"; 186 break; 187 case dwarf_s17: 188 reg_info.name = "s17"; 189 break; 190 case dwarf_s18: 191 reg_info.name = "s18"; 192 break; 193 case dwarf_s19: 194 reg_info.name = "s19"; 195 break; 196 case dwarf_s20: 197 reg_info.name = "s20"; 198 break; 199 case dwarf_s21: 200 reg_info.name = "s21"; 201 break; 202 case dwarf_s22: 203 reg_info.name = "s22"; 204 break; 205 case dwarf_s23: 206 reg_info.name = "s23"; 207 break; 208 case dwarf_s24: 209 reg_info.name = "s24"; 210 break; 211 case dwarf_s25: 212 reg_info.name = "s25"; 213 break; 214 case dwarf_s26: 215 reg_info.name = "s26"; 216 break; 217 case dwarf_s27: 218 reg_info.name = "s27"; 219 break; 220 case dwarf_s28: 221 reg_info.name = "s28"; 222 break; 223 case dwarf_s29: 224 reg_info.name = "s29"; 225 break; 226 case dwarf_s30: 227 reg_info.name = "s30"; 228 break; 229 case dwarf_s31: 230 reg_info.name = "s31"; 231 break; 232 233 // FPA Registers 0-7 234 case dwarf_f0: 235 reg_info.name = "f0"; 236 break; 237 case dwarf_f1: 238 reg_info.name = "f1"; 239 break; 240 case dwarf_f2: 241 reg_info.name = "f2"; 242 break; 243 case dwarf_f3: 244 reg_info.name = "f3"; 245 break; 246 case dwarf_f4: 247 reg_info.name = "f4"; 248 break; 249 case dwarf_f5: 250 reg_info.name = "f5"; 251 break; 252 case dwarf_f6: 253 reg_info.name = "f6"; 254 break; 255 case dwarf_f7: 256 reg_info.name = "f7"; 257 break; 258 259 // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator 260 // register 0 - 7 (they do overlap with wCGR0 - wCGR7) 261 case dwarf_wCGR0: 262 reg_info.name = "wCGR0/ACC0"; 263 break; 264 case dwarf_wCGR1: 265 reg_info.name = "wCGR1/ACC1"; 266 break; 267 case dwarf_wCGR2: 268 reg_info.name = "wCGR2/ACC2"; 269 break; 270 case dwarf_wCGR3: 271 reg_info.name = "wCGR3/ACC3"; 272 break; 273 case dwarf_wCGR4: 274 reg_info.name = "wCGR4/ACC4"; 275 break; 276 case dwarf_wCGR5: 277 reg_info.name = "wCGR5/ACC5"; 278 break; 279 case dwarf_wCGR6: 280 reg_info.name = "wCGR6/ACC6"; 281 break; 282 case dwarf_wCGR7: 283 reg_info.name = "wCGR7/ACC7"; 284 break; 285 286 // Intel wireless MMX data registers 0 - 15 287 case dwarf_wR0: 288 reg_info.name = "wR0"; 289 break; 290 case dwarf_wR1: 291 reg_info.name = "wR1"; 292 break; 293 case dwarf_wR2: 294 reg_info.name = "wR2"; 295 break; 296 case dwarf_wR3: 297 reg_info.name = "wR3"; 298 break; 299 case dwarf_wR4: 300 reg_info.name = "wR4"; 301 break; 302 case dwarf_wR5: 303 reg_info.name = "wR5"; 304 break; 305 case dwarf_wR6: 306 reg_info.name = "wR6"; 307 break; 308 case dwarf_wR7: 309 reg_info.name = "wR7"; 310 break; 311 case dwarf_wR8: 312 reg_info.name = "wR8"; 313 break; 314 case dwarf_wR9: 315 reg_info.name = "wR9"; 316 break; 317 case dwarf_wR10: 318 reg_info.name = "wR10"; 319 break; 320 case dwarf_wR11: 321 reg_info.name = "wR11"; 322 break; 323 case dwarf_wR12: 324 reg_info.name = "wR12"; 325 break; 326 case dwarf_wR13: 327 reg_info.name = "wR13"; 328 break; 329 case dwarf_wR14: 330 reg_info.name = "wR14"; 331 break; 332 case dwarf_wR15: 333 reg_info.name = "wR15"; 334 break; 335 336 case dwarf_spsr: 337 reg_info.name = "spsr"; 338 break; 339 case dwarf_spsr_fiq: 340 reg_info.name = "spsr_fiq"; 341 break; 342 case dwarf_spsr_irq: 343 reg_info.name = "spsr_irq"; 344 break; 345 case dwarf_spsr_abt: 346 reg_info.name = "spsr_abt"; 347 break; 348 case dwarf_spsr_und: 349 reg_info.name = "spsr_und"; 350 break; 351 case dwarf_spsr_svc: 352 reg_info.name = "spsr_svc"; 353 break; 354 355 case dwarf_r8_usr: 356 reg_info.name = "r8_usr"; 357 break; 358 case dwarf_r9_usr: 359 reg_info.name = "r9_usr"; 360 break; 361 case dwarf_r10_usr: 362 reg_info.name = "r10_usr"; 363 break; 364 case dwarf_r11_usr: 365 reg_info.name = "r11_usr"; 366 break; 367 case dwarf_r12_usr: 368 reg_info.name = "r12_usr"; 369 break; 370 case dwarf_r13_usr: 371 reg_info.name = "r13_usr"; 372 break; 373 case dwarf_r14_usr: 374 reg_info.name = "r14_usr"; 375 break; 376 case dwarf_r8_fiq: 377 reg_info.name = "r8_fiq"; 378 break; 379 case dwarf_r9_fiq: 380 reg_info.name = "r9_fiq"; 381 break; 382 case dwarf_r10_fiq: 383 reg_info.name = "r10_fiq"; 384 break; 385 case dwarf_r11_fiq: 386 reg_info.name = "r11_fiq"; 387 break; 388 case dwarf_r12_fiq: 389 reg_info.name = "r12_fiq"; 390 break; 391 case dwarf_r13_fiq: 392 reg_info.name = "r13_fiq"; 393 break; 394 case dwarf_r14_fiq: 395 reg_info.name = "r14_fiq"; 396 break; 397 case dwarf_r13_irq: 398 reg_info.name = "r13_irq"; 399 break; 400 case dwarf_r14_irq: 401 reg_info.name = "r14_irq"; 402 break; 403 case dwarf_r13_abt: 404 reg_info.name = "r13_abt"; 405 break; 406 case dwarf_r14_abt: 407 reg_info.name = "r14_abt"; 408 break; 409 case dwarf_r13_und: 410 reg_info.name = "r13_und"; 411 break; 412 case dwarf_r14_und: 413 reg_info.name = "r14_und"; 414 break; 415 case dwarf_r13_svc: 416 reg_info.name = "r13_svc"; 417 break; 418 case dwarf_r14_svc: 419 reg_info.name = "r14_svc"; 420 break; 421 422 // Intel wireless MMX control register in co-processor 0 - 7 423 case dwarf_wC0: 424 reg_info.name = "wC0"; 425 break; 426 case dwarf_wC1: 427 reg_info.name = "wC1"; 428 break; 429 case dwarf_wC2: 430 reg_info.name = "wC2"; 431 break; 432 case dwarf_wC3: 433 reg_info.name = "wC3"; 434 break; 435 case dwarf_wC4: 436 reg_info.name = "wC4"; 437 break; 438 case dwarf_wC5: 439 reg_info.name = "wC5"; 440 break; 441 case dwarf_wC6: 442 reg_info.name = "wC6"; 443 break; 444 case dwarf_wC7: 445 reg_info.name = "wC7"; 446 break; 447 448 // VFP-v3/Neon 449 case dwarf_d0: 450 reg_info.name = "d0"; 451 break; 452 case dwarf_d1: 453 reg_info.name = "d1"; 454 break; 455 case dwarf_d2: 456 reg_info.name = "d2"; 457 break; 458 case dwarf_d3: 459 reg_info.name = "d3"; 460 break; 461 case dwarf_d4: 462 reg_info.name = "d4"; 463 break; 464 case dwarf_d5: 465 reg_info.name = "d5"; 466 break; 467 case dwarf_d6: 468 reg_info.name = "d6"; 469 break; 470 case dwarf_d7: 471 reg_info.name = "d7"; 472 break; 473 case dwarf_d8: 474 reg_info.name = "d8"; 475 break; 476 case dwarf_d9: 477 reg_info.name = "d9"; 478 break; 479 case dwarf_d10: 480 reg_info.name = "d10"; 481 break; 482 case dwarf_d11: 483 reg_info.name = "d11"; 484 break; 485 case dwarf_d12: 486 reg_info.name = "d12"; 487 break; 488 case dwarf_d13: 489 reg_info.name = "d13"; 490 break; 491 case dwarf_d14: 492 reg_info.name = "d14"; 493 break; 494 case dwarf_d15: 495 reg_info.name = "d15"; 496 break; 497 case dwarf_d16: 498 reg_info.name = "d16"; 499 break; 500 case dwarf_d17: 501 reg_info.name = "d17"; 502 break; 503 case dwarf_d18: 504 reg_info.name = "d18"; 505 break; 506 case dwarf_d19: 507 reg_info.name = "d19"; 508 break; 509 case dwarf_d20: 510 reg_info.name = "d20"; 511 break; 512 case dwarf_d21: 513 reg_info.name = "d21"; 514 break; 515 case dwarf_d22: 516 reg_info.name = "d22"; 517 break; 518 case dwarf_d23: 519 reg_info.name = "d23"; 520 break; 521 case dwarf_d24: 522 reg_info.name = "d24"; 523 break; 524 case dwarf_d25: 525 reg_info.name = "d25"; 526 break; 527 case dwarf_d26: 528 reg_info.name = "d26"; 529 break; 530 case dwarf_d27: 531 reg_info.name = "d27"; 532 break; 533 case dwarf_d28: 534 reg_info.name = "d28"; 535 break; 536 case dwarf_d29: 537 reg_info.name = "d29"; 538 break; 539 case dwarf_d30: 540 reg_info.name = "d30"; 541 break; 542 case dwarf_d31: 543 reg_info.name = "d31"; 544 break; 545 546 // NEON 128-bit vector registers (overlays the d registers) 547 case dwarf_q0: 548 reg_info.name = "q0"; 549 break; 550 case dwarf_q1: 551 reg_info.name = "q1"; 552 break; 553 case dwarf_q2: 554 reg_info.name = "q2"; 555 break; 556 case dwarf_q3: 557 reg_info.name = "q3"; 558 break; 559 case dwarf_q4: 560 reg_info.name = "q4"; 561 break; 562 case dwarf_q5: 563 reg_info.name = "q5"; 564 break; 565 case dwarf_q6: 566 reg_info.name = "q6"; 567 break; 568 case dwarf_q7: 569 reg_info.name = "q7"; 570 break; 571 case dwarf_q8: 572 reg_info.name = "q8"; 573 break; 574 case dwarf_q9: 575 reg_info.name = "q9"; 576 break; 577 case dwarf_q10: 578 reg_info.name = "q10"; 579 break; 580 case dwarf_q11: 581 reg_info.name = "q11"; 582 break; 583 case dwarf_q12: 584 reg_info.name = "q12"; 585 break; 586 case dwarf_q13: 587 reg_info.name = "q13"; 588 break; 589 case dwarf_q14: 590 reg_info.name = "q14"; 591 break; 592 case dwarf_q15: 593 reg_info.name = "q15"; 594 break; 595 596 default: 597 return false; 598 } 599 return true; 600 } 601 602 // A8.6.50 603 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 604 static uint32_t CountITSize(uint32_t ITMask) { 605 // First count the trailing zeros of the IT mask. 606 uint32_t TZ = llvm::countTrailingZeros(ITMask); 607 if (TZ > 3) { 608 #ifdef LLDB_CONFIGURATION_DEBUG 609 printf("Encoding error: IT Mask '0000'\n"); 610 #endif 611 return 0; 612 } 613 return (4 - TZ); 614 } 615 616 // Init ITState. Note that at least one bit is always 1 in mask. 617 bool ITSession::InitIT(uint32_t bits7_0) { 618 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 619 if (ITCounter == 0) 620 return false; 621 622 // A8.6.50 IT 623 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 624 if (FirstCond == 0xF) { 625 #ifdef LLDB_CONFIGURATION_DEBUG 626 printf("Encoding error: IT FirstCond '1111'\n"); 627 #endif 628 return false; 629 } 630 if (FirstCond == 0xE && ITCounter != 1) { 631 #ifdef LLDB_CONFIGURATION_DEBUG 632 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 633 #endif 634 return false; 635 } 636 637 ITState = bits7_0; 638 return true; 639 } 640 641 // Update ITState if necessary. 642 void ITSession::ITAdvance() { 643 // assert(ITCounter); 644 --ITCounter; 645 if (ITCounter == 0) 646 ITState = 0; 647 else { 648 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 649 SetBits32(ITState, 4, 0, NewITState4_0); 650 } 651 } 652 653 // Return true if we're inside an IT Block. 654 bool ITSession::InITBlock() { return ITCounter != 0; } 655 656 // Return true if we're the last instruction inside an IT Block. 657 bool ITSession::LastInITBlock() { return ITCounter == 1; } 658 659 // Get condition bits for the current thumb instruction. 660 uint32_t ITSession::GetCond() { 661 if (InITBlock()) 662 return Bits32(ITState, 7, 4); 663 else 664 return COND_AL; 665 } 666 667 // ARM constants used during decoding 668 #define REG_RD 0 669 #define LDM_REGLIST 1 670 #define SP_REG 13 671 #define LR_REG 14 672 #define PC_REG 15 673 #define PC_REGLIST_BIT 0x8000 674 675 #define ARMv4 (1u << 0) 676 #define ARMv4T (1u << 1) 677 #define ARMv5T (1u << 2) 678 #define ARMv5TE (1u << 3) 679 #define ARMv5TEJ (1u << 4) 680 #define ARMv6 (1u << 5) 681 #define ARMv6K (1u << 6) 682 #define ARMv6T2 (1u << 7) 683 #define ARMv7 (1u << 8) 684 #define ARMv7S (1u << 9) 685 #define ARMv8 (1u << 10) 686 #define ARMvAll (0xffffffffu) 687 688 #define ARMV4T_ABOVE \ 689 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \ 690 ARMv7S | ARMv8) 691 #define ARMV5_ABOVE \ 692 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \ 693 ARMv8) 694 #define ARMV5TE_ABOVE \ 695 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 696 #define ARMV5J_ABOVE \ 697 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 698 #define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 699 #define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 700 #define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8) 701 702 #define No_VFP 0 703 #define VFPv1 (1u << 1) 704 #define VFPv2 (1u << 2) 705 #define VFPv3 (1u << 3) 706 #define AdvancedSIMD (1u << 4) 707 708 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 709 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 710 #define VFPv2v3 (VFPv2 | VFPv3) 711 712 // 713 // EmulateInstructionARM implementation 714 // 715 716 void EmulateInstructionARM::Initialize() { 717 PluginManager::RegisterPlugin(GetPluginNameStatic(), 718 GetPluginDescriptionStatic(), CreateInstance); 719 } 720 721 void EmulateInstructionARM::Terminate() { 722 PluginManager::UnregisterPlugin(CreateInstance); 723 } 724 725 ConstString EmulateInstructionARM::GetPluginNameStatic() { 726 static ConstString g_name("arm"); 727 return g_name; 728 } 729 730 const char *EmulateInstructionARM::GetPluginDescriptionStatic() { 731 return "Emulate instructions for the ARM architecture."; 732 } 733 734 EmulateInstruction * 735 EmulateInstructionARM::CreateInstance(const ArchSpec &arch, 736 InstructionType inst_type) { 737 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic( 738 inst_type)) { 739 if (arch.GetTriple().getArch() == llvm::Triple::arm) { 740 std::unique_ptr<EmulateInstructionARM> emulate_insn_up( 741 new EmulateInstructionARM(arch)); 742 743 if (emulate_insn_up) 744 return emulate_insn_up.release(); 745 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) { 746 std::unique_ptr<EmulateInstructionARM> emulate_insn_up( 747 new EmulateInstructionARM(arch)); 748 749 if (emulate_insn_up) 750 return emulate_insn_up.release(); 751 } 752 } 753 754 return nullptr; 755 } 756 757 bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) { 758 if (arch.GetTriple().getArch() == llvm::Triple::arm) 759 return true; 760 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 761 return true; 762 763 return false; 764 } 765 766 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for 767 // many ARM instructions. 768 bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) { 769 EmulateInstruction::Context context; 770 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 771 context.SetNoArgs(); 772 773 uint32_t random_data = rand(); 774 const uint32_t addr_byte_size = GetAddressByteSize(); 775 776 return MemAWrite(context, address, random_data, addr_byte_size); 777 } 778 779 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM 780 // instructions. 781 bool EmulateInstructionARM::WriteBits32Unknown(int n) { 782 EmulateInstruction::Context context; 783 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 784 context.SetNoArgs(); 785 786 bool success; 787 uint32_t data = 788 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 789 790 if (!success) 791 return false; 792 793 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data)) 794 return false; 795 796 return true; 797 } 798 799 bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind, 800 uint32_t reg_num, 801 RegisterInfo ®_info) { 802 if (reg_kind == eRegisterKindGeneric) { 803 switch (reg_num) { 804 case LLDB_REGNUM_GENERIC_PC: 805 reg_kind = eRegisterKindDWARF; 806 reg_num = dwarf_pc; 807 break; 808 case LLDB_REGNUM_GENERIC_SP: 809 reg_kind = eRegisterKindDWARF; 810 reg_num = dwarf_sp; 811 break; 812 case LLDB_REGNUM_GENERIC_FP: 813 reg_kind = eRegisterKindDWARF; 814 reg_num = dwarf_r7; 815 break; 816 case LLDB_REGNUM_GENERIC_RA: 817 reg_kind = eRegisterKindDWARF; 818 reg_num = dwarf_lr; 819 break; 820 case LLDB_REGNUM_GENERIC_FLAGS: 821 reg_kind = eRegisterKindDWARF; 822 reg_num = dwarf_cpsr; 823 break; 824 default: 825 return false; 826 } 827 } 828 829 if (reg_kind == eRegisterKindDWARF) 830 return GetARMDWARFRegisterInfo(reg_num, reg_info); 831 return false; 832 } 833 834 uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const { 835 if (m_arch.GetTriple().isAndroid()) 836 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android 837 bool is_apple = false; 838 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 839 is_apple = true; 840 switch (m_arch.GetTriple().getOS()) { 841 case llvm::Triple::Darwin: 842 case llvm::Triple::MacOSX: 843 case llvm::Triple::IOS: 844 case llvm::Triple::TvOS: 845 case llvm::Triple::WatchOS: 846 // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS: 847 is_apple = true; 848 break; 849 default: 850 break; 851 } 852 853 /* On Apple iOS et al, the frame pointer register is always r7. 854 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 855 * Windows on ARM, which is in thumb mode, uses r11 though. 856 */ 857 858 uint32_t fp_regnum = 11; 859 860 if (is_apple) 861 fp_regnum = 7; 862 863 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows()) 864 fp_regnum = 7; 865 866 return fp_regnum; 867 } 868 869 uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const { 870 bool is_apple = false; 871 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 872 is_apple = true; 873 switch (m_arch.GetTriple().getOS()) { 874 case llvm::Triple::Darwin: 875 case llvm::Triple::MacOSX: 876 case llvm::Triple::IOS: 877 is_apple = true; 878 break; 879 default: 880 break; 881 } 882 883 /* On Apple iOS et al, the frame pointer register is always r7. 884 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 885 * Windows on ARM, which is in thumb mode, uses r11 though. 886 */ 887 888 uint32_t fp_regnum = dwarf_r11; 889 890 if (is_apple) 891 fp_regnum = dwarf_r7; 892 893 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows()) 894 fp_regnum = dwarf_r7; 895 896 return fp_regnum; 897 } 898 899 // Push Multiple Registers stores multiple registers to the stack, storing to 900 // consecutive memory locations ending just below the address in SP, and 901 // updates 902 // SP to point to the start of the stored data. 903 bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode, 904 const ARMEncoding encoding) { 905 #if 0 906 // ARM pseudo code... 907 if (ConditionPassed()) 908 { 909 EncodingSpecificOperations(); 910 NullCheckIfThumbEE(13); 911 address = SP - 4*BitCount(registers); 912 913 for (i = 0 to 14) 914 { 915 if (registers<i> == '1') 916 { 917 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 918 MemA[address,4] = bits(32) UNKNOWN; 919 else 920 MemA[address,4] = R[i]; 921 address = address + 4; 922 } 923 } 924 925 if (registers<15> == '1') // Only possible for encoding A1 or A2 926 MemA[address,4] = PCStoreValue(); 927 928 SP = SP - 4*BitCount(registers); 929 } 930 #endif 931 932 bool success = false; 933 if (ConditionPassed(opcode)) { 934 const uint32_t addr_byte_size = GetAddressByteSize(); 935 const addr_t sp = ReadCoreReg(SP_REG, &success); 936 if (!success) 937 return false; 938 uint32_t registers = 0; 939 uint32_t Rt; // the source register 940 switch (encoding) { 941 case eEncodingT1: 942 registers = Bits32(opcode, 7, 0); 943 // The M bit represents LR. 944 if (Bit32(opcode, 8)) 945 registers |= (1u << 14); 946 // if BitCount(registers) < 1 then UNPREDICTABLE; 947 if (BitCount(registers) < 1) 948 return false; 949 break; 950 case eEncodingT2: 951 // Ignore bits 15 & 13. 952 registers = Bits32(opcode, 15, 0) & ~0xa000; 953 // if BitCount(registers) < 2 then UNPREDICTABLE; 954 if (BitCount(registers) < 2) 955 return false; 956 break; 957 case eEncodingT3: 958 Rt = Bits32(opcode, 15, 12); 959 // if BadReg(t) then UNPREDICTABLE; 960 if (BadReg(Rt)) 961 return false; 962 registers = (1u << Rt); 963 break; 964 case eEncodingA1: 965 registers = Bits32(opcode, 15, 0); 966 // Instead of return false, let's handle the following case as well, 967 // which amounts to pushing one reg onto the full descending stacks. 968 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 969 break; 970 case eEncodingA2: 971 Rt = Bits32(opcode, 15, 12); 972 // if t == 13 then UNPREDICTABLE; 973 if (Rt == dwarf_sp) 974 return false; 975 registers = (1u << Rt); 976 break; 977 default: 978 return false; 979 } 980 addr_t sp_offset = addr_byte_size * BitCount(registers); 981 addr_t addr = sp - sp_offset; 982 uint32_t i; 983 984 EmulateInstruction::Context context; 985 context.type = EmulateInstruction::eContextPushRegisterOnStack; 986 RegisterInfo reg_info; 987 RegisterInfo sp_reg; 988 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 989 for (i = 0; i < 15; ++i) { 990 if (BitIsSet(registers, i)) { 991 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info); 992 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 993 uint32_t reg_value = ReadCoreReg(i, &success); 994 if (!success) 995 return false; 996 if (!MemAWrite(context, addr, reg_value, addr_byte_size)) 997 return false; 998 addr += addr_byte_size; 999 } 1000 } 1001 1002 if (BitIsSet(registers, 15)) { 1003 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info); 1004 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 1005 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1006 if (!success) 1007 return false; 1008 if (!MemAWrite(context, addr, pc, addr_byte_size)) 1009 return false; 1010 } 1011 1012 context.type = EmulateInstruction::eContextAdjustStackPointer; 1013 context.SetImmediateSigned(-sp_offset); 1014 1015 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1016 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1017 return false; 1018 } 1019 return true; 1020 } 1021 1022 // Pop Multiple Registers loads multiple registers from the stack, loading from 1023 // consecutive memory locations staring at the address in SP, and updates 1024 // SP to point just above the loaded data. 1025 bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode, 1026 const ARMEncoding encoding) { 1027 #if 0 1028 // ARM pseudo code... 1029 if (ConditionPassed()) 1030 { 1031 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 1032 address = SP; 1033 for i = 0 to 14 1034 if registers<i> == '1' then 1035 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 1036 if registers<15> == '1' then 1037 if UnalignedAllowed then 1038 LoadWritePC(MemU[address,4]); 1039 else 1040 LoadWritePC(MemA[address,4]); 1041 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 1042 if registers<13> == '1' then SP = bits(32) UNKNOWN; 1043 } 1044 #endif 1045 1046 bool success = false; 1047 1048 if (ConditionPassed(opcode)) { 1049 const uint32_t addr_byte_size = GetAddressByteSize(); 1050 const addr_t sp = ReadCoreReg(SP_REG, &success); 1051 if (!success) 1052 return false; 1053 uint32_t registers = 0; 1054 uint32_t Rt; // the destination register 1055 switch (encoding) { 1056 case eEncodingT1: 1057 registers = Bits32(opcode, 7, 0); 1058 // The P bit represents PC. 1059 if (Bit32(opcode, 8)) 1060 registers |= (1u << 15); 1061 // if BitCount(registers) < 1 then UNPREDICTABLE; 1062 if (BitCount(registers) < 1) 1063 return false; 1064 break; 1065 case eEncodingT2: 1066 // Ignore bit 13. 1067 registers = Bits32(opcode, 15, 0) & ~0x2000; 1068 // if BitCount(registers) < 2 || (P == '1' && M == '1') then 1069 // UNPREDICTABLE; 1070 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 1071 return false; 1072 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 1073 // UNPREDICTABLE; 1074 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 1075 return false; 1076 break; 1077 case eEncodingT3: 1078 Rt = Bits32(opcode, 15, 12); 1079 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then 1080 // UNPREDICTABLE; 1081 if (Rt == 13) 1082 return false; 1083 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1084 return false; 1085 registers = (1u << Rt); 1086 break; 1087 case eEncodingA1: 1088 registers = Bits32(opcode, 15, 0); 1089 // Instead of return false, let's handle the following case as well, 1090 // which amounts to popping one reg from the full descending stacks. 1091 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 1092 1093 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 1094 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 1095 return false; 1096 break; 1097 case eEncodingA2: 1098 Rt = Bits32(opcode, 15, 12); 1099 // if t == 13 then UNPREDICTABLE; 1100 if (Rt == dwarf_sp) 1101 return false; 1102 registers = (1u << Rt); 1103 break; 1104 default: 1105 return false; 1106 } 1107 addr_t sp_offset = addr_byte_size * BitCount(registers); 1108 addr_t addr = sp; 1109 uint32_t i, data; 1110 1111 EmulateInstruction::Context context; 1112 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1113 1114 RegisterInfo sp_reg; 1115 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1116 1117 for (i = 0; i < 15; ++i) { 1118 if (BitIsSet(registers, i)) { 1119 context.SetAddress(addr); 1120 data = MemARead(context, addr, 4, 0, &success); 1121 if (!success) 1122 return false; 1123 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 1124 data)) 1125 return false; 1126 addr += addr_byte_size; 1127 } 1128 } 1129 1130 if (BitIsSet(registers, 15)) { 1131 context.SetRegisterPlusOffset(sp_reg, addr - sp); 1132 data = MemARead(context, addr, 4, 0, &success); 1133 if (!success) 1134 return false; 1135 // In ARMv5T and above, this is an interworking branch. 1136 if (!LoadWritePC(context, data)) 1137 return false; 1138 // addr += addr_byte_size; 1139 } 1140 1141 context.type = EmulateInstruction::eContextAdjustStackPointer; 1142 context.SetImmediateSigned(sp_offset); 1143 1144 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1145 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1146 return false; 1147 } 1148 return true; 1149 } 1150 1151 // Set r7 or ip to point to saved value residing within the stack. 1152 // ADD (SP plus immediate) 1153 bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode, 1154 const ARMEncoding encoding) { 1155 #if 0 1156 // ARM pseudo code... 1157 if (ConditionPassed()) 1158 { 1159 EncodingSpecificOperations(); 1160 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1161 if d == 15 then 1162 ALUWritePC(result); // setflags is always FALSE here 1163 else 1164 R[d] = result; 1165 if setflags then 1166 APSR.N = result<31>; 1167 APSR.Z = IsZeroBit(result); 1168 APSR.C = carry; 1169 APSR.V = overflow; 1170 } 1171 #endif 1172 1173 bool success = false; 1174 1175 if (ConditionPassed(opcode)) { 1176 const addr_t sp = ReadCoreReg(SP_REG, &success); 1177 if (!success) 1178 return false; 1179 uint32_t Rd; // the destination register 1180 uint32_t imm32; 1181 switch (encoding) { 1182 case eEncodingT1: 1183 Rd = 7; 1184 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 1185 break; 1186 case eEncodingA1: 1187 Rd = Bits32(opcode, 15, 12); 1188 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1189 break; 1190 default: 1191 return false; 1192 } 1193 addr_t sp_offset = imm32; 1194 addr_t addr = sp + sp_offset; // a pointer to the stack area 1195 1196 EmulateInstruction::Context context; 1197 if (Rd == GetFramePointerRegisterNumber()) 1198 context.type = eContextSetFramePointer; 1199 else 1200 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1201 RegisterInfo sp_reg; 1202 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1203 context.SetRegisterPlusOffset(sp_reg, sp_offset); 1204 1205 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, 1206 addr)) 1207 return false; 1208 } 1209 return true; 1210 } 1211 1212 // Set r7 or ip to the current stack pointer. 1213 // MOV (register) 1214 bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode, 1215 const ARMEncoding encoding) { 1216 #if 0 1217 // ARM pseudo code... 1218 if (ConditionPassed()) 1219 { 1220 EncodingSpecificOperations(); 1221 result = R[m]; 1222 if d == 15 then 1223 ALUWritePC(result); // setflags is always FALSE here 1224 else 1225 R[d] = result; 1226 if setflags then 1227 APSR.N = result<31>; 1228 APSR.Z = IsZeroBit(result); 1229 // APSR.C unchanged 1230 // APSR.V unchanged 1231 } 1232 #endif 1233 1234 bool success = false; 1235 1236 if (ConditionPassed(opcode)) { 1237 const addr_t sp = ReadCoreReg(SP_REG, &success); 1238 if (!success) 1239 return false; 1240 uint32_t Rd; // the destination register 1241 switch (encoding) { 1242 case eEncodingT1: 1243 Rd = 7; 1244 break; 1245 case eEncodingA1: 1246 Rd = 12; 1247 break; 1248 default: 1249 return false; 1250 } 1251 1252 EmulateInstruction::Context context; 1253 if (Rd == GetFramePointerRegisterNumber()) 1254 context.type = EmulateInstruction::eContextSetFramePointer; 1255 else 1256 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1257 RegisterInfo sp_reg; 1258 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1259 context.SetRegisterPlusOffset(sp_reg, 0); 1260 1261 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 1262 return false; 1263 } 1264 return true; 1265 } 1266 1267 // Move from high register (r8-r15) to low register (r0-r7). 1268 // MOV (register) 1269 bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode, 1270 const ARMEncoding encoding) { 1271 return EmulateMOVRdRm(opcode, encoding); 1272 } 1273 1274 // Move from register to register. 1275 // MOV (register) 1276 bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode, 1277 const ARMEncoding encoding) { 1278 #if 0 1279 // ARM pseudo code... 1280 if (ConditionPassed()) 1281 { 1282 EncodingSpecificOperations(); 1283 result = R[m]; 1284 if d == 15 then 1285 ALUWritePC(result); // setflags is always FALSE here 1286 else 1287 R[d] = result; 1288 if setflags then 1289 APSR.N = result<31>; 1290 APSR.Z = IsZeroBit(result); 1291 // APSR.C unchanged 1292 // APSR.V unchanged 1293 } 1294 #endif 1295 1296 bool success = false; 1297 1298 if (ConditionPassed(opcode)) { 1299 uint32_t Rm; // the source register 1300 uint32_t Rd; // the destination register 1301 bool setflags; 1302 switch (encoding) { 1303 case eEncodingT1: 1304 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1305 Rm = Bits32(opcode, 6, 3); 1306 setflags = false; 1307 if (Rd == 15 && InITBlock() && !LastInITBlock()) 1308 return false; 1309 break; 1310 case eEncodingT2: 1311 Rd = Bits32(opcode, 2, 0); 1312 Rm = Bits32(opcode, 5, 3); 1313 setflags = true; 1314 if (InITBlock()) 1315 return false; 1316 break; 1317 case eEncodingT3: 1318 Rd = Bits32(opcode, 11, 8); 1319 Rm = Bits32(opcode, 3, 0); 1320 setflags = BitIsSet(opcode, 20); 1321 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1322 if (setflags && (BadReg(Rd) || BadReg(Rm))) 1323 return false; 1324 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then 1325 // UNPREDICTABLE; 1326 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 1327 return false; 1328 break; 1329 case eEncodingA1: 1330 Rd = Bits32(opcode, 15, 12); 1331 Rm = Bits32(opcode, 3, 0); 1332 setflags = BitIsSet(opcode, 20); 1333 1334 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1335 // instructions; 1336 if (Rd == 15 && setflags) 1337 return EmulateSUBSPcLrEtc(opcode, encoding); 1338 break; 1339 default: 1340 return false; 1341 } 1342 uint32_t result = ReadCoreReg(Rm, &success); 1343 if (!success) 1344 return false; 1345 1346 // The context specifies that Rm is to be moved into Rd. 1347 EmulateInstruction::Context context; 1348 if (Rd == 13) 1349 context.type = EmulateInstruction::eContextAdjustStackPointer; 1350 else if (Rd == GetFramePointerRegisterNumber() && Rm == 13) 1351 context.type = EmulateInstruction::eContextSetFramePointer; 1352 else 1353 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1354 RegisterInfo dwarf_reg; 1355 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1356 context.SetRegisterPlusOffset(dwarf_reg, 0); 1357 1358 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 1359 return false; 1360 } 1361 return true; 1362 } 1363 1364 // Move (immediate) writes an immediate value to the destination register. It 1365 // can optionally update the condition flags based on the value. 1366 // MOV (immediate) 1367 bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode, 1368 const ARMEncoding encoding) { 1369 #if 0 1370 // ARM pseudo code... 1371 if (ConditionPassed()) 1372 { 1373 EncodingSpecificOperations(); 1374 result = imm32; 1375 if d == 15 then // Can only occur for ARM encoding 1376 ALUWritePC(result); // setflags is always FALSE here 1377 else 1378 R[d] = result; 1379 if setflags then 1380 APSR.N = result<31>; 1381 APSR.Z = IsZeroBit(result); 1382 APSR.C = carry; 1383 // APSR.V unchanged 1384 } 1385 #endif 1386 1387 if (ConditionPassed(opcode)) { 1388 uint32_t Rd; // the destination register 1389 uint32_t imm32; // the immediate value to be written to Rd 1390 uint32_t carry = 1391 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 1392 // for setflags == false, this value is a don't care initialized to 1393 // 0 to silence the static analyzer 1394 bool setflags; 1395 switch (encoding) { 1396 case eEncodingT1: 1397 Rd = Bits32(opcode, 10, 8); 1398 setflags = !InITBlock(); 1399 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 1400 carry = APSR_C; 1401 1402 break; 1403 1404 case eEncodingT2: 1405 Rd = Bits32(opcode, 11, 8); 1406 setflags = BitIsSet(opcode, 20); 1407 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1408 if (BadReg(Rd)) 1409 return false; 1410 1411 break; 1412 1413 case eEncodingT3: { 1414 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 1415 // 32); 1416 Rd = Bits32(opcode, 11, 8); 1417 setflags = false; 1418 uint32_t imm4 = Bits32(opcode, 19, 16); 1419 uint32_t imm3 = Bits32(opcode, 14, 12); 1420 uint32_t i = Bit32(opcode, 26); 1421 uint32_t imm8 = Bits32(opcode, 7, 0); 1422 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 1423 1424 // if BadReg(d) then UNPREDICTABLE; 1425 if (BadReg(Rd)) 1426 return false; 1427 } break; 1428 1429 case eEncodingA1: 1430 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = 1431 // ARMExpandImm_C(imm12, APSR.C); 1432 Rd = Bits32(opcode, 15, 12); 1433 setflags = BitIsSet(opcode, 20); 1434 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1435 1436 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1437 // instructions; 1438 if ((Rd == 15) && setflags) 1439 return EmulateSUBSPcLrEtc(opcode, encoding); 1440 1441 break; 1442 1443 case eEncodingA2: { 1444 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 1445 Rd = Bits32(opcode, 15, 12); 1446 setflags = false; 1447 uint32_t imm4 = Bits32(opcode, 19, 16); 1448 uint32_t imm12 = Bits32(opcode, 11, 0); 1449 imm32 = (imm4 << 12) | imm12; 1450 1451 // if d == 15 then UNPREDICTABLE; 1452 if (Rd == 15) 1453 return false; 1454 } break; 1455 1456 default: 1457 return false; 1458 } 1459 uint32_t result = imm32; 1460 1461 // The context specifies that an immediate is to be moved into Rd. 1462 EmulateInstruction::Context context; 1463 context.type = EmulateInstruction::eContextImmediate; 1464 context.SetNoArgs(); 1465 1466 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1467 return false; 1468 } 1469 return true; 1470 } 1471 1472 // MUL multiplies two register values. The least significant 32 bits of the 1473 // result are written to the destination 1474 // register. These 32 bits do not depend on whether the source register values 1475 // are considered to be signed values or unsigned values. 1476 // 1477 // Optionally, it can update the condition flags based on the result. In the 1478 // Thumb instruction set, this option is limited to only a few forms of the 1479 // instruction. 1480 bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode, 1481 const ARMEncoding encoding) { 1482 #if 0 1483 if ConditionPassed() then 1484 EncodingSpecificOperations(); 1485 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1486 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1487 result = operand1 * operand2; 1488 R[d] = result<31:0>; 1489 if setflags then 1490 APSR.N = result<31>; 1491 APSR.Z = IsZeroBit(result); 1492 if ArchVersion() == 4 then 1493 APSR.C = bit UNKNOWN; 1494 // else APSR.C unchanged 1495 // APSR.V always unchanged 1496 #endif 1497 1498 if (ConditionPassed(opcode)) { 1499 uint32_t d; 1500 uint32_t n; 1501 uint32_t m; 1502 bool setflags; 1503 1504 // EncodingSpecificOperations(); 1505 switch (encoding) { 1506 case eEncodingT1: 1507 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 1508 d = Bits32(opcode, 2, 0); 1509 n = Bits32(opcode, 5, 3); 1510 m = Bits32(opcode, 2, 0); 1511 setflags = !InITBlock(); 1512 1513 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1514 if ((ArchVersion() < ARMv6) && (d == n)) 1515 return false; 1516 1517 break; 1518 1519 case eEncodingT2: 1520 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 1521 d = Bits32(opcode, 11, 8); 1522 n = Bits32(opcode, 19, 16); 1523 m = Bits32(opcode, 3, 0); 1524 setflags = false; 1525 1526 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 1527 if (BadReg(d) || BadReg(n) || BadReg(m)) 1528 return false; 1529 1530 break; 1531 1532 case eEncodingA1: 1533 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 1534 d = Bits32(opcode, 19, 16); 1535 n = Bits32(opcode, 3, 0); 1536 m = Bits32(opcode, 11, 8); 1537 setflags = BitIsSet(opcode, 20); 1538 1539 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1540 if ((d == 15) || (n == 15) || (m == 15)) 1541 return false; 1542 1543 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1544 if ((ArchVersion() < ARMv6) && (d == n)) 1545 return false; 1546 1547 break; 1548 1549 default: 1550 return false; 1551 } 1552 1553 bool success = false; 1554 1555 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final 1556 // results 1557 uint64_t operand1 = 1558 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1559 if (!success) 1560 return false; 1561 1562 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final 1563 // results 1564 uint64_t operand2 = 1565 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1566 if (!success) 1567 return false; 1568 1569 // result = operand1 * operand2; 1570 uint64_t result = operand1 * operand2; 1571 1572 // R[d] = result<31:0>; 1573 RegisterInfo op1_reg; 1574 RegisterInfo op2_reg; 1575 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1576 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1577 1578 EmulateInstruction::Context context; 1579 context.type = eContextArithmetic; 1580 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 1581 1582 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 1583 (0x0000ffff & result))) 1584 return false; 1585 1586 // if setflags then 1587 if (setflags) { 1588 // APSR.N = result<31>; 1589 // APSR.Z = IsZeroBit(result); 1590 m_new_inst_cpsr = m_opcode_cpsr; 1591 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31)); 1592 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1593 if (m_new_inst_cpsr != m_opcode_cpsr) { 1594 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1595 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1596 return false; 1597 } 1598 1599 // if ArchVersion() == 4 then 1600 // APSR.C = bit UNKNOWN; 1601 } 1602 } 1603 return true; 1604 } 1605 1606 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to 1607 // the destination register. It can optionally update the condition flags based 1608 // on the value. 1609 bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode, 1610 const ARMEncoding encoding) { 1611 #if 0 1612 // ARM pseudo code... 1613 if (ConditionPassed()) 1614 { 1615 EncodingSpecificOperations(); 1616 result = NOT(imm32); 1617 if d == 15 then // Can only occur for ARM encoding 1618 ALUWritePC(result); // setflags is always FALSE here 1619 else 1620 R[d] = result; 1621 if setflags then 1622 APSR.N = result<31>; 1623 APSR.Z = IsZeroBit(result); 1624 APSR.C = carry; 1625 // APSR.V unchanged 1626 } 1627 #endif 1628 1629 if (ConditionPassed(opcode)) { 1630 uint32_t Rd; // the destination register 1631 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1632 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1633 bool setflags; 1634 switch (encoding) { 1635 case eEncodingT1: 1636 Rd = Bits32(opcode, 11, 8); 1637 setflags = BitIsSet(opcode, 20); 1638 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1639 break; 1640 case eEncodingA1: 1641 Rd = Bits32(opcode, 15, 12); 1642 setflags = BitIsSet(opcode, 20); 1643 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1644 1645 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1646 // instructions; 1647 if (Rd == 15 && setflags) 1648 return EmulateSUBSPcLrEtc(opcode, encoding); 1649 break; 1650 default: 1651 return false; 1652 } 1653 uint32_t result = ~imm32; 1654 1655 // The context specifies that an immediate is to be moved into Rd. 1656 EmulateInstruction::Context context; 1657 context.type = EmulateInstruction::eContextImmediate; 1658 context.SetNoArgs(); 1659 1660 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1661 return false; 1662 } 1663 return true; 1664 } 1665 1666 // Bitwise NOT (register) writes the bitwise inverse of a register value to the 1667 // destination register. It can optionally update the condition flags based on 1668 // the result. 1669 bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode, 1670 const ARMEncoding encoding) { 1671 #if 0 1672 // ARM pseudo code... 1673 if (ConditionPassed()) 1674 { 1675 EncodingSpecificOperations(); 1676 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1677 result = NOT(shifted); 1678 if d == 15 then // Can only occur for ARM encoding 1679 ALUWritePC(result); // setflags is always FALSE here 1680 else 1681 R[d] = result; 1682 if setflags then 1683 APSR.N = result<31>; 1684 APSR.Z = IsZeroBit(result); 1685 APSR.C = carry; 1686 // APSR.V unchanged 1687 } 1688 #endif 1689 1690 if (ConditionPassed(opcode)) { 1691 uint32_t Rm; // the source register 1692 uint32_t Rd; // the destination register 1693 ARM_ShifterType shift_t; 1694 uint32_t shift_n; // the shift applied to the value read from Rm 1695 bool setflags; 1696 uint32_t carry; // the carry bit after the shift operation 1697 switch (encoding) { 1698 case eEncodingT1: 1699 Rd = Bits32(opcode, 2, 0); 1700 Rm = Bits32(opcode, 5, 3); 1701 setflags = !InITBlock(); 1702 shift_t = SRType_LSL; 1703 shift_n = 0; 1704 if (InITBlock()) 1705 return false; 1706 break; 1707 case eEncodingT2: 1708 Rd = Bits32(opcode, 11, 8); 1709 Rm = Bits32(opcode, 3, 0); 1710 setflags = BitIsSet(opcode, 20); 1711 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1712 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1713 if (BadReg(Rd) || BadReg(Rm)) 1714 return false; 1715 break; 1716 case eEncodingA1: 1717 Rd = Bits32(opcode, 15, 12); 1718 Rm = Bits32(opcode, 3, 0); 1719 setflags = BitIsSet(opcode, 20); 1720 shift_n = DecodeImmShiftARM(opcode, shift_t); 1721 break; 1722 default: 1723 return false; 1724 } 1725 bool success = false; 1726 uint32_t value = ReadCoreReg(Rm, &success); 1727 if (!success) 1728 return false; 1729 1730 uint32_t shifted = 1731 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1732 if (!success) 1733 return false; 1734 uint32_t result = ~shifted; 1735 1736 // The context specifies that an immediate is to be moved into Rd. 1737 EmulateInstruction::Context context; 1738 context.type = EmulateInstruction::eContextImmediate; 1739 context.SetNoArgs(); 1740 1741 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1742 return false; 1743 } 1744 return true; 1745 } 1746 1747 // PC relative immediate load into register, possibly followed by ADD (SP plus 1748 // register). 1749 // LDR (literal) 1750 bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode, 1751 const ARMEncoding encoding) { 1752 #if 0 1753 // ARM pseudo code... 1754 if (ConditionPassed()) 1755 { 1756 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1757 base = Align(PC,4); 1758 address = if add then (base + imm32) else (base - imm32); 1759 data = MemU[address,4]; 1760 if t == 15 then 1761 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1762 elsif UnalignedSupport() || address<1:0> = '00' then 1763 R[t] = data; 1764 else // Can only apply before ARMv7 1765 if CurrentInstrSet() == InstrSet_ARM then 1766 R[t] = ROR(data, 8*UInt(address<1:0>)); 1767 else 1768 R[t] = bits(32) UNKNOWN; 1769 } 1770 #endif 1771 1772 if (ConditionPassed(opcode)) { 1773 bool success = false; 1774 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1775 if (!success) 1776 return false; 1777 1778 // PC relative immediate load context 1779 EmulateInstruction::Context context; 1780 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1781 RegisterInfo pc_reg; 1782 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 1783 context.SetRegisterPlusOffset(pc_reg, 0); 1784 1785 uint32_t Rt; // the destination register 1786 uint32_t imm32; // immediate offset from the PC 1787 bool add; // +imm32 or -imm32? 1788 addr_t base; // the base address 1789 addr_t address; // the PC relative address 1790 uint32_t data; // the literal data value from the PC relative load 1791 switch (encoding) { 1792 case eEncodingT1: 1793 Rt = Bits32(opcode, 10, 8); 1794 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1795 add = true; 1796 break; 1797 case eEncodingT2: 1798 Rt = Bits32(opcode, 15, 12); 1799 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1800 add = BitIsSet(opcode, 23); 1801 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1802 return false; 1803 break; 1804 default: 1805 return false; 1806 } 1807 1808 base = Align(pc, 4); 1809 if (add) 1810 address = base + imm32; 1811 else 1812 address = base - imm32; 1813 1814 context.SetRegisterPlusOffset(pc_reg, address - base); 1815 data = MemURead(context, address, 4, 0, &success); 1816 if (!success) 1817 return false; 1818 1819 if (Rt == 15) { 1820 if (Bits32(address, 1, 0) == 0) { 1821 // In ARMv5T and above, this is an interworking branch. 1822 if (!LoadWritePC(context, data)) 1823 return false; 1824 } else 1825 return false; 1826 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 1827 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 1828 data)) 1829 return false; 1830 } else // We don't handle ARM for now. 1831 return false; 1832 } 1833 return true; 1834 } 1835 1836 // An add operation to adjust the SP. 1837 // ADD (SP plus immediate) 1838 bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode, 1839 const ARMEncoding encoding) { 1840 #if 0 1841 // ARM pseudo code... 1842 if (ConditionPassed()) 1843 { 1844 EncodingSpecificOperations(); 1845 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1846 if d == 15 then // Can only occur for ARM encoding 1847 ALUWritePC(result); // setflags is always FALSE here 1848 else 1849 R[d] = result; 1850 if setflags then 1851 APSR.N = result<31>; 1852 APSR.Z = IsZeroBit(result); 1853 APSR.C = carry; 1854 APSR.V = overflow; 1855 } 1856 #endif 1857 1858 bool success = false; 1859 1860 if (ConditionPassed(opcode)) { 1861 const addr_t sp = ReadCoreReg(SP_REG, &success); 1862 if (!success) 1863 return false; 1864 uint32_t imm32; // the immediate operand 1865 uint32_t d; 1866 bool setflags; 1867 switch (encoding) { 1868 case eEncodingT1: 1869 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1870 d = Bits32(opcode, 10, 8); 1871 imm32 = (Bits32(opcode, 7, 0) << 2); 1872 setflags = false; 1873 break; 1874 1875 case eEncodingT2: 1876 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1877 d = 13; 1878 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1879 setflags = false; 1880 break; 1881 1882 case eEncodingT3: 1883 // d = UInt(Rd); setflags = (S == "1"); imm32 = 1884 // ThumbExpandImm(i:imm3:imm8); 1885 d = Bits32(opcode, 11, 8); 1886 imm32 = ThumbExpandImm(opcode); 1887 setflags = Bit32(opcode, 20); 1888 1889 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 1890 if (d == 15 && setflags == 1) 1891 return false; // CMN (immediate) not yet supported 1892 1893 // if d == 15 && S == "0" then UNPREDICTABLE; 1894 if (d == 15 && setflags == 0) 1895 return false; 1896 break; 1897 1898 case eEncodingT4: { 1899 // if Rn == '1111' then SEE ADR; 1900 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 1901 d = Bits32(opcode, 11, 8); 1902 setflags = false; 1903 uint32_t i = Bit32(opcode, 26); 1904 uint32_t imm3 = Bits32(opcode, 14, 12); 1905 uint32_t imm8 = Bits32(opcode, 7, 0); 1906 imm32 = (i << 11) | (imm3 << 8) | imm8; 1907 1908 // if d == 15 then UNPREDICTABLE; 1909 if (d == 15) 1910 return false; 1911 } break; 1912 1913 default: 1914 return false; 1915 } 1916 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 1917 AddWithCarryResult res = AddWithCarry(sp, imm32, 0); 1918 1919 EmulateInstruction::Context context; 1920 if (d == 13) 1921 context.type = EmulateInstruction::eContextAdjustStackPointer; 1922 else 1923 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1924 1925 RegisterInfo sp_reg; 1926 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1927 context.SetRegisterPlusOffset(sp_reg, res.result - sp); 1928 1929 if (d == 15) { 1930 if (!ALUWritePC(context, res.result)) 1931 return false; 1932 } else { 1933 // R[d] = result; 1934 // if setflags then 1935 // APSR.N = result<31>; 1936 // APSR.Z = IsZeroBit(result); 1937 // APSR.C = carry; 1938 // APSR.V = overflow; 1939 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 1940 res.carry_out, res.overflow)) 1941 return false; 1942 } 1943 } 1944 return true; 1945 } 1946 1947 // An add operation to adjust the SP. 1948 // ADD (SP plus register) 1949 bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode, 1950 const ARMEncoding encoding) { 1951 #if 0 1952 // ARM pseudo code... 1953 if (ConditionPassed()) 1954 { 1955 EncodingSpecificOperations(); 1956 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1957 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1958 if d == 15 then 1959 ALUWritePC(result); // setflags is always FALSE here 1960 else 1961 R[d] = result; 1962 if setflags then 1963 APSR.N = result<31>; 1964 APSR.Z = IsZeroBit(result); 1965 APSR.C = carry; 1966 APSR.V = overflow; 1967 } 1968 #endif 1969 1970 bool success = false; 1971 1972 if (ConditionPassed(opcode)) { 1973 const addr_t sp = ReadCoreReg(SP_REG, &success); 1974 if (!success) 1975 return false; 1976 uint32_t Rm; // the second operand 1977 switch (encoding) { 1978 case eEncodingT2: 1979 Rm = Bits32(opcode, 6, 3); 1980 break; 1981 default: 1982 return false; 1983 } 1984 int32_t reg_value = ReadCoreReg(Rm, &success); 1985 if (!success) 1986 return false; 1987 1988 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1989 1990 EmulateInstruction::Context context; 1991 context.type = eContextArithmetic; 1992 RegisterInfo sp_reg; 1993 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1994 1995 RegisterInfo other_reg; 1996 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1997 context.SetRegisterRegisterOperands(sp_reg, other_reg); 1998 1999 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2000 LLDB_REGNUM_GENERIC_SP, addr)) 2001 return false; 2002 } 2003 return true; 2004 } 2005 2006 // Branch with Link and Exchange Instruction Sets (immediate) calls a 2007 // subroutine at a PC-relative address, and changes instruction set from ARM to 2008 // Thumb, or from Thumb to ARM. 2009 // BLX (immediate) 2010 bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode, 2011 const ARMEncoding encoding) { 2012 #if 0 2013 // ARM pseudo code... 2014 if (ConditionPassed()) 2015 { 2016 EncodingSpecificOperations(); 2017 if CurrentInstrSet() == InstrSet_ARM then 2018 LR = PC - 4; 2019 else 2020 LR = PC<31:1> : '1'; 2021 if targetInstrSet == InstrSet_ARM then 2022 targetAddress = Align(PC,4) + imm32; 2023 else 2024 targetAddress = PC + imm32; 2025 SelectInstrSet(targetInstrSet); 2026 BranchWritePC(targetAddress); 2027 } 2028 #endif 2029 2030 bool success = true; 2031 2032 if (ConditionPassed(opcode)) { 2033 EmulateInstruction::Context context; 2034 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2035 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2036 if (!success) 2037 return false; 2038 addr_t lr; // next instruction address 2039 addr_t target; // target address 2040 int32_t imm32; // PC-relative offset 2041 switch (encoding) { 2042 case eEncodingT1: { 2043 lr = pc | 1u; // return address 2044 uint32_t S = Bit32(opcode, 26); 2045 uint32_t imm10 = Bits32(opcode, 25, 16); 2046 uint32_t J1 = Bit32(opcode, 13); 2047 uint32_t J2 = Bit32(opcode, 11); 2048 uint32_t imm11 = Bits32(opcode, 10, 0); 2049 uint32_t I1 = !(J1 ^ S); 2050 uint32_t I2 = !(J2 ^ S); 2051 uint32_t imm25 = 2052 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2053 imm32 = llvm::SignExtend32<25>(imm25); 2054 target = pc + imm32; 2055 SelectInstrSet(eModeThumb); 2056 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2057 if (InITBlock() && !LastInITBlock()) 2058 return false; 2059 break; 2060 } 2061 case eEncodingT2: { 2062 lr = pc | 1u; // return address 2063 uint32_t S = Bit32(opcode, 26); 2064 uint32_t imm10H = Bits32(opcode, 25, 16); 2065 uint32_t J1 = Bit32(opcode, 13); 2066 uint32_t J2 = Bit32(opcode, 11); 2067 uint32_t imm10L = Bits32(opcode, 10, 1); 2068 uint32_t I1 = !(J1 ^ S); 2069 uint32_t I2 = !(J2 ^ S); 2070 uint32_t imm25 = 2071 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 2072 imm32 = llvm::SignExtend32<25>(imm25); 2073 target = Align(pc, 4) + imm32; 2074 SelectInstrSet(eModeARM); 2075 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32); 2076 if (InITBlock() && !LastInITBlock()) 2077 return false; 2078 break; 2079 } 2080 case eEncodingA1: 2081 lr = pc - 4; // return address 2082 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2083 target = Align(pc, 4) + imm32; 2084 SelectInstrSet(eModeARM); 2085 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2086 break; 2087 case eEncodingA2: 2088 lr = pc - 4; // return address 2089 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | 2090 Bits32(opcode, 24, 24) << 1); 2091 target = pc + imm32; 2092 SelectInstrSet(eModeThumb); 2093 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32); 2094 break; 2095 default: 2096 return false; 2097 } 2098 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2099 LLDB_REGNUM_GENERIC_RA, lr)) 2100 return false; 2101 if (!BranchWritePC(context, target)) 2102 return false; 2103 if (m_opcode_cpsr != m_new_inst_cpsr) 2104 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2105 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2106 return false; 2107 } 2108 return true; 2109 } 2110 2111 // Branch with Link and Exchange (register) calls a subroutine at an address 2112 // and instruction set specified by a register. 2113 // BLX (register) 2114 bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode, 2115 const ARMEncoding encoding) { 2116 #if 0 2117 // ARM pseudo code... 2118 if (ConditionPassed()) 2119 { 2120 EncodingSpecificOperations(); 2121 target = R[m]; 2122 if CurrentInstrSet() == InstrSet_ARM then 2123 next_instr_addr = PC - 4; 2124 LR = next_instr_addr; 2125 else 2126 next_instr_addr = PC - 2; 2127 LR = next_instr_addr<31:1> : '1'; 2128 BXWritePC(target); 2129 } 2130 #endif 2131 2132 bool success = false; 2133 2134 if (ConditionPassed(opcode)) { 2135 EmulateInstruction::Context context; 2136 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2137 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2138 addr_t lr; // next instruction address 2139 if (!success) 2140 return false; 2141 uint32_t Rm; // the register with the target address 2142 switch (encoding) { 2143 case eEncodingT1: 2144 lr = (pc - 2) | 1u; // return address 2145 Rm = Bits32(opcode, 6, 3); 2146 // if m == 15 then UNPREDICTABLE; 2147 if (Rm == 15) 2148 return false; 2149 if (InITBlock() && !LastInITBlock()) 2150 return false; 2151 break; 2152 case eEncodingA1: 2153 lr = pc - 4; // return address 2154 Rm = Bits32(opcode, 3, 0); 2155 // if m == 15 then UNPREDICTABLE; 2156 if (Rm == 15) 2157 return false; 2158 break; 2159 default: 2160 return false; 2161 } 2162 addr_t target = ReadCoreReg(Rm, &success); 2163 if (!success) 2164 return false; 2165 RegisterInfo dwarf_reg; 2166 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2167 context.SetRegister(dwarf_reg); 2168 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2169 LLDB_REGNUM_GENERIC_RA, lr)) 2170 return false; 2171 if (!BXWritePC(context, target)) 2172 return false; 2173 } 2174 return true; 2175 } 2176 2177 // Branch and Exchange causes a branch to an address and instruction set 2178 // specified by a register. 2179 bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode, 2180 const ARMEncoding encoding) { 2181 #if 0 2182 // ARM pseudo code... 2183 if (ConditionPassed()) 2184 { 2185 EncodingSpecificOperations(); 2186 BXWritePC(R[m]); 2187 } 2188 #endif 2189 2190 if (ConditionPassed(opcode)) { 2191 EmulateInstruction::Context context; 2192 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2193 uint32_t Rm; // the register with the target address 2194 switch (encoding) { 2195 case eEncodingT1: 2196 Rm = Bits32(opcode, 6, 3); 2197 if (InITBlock() && !LastInITBlock()) 2198 return false; 2199 break; 2200 case eEncodingA1: 2201 Rm = Bits32(opcode, 3, 0); 2202 break; 2203 default: 2204 return false; 2205 } 2206 bool success = false; 2207 addr_t target = ReadCoreReg(Rm, &success); 2208 if (!success) 2209 return false; 2210 2211 RegisterInfo dwarf_reg; 2212 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2213 context.SetRegister(dwarf_reg); 2214 if (!BXWritePC(context, target)) 2215 return false; 2216 } 2217 return true; 2218 } 2219 2220 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the 2221 // attempt fails, it branches to an address and instruction set specified by a 2222 // register as though it were a BX instruction. 2223 // 2224 // TODO: Emulate Jazelle architecture? 2225 // We currently assume that switching to Jazelle state fails, thus 2226 // treating BXJ as a BX operation. 2227 bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode, 2228 const ARMEncoding encoding) { 2229 #if 0 2230 // ARM pseudo code... 2231 if (ConditionPassed()) 2232 { 2233 EncodingSpecificOperations(); 2234 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 2235 BXWritePC(R[m]); 2236 else 2237 if JazelleAcceptsExecution() then 2238 SwitchToJazelleExecution(); 2239 else 2240 SUBARCHITECTURE_DEFINED handler call; 2241 } 2242 #endif 2243 2244 if (ConditionPassed(opcode)) { 2245 EmulateInstruction::Context context; 2246 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2247 uint32_t Rm; // the register with the target address 2248 switch (encoding) { 2249 case eEncodingT1: 2250 Rm = Bits32(opcode, 19, 16); 2251 if (BadReg(Rm)) 2252 return false; 2253 if (InITBlock() && !LastInITBlock()) 2254 return false; 2255 break; 2256 case eEncodingA1: 2257 Rm = Bits32(opcode, 3, 0); 2258 if (Rm == 15) 2259 return false; 2260 break; 2261 default: 2262 return false; 2263 } 2264 bool success = false; 2265 addr_t target = ReadCoreReg(Rm, &success); 2266 if (!success) 2267 return false; 2268 2269 RegisterInfo dwarf_reg; 2270 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2271 context.SetRegister(dwarf_reg); 2272 if (!BXWritePC(context, target)) 2273 return false; 2274 } 2275 return true; 2276 } 2277 2278 // Set r7 to point to some ip offset. 2279 // SUB (immediate) 2280 bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode, 2281 const ARMEncoding encoding) { 2282 #if 0 2283 // ARM pseudo code... 2284 if (ConditionPassed()) 2285 { 2286 EncodingSpecificOperations(); 2287 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2288 if d == 15 then // Can only occur for ARM encoding 2289 ALUWritePC(result); // setflags is always FALSE here 2290 else 2291 R[d] = result; 2292 if setflags then 2293 APSR.N = result<31>; 2294 APSR.Z = IsZeroBit(result); 2295 APSR.C = carry; 2296 APSR.V = overflow; 2297 } 2298 #endif 2299 2300 if (ConditionPassed(opcode)) { 2301 bool success = false; 2302 const addr_t ip = ReadCoreReg(12, &success); 2303 if (!success) 2304 return false; 2305 uint32_t imm32; 2306 switch (encoding) { 2307 case eEncodingA1: 2308 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2309 break; 2310 default: 2311 return false; 2312 } 2313 addr_t ip_offset = imm32; 2314 addr_t addr = ip - ip_offset; // the adjusted ip value 2315 2316 EmulateInstruction::Context context; 2317 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2318 RegisterInfo dwarf_reg; 2319 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg); 2320 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset); 2321 2322 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr)) 2323 return false; 2324 } 2325 return true; 2326 } 2327 2328 // Set ip to point to some stack offset. 2329 // SUB (SP minus immediate) 2330 bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode, 2331 const ARMEncoding encoding) { 2332 #if 0 2333 // ARM pseudo code... 2334 if (ConditionPassed()) 2335 { 2336 EncodingSpecificOperations(); 2337 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2338 if d == 15 then // Can only occur for ARM encoding 2339 ALUWritePC(result); // setflags is always FALSE here 2340 else 2341 R[d] = result; 2342 if setflags then 2343 APSR.N = result<31>; 2344 APSR.Z = IsZeroBit(result); 2345 APSR.C = carry; 2346 APSR.V = overflow; 2347 } 2348 #endif 2349 2350 if (ConditionPassed(opcode)) { 2351 bool success = false; 2352 const addr_t sp = ReadCoreReg(SP_REG, &success); 2353 if (!success) 2354 return false; 2355 uint32_t imm32; 2356 switch (encoding) { 2357 case eEncodingA1: 2358 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2359 break; 2360 default: 2361 return false; 2362 } 2363 addr_t sp_offset = imm32; 2364 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 2365 2366 EmulateInstruction::Context context; 2367 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2368 RegisterInfo dwarf_reg; 2369 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 2370 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset); 2371 2372 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr)) 2373 return false; 2374 } 2375 return true; 2376 } 2377 2378 // This instruction subtracts an immediate value from the SP value, and writes 2379 // the result to the destination register. 2380 // 2381 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local 2382 // storage. 2383 bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode, 2384 const ARMEncoding encoding) { 2385 #if 0 2386 // ARM pseudo code... 2387 if (ConditionPassed()) 2388 { 2389 EncodingSpecificOperations(); 2390 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2391 if d == 15 then // Can only occur for ARM encoding 2392 ALUWritePC(result); // setflags is always FALSE here 2393 else 2394 R[d] = result; 2395 if setflags then 2396 APSR.N = result<31>; 2397 APSR.Z = IsZeroBit(result); 2398 APSR.C = carry; 2399 APSR.V = overflow; 2400 } 2401 #endif 2402 2403 bool success = false; 2404 if (ConditionPassed(opcode)) { 2405 const addr_t sp = ReadCoreReg(SP_REG, &success); 2406 if (!success) 2407 return false; 2408 2409 uint32_t Rd; 2410 bool setflags; 2411 uint32_t imm32; 2412 switch (encoding) { 2413 case eEncodingT1: 2414 Rd = 13; 2415 setflags = false; 2416 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 2417 break; 2418 case eEncodingT2: 2419 Rd = Bits32(opcode, 11, 8); 2420 setflags = BitIsSet(opcode, 20); 2421 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2422 if (Rd == 15 && setflags) 2423 return EmulateCMPImm(opcode, eEncodingT2); 2424 if (Rd == 15 && !setflags) 2425 return false; 2426 break; 2427 case eEncodingT3: 2428 Rd = Bits32(opcode, 11, 8); 2429 setflags = false; 2430 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 2431 if (Rd == 15) 2432 return false; 2433 break; 2434 case eEncodingA1: 2435 Rd = Bits32(opcode, 15, 12); 2436 setflags = BitIsSet(opcode, 20); 2437 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2438 2439 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 2440 // instructions; 2441 if (Rd == 15 && setflags) 2442 return EmulateSUBSPcLrEtc(opcode, encoding); 2443 break; 2444 default: 2445 return false; 2446 } 2447 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 2448 2449 EmulateInstruction::Context context; 2450 if (Rd == 13) { 2451 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting 2452 // to negate it, or the wrong 2453 // value gets passed down to context.SetImmediateSigned. 2454 context.type = EmulateInstruction::eContextAdjustStackPointer; 2455 context.SetImmediateSigned(-imm64); // the stack pointer offset 2456 } else { 2457 context.type = EmulateInstruction::eContextImmediate; 2458 context.SetNoArgs(); 2459 } 2460 2461 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 2462 res.carry_out, res.overflow)) 2463 return false; 2464 } 2465 return true; 2466 } 2467 2468 // A store operation to the stack that also updates the SP. 2469 bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode, 2470 const ARMEncoding encoding) { 2471 #if 0 2472 // ARM pseudo code... 2473 if (ConditionPassed()) 2474 { 2475 EncodingSpecificOperations(); 2476 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2477 address = if index then offset_addr else R[n]; 2478 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 2479 if wback then R[n] = offset_addr; 2480 } 2481 #endif 2482 2483 bool success = false; 2484 if (ConditionPassed(opcode)) { 2485 const uint32_t addr_byte_size = GetAddressByteSize(); 2486 const addr_t sp = ReadCoreReg(SP_REG, &success); 2487 if (!success) 2488 return false; 2489 uint32_t Rt; // the source register 2490 uint32_t imm12; 2491 uint32_t 2492 Rn; // This function assumes Rn is the SP, but we should verify that. 2493 2494 bool index; 2495 bool add; 2496 bool wback; 2497 switch (encoding) { 2498 case eEncodingA1: 2499 Rt = Bits32(opcode, 15, 12); 2500 imm12 = Bits32(opcode, 11, 0); 2501 Rn = Bits32(opcode, 19, 16); 2502 2503 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 2504 return false; 2505 2506 index = BitIsSet(opcode, 24); 2507 add = BitIsSet(opcode, 23); 2508 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 2509 2510 if (wback && ((Rn == 15) || (Rn == Rt))) 2511 return false; 2512 break; 2513 default: 2514 return false; 2515 } 2516 addr_t offset_addr; 2517 if (add) 2518 offset_addr = sp + imm12; 2519 else 2520 offset_addr = sp - imm12; 2521 2522 addr_t addr; 2523 if (index) 2524 addr = offset_addr; 2525 else 2526 addr = sp; 2527 2528 EmulateInstruction::Context context; 2529 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2530 RegisterInfo sp_reg; 2531 RegisterInfo dwarf_reg; 2532 2533 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2534 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2535 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2536 if (Rt != 15) { 2537 uint32_t reg_value = ReadCoreReg(Rt, &success); 2538 if (!success) 2539 return false; 2540 if (!MemUWrite(context, addr, reg_value, addr_byte_size)) 2541 return false; 2542 } else { 2543 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2544 if (!success) 2545 return false; 2546 if (!MemUWrite(context, addr, pc, addr_byte_size)) 2547 return false; 2548 } 2549 2550 if (wback) { 2551 context.type = EmulateInstruction::eContextAdjustStackPointer; 2552 context.SetImmediateSigned(addr - sp); 2553 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2554 LLDB_REGNUM_GENERIC_SP, offset_addr)) 2555 return false; 2556 } 2557 } 2558 return true; 2559 } 2560 2561 // Vector Push stores multiple extension registers to the stack. It also 2562 // updates SP to point to the start of the stored data. 2563 bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode, 2564 const ARMEncoding encoding) { 2565 #if 0 2566 // ARM pseudo code... 2567 if (ConditionPassed()) 2568 { 2569 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2570 address = SP - imm32; 2571 SP = SP - imm32; 2572 if single_regs then 2573 for r = 0 to regs-1 2574 MemA[address,4] = S[d+r]; address = address+4; 2575 else 2576 for r = 0 to regs-1 2577 // Store as two word-aligned words in the correct order for 2578 // current endianness. 2579 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2580 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2581 address = address+8; 2582 } 2583 #endif 2584 2585 bool success = false; 2586 if (ConditionPassed(opcode)) { 2587 const uint32_t addr_byte_size = GetAddressByteSize(); 2588 const addr_t sp = ReadCoreReg(SP_REG, &success); 2589 if (!success) 2590 return false; 2591 bool single_regs; 2592 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2593 uint32_t imm32; // stack offset 2594 uint32_t regs; // number of registers 2595 switch (encoding) { 2596 case eEncodingT1: 2597 case eEncodingA1: 2598 single_regs = false; 2599 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2600 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2601 // If UInt(imm8) is odd, see "FSTMX". 2602 regs = Bits32(opcode, 7, 0) / 2; 2603 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2604 if (regs == 0 || regs > 16 || (d + regs) > 32) 2605 return false; 2606 break; 2607 case eEncodingT2: 2608 case eEncodingA2: 2609 single_regs = true; 2610 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2611 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2612 regs = Bits32(opcode, 7, 0); 2613 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2614 if (regs == 0 || regs > 16 || (d + regs) > 32) 2615 return false; 2616 break; 2617 default: 2618 return false; 2619 } 2620 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2621 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2622 addr_t sp_offset = imm32; 2623 addr_t addr = sp - sp_offset; 2624 uint32_t i; 2625 2626 EmulateInstruction::Context context; 2627 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2628 2629 RegisterInfo dwarf_reg; 2630 RegisterInfo sp_reg; 2631 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2632 for (i = 0; i < regs; ++i) { 2633 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2634 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2635 // uint64_t to accommodate 64-bit registers. 2636 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success); 2637 if (!success) 2638 return false; 2639 if (!MemAWrite(context, addr, reg_value, reg_byte_size)) 2640 return false; 2641 addr += reg_byte_size; 2642 } 2643 2644 context.type = EmulateInstruction::eContextAdjustStackPointer; 2645 context.SetImmediateSigned(-sp_offset); 2646 2647 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2648 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2649 return false; 2650 } 2651 return true; 2652 } 2653 2654 // Vector Pop loads multiple extension registers from the stack. It also 2655 // updates SP to point just above the loaded data. 2656 bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode, 2657 const ARMEncoding encoding) { 2658 #if 0 2659 // ARM pseudo code... 2660 if (ConditionPassed()) 2661 { 2662 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2663 address = SP; 2664 SP = SP + imm32; 2665 if single_regs then 2666 for r = 0 to regs-1 2667 S[d+r] = MemA[address,4]; address = address+4; 2668 else 2669 for r = 0 to regs-1 2670 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2671 // Combine the word-aligned words in the correct order for 2672 // current endianness. 2673 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2674 } 2675 #endif 2676 2677 bool success = false; 2678 if (ConditionPassed(opcode)) { 2679 const uint32_t addr_byte_size = GetAddressByteSize(); 2680 const addr_t sp = ReadCoreReg(SP_REG, &success); 2681 if (!success) 2682 return false; 2683 bool single_regs; 2684 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2685 uint32_t imm32; // stack offset 2686 uint32_t regs; // number of registers 2687 switch (encoding) { 2688 case eEncodingT1: 2689 case eEncodingA1: 2690 single_regs = false; 2691 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2692 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2693 // If UInt(imm8) is odd, see "FLDMX". 2694 regs = Bits32(opcode, 7, 0) / 2; 2695 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2696 if (regs == 0 || regs > 16 || (d + regs) > 32) 2697 return false; 2698 break; 2699 case eEncodingT2: 2700 case eEncodingA2: 2701 single_regs = true; 2702 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2703 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2704 regs = Bits32(opcode, 7, 0); 2705 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2706 if (regs == 0 || regs > 16 || (d + regs) > 32) 2707 return false; 2708 break; 2709 default: 2710 return false; 2711 } 2712 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2713 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2714 addr_t sp_offset = imm32; 2715 addr_t addr = sp; 2716 uint32_t i; 2717 uint64_t data; // uint64_t to accommodate 64-bit registers. 2718 2719 EmulateInstruction::Context context; 2720 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2721 2722 RegisterInfo dwarf_reg; 2723 RegisterInfo sp_reg; 2724 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2725 for (i = 0; i < regs; ++i) { 2726 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2727 context.SetAddress(addr); 2728 data = MemARead(context, addr, reg_byte_size, 0, &success); 2729 if (!success) 2730 return false; 2731 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2732 return false; 2733 addr += reg_byte_size; 2734 } 2735 2736 context.type = EmulateInstruction::eContextAdjustStackPointer; 2737 context.SetImmediateSigned(sp_offset); 2738 2739 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2740 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2741 return false; 2742 } 2743 return true; 2744 } 2745 2746 // SVC (previously SWI) 2747 bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode, 2748 const ARMEncoding encoding) { 2749 #if 0 2750 // ARM pseudo code... 2751 if (ConditionPassed()) 2752 { 2753 EncodingSpecificOperations(); 2754 CallSupervisor(); 2755 } 2756 #endif 2757 2758 bool success = false; 2759 2760 if (ConditionPassed(opcode)) { 2761 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2762 addr_t lr; // next instruction address 2763 if (!success) 2764 return false; 2765 uint32_t imm32; // the immediate constant 2766 uint32_t mode; // ARM or Thumb mode 2767 switch (encoding) { 2768 case eEncodingT1: 2769 lr = (pc + 2) | 1u; // return address 2770 imm32 = Bits32(opcode, 7, 0); 2771 mode = eModeThumb; 2772 break; 2773 case eEncodingA1: 2774 lr = pc + 4; // return address 2775 imm32 = Bits32(opcode, 23, 0); 2776 mode = eModeARM; 2777 break; 2778 default: 2779 return false; 2780 } 2781 2782 EmulateInstruction::Context context; 2783 context.type = EmulateInstruction::eContextSupervisorCall; 2784 context.SetISAAndImmediate(mode, imm32); 2785 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2786 LLDB_REGNUM_GENERIC_RA, lr)) 2787 return false; 2788 } 2789 return true; 2790 } 2791 2792 // If Then makes up to four following instructions (the IT block) conditional. 2793 bool EmulateInstructionARM::EmulateIT(const uint32_t opcode, 2794 const ARMEncoding encoding) { 2795 #if 0 2796 // ARM pseudo code... 2797 EncodingSpecificOperations(); 2798 ITSTATE.IT<7:0> = firstcond:mask; 2799 #endif 2800 2801 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2802 return true; 2803 } 2804 2805 bool EmulateInstructionARM::EmulateNop(const uint32_t opcode, 2806 const ARMEncoding encoding) { 2807 // NOP, nothing to do... 2808 return true; 2809 } 2810 2811 // Branch causes a branch to a target address. 2812 bool EmulateInstructionARM::EmulateB(const uint32_t opcode, 2813 const ARMEncoding encoding) { 2814 #if 0 2815 // ARM pseudo code... 2816 if (ConditionPassed()) 2817 { 2818 EncodingSpecificOperations(); 2819 BranchWritePC(PC + imm32); 2820 } 2821 #endif 2822 2823 bool success = false; 2824 2825 if (ConditionPassed(opcode)) { 2826 EmulateInstruction::Context context; 2827 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2828 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2829 if (!success) 2830 return false; 2831 addr_t target; // target address 2832 int32_t imm32; // PC-relative offset 2833 switch (encoding) { 2834 case eEncodingT1: 2835 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2836 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2837 target = pc + imm32; 2838 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2839 break; 2840 case eEncodingT2: 2841 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2842 target = pc + imm32; 2843 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2844 break; 2845 case eEncodingT3: 2846 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2847 { 2848 if (Bits32(opcode, 25, 23) == 7) 2849 return false; // See Branches and miscellaneous control on page 2850 // A6-235. 2851 2852 uint32_t S = Bit32(opcode, 26); 2853 uint32_t imm6 = Bits32(opcode, 21, 16); 2854 uint32_t J1 = Bit32(opcode, 13); 2855 uint32_t J2 = Bit32(opcode, 11); 2856 uint32_t imm11 = Bits32(opcode, 10, 0); 2857 uint32_t imm21 = 2858 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2859 imm32 = llvm::SignExtend32<21>(imm21); 2860 target = pc + imm32; 2861 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2862 break; 2863 } 2864 case eEncodingT4: { 2865 uint32_t S = Bit32(opcode, 26); 2866 uint32_t imm10 = Bits32(opcode, 25, 16); 2867 uint32_t J1 = Bit32(opcode, 13); 2868 uint32_t J2 = Bit32(opcode, 11); 2869 uint32_t imm11 = Bits32(opcode, 10, 0); 2870 uint32_t I1 = !(J1 ^ S); 2871 uint32_t I2 = !(J2 ^ S); 2872 uint32_t imm25 = 2873 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2874 imm32 = llvm::SignExtend32<25>(imm25); 2875 target = pc + imm32; 2876 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2877 break; 2878 } 2879 case eEncodingA1: 2880 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2881 target = pc + imm32; 2882 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2883 break; 2884 default: 2885 return false; 2886 } 2887 if (!BranchWritePC(context, target)) 2888 return false; 2889 } 2890 return true; 2891 } 2892 2893 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the 2894 // value in a register with zero and conditionally branch forward a constant 2895 // value. They do not affect the condition flags. CBNZ, CBZ 2896 bool EmulateInstructionARM::EmulateCB(const uint32_t opcode, 2897 const ARMEncoding encoding) { 2898 #if 0 2899 // ARM pseudo code... 2900 EncodingSpecificOperations(); 2901 if nonzero ^ IsZero(R[n]) then 2902 BranchWritePC(PC + imm32); 2903 #endif 2904 2905 bool success = false; 2906 2907 // Read the register value from the operand register Rn. 2908 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2909 if (!success) 2910 return false; 2911 2912 EmulateInstruction::Context context; 2913 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2914 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2915 if (!success) 2916 return false; 2917 2918 addr_t target; // target address 2919 uint32_t imm32; // PC-relative offset to branch forward 2920 bool nonzero; 2921 switch (encoding) { 2922 case eEncodingT1: 2923 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2924 nonzero = BitIsSet(opcode, 11); 2925 target = pc + imm32; 2926 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2927 break; 2928 default: 2929 return false; 2930 } 2931 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2932 if (!BranchWritePC(context, target)) 2933 return false; 2934 2935 return true; 2936 } 2937 2938 // Table Branch Byte causes a PC-relative forward branch using a table of 2939 // single byte offsets. 2940 // A base register provides a pointer to the table, and a second register 2941 // supplies an index into the table. 2942 // The branch length is twice the value of the byte returned from the table. 2943 // 2944 // Table Branch Halfword causes a PC-relative forward branch using a table of 2945 // single halfword offsets. 2946 // A base register provides a pointer to the table, and a second register 2947 // supplies an index into the table. 2948 // The branch length is twice the value of the halfword returned from the 2949 // table. TBB, TBH 2950 bool EmulateInstructionARM::EmulateTB(const uint32_t opcode, 2951 const ARMEncoding encoding) { 2952 #if 0 2953 // ARM pseudo code... 2954 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2955 if is_tbh then 2956 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2957 else 2958 halfwords = UInt(MemU[R[n]+R[m], 1]); 2959 BranchWritePC(PC + 2*halfwords); 2960 #endif 2961 2962 bool success = false; 2963 2964 if (ConditionPassed(opcode)) { 2965 uint32_t Rn; // the base register which contains the address of the table of 2966 // branch lengths 2967 uint32_t Rm; // the index register which contains an integer pointing to a 2968 // byte/halfword in the table 2969 bool is_tbh; // true if table branch halfword 2970 switch (encoding) { 2971 case eEncodingT1: 2972 Rn = Bits32(opcode, 19, 16); 2973 Rm = Bits32(opcode, 3, 0); 2974 is_tbh = BitIsSet(opcode, 4); 2975 if (Rn == 13 || BadReg(Rm)) 2976 return false; 2977 if (InITBlock() && !LastInITBlock()) 2978 return false; 2979 break; 2980 default: 2981 return false; 2982 } 2983 2984 // Read the address of the table from the operand register Rn. The PC can 2985 // be used, in which case the table immediately follows this instruction. 2986 uint32_t base = ReadCoreReg(Rn, &success); 2987 if (!success) 2988 return false; 2989 2990 // the table index 2991 uint32_t index = ReadCoreReg(Rm, &success); 2992 if (!success) 2993 return false; 2994 2995 // the offsetted table address 2996 addr_t addr = base + (is_tbh ? index * 2 : index); 2997 2998 // PC-relative offset to branch forward 2999 EmulateInstruction::Context context; 3000 context.type = EmulateInstruction::eContextTableBranchReadMemory; 3001 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 3002 if (!success) 3003 return false; 3004 3005 const uint32_t pc = ReadCoreReg(PC_REG, &success); 3006 if (!success) 3007 return false; 3008 3009 // target address 3010 addr_t target = pc + offset; 3011 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 3012 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset); 3013 3014 if (!BranchWritePC(context, target)) 3015 return false; 3016 } 3017 3018 return true; 3019 } 3020 3021 // This instruction adds an immediate value to a register value, and writes the 3022 // result to the destination register. It can optionally update the condition 3023 // flags based on the result. 3024 bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode, 3025 const ARMEncoding encoding) { 3026 #if 0 3027 if ConditionPassed() then 3028 EncodingSpecificOperations(); 3029 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3030 R[d] = result; 3031 if setflags then 3032 APSR.N = result<31>; 3033 APSR.Z = IsZeroBit(result); 3034 APSR.C = carry; 3035 APSR.V = overflow; 3036 #endif 3037 3038 bool success = false; 3039 3040 if (ConditionPassed(opcode)) { 3041 uint32_t d; 3042 uint32_t n; 3043 bool setflags; 3044 uint32_t imm32; 3045 uint32_t carry_out; 3046 3047 // EncodingSpecificOperations(); 3048 switch (encoding) { 3049 case eEncodingT1: 3050 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = 3051 // ZeroExtend(imm3, 32); 3052 d = Bits32(opcode, 2, 0); 3053 n = Bits32(opcode, 5, 3); 3054 setflags = !InITBlock(); 3055 imm32 = Bits32(opcode, 8, 6); 3056 3057 break; 3058 3059 case eEncodingT2: 3060 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = 3061 // ZeroExtend(imm8, 32); 3062 d = Bits32(opcode, 10, 8); 3063 n = Bits32(opcode, 10, 8); 3064 setflags = !InITBlock(); 3065 imm32 = Bits32(opcode, 7, 0); 3066 3067 break; 3068 3069 case eEncodingT3: 3070 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 3071 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = 3072 // ThumbExpandImm(i:imm3:imm8); 3073 d = Bits32(opcode, 11, 8); 3074 n = Bits32(opcode, 19, 16); 3075 setflags = BitIsSet(opcode, 20); 3076 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out); 3077 3078 // if Rn == '1101' then SEE ADD (SP plus immediate); 3079 if (n == 13) 3080 return EmulateADDSPImm(opcode, eEncodingT3); 3081 3082 // if BadReg(d) || n == 15 then UNPREDICTABLE; 3083 if (BadReg(d) || (n == 15)) 3084 return false; 3085 3086 break; 3087 3088 case eEncodingT4: { 3089 // if Rn == '1111' then SEE ADR; 3090 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = 3091 // ZeroExtend(i:imm3:imm8, 32); 3092 d = Bits32(opcode, 11, 8); 3093 n = Bits32(opcode, 19, 16); 3094 setflags = false; 3095 uint32_t i = Bit32(opcode, 26); 3096 uint32_t imm3 = Bits32(opcode, 14, 12); 3097 uint32_t imm8 = Bits32(opcode, 7, 0); 3098 imm32 = (i << 11) | (imm3 << 8) | imm8; 3099 3100 // if Rn == '1101' then SEE ADD (SP plus immediate); 3101 if (n == 13) 3102 return EmulateADDSPImm(opcode, eEncodingT4); 3103 3104 // if BadReg(d) then UNPREDICTABLE; 3105 if (BadReg(d)) 3106 return false; 3107 3108 break; 3109 } 3110 3111 default: 3112 return false; 3113 } 3114 3115 uint64_t Rn = 3116 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3117 if (!success) 3118 return false; 3119 3120 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3121 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0); 3122 3123 RegisterInfo reg_n; 3124 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 3125 3126 EmulateInstruction::Context context; 3127 context.type = eContextArithmetic; 3128 context.SetRegisterPlusOffset(reg_n, imm32); 3129 3130 // R[d] = result; 3131 // if setflags then 3132 // APSR.N = result<31>; 3133 // APSR.Z = IsZeroBit(result); 3134 // APSR.C = carry; 3135 // APSR.V = overflow; 3136 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 3137 res.carry_out, res.overflow)) 3138 return false; 3139 } 3140 return true; 3141 } 3142 3143 // This instruction adds an immediate value to a register value, and writes the 3144 // result to the destination register. It can optionally update the condition 3145 // flags based on the result. 3146 bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode, 3147 const ARMEncoding encoding) { 3148 #if 0 3149 // ARM pseudo code... 3150 if ConditionPassed() then 3151 EncodingSpecificOperations(); 3152 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3153 if d == 15 then 3154 ALUWritePC(result); // setflags is always FALSE here 3155 else 3156 R[d] = result; 3157 if setflags then 3158 APSR.N = result<31>; 3159 APSR.Z = IsZeroBit(result); 3160 APSR.C = carry; 3161 APSR.V = overflow; 3162 #endif 3163 3164 bool success = false; 3165 3166 if (ConditionPassed(opcode)) { 3167 uint32_t Rd, Rn; 3168 uint32_t 3169 imm32; // the immediate value to be added to the value obtained from Rn 3170 bool setflags; 3171 switch (encoding) { 3172 case eEncodingA1: 3173 Rd = Bits32(opcode, 15, 12); 3174 Rn = Bits32(opcode, 19, 16); 3175 setflags = BitIsSet(opcode, 20); 3176 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3177 break; 3178 default: 3179 return false; 3180 } 3181 3182 // Read the first operand. 3183 uint32_t val1 = ReadCoreReg(Rn, &success); 3184 if (!success) 3185 return false; 3186 3187 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 3188 3189 EmulateInstruction::Context context; 3190 if (Rd == 13) 3191 context.type = EmulateInstruction::eContextAdjustStackPointer; 3192 else if (Rd == GetFramePointerRegisterNumber()) 3193 context.type = EmulateInstruction::eContextSetFramePointer; 3194 else 3195 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3196 3197 RegisterInfo dwarf_reg; 3198 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 3199 context.SetRegisterPlusOffset(dwarf_reg, imm32); 3200 3201 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3202 res.carry_out, res.overflow)) 3203 return false; 3204 } 3205 return true; 3206 } 3207 3208 // This instruction adds a register value and an optionally-shifted register 3209 // value, and writes the result to the destination register. It can optionally 3210 // update the condition flags based on the result. 3211 bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode, 3212 const ARMEncoding encoding) { 3213 #if 0 3214 // ARM pseudo code... 3215 if ConditionPassed() then 3216 EncodingSpecificOperations(); 3217 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3218 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3219 if d == 15 then 3220 ALUWritePC(result); // setflags is always FALSE here 3221 else 3222 R[d] = result; 3223 if setflags then 3224 APSR.N = result<31>; 3225 APSR.Z = IsZeroBit(result); 3226 APSR.C = carry; 3227 APSR.V = overflow; 3228 #endif 3229 3230 bool success = false; 3231 3232 if (ConditionPassed(opcode)) { 3233 uint32_t Rd, Rn, Rm; 3234 ARM_ShifterType shift_t; 3235 uint32_t shift_n; // the shift applied to the value read from Rm 3236 bool setflags; 3237 switch (encoding) { 3238 case eEncodingT1: 3239 Rd = Bits32(opcode, 2, 0); 3240 Rn = Bits32(opcode, 5, 3); 3241 Rm = Bits32(opcode, 8, 6); 3242 setflags = !InITBlock(); 3243 shift_t = SRType_LSL; 3244 shift_n = 0; 3245 break; 3246 case eEncodingT2: 3247 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3248 Rm = Bits32(opcode, 6, 3); 3249 setflags = false; 3250 shift_t = SRType_LSL; 3251 shift_n = 0; 3252 if (Rn == 15 && Rm == 15) 3253 return false; 3254 if (Rd == 15 && InITBlock() && !LastInITBlock()) 3255 return false; 3256 break; 3257 case eEncodingA1: 3258 Rd = Bits32(opcode, 15, 12); 3259 Rn = Bits32(opcode, 19, 16); 3260 Rm = Bits32(opcode, 3, 0); 3261 setflags = BitIsSet(opcode, 20); 3262 shift_n = DecodeImmShiftARM(opcode, shift_t); 3263 break; 3264 default: 3265 return false; 3266 } 3267 3268 // Read the first operand. 3269 uint32_t val1 = ReadCoreReg(Rn, &success); 3270 if (!success) 3271 return false; 3272 3273 // Read the second operand. 3274 uint32_t val2 = ReadCoreReg(Rm, &success); 3275 if (!success) 3276 return false; 3277 3278 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3279 if (!success) 3280 return false; 3281 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3282 3283 EmulateInstruction::Context context; 3284 context.type = eContextArithmetic; 3285 RegisterInfo op1_reg; 3286 RegisterInfo op2_reg; 3287 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 3288 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 3289 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 3290 3291 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3292 res.carry_out, res.overflow)) 3293 return false; 3294 } 3295 return true; 3296 } 3297 3298 // Compare Negative (immediate) adds a register value and an immediate value. 3299 // It updates the condition flags based on the result, and discards the result. 3300 bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode, 3301 const ARMEncoding encoding) { 3302 #if 0 3303 // ARM pseudo code... 3304 if ConditionPassed() then 3305 EncodingSpecificOperations(); 3306 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3307 APSR.N = result<31>; 3308 APSR.Z = IsZeroBit(result); 3309 APSR.C = carry; 3310 APSR.V = overflow; 3311 #endif 3312 3313 bool success = false; 3314 3315 uint32_t Rn; // the first operand 3316 uint32_t imm32; // the immediate value to be compared with 3317 switch (encoding) { 3318 case eEncodingT1: 3319 Rn = Bits32(opcode, 19, 16); 3320 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3321 if (Rn == 15) 3322 return false; 3323 break; 3324 case eEncodingA1: 3325 Rn = Bits32(opcode, 19, 16); 3326 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3327 break; 3328 default: 3329 return false; 3330 } 3331 // Read the register value from the operand register Rn. 3332 uint32_t reg_val = ReadCoreReg(Rn, &success); 3333 if (!success) 3334 return false; 3335 3336 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 3337 3338 EmulateInstruction::Context context; 3339 context.type = EmulateInstruction::eContextImmediate; 3340 context.SetNoArgs(); 3341 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3342 } 3343 3344 // Compare Negative (register) adds a register value and an optionally-shifted 3345 // register value. It updates the condition flags based on the result, and 3346 // discards the result. 3347 bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode, 3348 const ARMEncoding encoding) { 3349 #if 0 3350 // ARM pseudo code... 3351 if ConditionPassed() then 3352 EncodingSpecificOperations(); 3353 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3354 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3355 APSR.N = result<31>; 3356 APSR.Z = IsZeroBit(result); 3357 APSR.C = carry; 3358 APSR.V = overflow; 3359 #endif 3360 3361 bool success = false; 3362 3363 uint32_t Rn; // the first operand 3364 uint32_t Rm; // the second operand 3365 ARM_ShifterType shift_t; 3366 uint32_t shift_n; // the shift applied to the value read from Rm 3367 switch (encoding) { 3368 case eEncodingT1: 3369 Rn = Bits32(opcode, 2, 0); 3370 Rm = Bits32(opcode, 5, 3); 3371 shift_t = SRType_LSL; 3372 shift_n = 0; 3373 break; 3374 case eEncodingT2: 3375 Rn = Bits32(opcode, 19, 16); 3376 Rm = Bits32(opcode, 3, 0); 3377 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3378 // if n == 15 || BadReg(m) then UNPREDICTABLE; 3379 if (Rn == 15 || BadReg(Rm)) 3380 return false; 3381 break; 3382 case eEncodingA1: 3383 Rn = Bits32(opcode, 19, 16); 3384 Rm = Bits32(opcode, 3, 0); 3385 shift_n = DecodeImmShiftARM(opcode, shift_t); 3386 break; 3387 default: 3388 return false; 3389 } 3390 // Read the register value from register Rn. 3391 uint32_t val1 = ReadCoreReg(Rn, &success); 3392 if (!success) 3393 return false; 3394 3395 // Read the register value from register Rm. 3396 uint32_t val2 = ReadCoreReg(Rm, &success); 3397 if (!success) 3398 return false; 3399 3400 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3401 if (!success) 3402 return false; 3403 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3404 3405 EmulateInstruction::Context context; 3406 context.type = EmulateInstruction::eContextImmediate; 3407 context.SetNoArgs(); 3408 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3409 } 3410 3411 // Compare (immediate) subtracts an immediate value from a register value. It 3412 // updates the condition flags based on the result, and discards the result. 3413 bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode, 3414 const ARMEncoding encoding) { 3415 #if 0 3416 // ARM pseudo code... 3417 if ConditionPassed() then 3418 EncodingSpecificOperations(); 3419 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 3420 APSR.N = result<31>; 3421 APSR.Z = IsZeroBit(result); 3422 APSR.C = carry; 3423 APSR.V = overflow; 3424 #endif 3425 3426 bool success = false; 3427 3428 uint32_t Rn; // the first operand 3429 uint32_t imm32; // the immediate value to be compared with 3430 switch (encoding) { 3431 case eEncodingT1: 3432 Rn = Bits32(opcode, 10, 8); 3433 imm32 = Bits32(opcode, 7, 0); 3434 break; 3435 case eEncodingT2: 3436 Rn = Bits32(opcode, 19, 16); 3437 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3438 if (Rn == 15) 3439 return false; 3440 break; 3441 case eEncodingA1: 3442 Rn = Bits32(opcode, 19, 16); 3443 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3444 break; 3445 default: 3446 return false; 3447 } 3448 // Read the register value from the operand register Rn. 3449 uint32_t reg_val = ReadCoreReg(Rn, &success); 3450 if (!success) 3451 return false; 3452 3453 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 3454 3455 EmulateInstruction::Context context; 3456 context.type = EmulateInstruction::eContextImmediate; 3457 context.SetNoArgs(); 3458 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3459 } 3460 3461 // Compare (register) subtracts an optionally-shifted register value from a 3462 // register value. It updates the condition flags based on the result, and 3463 // discards the result. 3464 bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode, 3465 const ARMEncoding encoding) { 3466 #if 0 3467 // ARM pseudo code... 3468 if ConditionPassed() then 3469 EncodingSpecificOperations(); 3470 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3471 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 3472 APSR.N = result<31>; 3473 APSR.Z = IsZeroBit(result); 3474 APSR.C = carry; 3475 APSR.V = overflow; 3476 #endif 3477 3478 bool success = false; 3479 3480 uint32_t Rn; // the first operand 3481 uint32_t Rm; // the second operand 3482 ARM_ShifterType shift_t; 3483 uint32_t shift_n; // the shift applied to the value read from Rm 3484 switch (encoding) { 3485 case eEncodingT1: 3486 Rn = Bits32(opcode, 2, 0); 3487 Rm = Bits32(opcode, 5, 3); 3488 shift_t = SRType_LSL; 3489 shift_n = 0; 3490 break; 3491 case eEncodingT2: 3492 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3493 Rm = Bits32(opcode, 6, 3); 3494 shift_t = SRType_LSL; 3495 shift_n = 0; 3496 if (Rn < 8 && Rm < 8) 3497 return false; 3498 if (Rn == 15 || Rm == 15) 3499 return false; 3500 break; 3501 case eEncodingT3: 3502 Rn = Bits32(opcode, 19, 16); 3503 Rm = Bits32(opcode, 3, 0); 3504 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3505 if (Rn == 15 || BadReg(Rm)) 3506 return false; 3507 break; 3508 case eEncodingA1: 3509 Rn = Bits32(opcode, 19, 16); 3510 Rm = Bits32(opcode, 3, 0); 3511 shift_n = DecodeImmShiftARM(opcode, shift_t); 3512 break; 3513 default: 3514 return false; 3515 } 3516 // Read the register value from register Rn. 3517 uint32_t val1 = ReadCoreReg(Rn, &success); 3518 if (!success) 3519 return false; 3520 3521 // Read the register value from register Rm. 3522 uint32_t val2 = ReadCoreReg(Rm, &success); 3523 if (!success) 3524 return false; 3525 3526 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3527 if (!success) 3528 return false; 3529 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3530 3531 EmulateInstruction::Context context; 3532 context.type = EmulateInstruction::eContextImmediate; 3533 context.SetNoArgs(); 3534 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3535 } 3536 3537 // Arithmetic Shift Right (immediate) shifts a register value right by an 3538 // immediate number of bits, shifting in copies of its sign bit, and writes the 3539 // result to the destination register. It can optionally update the condition 3540 // flags based on the result. 3541 bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode, 3542 const ARMEncoding encoding) { 3543 #if 0 3544 // ARM pseudo code... 3545 if ConditionPassed() then 3546 EncodingSpecificOperations(); 3547 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3548 if d == 15 then // Can only occur for ARM encoding 3549 ALUWritePC(result); // setflags is always FALSE here 3550 else 3551 R[d] = result; 3552 if setflags then 3553 APSR.N = result<31>; 3554 APSR.Z = IsZeroBit(result); 3555 APSR.C = carry; 3556 // APSR.V unchanged 3557 #endif 3558 3559 return EmulateShiftImm(opcode, encoding, SRType_ASR); 3560 } 3561 3562 // Arithmetic Shift Right (register) shifts a register value right by a 3563 // variable number of bits, shifting in copies of its sign bit, and writes the 3564 // result to the destination register. The variable number of bits is read from 3565 // the bottom byte of a register. It can optionally update the condition flags 3566 // based on the result. 3567 bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode, 3568 const ARMEncoding encoding) { 3569 #if 0 3570 // ARM pseudo code... 3571 if ConditionPassed() then 3572 EncodingSpecificOperations(); 3573 shift_n = UInt(R[m]<7:0>); 3574 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3575 R[d] = result; 3576 if setflags then 3577 APSR.N = result<31>; 3578 APSR.Z = IsZeroBit(result); 3579 APSR.C = carry; 3580 // APSR.V unchanged 3581 #endif 3582 3583 return EmulateShiftReg(opcode, encoding, SRType_ASR); 3584 } 3585 3586 // Logical Shift Left (immediate) shifts a register value left by an immediate 3587 // number of bits, shifting in zeros, and writes the result to the destination 3588 // register. It can optionally update the condition flags based on the result. 3589 bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode, 3590 const ARMEncoding encoding) { 3591 #if 0 3592 // ARM pseudo code... 3593 if ConditionPassed() then 3594 EncodingSpecificOperations(); 3595 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3596 if d == 15 then // Can only occur for ARM encoding 3597 ALUWritePC(result); // setflags is always FALSE here 3598 else 3599 R[d] = result; 3600 if setflags then 3601 APSR.N = result<31>; 3602 APSR.Z = IsZeroBit(result); 3603 APSR.C = carry; 3604 // APSR.V unchanged 3605 #endif 3606 3607 return EmulateShiftImm(opcode, encoding, SRType_LSL); 3608 } 3609 3610 // Logical Shift Left (register) shifts a register value left by a variable 3611 // number of bits, shifting in zeros, and writes the result to the destination 3612 // register. The variable number of bits is read from the bottom byte of a 3613 // register. It can optionally update the condition flags based on the result. 3614 bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode, 3615 const ARMEncoding encoding) { 3616 #if 0 3617 // ARM pseudo code... 3618 if ConditionPassed() then 3619 EncodingSpecificOperations(); 3620 shift_n = UInt(R[m]<7:0>); 3621 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3622 R[d] = result; 3623 if setflags then 3624 APSR.N = result<31>; 3625 APSR.Z = IsZeroBit(result); 3626 APSR.C = carry; 3627 // APSR.V unchanged 3628 #endif 3629 3630 return EmulateShiftReg(opcode, encoding, SRType_LSL); 3631 } 3632 3633 // Logical Shift Right (immediate) shifts a register value right by an 3634 // immediate number of bits, shifting in zeros, and writes the result to the 3635 // destination register. It can optionally update the condition flags based on 3636 // the result. 3637 bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode, 3638 const ARMEncoding encoding) { 3639 #if 0 3640 // ARM pseudo code... 3641 if ConditionPassed() then 3642 EncodingSpecificOperations(); 3643 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3644 if d == 15 then // Can only occur for ARM encoding 3645 ALUWritePC(result); // setflags is always FALSE here 3646 else 3647 R[d] = result; 3648 if setflags then 3649 APSR.N = result<31>; 3650 APSR.Z = IsZeroBit(result); 3651 APSR.C = carry; 3652 // APSR.V unchanged 3653 #endif 3654 3655 return EmulateShiftImm(opcode, encoding, SRType_LSR); 3656 } 3657 3658 // Logical Shift Right (register) shifts a register value right by a variable 3659 // number of bits, shifting in zeros, and writes the result to the destination 3660 // register. The variable number of bits is read from the bottom byte of a 3661 // register. It can optionally update the condition flags based on the result. 3662 bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode, 3663 const ARMEncoding encoding) { 3664 #if 0 3665 // ARM pseudo code... 3666 if ConditionPassed() then 3667 EncodingSpecificOperations(); 3668 shift_n = UInt(R[m]<7:0>); 3669 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3670 R[d] = result; 3671 if setflags then 3672 APSR.N = result<31>; 3673 APSR.Z = IsZeroBit(result); 3674 APSR.C = carry; 3675 // APSR.V unchanged 3676 #endif 3677 3678 return EmulateShiftReg(opcode, encoding, SRType_LSR); 3679 } 3680 3681 // Rotate Right (immediate) provides the value of the contents of a register 3682 // rotated by a constant value. The bits that are rotated off the right end are 3683 // inserted into the vacated bit positions on the left. It can optionally 3684 // update the condition flags based on the result. 3685 bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode, 3686 const ARMEncoding encoding) { 3687 #if 0 3688 // ARM pseudo code... 3689 if ConditionPassed() then 3690 EncodingSpecificOperations(); 3691 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3692 if d == 15 then // Can only occur for ARM encoding 3693 ALUWritePC(result); // setflags is always FALSE here 3694 else 3695 R[d] = result; 3696 if setflags then 3697 APSR.N = result<31>; 3698 APSR.Z = IsZeroBit(result); 3699 APSR.C = carry; 3700 // APSR.V unchanged 3701 #endif 3702 3703 return EmulateShiftImm(opcode, encoding, SRType_ROR); 3704 } 3705 3706 // Rotate Right (register) provides the value of the contents of a register 3707 // rotated by a variable number of bits. The bits that are rotated off the 3708 // right end are inserted into the vacated bit positions on the left. The 3709 // variable number of bits is read from the bottom byte of a register. It can 3710 // optionally update the condition flags based on the result. 3711 bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode, 3712 const ARMEncoding encoding) { 3713 #if 0 3714 // ARM pseudo code... 3715 if ConditionPassed() then 3716 EncodingSpecificOperations(); 3717 shift_n = UInt(R[m]<7:0>); 3718 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3719 R[d] = result; 3720 if setflags then 3721 APSR.N = result<31>; 3722 APSR.Z = IsZeroBit(result); 3723 APSR.C = carry; 3724 // APSR.V unchanged 3725 #endif 3726 3727 return EmulateShiftReg(opcode, encoding, SRType_ROR); 3728 } 3729 3730 // Rotate Right with Extend provides the value of the contents of a register 3731 // shifted right by one place, with the carry flag shifted into bit [31]. 3732 // 3733 // RRX can optionally update the condition flags based on the result. 3734 // In that case, bit [0] is shifted into the carry flag. 3735 bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode, 3736 const ARMEncoding encoding) { 3737 #if 0 3738 // ARM pseudo code... 3739 if ConditionPassed() then 3740 EncodingSpecificOperations(); 3741 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3742 if d == 15 then // Can only occur for ARM encoding 3743 ALUWritePC(result); // setflags is always FALSE here 3744 else 3745 R[d] = result; 3746 if setflags then 3747 APSR.N = result<31>; 3748 APSR.Z = IsZeroBit(result); 3749 APSR.C = carry; 3750 // APSR.V unchanged 3751 #endif 3752 3753 return EmulateShiftImm(opcode, encoding, SRType_RRX); 3754 } 3755 3756 bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode, 3757 const ARMEncoding encoding, 3758 ARM_ShifterType shift_type) { 3759 // assert(shift_type == SRType_ASR 3760 // || shift_type == SRType_LSL 3761 // || shift_type == SRType_LSR 3762 // || shift_type == SRType_ROR 3763 // || shift_type == SRType_RRX); 3764 3765 bool success = false; 3766 3767 if (ConditionPassed(opcode)) { 3768 uint32_t Rd; // the destination register 3769 uint32_t Rm; // the first operand register 3770 uint32_t imm5; // encoding for the shift amount 3771 uint32_t carry; // the carry bit after the shift operation 3772 bool setflags; 3773 3774 // Special case handling! 3775 // A8.6.139 ROR (immediate) -- Encoding T1 3776 ARMEncoding use_encoding = encoding; 3777 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) { 3778 // Morph the T1 encoding from the ARM Architecture Manual into T2 3779 // encoding to have the same decoding of bit fields as the other Thumb2 3780 // shift operations. 3781 use_encoding = eEncodingT2; 3782 } 3783 3784 switch (use_encoding) { 3785 case eEncodingT1: 3786 // Due to the above special case handling! 3787 if (shift_type == SRType_ROR) 3788 return false; 3789 3790 Rd = Bits32(opcode, 2, 0); 3791 Rm = Bits32(opcode, 5, 3); 3792 setflags = !InITBlock(); 3793 imm5 = Bits32(opcode, 10, 6); 3794 break; 3795 case eEncodingT2: 3796 // A8.6.141 RRX 3797 // There's no imm form of RRX instructions. 3798 if (shift_type == SRType_RRX) 3799 return false; 3800 3801 Rd = Bits32(opcode, 11, 8); 3802 Rm = Bits32(opcode, 3, 0); 3803 setflags = BitIsSet(opcode, 20); 3804 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3805 if (BadReg(Rd) || BadReg(Rm)) 3806 return false; 3807 break; 3808 case eEncodingA1: 3809 Rd = Bits32(opcode, 15, 12); 3810 Rm = Bits32(opcode, 3, 0); 3811 setflags = BitIsSet(opcode, 20); 3812 imm5 = Bits32(opcode, 11, 7); 3813 break; 3814 default: 3815 return false; 3816 } 3817 3818 // A8.6.139 ROR (immediate) 3819 if (shift_type == SRType_ROR && imm5 == 0) 3820 shift_type = SRType_RRX; 3821 3822 // Get the first operand. 3823 uint32_t value = ReadCoreReg(Rm, &success); 3824 if (!success) 3825 return false; 3826 3827 // Decode the shift amount if not RRX. 3828 uint32_t amt = 3829 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3830 3831 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3832 if (!success) 3833 return false; 3834 3835 // The context specifies that an immediate is to be moved into Rd. 3836 EmulateInstruction::Context context; 3837 context.type = EmulateInstruction::eContextImmediate; 3838 context.SetNoArgs(); 3839 3840 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3841 return false; 3842 } 3843 return true; 3844 } 3845 3846 bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode, 3847 const ARMEncoding encoding, 3848 ARM_ShifterType shift_type) { 3849 // assert(shift_type == SRType_ASR 3850 // || shift_type == SRType_LSL 3851 // || shift_type == SRType_LSR 3852 // || shift_type == SRType_ROR); 3853 3854 bool success = false; 3855 3856 if (ConditionPassed(opcode)) { 3857 uint32_t Rd; // the destination register 3858 uint32_t Rn; // the first operand register 3859 uint32_t 3860 Rm; // the register whose bottom byte contains the amount to shift by 3861 uint32_t carry; // the carry bit after the shift operation 3862 bool setflags; 3863 switch (encoding) { 3864 case eEncodingT1: 3865 Rd = Bits32(opcode, 2, 0); 3866 Rn = Rd; 3867 Rm = Bits32(opcode, 5, 3); 3868 setflags = !InITBlock(); 3869 break; 3870 case eEncodingT2: 3871 Rd = Bits32(opcode, 11, 8); 3872 Rn = Bits32(opcode, 19, 16); 3873 Rm = Bits32(opcode, 3, 0); 3874 setflags = BitIsSet(opcode, 20); 3875 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3876 return false; 3877 break; 3878 case eEncodingA1: 3879 Rd = Bits32(opcode, 15, 12); 3880 Rn = Bits32(opcode, 3, 0); 3881 Rm = Bits32(opcode, 11, 8); 3882 setflags = BitIsSet(opcode, 20); 3883 if (Rd == 15 || Rn == 15 || Rm == 15) 3884 return false; 3885 break; 3886 default: 3887 return false; 3888 } 3889 3890 // Get the first operand. 3891 uint32_t value = ReadCoreReg(Rn, &success); 3892 if (!success) 3893 return false; 3894 // Get the Rm register content. 3895 uint32_t val = ReadCoreReg(Rm, &success); 3896 if (!success) 3897 return false; 3898 3899 // Get the shift amount. 3900 uint32_t amt = Bits32(val, 7, 0); 3901 3902 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3903 if (!success) 3904 return false; 3905 3906 // The context specifies that an immediate is to be moved into Rd. 3907 EmulateInstruction::Context context; 3908 context.type = EmulateInstruction::eContextImmediate; 3909 context.SetNoArgs(); 3910 3911 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3912 return false; 3913 } 3914 return true; 3915 } 3916 3917 // LDM loads multiple registers from consecutive memory locations, using an 3918 // address from a base register. Optionally the address just above the highest 3919 // of those locations can be written back to the base register. 3920 bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode, 3921 const ARMEncoding encoding) { 3922 #if 0 3923 // ARM pseudo code... 3924 if ConditionPassed() 3925 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3926 address = R[n]; 3927 3928 for i = 0 to 14 3929 if registers<i> == '1' then 3930 R[i] = MemA[address, 4]; address = address + 4; 3931 if registers<15> == '1' then 3932 LoadWritePC (MemA[address, 4]); 3933 3934 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3935 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3936 3937 #endif 3938 3939 bool success = false; 3940 if (ConditionPassed(opcode)) { 3941 uint32_t n; 3942 uint32_t registers = 0; 3943 bool wback; 3944 const uint32_t addr_byte_size = GetAddressByteSize(); 3945 switch (encoding) { 3946 case eEncodingT1: 3947 // n = UInt(Rn); registers = '00000000':register_list; wback = 3948 // (registers<n> == '0'); 3949 n = Bits32(opcode, 10, 8); 3950 registers = Bits32(opcode, 7, 0); 3951 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3952 wback = BitIsClear(registers, n); 3953 // if BitCount(registers) < 1 then UNPREDICTABLE; 3954 if (BitCount(registers) < 1) 3955 return false; 3956 break; 3957 case eEncodingT2: 3958 // if W == '1' && Rn == '1101' then SEE POP; 3959 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3960 n = Bits32(opcode, 19, 16); 3961 registers = Bits32(opcode, 15, 0); 3962 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3963 wback = BitIsSet(opcode, 21); 3964 3965 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 3966 // UNPREDICTABLE; 3967 if ((n == 15) || (BitCount(registers) < 2) || 3968 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 3969 return false; 3970 3971 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 3972 // UNPREDICTABLE; 3973 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 3974 return false; 3975 3976 // if wback && registers<n> == '1' then UNPREDICTABLE; 3977 if (wback && BitIsSet(registers, n)) 3978 return false; 3979 break; 3980 3981 case eEncodingA1: 3982 n = Bits32(opcode, 19, 16); 3983 registers = Bits32(opcode, 15, 0); 3984 wback = BitIsSet(opcode, 21); 3985 if ((n == 15) || (BitCount(registers) < 1)) 3986 return false; 3987 break; 3988 default: 3989 return false; 3990 } 3991 3992 int32_t offset = 0; 3993 const addr_t base_address = 3994 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3995 if (!success) 3996 return false; 3997 3998 EmulateInstruction::Context context; 3999 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4000 RegisterInfo dwarf_reg; 4001 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4002 context.SetRegisterPlusOffset(dwarf_reg, offset); 4003 4004 for (int i = 0; i < 14; ++i) { 4005 if (BitIsSet(registers, i)) { 4006 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4007 context.SetRegisterPlusOffset(dwarf_reg, offset); 4008 if (wback && (n == 13)) // Pop Instruction 4009 { 4010 context.type = EmulateInstruction::eContextPopRegisterOffStack; 4011 context.SetAddress(base_address + offset); 4012 } 4013 4014 // R[i] = MemA [address, 4]; address = address + 4; 4015 uint32_t data = MemARead(context, base_address + offset, addr_byte_size, 4016 0, &success); 4017 if (!success) 4018 return false; 4019 4020 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4021 data)) 4022 return false; 4023 4024 offset += addr_byte_size; 4025 } 4026 } 4027 4028 if (BitIsSet(registers, 15)) { 4029 // LoadWritePC (MemA [address, 4]); 4030 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4031 context.SetRegisterPlusOffset(dwarf_reg, offset); 4032 uint32_t data = 4033 MemARead(context, base_address + offset, addr_byte_size, 0, &success); 4034 if (!success) 4035 return false; 4036 // In ARMv5T and above, this is an interworking branch. 4037 if (!LoadWritePC(context, data)) 4038 return false; 4039 } 4040 4041 if (wback && BitIsClear(registers, n)) { 4042 // R[n] = R[n] + 4 * BitCount (registers) 4043 int32_t offset = addr_byte_size * BitCount(registers); 4044 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4045 context.SetRegisterPlusOffset(dwarf_reg, offset); 4046 4047 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4048 base_address + offset)) 4049 return false; 4050 } 4051 if (wback && BitIsSet(registers, n)) 4052 // R[n] bits(32) UNKNOWN; 4053 return WriteBits32Unknown(n); 4054 } 4055 return true; 4056 } 4057 4058 // LDMDA loads multiple registers from consecutive memory locations using an 4059 // address from a base register. 4060 // The consecutive memory locations end at this address and the address just 4061 // below the lowest of those locations can optionally be written back to the 4062 // base register. 4063 bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode, 4064 const ARMEncoding encoding) { 4065 #if 0 4066 // ARM pseudo code... 4067 if ConditionPassed() then 4068 EncodingSpecificOperations(); 4069 address = R[n] - 4*BitCount(registers) + 4; 4070 4071 for i = 0 to 14 4072 if registers<i> == '1' then 4073 R[i] = MemA[address,4]; address = address + 4; 4074 4075 if registers<15> == '1' then 4076 LoadWritePC(MemA[address,4]); 4077 4078 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4079 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4080 #endif 4081 4082 bool success = false; 4083 4084 if (ConditionPassed(opcode)) { 4085 uint32_t n; 4086 uint32_t registers = 0; 4087 bool wback; 4088 const uint32_t addr_byte_size = GetAddressByteSize(); 4089 4090 // EncodingSpecificOperations(); 4091 switch (encoding) { 4092 case eEncodingA1: 4093 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4094 n = Bits32(opcode, 19, 16); 4095 registers = Bits32(opcode, 15, 0); 4096 wback = BitIsSet(opcode, 21); 4097 4098 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4099 if ((n == 15) || (BitCount(registers) < 1)) 4100 return false; 4101 4102 break; 4103 4104 default: 4105 return false; 4106 } 4107 // address = R[n] - 4*BitCount(registers) + 4; 4108 4109 int32_t offset = 0; 4110 addr_t Rn = ReadCoreReg(n, &success); 4111 4112 if (!success) 4113 return false; 4114 4115 addr_t address = 4116 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size; 4117 4118 EmulateInstruction::Context context; 4119 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4120 RegisterInfo dwarf_reg; 4121 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4122 context.SetRegisterPlusOffset(dwarf_reg, offset); 4123 4124 // for i = 0 to 14 4125 for (int i = 0; i < 14; ++i) { 4126 // if registers<i> == '1' then 4127 if (BitIsSet(registers, i)) { 4128 // R[i] = MemA[address,4]; address = address + 4; 4129 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4130 uint32_t data = 4131 MemARead(context, address + offset, addr_byte_size, 0, &success); 4132 if (!success) 4133 return false; 4134 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4135 data)) 4136 return false; 4137 offset += addr_byte_size; 4138 } 4139 } 4140 4141 // if registers<15> == '1' then 4142 // LoadWritePC(MemA[address,4]); 4143 if (BitIsSet(registers, 15)) { 4144 context.SetRegisterPlusOffset(dwarf_reg, offset); 4145 uint32_t data = 4146 MemARead(context, address + offset, addr_byte_size, 0, &success); 4147 if (!success) 4148 return false; 4149 // In ARMv5T and above, this is an interworking branch. 4150 if (!LoadWritePC(context, data)) 4151 return false; 4152 } 4153 4154 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4155 if (wback && BitIsClear(registers, n)) { 4156 if (!success) 4157 return false; 4158 4159 offset = (addr_byte_size * BitCount(registers)) * -1; 4160 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4161 context.SetImmediateSigned(offset); 4162 addr_t addr = Rn + offset; 4163 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4164 addr)) 4165 return false; 4166 } 4167 4168 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4169 if (wback && BitIsSet(registers, n)) 4170 return WriteBits32Unknown(n); 4171 } 4172 return true; 4173 } 4174 4175 // LDMDB loads multiple registers from consecutive memory locations using an 4176 // address from a base register. The 4177 // consecutive memory locations end just below this address, and the address of 4178 // the lowest of those locations can be optionally written back to the base 4179 // register. 4180 bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode, 4181 const ARMEncoding encoding) { 4182 #if 0 4183 // ARM pseudo code... 4184 if ConditionPassed() then 4185 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4186 address = R[n] - 4*BitCount(registers); 4187 4188 for i = 0 to 14 4189 if registers<i> == '1' then 4190 R[i] = MemA[address,4]; address = address + 4; 4191 if registers<15> == '1' then 4192 LoadWritePC(MemA[address,4]); 4193 4194 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4195 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 4196 #endif 4197 4198 bool success = false; 4199 4200 if (ConditionPassed(opcode)) { 4201 uint32_t n; 4202 uint32_t registers = 0; 4203 bool wback; 4204 const uint32_t addr_byte_size = GetAddressByteSize(); 4205 switch (encoding) { 4206 case eEncodingT1: 4207 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 4208 n = Bits32(opcode, 19, 16); 4209 registers = Bits32(opcode, 15, 0); 4210 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 4211 wback = BitIsSet(opcode, 21); 4212 4213 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 4214 // UNPREDICTABLE; 4215 if ((n == 15) || (BitCount(registers) < 2) || 4216 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 4217 return false; 4218 4219 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 4220 // UNPREDICTABLE; 4221 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 4222 return false; 4223 4224 // if wback && registers<n> == '1' then UNPREDICTABLE; 4225 if (wback && BitIsSet(registers, n)) 4226 return false; 4227 4228 break; 4229 4230 case eEncodingA1: 4231 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4232 n = Bits32(opcode, 19, 16); 4233 registers = Bits32(opcode, 15, 0); 4234 wback = BitIsSet(opcode, 21); 4235 4236 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4237 if ((n == 15) || (BitCount(registers) < 1)) 4238 return false; 4239 4240 break; 4241 4242 default: 4243 return false; 4244 } 4245 4246 // address = R[n] - 4*BitCount(registers); 4247 4248 int32_t offset = 0; 4249 addr_t Rn = 4250 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4251 4252 if (!success) 4253 return false; 4254 4255 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4256 EmulateInstruction::Context context; 4257 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4258 RegisterInfo dwarf_reg; 4259 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4260 context.SetRegisterPlusOffset(dwarf_reg, Rn - address); 4261 4262 for (int i = 0; i < 14; ++i) { 4263 if (BitIsSet(registers, i)) { 4264 // R[i] = MemA[address,4]; address = address + 4; 4265 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4266 uint32_t data = 4267 MemARead(context, address + offset, addr_byte_size, 0, &success); 4268 if (!success) 4269 return false; 4270 4271 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4272 data)) 4273 return false; 4274 4275 offset += addr_byte_size; 4276 } 4277 } 4278 4279 // if registers<15> == '1' then 4280 // LoadWritePC(MemA[address,4]); 4281 if (BitIsSet(registers, 15)) { 4282 context.SetRegisterPlusOffset(dwarf_reg, offset); 4283 uint32_t data = 4284 MemARead(context, address + offset, addr_byte_size, 0, &success); 4285 if (!success) 4286 return false; 4287 // In ARMv5T and above, this is an interworking branch. 4288 if (!LoadWritePC(context, data)) 4289 return false; 4290 } 4291 4292 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4293 if (wback && BitIsClear(registers, n)) { 4294 if (!success) 4295 return false; 4296 4297 offset = (addr_byte_size * BitCount(registers)) * -1; 4298 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4299 context.SetImmediateSigned(offset); 4300 addr_t addr = Rn + offset; 4301 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4302 addr)) 4303 return false; 4304 } 4305 4306 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4307 // possible for encoding A1 4308 if (wback && BitIsSet(registers, n)) 4309 return WriteBits32Unknown(n); 4310 } 4311 return true; 4312 } 4313 4314 // LDMIB loads multiple registers from consecutive memory locations using an 4315 // address from a base register. The 4316 // consecutive memory locations start just above this address, and thea ddress 4317 // of the last of those locations can optinoally be written back to the base 4318 // register. 4319 bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode, 4320 const ARMEncoding encoding) { 4321 #if 0 4322 if ConditionPassed() then 4323 EncodingSpecificOperations(); 4324 address = R[n] + 4; 4325 4326 for i = 0 to 14 4327 if registers<i> == '1' then 4328 R[i] = MemA[address,4]; address = address + 4; 4329 if registers<15> == '1' then 4330 LoadWritePC(MemA[address,4]); 4331 4332 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4333 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4334 #endif 4335 4336 bool success = false; 4337 4338 if (ConditionPassed(opcode)) { 4339 uint32_t n; 4340 uint32_t registers = 0; 4341 bool wback; 4342 const uint32_t addr_byte_size = GetAddressByteSize(); 4343 switch (encoding) { 4344 case eEncodingA1: 4345 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4346 n = Bits32(opcode, 19, 16); 4347 registers = Bits32(opcode, 15, 0); 4348 wback = BitIsSet(opcode, 21); 4349 4350 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4351 if ((n == 15) || (BitCount(registers) < 1)) 4352 return false; 4353 4354 break; 4355 default: 4356 return false; 4357 } 4358 // address = R[n] + 4; 4359 4360 int32_t offset = 0; 4361 addr_t Rn = 4362 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4363 4364 if (!success) 4365 return false; 4366 4367 addr_t address = Rn + addr_byte_size; 4368 4369 EmulateInstruction::Context context; 4370 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4371 RegisterInfo dwarf_reg; 4372 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4373 context.SetRegisterPlusOffset(dwarf_reg, offset); 4374 4375 for (int i = 0; i < 14; ++i) { 4376 if (BitIsSet(registers, i)) { 4377 // R[i] = MemA[address,4]; address = address + 4; 4378 4379 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size); 4380 uint32_t data = 4381 MemARead(context, address + offset, addr_byte_size, 0, &success); 4382 if (!success) 4383 return false; 4384 4385 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4386 data)) 4387 return false; 4388 4389 offset += addr_byte_size; 4390 } 4391 } 4392 4393 // if registers<15> == '1' then 4394 // LoadWritePC(MemA[address,4]); 4395 if (BitIsSet(registers, 15)) { 4396 context.SetRegisterPlusOffset(dwarf_reg, offset); 4397 uint32_t data = 4398 MemARead(context, address + offset, addr_byte_size, 0, &success); 4399 if (!success) 4400 return false; 4401 // In ARMv5T and above, this is an interworking branch. 4402 if (!LoadWritePC(context, data)) 4403 return false; 4404 } 4405 4406 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4407 if (wback && BitIsClear(registers, n)) { 4408 if (!success) 4409 return false; 4410 4411 offset = addr_byte_size * BitCount(registers); 4412 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4413 context.SetImmediateSigned(offset); 4414 addr_t addr = Rn + offset; 4415 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4416 addr)) 4417 return false; 4418 } 4419 4420 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4421 // possible for encoding A1 4422 if (wback && BitIsSet(registers, n)) 4423 return WriteBits32Unknown(n); 4424 } 4425 return true; 4426 } 4427 4428 // Load Register (immediate) calculates an address from a base register value 4429 // and an immediate offset, loads a word from memory, and writes to a register. 4430 // LDR (immediate, Thumb) 4431 bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode, 4432 const ARMEncoding encoding) { 4433 #if 0 4434 // ARM pseudo code... 4435 if (ConditionPassed()) 4436 { 4437 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 4438 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4439 address = if index then offset_addr else R[n]; 4440 data = MemU[address,4]; 4441 if wback then R[n] = offset_addr; 4442 if t == 15 then 4443 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 4444 elsif UnalignedSupport() || address<1:0> = '00' then 4445 R[t] = data; 4446 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 4447 } 4448 #endif 4449 4450 bool success = false; 4451 4452 if (ConditionPassed(opcode)) { 4453 uint32_t Rt; // the destination register 4454 uint32_t Rn; // the base register 4455 uint32_t imm32; // the immediate offset used to form the address 4456 addr_t offset_addr; // the offset address 4457 addr_t address; // the calculated address 4458 uint32_t data; // the literal data value from memory load 4459 bool add, index, wback; 4460 switch (encoding) { 4461 case eEncodingT1: 4462 Rt = Bits32(opcode, 2, 0); 4463 Rn = Bits32(opcode, 5, 3); 4464 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 4465 // index = TRUE; add = TRUE; wback = FALSE 4466 add = true; 4467 index = true; 4468 wback = false; 4469 4470 break; 4471 4472 case eEncodingT2: 4473 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4474 Rt = Bits32(opcode, 10, 8); 4475 Rn = 13; 4476 imm32 = Bits32(opcode, 7, 0) << 2; 4477 4478 // index = TRUE; add = TRUE; wback = FALSE; 4479 index = true; 4480 add = true; 4481 wback = false; 4482 4483 break; 4484 4485 case eEncodingT3: 4486 // if Rn == '1111' then SEE LDR (literal); 4487 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4488 Rt = Bits32(opcode, 15, 12); 4489 Rn = Bits32(opcode, 19, 16); 4490 imm32 = Bits32(opcode, 11, 0); 4491 4492 // index = TRUE; add = TRUE; wback = FALSE; 4493 index = true; 4494 add = true; 4495 wback = false; 4496 4497 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4498 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4499 return false; 4500 4501 break; 4502 4503 case eEncodingT4: 4504 // if Rn == '1111' then SEE LDR (literal); 4505 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4506 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == 4507 // '00000100' then SEE POP; 4508 // if P == '0' && W == '0' then UNDEFINED; 4509 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 4510 return false; 4511 4512 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4513 Rt = Bits32(opcode, 15, 12); 4514 Rn = Bits32(opcode, 19, 16); 4515 imm32 = Bits32(opcode, 7, 0); 4516 4517 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4518 index = BitIsSet(opcode, 10); 4519 add = BitIsSet(opcode, 9); 4520 wback = BitIsSet(opcode, 8); 4521 4522 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) 4523 // then UNPREDICTABLE; 4524 if ((wback && (Rn == Rt)) || 4525 ((Rt == 15) && InITBlock() && !LastInITBlock())) 4526 return false; 4527 4528 break; 4529 4530 default: 4531 return false; 4532 } 4533 uint32_t base = ReadCoreReg(Rn, &success); 4534 if (!success) 4535 return false; 4536 if (add) 4537 offset_addr = base + imm32; 4538 else 4539 offset_addr = base - imm32; 4540 4541 address = (index ? offset_addr : base); 4542 4543 RegisterInfo base_reg; 4544 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4545 if (wback) { 4546 EmulateInstruction::Context ctx; 4547 if (Rn == 13) { 4548 ctx.type = eContextAdjustStackPointer; 4549 ctx.SetImmediateSigned((int32_t)(offset_addr - base)); 4550 } else if (Rn == GetFramePointerRegisterNumber()) { 4551 ctx.type = eContextSetFramePointer; 4552 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4553 } else { 4554 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4555 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4556 } 4557 4558 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn, 4559 offset_addr)) 4560 return false; 4561 } 4562 4563 // Prepare to write to the Rt register. 4564 EmulateInstruction::Context context; 4565 context.type = EmulateInstruction::eContextRegisterLoad; 4566 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4567 4568 // Read memory from the address. 4569 data = MemURead(context, address, 4, 0, &success); 4570 if (!success) 4571 return false; 4572 4573 if (Rt == 15) { 4574 if (Bits32(address, 1, 0) == 0) { 4575 if (!LoadWritePC(context, data)) 4576 return false; 4577 } else 4578 return false; 4579 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 4580 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 4581 data)) 4582 return false; 4583 } else 4584 WriteBits32Unknown(Rt); 4585 } 4586 return true; 4587 } 4588 4589 // STM (Store Multiple Increment After) stores multiple registers to consecutive 4590 // memory locations using an address 4591 // from a base register. The consecutive memory locations start at this 4592 // address, and the address just above the last of those locations can 4593 // optionally be written back to the base register. 4594 bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode, 4595 const ARMEncoding encoding) { 4596 #if 0 4597 if ConditionPassed() then 4598 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4599 address = R[n]; 4600 4601 for i = 0 to 14 4602 if registers<i> == '1' then 4603 if i == n && wback && i != LowestSetBit(registers) then 4604 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4605 else 4606 MemA[address,4] = R[i]; 4607 address = address + 4; 4608 4609 if registers<15> == '1' then // Only possible for encoding A1 4610 MemA[address,4] = PCStoreValue(); 4611 if wback then R[n] = R[n] + 4*BitCount(registers); 4612 #endif 4613 4614 bool success = false; 4615 4616 if (ConditionPassed(opcode)) { 4617 uint32_t n; 4618 uint32_t registers = 0; 4619 bool wback; 4620 const uint32_t addr_byte_size = GetAddressByteSize(); 4621 4622 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4623 switch (encoding) { 4624 case eEncodingT1: 4625 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4626 n = Bits32(opcode, 10, 8); 4627 registers = Bits32(opcode, 7, 0); 4628 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4629 wback = true; 4630 4631 // if BitCount(registers) < 1 then UNPREDICTABLE; 4632 if (BitCount(registers) < 1) 4633 return false; 4634 4635 break; 4636 4637 case eEncodingT2: 4638 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4639 n = Bits32(opcode, 19, 16); 4640 registers = Bits32(opcode, 15, 0); 4641 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4642 wback = BitIsSet(opcode, 21); 4643 4644 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4645 if ((n == 15) || (BitCount(registers) < 2)) 4646 return false; 4647 4648 // if wback && registers<n> == '1' then UNPREDICTABLE; 4649 if (wback && BitIsSet(registers, n)) 4650 return false; 4651 4652 break; 4653 4654 case eEncodingA1: 4655 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4656 n = Bits32(opcode, 19, 16); 4657 registers = Bits32(opcode, 15, 0); 4658 wback = BitIsSet(opcode, 21); 4659 4660 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4661 if ((n == 15) || (BitCount(registers) < 1)) 4662 return false; 4663 4664 break; 4665 4666 default: 4667 return false; 4668 } 4669 4670 // address = R[n]; 4671 int32_t offset = 0; 4672 const addr_t address = 4673 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4674 if (!success) 4675 return false; 4676 4677 EmulateInstruction::Context context; 4678 context.type = EmulateInstruction::eContextRegisterStore; 4679 RegisterInfo base_reg; 4680 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4681 4682 // for i = 0 to 14 4683 uint32_t lowest_set_bit = 14; 4684 for (uint32_t i = 0; i < 14; ++i) { 4685 // if registers<i> == '1' then 4686 if (BitIsSet(registers, i)) { 4687 if (i < lowest_set_bit) 4688 lowest_set_bit = i; 4689 // if i == n && wback && i != LowestSetBit(registers) then 4690 if ((i == n) && wback && (i != lowest_set_bit)) 4691 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings 4692 // T1 and A1 4693 WriteBits32UnknownToMemory(address + offset); 4694 else { 4695 // MemA[address,4] = R[i]; 4696 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4697 0, &success); 4698 if (!success) 4699 return false; 4700 4701 RegisterInfo data_reg; 4702 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4703 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 4704 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4705 return false; 4706 } 4707 4708 // address = address + 4; 4709 offset += addr_byte_size; 4710 } 4711 } 4712 4713 // if registers<15> == '1' then // Only possible for encoding A1 4714 // MemA[address,4] = PCStoreValue(); 4715 if (BitIsSet(registers, 15)) { 4716 RegisterInfo pc_reg; 4717 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4718 context.SetRegisterPlusOffset(pc_reg, 8); 4719 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4720 if (!success) 4721 return false; 4722 4723 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4724 return false; 4725 } 4726 4727 // if wback then R[n] = R[n] + 4*BitCount(registers); 4728 if (wback) { 4729 offset = addr_byte_size * BitCount(registers); 4730 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4731 context.SetImmediateSigned(offset); 4732 addr_t data = address + offset; 4733 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4734 data)) 4735 return false; 4736 } 4737 } 4738 return true; 4739 } 4740 4741 // STMDA (Store Multiple Decrement After) stores multiple registers to 4742 // consecutive memory locations using an address from a base register. The 4743 // consecutive memory locations end at this address, and the address just below 4744 // the lowest of those locations can optionally be written back to the base 4745 // register. 4746 bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode, 4747 const ARMEncoding encoding) { 4748 #if 0 4749 if ConditionPassed() then 4750 EncodingSpecificOperations(); 4751 address = R[n] - 4*BitCount(registers) + 4; 4752 4753 for i = 0 to 14 4754 if registers<i> == '1' then 4755 if i == n && wback && i != LowestSetBit(registers) then 4756 MemA[address,4] = bits(32) UNKNOWN; 4757 else 4758 MemA[address,4] = R[i]; 4759 address = address + 4; 4760 4761 if registers<15> == '1' then 4762 MemA[address,4] = PCStoreValue(); 4763 4764 if wback then R[n] = R[n] - 4*BitCount(registers); 4765 #endif 4766 4767 bool success = false; 4768 4769 if (ConditionPassed(opcode)) { 4770 uint32_t n; 4771 uint32_t registers = 0; 4772 bool wback; 4773 const uint32_t addr_byte_size = GetAddressByteSize(); 4774 4775 // EncodingSpecificOperations(); 4776 switch (encoding) { 4777 case eEncodingA1: 4778 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4779 n = Bits32(opcode, 19, 16); 4780 registers = Bits32(opcode, 15, 0); 4781 wback = BitIsSet(opcode, 21); 4782 4783 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4784 if ((n == 15) || (BitCount(registers) < 1)) 4785 return false; 4786 break; 4787 default: 4788 return false; 4789 } 4790 4791 // address = R[n] - 4*BitCount(registers) + 4; 4792 int32_t offset = 0; 4793 addr_t Rn = ReadCoreReg(n, &success); 4794 if (!success) 4795 return false; 4796 4797 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4; 4798 4799 EmulateInstruction::Context context; 4800 context.type = EmulateInstruction::eContextRegisterStore; 4801 RegisterInfo base_reg; 4802 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4803 4804 // for i = 0 to 14 4805 uint32_t lowest_bit_set = 14; 4806 for (uint32_t i = 0; i < 14; ++i) { 4807 // if registers<i> == '1' then 4808 if (BitIsSet(registers, i)) { 4809 if (i < lowest_bit_set) 4810 lowest_bit_set = i; 4811 // if i == n && wback && i != LowestSetBit(registers) then 4812 if ((i == n) && wback && (i != lowest_bit_set)) 4813 // MemA[address,4] = bits(32) UNKNOWN; 4814 WriteBits32UnknownToMemory(address + offset); 4815 else { 4816 // MemA[address,4] = R[i]; 4817 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4818 0, &success); 4819 if (!success) 4820 return false; 4821 4822 RegisterInfo data_reg; 4823 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4824 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4825 Rn - (address + offset)); 4826 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4827 return false; 4828 } 4829 4830 // address = address + 4; 4831 offset += addr_byte_size; 4832 } 4833 } 4834 4835 // if registers<15> == '1' then 4836 // MemA[address,4] = PCStoreValue(); 4837 if (BitIsSet(registers, 15)) { 4838 RegisterInfo pc_reg; 4839 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4840 context.SetRegisterPlusOffset(pc_reg, 8); 4841 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4842 if (!success) 4843 return false; 4844 4845 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4846 return false; 4847 } 4848 4849 // if wback then R[n] = R[n] - 4*BitCount(registers); 4850 if (wback) { 4851 offset = (addr_byte_size * BitCount(registers)) * -1; 4852 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4853 context.SetImmediateSigned(offset); 4854 addr_t data = Rn + offset; 4855 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4856 data)) 4857 return false; 4858 } 4859 } 4860 return true; 4861 } 4862 4863 // STMDB (Store Multiple Decrement Before) stores multiple registers to 4864 // consecutive memory locations using an address from a base register. The 4865 // consecutive memory locations end just below this address, and the address of 4866 // the first of those locations can optionally be written back to the base 4867 // register. 4868 bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode, 4869 const ARMEncoding encoding) { 4870 #if 0 4871 if ConditionPassed() then 4872 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4873 address = R[n] - 4*BitCount(registers); 4874 4875 for i = 0 to 14 4876 if registers<i> == '1' then 4877 if i == n && wback && i != LowestSetBit(registers) then 4878 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4879 else 4880 MemA[address,4] = R[i]; 4881 address = address + 4; 4882 4883 if registers<15> == '1' then // Only possible for encoding A1 4884 MemA[address,4] = PCStoreValue(); 4885 4886 if wback then R[n] = R[n] - 4*BitCount(registers); 4887 #endif 4888 4889 bool success = false; 4890 4891 if (ConditionPassed(opcode)) { 4892 uint32_t n; 4893 uint32_t registers = 0; 4894 bool wback; 4895 const uint32_t addr_byte_size = GetAddressByteSize(); 4896 4897 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4898 switch (encoding) { 4899 case eEncodingT1: 4900 // if W == '1' && Rn == '1101' then SEE PUSH; 4901 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) { 4902 // See PUSH 4903 } 4904 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4905 n = Bits32(opcode, 19, 16); 4906 registers = Bits32(opcode, 15, 0); 4907 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4908 wback = BitIsSet(opcode, 21); 4909 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4910 if ((n == 15) || BitCount(registers) < 2) 4911 return false; 4912 // if wback && registers<n> == '1' then UNPREDICTABLE; 4913 if (wback && BitIsSet(registers, n)) 4914 return false; 4915 break; 4916 4917 case eEncodingA1: 4918 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE 4919 // PUSH; 4920 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) && 4921 BitCount(Bits32(opcode, 15, 0)) >= 2) { 4922 // See Push 4923 } 4924 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4925 n = Bits32(opcode, 19, 16); 4926 registers = Bits32(opcode, 15, 0); 4927 wback = BitIsSet(opcode, 21); 4928 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4929 if ((n == 15) || BitCount(registers) < 1) 4930 return false; 4931 break; 4932 4933 default: 4934 return false; 4935 } 4936 4937 // address = R[n] - 4*BitCount(registers); 4938 4939 int32_t offset = 0; 4940 addr_t Rn = 4941 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4942 if (!success) 4943 return false; 4944 4945 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4946 4947 EmulateInstruction::Context context; 4948 context.type = EmulateInstruction::eContextRegisterStore; 4949 RegisterInfo base_reg; 4950 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4951 4952 // for i = 0 to 14 4953 uint32_t lowest_set_bit = 14; 4954 for (uint32_t i = 0; i < 14; ++i) { 4955 // if registers<i> == '1' then 4956 if (BitIsSet(registers, i)) { 4957 if (i < lowest_set_bit) 4958 lowest_set_bit = i; 4959 // if i == n && wback && i != LowestSetBit(registers) then 4960 if ((i == n) && wback && (i != lowest_set_bit)) 4961 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding 4962 // A1 4963 WriteBits32UnknownToMemory(address + offset); 4964 else { 4965 // MemA[address,4] = R[i]; 4966 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4967 0, &success); 4968 if (!success) 4969 return false; 4970 4971 RegisterInfo data_reg; 4972 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4973 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4974 Rn - (address + offset)); 4975 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4976 return false; 4977 } 4978 4979 // address = address + 4; 4980 offset += addr_byte_size; 4981 } 4982 } 4983 4984 // if registers<15> == '1' then // Only possible for encoding A1 4985 // MemA[address,4] = PCStoreValue(); 4986 if (BitIsSet(registers, 15)) { 4987 RegisterInfo pc_reg; 4988 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4989 context.SetRegisterPlusOffset(pc_reg, 8); 4990 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4991 if (!success) 4992 return false; 4993 4994 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4995 return false; 4996 } 4997 4998 // if wback then R[n] = R[n] - 4*BitCount(registers); 4999 if (wback) { 5000 offset = (addr_byte_size * BitCount(registers)) * -1; 5001 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5002 context.SetImmediateSigned(offset); 5003 addr_t data = Rn + offset; 5004 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5005 data)) 5006 return false; 5007 } 5008 } 5009 return true; 5010 } 5011 5012 // STMIB (Store Multiple Increment Before) stores multiple registers to 5013 // consecutive memory locations using an address from a base register. The 5014 // consecutive memory locations start just above this address, and the address 5015 // of the last of those locations can optionally be written back to the base 5016 // register. 5017 bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode, 5018 const ARMEncoding encoding) { 5019 #if 0 5020 if ConditionPassed() then 5021 EncodingSpecificOperations(); 5022 address = R[n] + 4; 5023 5024 for i = 0 to 14 5025 if registers<i> == '1' then 5026 if i == n && wback && i != LowestSetBit(registers) then 5027 MemA[address,4] = bits(32) UNKNOWN; 5028 else 5029 MemA[address,4] = R[i]; 5030 address = address + 4; 5031 5032 if registers<15> == '1' then 5033 MemA[address,4] = PCStoreValue(); 5034 5035 if wback then R[n] = R[n] + 4*BitCount(registers); 5036 #endif 5037 5038 bool success = false; 5039 5040 if (ConditionPassed(opcode)) { 5041 uint32_t n; 5042 uint32_t registers = 0; 5043 bool wback; 5044 const uint32_t addr_byte_size = GetAddressByteSize(); 5045 5046 // EncodingSpecificOperations(); 5047 switch (encoding) { 5048 case eEncodingA1: 5049 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 5050 n = Bits32(opcode, 19, 16); 5051 registers = Bits32(opcode, 15, 0); 5052 wback = BitIsSet(opcode, 21); 5053 5054 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 5055 if ((n == 15) && (BitCount(registers) < 1)) 5056 return false; 5057 break; 5058 default: 5059 return false; 5060 } 5061 // address = R[n] + 4; 5062 5063 int32_t offset = 0; 5064 addr_t Rn = ReadCoreReg(n, &success); 5065 if (!success) 5066 return false; 5067 5068 addr_t address = Rn + addr_byte_size; 5069 5070 EmulateInstruction::Context context; 5071 context.type = EmulateInstruction::eContextRegisterStore; 5072 RegisterInfo base_reg; 5073 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5074 5075 uint32_t lowest_set_bit = 14; 5076 // for i = 0 to 14 5077 for (uint32_t i = 0; i < 14; ++i) { 5078 // if registers<i> == '1' then 5079 if (BitIsSet(registers, i)) { 5080 if (i < lowest_set_bit) 5081 lowest_set_bit = i; 5082 // if i == n && wback && i != LowestSetBit(registers) then 5083 if ((i == n) && wback && (i != lowest_set_bit)) 5084 // MemA[address,4] = bits(32) UNKNOWN; 5085 WriteBits32UnknownToMemory(address + offset); 5086 // else 5087 else { 5088 // MemA[address,4] = R[i]; 5089 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5090 0, &success); 5091 if (!success) 5092 return false; 5093 5094 RegisterInfo data_reg; 5095 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5096 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5097 offset + addr_byte_size); 5098 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5099 return false; 5100 } 5101 5102 // address = address + 4; 5103 offset += addr_byte_size; 5104 } 5105 } 5106 5107 // if registers<15> == '1' then 5108 // MemA[address,4] = PCStoreValue(); 5109 if (BitIsSet(registers, 15)) { 5110 RegisterInfo pc_reg; 5111 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5112 context.SetRegisterPlusOffset(pc_reg, 8); 5113 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5114 if (!success) 5115 return false; 5116 5117 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5118 return false; 5119 } 5120 5121 // if wback then R[n] = R[n] + 4*BitCount(registers); 5122 if (wback) { 5123 offset = addr_byte_size * BitCount(registers); 5124 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5125 context.SetImmediateSigned(offset); 5126 addr_t data = Rn + offset; 5127 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5128 data)) 5129 return false; 5130 } 5131 } 5132 return true; 5133 } 5134 5135 // STR (store immediate) calculates an address from a base register value and an 5136 // immediate offset, and stores a word 5137 // from a register to memory. It can use offset, post-indexed, or pre-indexed 5138 // addressing. 5139 bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode, 5140 const ARMEncoding encoding) { 5141 #if 0 5142 if ConditionPassed() then 5143 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5144 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5145 address = if index then offset_addr else R[n]; 5146 if UnalignedSupport() || address<1:0> == '00' then 5147 MemU[address,4] = R[t]; 5148 else // Can only occur before ARMv7 5149 MemU[address,4] = bits(32) UNKNOWN; 5150 if wback then R[n] = offset_addr; 5151 #endif 5152 5153 bool success = false; 5154 5155 if (ConditionPassed(opcode)) { 5156 const uint32_t addr_byte_size = GetAddressByteSize(); 5157 5158 uint32_t t; 5159 uint32_t n; 5160 uint32_t imm32; 5161 bool index; 5162 bool add; 5163 bool wback; 5164 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5165 switch (encoding) { 5166 case eEncodingT1: 5167 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 5168 t = Bits32(opcode, 2, 0); 5169 n = Bits32(opcode, 5, 3); 5170 imm32 = Bits32(opcode, 10, 6) << 2; 5171 5172 // index = TRUE; add = TRUE; wback = FALSE; 5173 index = true; 5174 add = false; 5175 wback = false; 5176 break; 5177 5178 case eEncodingT2: 5179 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 5180 t = Bits32(opcode, 10, 8); 5181 n = 13; 5182 imm32 = Bits32(opcode, 7, 0) << 2; 5183 5184 // index = TRUE; add = TRUE; wback = FALSE; 5185 index = true; 5186 add = true; 5187 wback = false; 5188 break; 5189 5190 case eEncodingT3: 5191 // if Rn == '1111' then UNDEFINED; 5192 if (Bits32(opcode, 19, 16) == 15) 5193 return false; 5194 5195 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5196 t = Bits32(opcode, 15, 12); 5197 n = Bits32(opcode, 19, 16); 5198 imm32 = Bits32(opcode, 11, 0); 5199 5200 // index = TRUE; add = TRUE; wback = FALSE; 5201 index = true; 5202 add = true; 5203 wback = false; 5204 5205 // if t == 15 then UNPREDICTABLE; 5206 if (t == 15) 5207 return false; 5208 break; 5209 5210 case eEncodingT4: 5211 // if P == '1' && U == '1' && W == '0' then SEE STRT; 5212 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == 5213 // '00000100' then SEE PUSH; 5214 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5215 if ((Bits32(opcode, 19, 16) == 15) || 5216 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))) 5217 return false; 5218 5219 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5220 t = Bits32(opcode, 15, 12); 5221 n = Bits32(opcode, 19, 16); 5222 imm32 = Bits32(opcode, 7, 0); 5223 5224 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5225 index = BitIsSet(opcode, 10); 5226 add = BitIsSet(opcode, 9); 5227 wback = BitIsSet(opcode, 8); 5228 5229 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 5230 if ((t == 15) || (wback && (n == t))) 5231 return false; 5232 break; 5233 5234 default: 5235 return false; 5236 } 5237 5238 addr_t offset_addr; 5239 addr_t address; 5240 5241 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5242 uint32_t base_address = ReadCoreReg(n, &success); 5243 if (!success) 5244 return false; 5245 5246 if (add) 5247 offset_addr = base_address + imm32; 5248 else 5249 offset_addr = base_address - imm32; 5250 5251 // address = if index then offset_addr else R[n]; 5252 if (index) 5253 address = offset_addr; 5254 else 5255 address = base_address; 5256 5257 EmulateInstruction::Context context; 5258 if (n == 13) 5259 context.type = eContextPushRegisterOnStack; 5260 else 5261 context.type = eContextRegisterStore; 5262 5263 RegisterInfo base_reg; 5264 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5265 5266 // if UnalignedSupport() || address<1:0> == '00' then 5267 if (UnalignedSupport() || 5268 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 5269 // MemU[address,4] = R[t]; 5270 uint32_t data = 5271 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5272 if (!success) 5273 return false; 5274 5275 RegisterInfo data_reg; 5276 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5277 int32_t offset = address - base_address; 5278 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 5279 if (!MemUWrite(context, address, data, addr_byte_size)) 5280 return false; 5281 } else { 5282 // MemU[address,4] = bits(32) UNKNOWN; 5283 WriteBits32UnknownToMemory(address); 5284 } 5285 5286 // if wback then R[n] = offset_addr; 5287 if (wback) { 5288 if (n == 13) 5289 context.type = eContextAdjustStackPointer; 5290 else 5291 context.type = eContextAdjustBaseRegister; 5292 context.SetAddress(offset_addr); 5293 5294 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5295 offset_addr)) 5296 return false; 5297 } 5298 } 5299 return true; 5300 } 5301 5302 // STR (Store Register) calculates an address from a base register value and an 5303 // offset register value, stores a 5304 // word from a register to memory. The offset register value can optionally 5305 // be shifted. 5306 bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode, 5307 const ARMEncoding encoding) { 5308 #if 0 5309 if ConditionPassed() then 5310 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5311 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5312 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5313 address = if index then offset_addr else R[n]; 5314 if t == 15 then // Only possible for encoding A1 5315 data = PCStoreValue(); 5316 else 5317 data = R[t]; 5318 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 5319 MemU[address,4] = data; 5320 else // Can only occur before ARMv7 5321 MemU[address,4] = bits(32) UNKNOWN; 5322 if wback then R[n] = offset_addr; 5323 #endif 5324 5325 bool success = false; 5326 5327 if (ConditionPassed(opcode)) { 5328 const uint32_t addr_byte_size = GetAddressByteSize(); 5329 5330 uint32_t t; 5331 uint32_t n; 5332 uint32_t m; 5333 ARM_ShifterType shift_t; 5334 uint32_t shift_n; 5335 bool index; 5336 bool add; 5337 bool wback; 5338 5339 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5340 switch (encoding) { 5341 case eEncodingT1: 5342 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5343 // in ThumbEE"; 5344 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5345 t = Bits32(opcode, 2, 0); 5346 n = Bits32(opcode, 5, 3); 5347 m = Bits32(opcode, 8, 6); 5348 5349 // index = TRUE; add = TRUE; wback = FALSE; 5350 index = true; 5351 add = true; 5352 wback = false; 5353 5354 // (shift_t, shift_n) = (SRType_LSL, 0); 5355 shift_t = SRType_LSL; 5356 shift_n = 0; 5357 break; 5358 5359 case eEncodingT2: 5360 // if Rn == '1111' then UNDEFINED; 5361 if (Bits32(opcode, 19, 16) == 15) 5362 return false; 5363 5364 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5365 t = Bits32(opcode, 15, 12); 5366 n = Bits32(opcode, 19, 16); 5367 m = Bits32(opcode, 3, 0); 5368 5369 // index = TRUE; add = TRUE; wback = FALSE; 5370 index = true; 5371 add = true; 5372 wback = false; 5373 5374 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5375 shift_t = SRType_LSL; 5376 shift_n = Bits32(opcode, 5, 4); 5377 5378 // if t == 15 || BadReg(m) then UNPREDICTABLE; 5379 if ((t == 15) || (BadReg(m))) 5380 return false; 5381 break; 5382 5383 case eEncodingA1: { 5384 // if P == '0' && W == '1' then SEE STRT; 5385 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5386 t = Bits32(opcode, 15, 12); 5387 n = Bits32(opcode, 19, 16); 5388 m = Bits32(opcode, 3, 0); 5389 5390 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5391 // (W == '1'); 5392 index = BitIsSet(opcode, 24); 5393 add = BitIsSet(opcode, 23); 5394 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5395 5396 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5397 uint32_t typ = Bits32(opcode, 6, 5); 5398 uint32_t imm5 = Bits32(opcode, 11, 7); 5399 shift_n = DecodeImmShift(typ, imm5, shift_t); 5400 5401 // if m == 15 then UNPREDICTABLE; 5402 if (m == 15) 5403 return false; 5404 5405 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5406 if (wback && ((n == 15) || (n == t))) 5407 return false; 5408 5409 break; 5410 } 5411 default: 5412 return false; 5413 } 5414 5415 addr_t offset_addr; 5416 addr_t address; 5417 int32_t offset = 0; 5418 5419 addr_t base_address = 5420 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5421 if (!success) 5422 return false; 5423 5424 uint32_t Rm_data = 5425 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5426 if (!success) 5427 return false; 5428 5429 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5430 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success); 5431 if (!success) 5432 return false; 5433 5434 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5435 if (add) 5436 offset_addr = base_address + offset; 5437 else 5438 offset_addr = base_address - offset; 5439 5440 // address = if index then offset_addr else R[n]; 5441 if (index) 5442 address = offset_addr; 5443 else 5444 address = base_address; 5445 5446 uint32_t data; 5447 // if t == 15 then // Only possible for encoding A1 5448 if (t == 15) 5449 // data = PCStoreValue(); 5450 data = ReadCoreReg(PC_REG, &success); 5451 else 5452 // data = R[t]; 5453 data = 5454 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5455 5456 if (!success) 5457 return false; 5458 5459 EmulateInstruction::Context context; 5460 context.type = eContextRegisterStore; 5461 5462 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == 5463 // InstrSet_ARM then 5464 if (UnalignedSupport() || 5465 (BitIsClear(address, 1) && BitIsClear(address, 0)) || 5466 CurrentInstrSet() == eModeARM) { 5467 // MemU[address,4] = data; 5468 5469 RegisterInfo base_reg; 5470 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5471 5472 RegisterInfo data_reg; 5473 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5474 5475 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5476 address - base_address); 5477 if (!MemUWrite(context, address, data, addr_byte_size)) 5478 return false; 5479 5480 } else 5481 // MemU[address,4] = bits(32) UNKNOWN; 5482 WriteBits32UnknownToMemory(address); 5483 5484 // if wback then R[n] = offset_addr; 5485 if (wback) { 5486 context.type = eContextRegisterLoad; 5487 context.SetAddress(offset_addr); 5488 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5489 offset_addr)) 5490 return false; 5491 } 5492 } 5493 return true; 5494 } 5495 5496 bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode, 5497 const ARMEncoding encoding) { 5498 #if 0 5499 if ConditionPassed() then 5500 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5501 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5502 address = if index then offset_addr else R[n]; 5503 MemU[address,1] = R[t]<7:0>; 5504 if wback then R[n] = offset_addr; 5505 #endif 5506 5507 bool success = false; 5508 5509 if (ConditionPassed(opcode)) { 5510 uint32_t t; 5511 uint32_t n; 5512 uint32_t imm32; 5513 bool index; 5514 bool add; 5515 bool wback; 5516 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5517 switch (encoding) { 5518 case eEncodingT1: 5519 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5520 t = Bits32(opcode, 2, 0); 5521 n = Bits32(opcode, 5, 3); 5522 imm32 = Bits32(opcode, 10, 6); 5523 5524 // index = TRUE; add = TRUE; wback = FALSE; 5525 index = true; 5526 add = true; 5527 wback = false; 5528 break; 5529 5530 case eEncodingT2: 5531 // if Rn == '1111' then UNDEFINED; 5532 if (Bits32(opcode, 19, 16) == 15) 5533 return false; 5534 5535 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5536 t = Bits32(opcode, 15, 12); 5537 n = Bits32(opcode, 19, 16); 5538 imm32 = Bits32(opcode, 11, 0); 5539 5540 // index = TRUE; add = TRUE; wback = FALSE; 5541 index = true; 5542 add = true; 5543 wback = false; 5544 5545 // if BadReg(t) then UNPREDICTABLE; 5546 if (BadReg(t)) 5547 return false; 5548 break; 5549 5550 case eEncodingT3: 5551 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5552 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5553 if (Bits32(opcode, 19, 16) == 15) 5554 return false; 5555 5556 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5557 t = Bits32(opcode, 15, 12); 5558 n = Bits32(opcode, 19, 16); 5559 imm32 = Bits32(opcode, 7, 0); 5560 5561 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5562 index = BitIsSet(opcode, 10); 5563 add = BitIsSet(opcode, 9); 5564 wback = BitIsSet(opcode, 8); 5565 5566 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5567 if ((BadReg(t)) || (wback && (n == t))) 5568 return false; 5569 break; 5570 5571 default: 5572 return false; 5573 } 5574 5575 addr_t offset_addr; 5576 addr_t address; 5577 addr_t base_address = 5578 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5579 if (!success) 5580 return false; 5581 5582 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5583 if (add) 5584 offset_addr = base_address + imm32; 5585 else 5586 offset_addr = base_address - imm32; 5587 5588 // address = if index then offset_addr else R[n]; 5589 if (index) 5590 address = offset_addr; 5591 else 5592 address = base_address; 5593 5594 // MemU[address,1] = R[t]<7:0> 5595 RegisterInfo base_reg; 5596 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5597 5598 RegisterInfo data_reg; 5599 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5600 5601 EmulateInstruction::Context context; 5602 context.type = eContextRegisterStore; 5603 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5604 address - base_address); 5605 5606 uint32_t data = 5607 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5608 if (!success) 5609 return false; 5610 5611 data = Bits32(data, 7, 0); 5612 5613 if (!MemUWrite(context, address, data, 1)) 5614 return false; 5615 5616 // if wback then R[n] = offset_addr; 5617 if (wback) { 5618 context.type = eContextRegisterLoad; 5619 context.SetAddress(offset_addr); 5620 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5621 offset_addr)) 5622 return false; 5623 } 5624 } 5625 5626 return true; 5627 } 5628 5629 // STRH (register) calculates an address from a base register value and an 5630 // offset register value, and stores a 5631 // halfword from a register to memory. The offset register value can be 5632 // shifted left by 0, 1, 2, or 3 bits. 5633 bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode, 5634 const ARMEncoding encoding) { 5635 #if 0 5636 if ConditionPassed() then 5637 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5638 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5639 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5640 address = if index then offset_addr else R[n]; 5641 if UnalignedSupport() || address<0> == '0' then 5642 MemU[address,2] = R[t]<15:0>; 5643 else // Can only occur before ARMv7 5644 MemU[address,2] = bits(16) UNKNOWN; 5645 if wback then R[n] = offset_addr; 5646 #endif 5647 5648 bool success = false; 5649 5650 if (ConditionPassed(opcode)) { 5651 uint32_t t; 5652 uint32_t n; 5653 uint32_t m; 5654 bool index; 5655 bool add; 5656 bool wback; 5657 ARM_ShifterType shift_t; 5658 uint32_t shift_n; 5659 5660 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5661 switch (encoding) { 5662 case eEncodingT1: 5663 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5664 // in ThumbEE"; 5665 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5666 t = Bits32(opcode, 2, 0); 5667 n = Bits32(opcode, 5, 3); 5668 m = Bits32(opcode, 8, 6); 5669 5670 // index = TRUE; add = TRUE; wback = FALSE; 5671 index = true; 5672 add = true; 5673 wback = false; 5674 5675 // (shift_t, shift_n) = (SRType_LSL, 0); 5676 shift_t = SRType_LSL; 5677 shift_n = 0; 5678 5679 break; 5680 5681 case eEncodingT2: 5682 // if Rn == '1111' then UNDEFINED; 5683 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5684 t = Bits32(opcode, 15, 12); 5685 n = Bits32(opcode, 19, 16); 5686 m = Bits32(opcode, 3, 0); 5687 if (n == 15) 5688 return false; 5689 5690 // index = TRUE; add = TRUE; wback = FALSE; 5691 index = true; 5692 add = true; 5693 wback = false; 5694 5695 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5696 shift_t = SRType_LSL; 5697 shift_n = Bits32(opcode, 5, 4); 5698 5699 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5700 if (BadReg(t) || BadReg(m)) 5701 return false; 5702 5703 break; 5704 5705 case eEncodingA1: 5706 // if P == '0' && W == '1' then SEE STRHT; 5707 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5708 t = Bits32(opcode, 15, 12); 5709 n = Bits32(opcode, 19, 16); 5710 m = Bits32(opcode, 3, 0); 5711 5712 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5713 // (W == '1'); 5714 index = BitIsSet(opcode, 24); 5715 add = BitIsSet(opcode, 23); 5716 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5717 5718 // (shift_t, shift_n) = (SRType_LSL, 0); 5719 shift_t = SRType_LSL; 5720 shift_n = 0; 5721 5722 // if t == 15 || m == 15 then UNPREDICTABLE; 5723 if ((t == 15) || (m == 15)) 5724 return false; 5725 5726 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5727 if (wback && ((n == 15) || (n == t))) 5728 return false; 5729 5730 break; 5731 5732 default: 5733 return false; 5734 } 5735 5736 uint32_t Rm = ReadCoreReg(m, &success); 5737 if (!success) 5738 return false; 5739 5740 uint32_t Rn = ReadCoreReg(n, &success); 5741 if (!success) 5742 return false; 5743 5744 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5745 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 5746 if (!success) 5747 return false; 5748 5749 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5750 addr_t offset_addr; 5751 if (add) 5752 offset_addr = Rn + offset; 5753 else 5754 offset_addr = Rn - offset; 5755 5756 // address = if index then offset_addr else R[n]; 5757 addr_t address; 5758 if (index) 5759 address = offset_addr; 5760 else 5761 address = Rn; 5762 5763 EmulateInstruction::Context context; 5764 context.type = eContextRegisterStore; 5765 RegisterInfo base_reg; 5766 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5767 RegisterInfo offset_reg; 5768 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5769 5770 // if UnalignedSupport() || address<0> == '0' then 5771 if (UnalignedSupport() || BitIsClear(address, 0)) { 5772 // MemU[address,2] = R[t]<15:0>; 5773 uint32_t Rt = ReadCoreReg(t, &success); 5774 if (!success) 5775 return false; 5776 5777 EmulateInstruction::Context context; 5778 context.type = eContextRegisterStore; 5779 RegisterInfo base_reg; 5780 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5781 RegisterInfo offset_reg; 5782 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5783 RegisterInfo data_reg; 5784 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5785 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 5786 data_reg); 5787 5788 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2)) 5789 return false; 5790 } else // Can only occur before ARMv7 5791 { 5792 // MemU[address,2] = bits(16) UNKNOWN; 5793 } 5794 5795 // if wback then R[n] = offset_addr; 5796 if (wback) { 5797 context.type = eContextAdjustBaseRegister; 5798 context.SetAddress(offset_addr); 5799 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5800 offset_addr)) 5801 return false; 5802 } 5803 } 5804 5805 return true; 5806 } 5807 5808 // Add with Carry (immediate) adds an immediate value and the carry flag value 5809 // to a register value, and writes the result to the destination register. It 5810 // can optionally update the condition flags based on the result. 5811 bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode, 5812 const ARMEncoding encoding) { 5813 #if 0 5814 // ARM pseudo code... 5815 if ConditionPassed() then 5816 EncodingSpecificOperations(); 5817 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5818 if d == 15 then // Can only occur for ARM encoding 5819 ALUWritePC(result); // setflags is always FALSE here 5820 else 5821 R[d] = result; 5822 if setflags then 5823 APSR.N = result<31>; 5824 APSR.Z = IsZeroBit(result); 5825 APSR.C = carry; 5826 APSR.V = overflow; 5827 #endif 5828 5829 bool success = false; 5830 5831 if (ConditionPassed(opcode)) { 5832 uint32_t Rd, Rn; 5833 uint32_t 5834 imm32; // the immediate value to be added to the value obtained from Rn 5835 bool setflags; 5836 switch (encoding) { 5837 case eEncodingT1: 5838 Rd = Bits32(opcode, 11, 8); 5839 Rn = Bits32(opcode, 19, 16); 5840 setflags = BitIsSet(opcode, 20); 5841 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5842 if (BadReg(Rd) || BadReg(Rn)) 5843 return false; 5844 break; 5845 case eEncodingA1: 5846 Rd = Bits32(opcode, 15, 12); 5847 Rn = Bits32(opcode, 19, 16); 5848 setflags = BitIsSet(opcode, 20); 5849 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5850 5851 if (Rd == 15 && setflags) 5852 return EmulateSUBSPcLrEtc(opcode, encoding); 5853 break; 5854 default: 5855 return false; 5856 } 5857 5858 // Read the first operand. 5859 int32_t val1 = ReadCoreReg(Rn, &success); 5860 if (!success) 5861 return false; 5862 5863 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5864 5865 EmulateInstruction::Context context; 5866 context.type = EmulateInstruction::eContextImmediate; 5867 context.SetNoArgs(); 5868 5869 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5870 res.carry_out, res.overflow)) 5871 return false; 5872 } 5873 return true; 5874 } 5875 5876 // Add with Carry (register) adds a register value, the carry flag value, and 5877 // an optionally-shifted register value, and writes the result to the 5878 // destination register. It can optionally update the condition flags based on 5879 // the result. 5880 bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode, 5881 const ARMEncoding encoding) { 5882 #if 0 5883 // ARM pseudo code... 5884 if ConditionPassed() then 5885 EncodingSpecificOperations(); 5886 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5887 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5888 if d == 15 then // Can only occur for ARM encoding 5889 ALUWritePC(result); // setflags is always FALSE here 5890 else 5891 R[d] = result; 5892 if setflags then 5893 APSR.N = result<31>; 5894 APSR.Z = IsZeroBit(result); 5895 APSR.C = carry; 5896 APSR.V = overflow; 5897 #endif 5898 5899 bool success = false; 5900 5901 if (ConditionPassed(opcode)) { 5902 uint32_t Rd, Rn, Rm; 5903 ARM_ShifterType shift_t; 5904 uint32_t shift_n; // the shift applied to the value read from Rm 5905 bool setflags; 5906 switch (encoding) { 5907 case eEncodingT1: 5908 Rd = Rn = Bits32(opcode, 2, 0); 5909 Rm = Bits32(opcode, 5, 3); 5910 setflags = !InITBlock(); 5911 shift_t = SRType_LSL; 5912 shift_n = 0; 5913 break; 5914 case eEncodingT2: 5915 Rd = Bits32(opcode, 11, 8); 5916 Rn = Bits32(opcode, 19, 16); 5917 Rm = Bits32(opcode, 3, 0); 5918 setflags = BitIsSet(opcode, 20); 5919 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5920 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5921 return false; 5922 break; 5923 case eEncodingA1: 5924 Rd = Bits32(opcode, 15, 12); 5925 Rn = Bits32(opcode, 19, 16); 5926 Rm = Bits32(opcode, 3, 0); 5927 setflags = BitIsSet(opcode, 20); 5928 shift_n = DecodeImmShiftARM(opcode, shift_t); 5929 5930 if (Rd == 15 && setflags) 5931 return EmulateSUBSPcLrEtc(opcode, encoding); 5932 break; 5933 default: 5934 return false; 5935 } 5936 5937 // Read the first operand. 5938 int32_t val1 = ReadCoreReg(Rn, &success); 5939 if (!success) 5940 return false; 5941 5942 // Read the second operand. 5943 int32_t val2 = ReadCoreReg(Rm, &success); 5944 if (!success) 5945 return false; 5946 5947 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5948 if (!success) 5949 return false; 5950 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5951 5952 EmulateInstruction::Context context; 5953 context.type = EmulateInstruction::eContextImmediate; 5954 context.SetNoArgs(); 5955 5956 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5957 res.carry_out, res.overflow)) 5958 return false; 5959 } 5960 return true; 5961 } 5962 5963 // This instruction adds an immediate value to the PC value to form a PC- 5964 // relative address, and writes the result to the destination register. 5965 bool EmulateInstructionARM::EmulateADR(const uint32_t opcode, 5966 const ARMEncoding encoding) { 5967 #if 0 5968 // ARM pseudo code... 5969 if ConditionPassed() then 5970 EncodingSpecificOperations(); 5971 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5972 if d == 15 then // Can only occur for ARM encodings 5973 ALUWritePC(result); 5974 else 5975 R[d] = result; 5976 #endif 5977 5978 bool success = false; 5979 5980 if (ConditionPassed(opcode)) { 5981 uint32_t Rd; 5982 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5983 bool add; 5984 switch (encoding) { 5985 case eEncodingT1: 5986 Rd = Bits32(opcode, 10, 8); 5987 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5988 add = true; 5989 break; 5990 case eEncodingT2: 5991 case eEncodingT3: 5992 Rd = Bits32(opcode, 11, 8); 5993 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5994 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5995 if (BadReg(Rd)) 5996 return false; 5997 break; 5998 case eEncodingA1: 5999 case eEncodingA2: 6000 Rd = Bits32(opcode, 15, 12); 6001 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 6002 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 6003 break; 6004 default: 6005 return false; 6006 } 6007 6008 // Read the PC value. 6009 uint32_t pc = ReadCoreReg(PC_REG, &success); 6010 if (!success) 6011 return false; 6012 6013 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 6014 6015 EmulateInstruction::Context context; 6016 context.type = EmulateInstruction::eContextImmediate; 6017 context.SetNoArgs(); 6018 6019 if (!WriteCoreReg(context, result, Rd)) 6020 return false; 6021 } 6022 return true; 6023 } 6024 6025 // This instruction performs a bitwise AND of a register value and an immediate 6026 // value, and writes the result to the destination register. It can optionally 6027 // update the condition flags based on the result. 6028 bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode, 6029 const ARMEncoding encoding) { 6030 #if 0 6031 // ARM pseudo code... 6032 if ConditionPassed() then 6033 EncodingSpecificOperations(); 6034 result = R[n] AND imm32; 6035 if d == 15 then // Can only occur for ARM encoding 6036 ALUWritePC(result); // setflags is always FALSE here 6037 else 6038 R[d] = result; 6039 if setflags then 6040 APSR.N = result<31>; 6041 APSR.Z = IsZeroBit(result); 6042 APSR.C = carry; 6043 // APSR.V unchanged 6044 #endif 6045 6046 bool success = false; 6047 6048 if (ConditionPassed(opcode)) { 6049 uint32_t Rd, Rn; 6050 uint32_t 6051 imm32; // the immediate value to be ANDed to the value obtained from Rn 6052 bool setflags; 6053 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6054 switch (encoding) { 6055 case eEncodingT1: 6056 Rd = Bits32(opcode, 11, 8); 6057 Rn = Bits32(opcode, 19, 16); 6058 setflags = BitIsSet(opcode, 20); 6059 imm32 = ThumbExpandImm_C( 6060 opcode, APSR_C, 6061 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6062 // if Rd == '1111' && S == '1' then SEE TST (immediate); 6063 if (Rd == 15 && setflags) 6064 return EmulateTSTImm(opcode, eEncodingT1); 6065 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 6066 return false; 6067 break; 6068 case eEncodingA1: 6069 Rd = Bits32(opcode, 15, 12); 6070 Rn = Bits32(opcode, 19, 16); 6071 setflags = BitIsSet(opcode, 20); 6072 imm32 = 6073 ARMExpandImm_C(opcode, APSR_C, 6074 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6075 6076 if (Rd == 15 && setflags) 6077 return EmulateSUBSPcLrEtc(opcode, encoding); 6078 break; 6079 default: 6080 return false; 6081 } 6082 6083 // Read the first operand. 6084 uint32_t val1 = ReadCoreReg(Rn, &success); 6085 if (!success) 6086 return false; 6087 6088 uint32_t result = val1 & imm32; 6089 6090 EmulateInstruction::Context context; 6091 context.type = EmulateInstruction::eContextImmediate; 6092 context.SetNoArgs(); 6093 6094 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6095 return false; 6096 } 6097 return true; 6098 } 6099 6100 // This instruction performs a bitwise AND of a register value and an 6101 // optionally-shifted register value, and writes the result to the destination 6102 // register. It can optionally update the condition flags based on the result. 6103 bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode, 6104 const ARMEncoding encoding) { 6105 #if 0 6106 // ARM pseudo code... 6107 if ConditionPassed() then 6108 EncodingSpecificOperations(); 6109 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6110 result = R[n] AND shifted; 6111 if d == 15 then // Can only occur for ARM encoding 6112 ALUWritePC(result); // setflags is always FALSE here 6113 else 6114 R[d] = result; 6115 if setflags then 6116 APSR.N = result<31>; 6117 APSR.Z = IsZeroBit(result); 6118 APSR.C = carry; 6119 // APSR.V unchanged 6120 #endif 6121 6122 bool success = false; 6123 6124 if (ConditionPassed(opcode)) { 6125 uint32_t Rd, Rn, Rm; 6126 ARM_ShifterType shift_t; 6127 uint32_t shift_n; // the shift applied to the value read from Rm 6128 bool setflags; 6129 uint32_t carry; 6130 switch (encoding) { 6131 case eEncodingT1: 6132 Rd = Rn = Bits32(opcode, 2, 0); 6133 Rm = Bits32(opcode, 5, 3); 6134 setflags = !InITBlock(); 6135 shift_t = SRType_LSL; 6136 shift_n = 0; 6137 break; 6138 case eEncodingT2: 6139 Rd = Bits32(opcode, 11, 8); 6140 Rn = Bits32(opcode, 19, 16); 6141 Rm = Bits32(opcode, 3, 0); 6142 setflags = BitIsSet(opcode, 20); 6143 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6144 // if Rd == '1111' && S == '1' then SEE TST (register); 6145 if (Rd == 15 && setflags) 6146 return EmulateTSTReg(opcode, eEncodingT2); 6147 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 6148 return false; 6149 break; 6150 case eEncodingA1: 6151 Rd = Bits32(opcode, 15, 12); 6152 Rn = Bits32(opcode, 19, 16); 6153 Rm = Bits32(opcode, 3, 0); 6154 setflags = BitIsSet(opcode, 20); 6155 shift_n = DecodeImmShiftARM(opcode, shift_t); 6156 6157 if (Rd == 15 && setflags) 6158 return EmulateSUBSPcLrEtc(opcode, encoding); 6159 break; 6160 default: 6161 return false; 6162 } 6163 6164 // Read the first operand. 6165 uint32_t val1 = ReadCoreReg(Rn, &success); 6166 if (!success) 6167 return false; 6168 6169 // Read the second operand. 6170 uint32_t val2 = ReadCoreReg(Rm, &success); 6171 if (!success) 6172 return false; 6173 6174 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6175 if (!success) 6176 return false; 6177 uint32_t result = val1 & shifted; 6178 6179 EmulateInstruction::Context context; 6180 context.type = EmulateInstruction::eContextImmediate; 6181 context.SetNoArgs(); 6182 6183 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6184 return false; 6185 } 6186 return true; 6187 } 6188 6189 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and 6190 // the complement of an immediate value, and writes the result to the 6191 // destination register. It can optionally update the condition flags based on 6192 // the result. 6193 bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode, 6194 const ARMEncoding encoding) { 6195 #if 0 6196 // ARM pseudo code... 6197 if ConditionPassed() then 6198 EncodingSpecificOperations(); 6199 result = R[n] AND NOT(imm32); 6200 if d == 15 then // Can only occur for ARM encoding 6201 ALUWritePC(result); // setflags is always FALSE here 6202 else 6203 R[d] = result; 6204 if setflags then 6205 APSR.N = result<31>; 6206 APSR.Z = IsZeroBit(result); 6207 APSR.C = carry; 6208 // APSR.V unchanged 6209 #endif 6210 6211 bool success = false; 6212 6213 if (ConditionPassed(opcode)) { 6214 uint32_t Rd, Rn; 6215 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to 6216 // the value obtained from Rn 6217 bool setflags; 6218 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6219 switch (encoding) { 6220 case eEncodingT1: 6221 Rd = Bits32(opcode, 11, 8); 6222 Rn = Bits32(opcode, 19, 16); 6223 setflags = BitIsSet(opcode, 20); 6224 imm32 = ThumbExpandImm_C( 6225 opcode, APSR_C, 6226 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6227 if (BadReg(Rd) || BadReg(Rn)) 6228 return false; 6229 break; 6230 case eEncodingA1: 6231 Rd = Bits32(opcode, 15, 12); 6232 Rn = Bits32(opcode, 19, 16); 6233 setflags = BitIsSet(opcode, 20); 6234 imm32 = 6235 ARMExpandImm_C(opcode, APSR_C, 6236 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6237 6238 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6239 // instructions; 6240 if (Rd == 15 && setflags) 6241 return EmulateSUBSPcLrEtc(opcode, encoding); 6242 break; 6243 default: 6244 return false; 6245 } 6246 6247 // Read the first operand. 6248 uint32_t val1 = ReadCoreReg(Rn, &success); 6249 if (!success) 6250 return false; 6251 6252 uint32_t result = val1 & ~imm32; 6253 6254 EmulateInstruction::Context context; 6255 context.type = EmulateInstruction::eContextImmediate; 6256 context.SetNoArgs(); 6257 6258 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6259 return false; 6260 } 6261 return true; 6262 } 6263 6264 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and 6265 // the complement of an optionally-shifted register value, and writes the 6266 // result to the destination register. It can optionally update the condition 6267 // flags based on the result. 6268 bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode, 6269 const ARMEncoding encoding) { 6270 #if 0 6271 // ARM pseudo code... 6272 if ConditionPassed() then 6273 EncodingSpecificOperations(); 6274 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6275 result = R[n] AND NOT(shifted); 6276 if d == 15 then // Can only occur for ARM encoding 6277 ALUWritePC(result); // setflags is always FALSE here 6278 else 6279 R[d] = result; 6280 if setflags then 6281 APSR.N = result<31>; 6282 APSR.Z = IsZeroBit(result); 6283 APSR.C = carry; 6284 // APSR.V unchanged 6285 #endif 6286 6287 bool success = false; 6288 6289 if (ConditionPassed(opcode)) { 6290 uint32_t Rd, Rn, Rm; 6291 ARM_ShifterType shift_t; 6292 uint32_t shift_n; // the shift applied to the value read from Rm 6293 bool setflags; 6294 uint32_t carry; 6295 switch (encoding) { 6296 case eEncodingT1: 6297 Rd = Rn = Bits32(opcode, 2, 0); 6298 Rm = Bits32(opcode, 5, 3); 6299 setflags = !InITBlock(); 6300 shift_t = SRType_LSL; 6301 shift_n = 0; 6302 break; 6303 case eEncodingT2: 6304 Rd = Bits32(opcode, 11, 8); 6305 Rn = Bits32(opcode, 19, 16); 6306 Rm = Bits32(opcode, 3, 0); 6307 setflags = BitIsSet(opcode, 20); 6308 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6309 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 6310 return false; 6311 break; 6312 case eEncodingA1: 6313 Rd = Bits32(opcode, 15, 12); 6314 Rn = Bits32(opcode, 19, 16); 6315 Rm = Bits32(opcode, 3, 0); 6316 setflags = BitIsSet(opcode, 20); 6317 shift_n = DecodeImmShiftARM(opcode, shift_t); 6318 6319 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6320 // instructions; 6321 if (Rd == 15 && setflags) 6322 return EmulateSUBSPcLrEtc(opcode, encoding); 6323 break; 6324 default: 6325 return false; 6326 } 6327 6328 // Read the first operand. 6329 uint32_t val1 = ReadCoreReg(Rn, &success); 6330 if (!success) 6331 return false; 6332 6333 // Read the second operand. 6334 uint32_t val2 = ReadCoreReg(Rm, &success); 6335 if (!success) 6336 return false; 6337 6338 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6339 if (!success) 6340 return false; 6341 uint32_t result = val1 & ~shifted; 6342 6343 EmulateInstruction::Context context; 6344 context.type = EmulateInstruction::eContextImmediate; 6345 context.SetNoArgs(); 6346 6347 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6348 return false; 6349 } 6350 return true; 6351 } 6352 6353 // LDR (immediate, ARM) calculates an address from a base register value and an 6354 // immediate offset, loads a word 6355 // from memory, and writes it to a register. It can use offset, post-indexed, 6356 // or pre-indexed addressing. 6357 bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode, 6358 const ARMEncoding encoding) { 6359 #if 0 6360 if ConditionPassed() then 6361 EncodingSpecificOperations(); 6362 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6363 address = if index then offset_addr else R[n]; 6364 data = MemU[address,4]; 6365 if wback then R[n] = offset_addr; 6366 if t == 15 then 6367 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6368 elsif UnalignedSupport() || address<1:0> = '00' then 6369 R[t] = data; 6370 else // Can only apply before ARMv7 6371 R[t] = ROR(data, 8*UInt(address<1:0>)); 6372 #endif 6373 6374 bool success = false; 6375 6376 if (ConditionPassed(opcode)) { 6377 const uint32_t addr_byte_size = GetAddressByteSize(); 6378 6379 uint32_t t; 6380 uint32_t n; 6381 uint32_t imm32; 6382 bool index; 6383 bool add; 6384 bool wback; 6385 6386 switch (encoding) { 6387 case eEncodingA1: 6388 // if Rn == '1111' then SEE LDR (literal); 6389 // if P == '0' && W == '1' then SEE LDRT; 6390 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == 6391 // '000000000100' then SEE POP; 6392 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6393 t = Bits32(opcode, 15, 12); 6394 n = Bits32(opcode, 19, 16); 6395 imm32 = Bits32(opcode, 11, 0); 6396 6397 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6398 // (W == '1'); 6399 index = BitIsSet(opcode, 24); 6400 add = BitIsSet(opcode, 23); 6401 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6402 6403 // if wback && n == t then UNPREDICTABLE; 6404 if (wback && (n == t)) 6405 return false; 6406 6407 break; 6408 6409 default: 6410 return false; 6411 } 6412 6413 addr_t address; 6414 addr_t offset_addr; 6415 addr_t base_address = ReadCoreReg(n, &success); 6416 if (!success) 6417 return false; 6418 6419 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6420 if (add) 6421 offset_addr = base_address + imm32; 6422 else 6423 offset_addr = base_address - imm32; 6424 6425 // address = if index then offset_addr else R[n]; 6426 if (index) 6427 address = offset_addr; 6428 else 6429 address = base_address; 6430 6431 // data = MemU[address,4]; 6432 6433 RegisterInfo base_reg; 6434 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6435 6436 EmulateInstruction::Context context; 6437 context.type = eContextRegisterLoad; 6438 context.SetRegisterPlusOffset(base_reg, address - base_address); 6439 6440 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6441 if (!success) 6442 return false; 6443 6444 // if wback then R[n] = offset_addr; 6445 if (wback) { 6446 context.type = eContextAdjustBaseRegister; 6447 context.SetAddress(offset_addr); 6448 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6449 offset_addr)) 6450 return false; 6451 } 6452 6453 // if t == 15 then 6454 if (t == 15) { 6455 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6456 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6457 // LoadWritePC (data); 6458 context.type = eContextRegisterLoad; 6459 context.SetRegisterPlusOffset(base_reg, address - base_address); 6460 LoadWritePC(context, data); 6461 } else 6462 return false; 6463 } 6464 // elsif UnalignedSupport() || address<1:0> = '00' then 6465 else if (UnalignedSupport() || 6466 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6467 // R[t] = data; 6468 context.type = eContextRegisterLoad; 6469 context.SetRegisterPlusOffset(base_reg, address - base_address); 6470 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6471 data)) 6472 return false; 6473 } 6474 // else // Can only apply before ARMv7 6475 else { 6476 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6477 data = ROR(data, Bits32(address, 1, 0), &success); 6478 if (!success) 6479 return false; 6480 context.type = eContextRegisterLoad; 6481 context.SetImmediate(data); 6482 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6483 data)) 6484 return false; 6485 } 6486 } 6487 return true; 6488 } 6489 6490 // LDR (register) calculates an address from a base register value and an offset 6491 // register value, loads a word 6492 // from memory, and writes it to a register. The offset register value can 6493 // optionally be shifted. 6494 bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode, 6495 const ARMEncoding encoding) { 6496 #if 0 6497 if ConditionPassed() then 6498 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6499 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6500 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6501 address = if index then offset_addr else R[n]; 6502 data = MemU[address,4]; 6503 if wback then R[n] = offset_addr; 6504 if t == 15 then 6505 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6506 elsif UnalignedSupport() || address<1:0> = '00' then 6507 R[t] = data; 6508 else // Can only apply before ARMv7 6509 if CurrentInstrSet() == InstrSet_ARM then 6510 R[t] = ROR(data, 8*UInt(address<1:0>)); 6511 else 6512 R[t] = bits(32) UNKNOWN; 6513 #endif 6514 6515 bool success = false; 6516 6517 if (ConditionPassed(opcode)) { 6518 const uint32_t addr_byte_size = GetAddressByteSize(); 6519 6520 uint32_t t; 6521 uint32_t n; 6522 uint32_t m; 6523 bool index; 6524 bool add; 6525 bool wback; 6526 ARM_ShifterType shift_t; 6527 uint32_t shift_n; 6528 6529 switch (encoding) { 6530 case eEncodingT1: 6531 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 6532 // in ThumbEE"; 6533 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6534 t = Bits32(opcode, 2, 0); 6535 n = Bits32(opcode, 5, 3); 6536 m = Bits32(opcode, 8, 6); 6537 6538 // index = TRUE; add = TRUE; wback = FALSE; 6539 index = true; 6540 add = true; 6541 wback = false; 6542 6543 // (shift_t, shift_n) = (SRType_LSL, 0); 6544 shift_t = SRType_LSL; 6545 shift_n = 0; 6546 6547 break; 6548 6549 case eEncodingT2: 6550 // if Rn == '1111' then SEE LDR (literal); 6551 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6552 t = Bits32(opcode, 15, 12); 6553 n = Bits32(opcode, 19, 16); 6554 m = Bits32(opcode, 3, 0); 6555 6556 // index = TRUE; add = TRUE; wback = FALSE; 6557 index = true; 6558 add = true; 6559 wback = false; 6560 6561 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6562 shift_t = SRType_LSL; 6563 shift_n = Bits32(opcode, 5, 4); 6564 6565 // if BadReg(m) then UNPREDICTABLE; 6566 if (BadReg(m)) 6567 return false; 6568 6569 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6570 if ((t == 15) && InITBlock() && !LastInITBlock()) 6571 return false; 6572 6573 break; 6574 6575 case eEncodingA1: { 6576 // if P == '0' && W == '1' then SEE LDRT; 6577 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6578 t = Bits32(opcode, 15, 12); 6579 n = Bits32(opcode, 19, 16); 6580 m = Bits32(opcode, 3, 0); 6581 6582 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6583 // (W == '1'); 6584 index = BitIsSet(opcode, 24); 6585 add = BitIsSet(opcode, 23); 6586 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6587 6588 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6589 uint32_t type = Bits32(opcode, 6, 5); 6590 uint32_t imm5 = Bits32(opcode, 11, 7); 6591 shift_n = DecodeImmShift(type, imm5, shift_t); 6592 6593 // if m == 15 then UNPREDICTABLE; 6594 if (m == 15) 6595 return false; 6596 6597 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6598 if (wback && ((n == 15) || (n == t))) 6599 return false; 6600 } break; 6601 6602 default: 6603 return false; 6604 } 6605 6606 uint32_t Rm = 6607 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6608 if (!success) 6609 return false; 6610 6611 uint32_t Rn = 6612 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6613 if (!success) 6614 return false; 6615 6616 addr_t offset_addr; 6617 addr_t address; 6618 6619 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is 6620 // an application level alias for the CPSR". 6621 addr_t offset = 6622 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success); 6623 if (!success) 6624 return false; 6625 6626 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6627 if (add) 6628 offset_addr = Rn + offset; 6629 else 6630 offset_addr = Rn - offset; 6631 6632 // address = if index then offset_addr else R[n]; 6633 if (index) 6634 address = offset_addr; 6635 else 6636 address = Rn; 6637 6638 // data = MemU[address,4]; 6639 RegisterInfo base_reg; 6640 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6641 6642 EmulateInstruction::Context context; 6643 context.type = eContextRegisterLoad; 6644 context.SetRegisterPlusOffset(base_reg, address - Rn); 6645 6646 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6647 if (!success) 6648 return false; 6649 6650 // if wback then R[n] = offset_addr; 6651 if (wback) { 6652 context.type = eContextAdjustBaseRegister; 6653 context.SetAddress(offset_addr); 6654 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6655 offset_addr)) 6656 return false; 6657 } 6658 6659 // if t == 15 then 6660 if (t == 15) { 6661 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6662 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6663 context.type = eContextRegisterLoad; 6664 context.SetRegisterPlusOffset(base_reg, address - Rn); 6665 LoadWritePC(context, data); 6666 } else 6667 return false; 6668 } 6669 // elsif UnalignedSupport() || address<1:0> = '00' then 6670 else if (UnalignedSupport() || 6671 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6672 // R[t] = data; 6673 context.type = eContextRegisterLoad; 6674 context.SetRegisterPlusOffset(base_reg, address - Rn); 6675 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6676 data)) 6677 return false; 6678 } else // Can only apply before ARMv7 6679 { 6680 // if CurrentInstrSet() == InstrSet_ARM then 6681 if (CurrentInstrSet() == eModeARM) { 6682 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6683 data = ROR(data, Bits32(address, 1, 0), &success); 6684 if (!success) 6685 return false; 6686 context.type = eContextRegisterLoad; 6687 context.SetImmediate(data); 6688 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6689 data)) 6690 return false; 6691 } else { 6692 // R[t] = bits(32) UNKNOWN; 6693 WriteBits32Unknown(t); 6694 } 6695 } 6696 } 6697 return true; 6698 } 6699 6700 // LDRB (immediate, Thumb) 6701 bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode, 6702 const ARMEncoding encoding) { 6703 #if 0 6704 if ConditionPassed() then 6705 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6706 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6707 address = if index then offset_addr else R[n]; 6708 R[t] = ZeroExtend(MemU[address,1], 32); 6709 if wback then R[n] = offset_addr; 6710 #endif 6711 6712 bool success = false; 6713 6714 if (ConditionPassed(opcode)) { 6715 uint32_t t; 6716 uint32_t n; 6717 uint32_t imm32; 6718 bool index; 6719 bool add; 6720 bool wback; 6721 6722 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6723 switch (encoding) { 6724 case eEncodingT1: 6725 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6726 t = Bits32(opcode, 2, 0); 6727 n = Bits32(opcode, 5, 3); 6728 imm32 = Bits32(opcode, 10, 6); 6729 6730 // index = TRUE; add = TRUE; wback = FALSE; 6731 index = true; 6732 add = true; 6733 wback = false; 6734 6735 break; 6736 6737 case eEncodingT2: 6738 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6739 t = Bits32(opcode, 15, 12); 6740 n = Bits32(opcode, 19, 16); 6741 imm32 = Bits32(opcode, 11, 0); 6742 6743 // index = TRUE; add = TRUE; wback = FALSE; 6744 index = true; 6745 add = true; 6746 wback = false; 6747 6748 // if Rt == '1111' then SEE PLD; 6749 if (t == 15) 6750 return false; // PLD is not implemented yet 6751 6752 // if Rn == '1111' then SEE LDRB (literal); 6753 if (n == 15) 6754 return EmulateLDRBLiteral(opcode, eEncodingT1); 6755 6756 // if t == 13 then UNPREDICTABLE; 6757 if (t == 13) 6758 return false; 6759 6760 break; 6761 6762 case eEncodingT3: 6763 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6764 // if P == '0' && W == '0' then UNDEFINED; 6765 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 6766 return false; 6767 6768 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6769 t = Bits32(opcode, 15, 12); 6770 n = Bits32(opcode, 19, 16); 6771 imm32 = Bits32(opcode, 7, 0); 6772 6773 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6774 index = BitIsSet(opcode, 10); 6775 add = BitIsSet(opcode, 9); 6776 wback = BitIsSet(opcode, 8); 6777 6778 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6779 if (t == 15) 6780 return false; // PLD is not implemented yet 6781 6782 // if Rn == '1111' then SEE LDRB (literal); 6783 if (n == 15) 6784 return EmulateLDRBLiteral(opcode, eEncodingT1); 6785 6786 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6787 if (BadReg(t) || (wback && (n == t))) 6788 return false; 6789 6790 break; 6791 6792 default: 6793 return false; 6794 } 6795 6796 uint32_t Rn = 6797 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6798 if (!success) 6799 return false; 6800 6801 addr_t address; 6802 addr_t offset_addr; 6803 6804 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6805 if (add) 6806 offset_addr = Rn + imm32; 6807 else 6808 offset_addr = Rn - imm32; 6809 6810 // address = if index then offset_addr else R[n]; 6811 if (index) 6812 address = offset_addr; 6813 else 6814 address = Rn; 6815 6816 // R[t] = ZeroExtend(MemU[address,1], 32); 6817 RegisterInfo base_reg; 6818 RegisterInfo data_reg; 6819 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6820 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6821 6822 EmulateInstruction::Context context; 6823 context.type = eContextRegisterLoad; 6824 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 6825 6826 uint64_t data = MemURead(context, address, 1, 0, &success); 6827 if (!success) 6828 return false; 6829 6830 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6831 return false; 6832 6833 // if wback then R[n] = offset_addr; 6834 if (wback) { 6835 context.type = eContextAdjustBaseRegister; 6836 context.SetAddress(offset_addr); 6837 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6838 offset_addr)) 6839 return false; 6840 } 6841 } 6842 return true; 6843 } 6844 6845 // LDRB (literal) calculates an address from the PC value and an immediate 6846 // offset, loads a byte from memory, 6847 // zero-extends it to form a 32-bit word and writes it to a register. 6848 bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode, 6849 const ARMEncoding encoding) { 6850 #if 0 6851 if ConditionPassed() then 6852 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6853 base = Align(PC,4); 6854 address = if add then (base + imm32) else (base - imm32); 6855 R[t] = ZeroExtend(MemU[address,1], 32); 6856 #endif 6857 6858 bool success = false; 6859 6860 if (ConditionPassed(opcode)) { 6861 uint32_t t; 6862 uint32_t imm32; 6863 bool add; 6864 switch (encoding) { 6865 case eEncodingT1: 6866 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6867 t = Bits32(opcode, 15, 12); 6868 imm32 = Bits32(opcode, 11, 0); 6869 add = BitIsSet(opcode, 23); 6870 6871 // if Rt == '1111' then SEE PLD; 6872 if (t == 15) 6873 return false; // PLD is not implemented yet 6874 6875 // if t == 13 then UNPREDICTABLE; 6876 if (t == 13) 6877 return false; 6878 6879 break; 6880 6881 case eEncodingA1: 6882 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6883 t = Bits32(opcode, 15, 12); 6884 imm32 = Bits32(opcode, 11, 0); 6885 add = BitIsSet(opcode, 23); 6886 6887 // if t == 15 then UNPREDICTABLE; 6888 if (t == 15) 6889 return false; 6890 break; 6891 6892 default: 6893 return false; 6894 } 6895 6896 // base = Align(PC,4); 6897 uint32_t pc_val = ReadCoreReg(PC_REG, &success); 6898 if (!success) 6899 return false; 6900 6901 uint32_t base = AlignPC(pc_val); 6902 6903 addr_t address; 6904 // address = if add then (base + imm32) else (base - imm32); 6905 if (add) 6906 address = base + imm32; 6907 else 6908 address = base - imm32; 6909 6910 // R[t] = ZeroExtend(MemU[address,1], 32); 6911 EmulateInstruction::Context context; 6912 context.type = eContextRelativeBranchImmediate; 6913 context.SetImmediate(address - base); 6914 6915 uint64_t data = MemURead(context, address, 1, 0, &success); 6916 if (!success) 6917 return false; 6918 6919 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6920 return false; 6921 } 6922 return true; 6923 } 6924 6925 // LDRB (register) calculates an address from a base register value and an 6926 // offset rigister value, loads a byte from memory, zero-extends it to form a 6927 // 32-bit word, and writes it to a register. The offset register value can 6928 // optionally be shifted. 6929 bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode, 6930 const ARMEncoding encoding) { 6931 #if 0 6932 if ConditionPassed() then 6933 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6934 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6935 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6936 address = if index then offset_addr else R[n]; 6937 R[t] = ZeroExtend(MemU[address,1],32); 6938 if wback then R[n] = offset_addr; 6939 #endif 6940 6941 bool success = false; 6942 6943 if (ConditionPassed(opcode)) { 6944 uint32_t t; 6945 uint32_t n; 6946 uint32_t m; 6947 bool index; 6948 bool add; 6949 bool wback; 6950 ARM_ShifterType shift_t; 6951 uint32_t shift_n; 6952 6953 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6954 switch (encoding) { 6955 case eEncodingT1: 6956 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6957 t = Bits32(opcode, 2, 0); 6958 n = Bits32(opcode, 5, 3); 6959 m = Bits32(opcode, 8, 6); 6960 6961 // index = TRUE; add = TRUE; wback = FALSE; 6962 index = true; 6963 add = true; 6964 wback = false; 6965 6966 // (shift_t, shift_n) = (SRType_LSL, 0); 6967 shift_t = SRType_LSL; 6968 shift_n = 0; 6969 break; 6970 6971 case eEncodingT2: 6972 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6973 t = Bits32(opcode, 15, 12); 6974 n = Bits32(opcode, 19, 16); 6975 m = Bits32(opcode, 3, 0); 6976 6977 // index = TRUE; add = TRUE; wback = FALSE; 6978 index = true; 6979 add = true; 6980 wback = false; 6981 6982 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6983 shift_t = SRType_LSL; 6984 shift_n = Bits32(opcode, 5, 4); 6985 6986 // if Rt == '1111' then SEE PLD; 6987 if (t == 15) 6988 return false; // PLD is not implemented yet 6989 6990 // if Rn == '1111' then SEE LDRB (literal); 6991 if (n == 15) 6992 return EmulateLDRBLiteral(opcode, eEncodingT1); 6993 6994 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6995 if ((t == 13) || BadReg(m)) 6996 return false; 6997 break; 6998 6999 case eEncodingA1: { 7000 // if P == '0' && W == '1' then SEE LDRBT; 7001 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7002 t = Bits32(opcode, 15, 12); 7003 n = Bits32(opcode, 19, 16); 7004 m = Bits32(opcode, 3, 0); 7005 7006 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7007 // (W == '1'); 7008 index = BitIsSet(opcode, 24); 7009 add = BitIsSet(opcode, 23); 7010 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7011 7012 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 7013 uint32_t type = Bits32(opcode, 6, 5); 7014 uint32_t imm5 = Bits32(opcode, 11, 7); 7015 shift_n = DecodeImmShift(type, imm5, shift_t); 7016 7017 // if t == 15 || m == 15 then UNPREDICTABLE; 7018 if ((t == 15) || (m == 15)) 7019 return false; 7020 7021 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7022 if (wback && ((n == 15) || (n == t))) 7023 return false; 7024 } break; 7025 7026 default: 7027 return false; 7028 } 7029 7030 addr_t offset_addr; 7031 addr_t address; 7032 7033 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7034 uint32_t Rm = 7035 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7036 if (!success) 7037 return false; 7038 7039 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7040 if (!success) 7041 return false; 7042 7043 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7044 uint32_t Rn = 7045 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7046 if (!success) 7047 return false; 7048 7049 if (add) 7050 offset_addr = Rn + offset; 7051 else 7052 offset_addr = Rn - offset; 7053 7054 // address = if index then offset_addr else R[n]; 7055 if (index) 7056 address = offset_addr; 7057 else 7058 address = Rn; 7059 7060 // R[t] = ZeroExtend(MemU[address,1],32); 7061 RegisterInfo base_reg; 7062 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7063 7064 EmulateInstruction::Context context; 7065 context.type = eContextRegisterLoad; 7066 context.SetRegisterPlusOffset(base_reg, address - Rn); 7067 7068 uint64_t data = MemURead(context, address, 1, 0, &success); 7069 if (!success) 7070 return false; 7071 7072 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7073 return false; 7074 7075 // if wback then R[n] = offset_addr; 7076 if (wback) { 7077 context.type = eContextAdjustBaseRegister; 7078 context.SetAddress(offset_addr); 7079 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7080 offset_addr)) 7081 return false; 7082 } 7083 } 7084 return true; 7085 } 7086 7087 // LDRH (immediate, Thumb) calculates an address from a base register value and 7088 // an immediate offset, loads a 7089 // halfword from memory, zero-extends it to form a 32-bit word, and writes it 7090 // to a register. It can use offset, post-indexed, or pre-indexed addressing. 7091 bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode, 7092 const ARMEncoding encoding) { 7093 #if 0 7094 if ConditionPassed() then 7095 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7096 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7097 address = if index then offset_addr else R[n]; 7098 data = MemU[address,2]; 7099 if wback then R[n] = offset_addr; 7100 if UnalignedSupport() || address<0> = '0' then 7101 R[t] = ZeroExtend(data, 32); 7102 else // Can only apply before ARMv7 7103 R[t] = bits(32) UNKNOWN; 7104 #endif 7105 7106 bool success = false; 7107 7108 if (ConditionPassed(opcode)) { 7109 uint32_t t; 7110 uint32_t n; 7111 uint32_t imm32; 7112 bool index; 7113 bool add; 7114 bool wback; 7115 7116 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7117 switch (encoding) { 7118 case eEncodingT1: 7119 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 7120 t = Bits32(opcode, 2, 0); 7121 n = Bits32(opcode, 5, 3); 7122 imm32 = Bits32(opcode, 10, 6) << 1; 7123 7124 // index = TRUE; add = TRUE; wback = FALSE; 7125 index = true; 7126 add = true; 7127 wback = false; 7128 7129 break; 7130 7131 case eEncodingT2: 7132 // if Rt == '1111' then SEE "Unallocated memory hints"; 7133 // if Rn == '1111' then SEE LDRH (literal); 7134 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7135 t = Bits32(opcode, 15, 12); 7136 n = Bits32(opcode, 19, 16); 7137 imm32 = Bits32(opcode, 11, 0); 7138 7139 // index = TRUE; add = TRUE; wback = FALSE; 7140 index = true; 7141 add = true; 7142 wback = false; 7143 7144 // if t == 13 then UNPREDICTABLE; 7145 if (t == 13) 7146 return false; 7147 break; 7148 7149 case eEncodingT3: 7150 // if Rn == '1111' then SEE LDRH (literal); 7151 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7152 // "Unallocated memory hints"; 7153 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 7154 // if P == '0' && W == '0' then UNDEFINED; 7155 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7156 return false; 7157 7158 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7159 t = Bits32(opcode, 15, 12); 7160 n = Bits32(opcode, 19, 16); 7161 imm32 = Bits32(opcode, 7, 0); 7162 7163 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7164 index = BitIsSet(opcode, 10); 7165 add = BitIsSet(opcode, 9); 7166 wback = BitIsSet(opcode, 8); 7167 7168 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7169 if (BadReg(t) || (wback && (n == t))) 7170 return false; 7171 break; 7172 7173 default: 7174 return false; 7175 } 7176 7177 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7178 uint32_t Rn = 7179 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7180 if (!success) 7181 return false; 7182 7183 addr_t offset_addr; 7184 addr_t address; 7185 7186 if (add) 7187 offset_addr = Rn + imm32; 7188 else 7189 offset_addr = Rn - imm32; 7190 7191 // address = if index then offset_addr else R[n]; 7192 if (index) 7193 address = offset_addr; 7194 else 7195 address = Rn; 7196 7197 // data = MemU[address,2]; 7198 RegisterInfo base_reg; 7199 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7200 7201 EmulateInstruction::Context context; 7202 context.type = eContextRegisterLoad; 7203 context.SetRegisterPlusOffset(base_reg, address - Rn); 7204 7205 uint64_t data = MemURead(context, address, 2, 0, &success); 7206 if (!success) 7207 return false; 7208 7209 // if wback then R[n] = offset_addr; 7210 if (wback) { 7211 context.type = eContextAdjustBaseRegister; 7212 context.SetAddress(offset_addr); 7213 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7214 offset_addr)) 7215 return false; 7216 } 7217 7218 // if UnalignedSupport() || address<0> = '0' then 7219 if (UnalignedSupport() || BitIsClear(address, 0)) { 7220 // R[t] = ZeroExtend(data, 32); 7221 context.type = eContextRegisterLoad; 7222 context.SetRegisterPlusOffset(base_reg, address - Rn); 7223 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7224 data)) 7225 return false; 7226 } else // Can only apply before ARMv7 7227 { 7228 // R[t] = bits(32) UNKNOWN; 7229 WriteBits32Unknown(t); 7230 } 7231 } 7232 return true; 7233 } 7234 7235 // LDRH (literal) caculates an address from the PC value and an immediate 7236 // offset, loads a halfword from memory, 7237 // zero-extends it to form a 32-bit word, and writes it to a register. 7238 bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode, 7239 const ARMEncoding encoding) { 7240 #if 0 7241 if ConditionPassed() then 7242 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7243 base = Align(PC,4); 7244 address = if add then (base + imm32) else (base - imm32); 7245 data = MemU[address,2]; 7246 if UnalignedSupport() || address<0> = '0' then 7247 R[t] = ZeroExtend(data, 32); 7248 else // Can only apply before ARMv7 7249 R[t] = bits(32) UNKNOWN; 7250 #endif 7251 7252 bool success = false; 7253 7254 if (ConditionPassed(opcode)) { 7255 uint32_t t; 7256 uint32_t imm32; 7257 bool add; 7258 7259 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7260 switch (encoding) { 7261 case eEncodingT1: 7262 // if Rt == '1111' then SEE "Unallocated memory hints"; 7263 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7264 t = Bits32(opcode, 15, 12); 7265 imm32 = Bits32(opcode, 11, 0); 7266 add = BitIsSet(opcode, 23); 7267 7268 // if t == 13 then UNPREDICTABLE; 7269 if (t == 13) 7270 return false; 7271 7272 break; 7273 7274 case eEncodingA1: { 7275 uint32_t imm4H = Bits32(opcode, 11, 8); 7276 uint32_t imm4L = Bits32(opcode, 3, 0); 7277 7278 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7279 t = Bits32(opcode, 15, 12); 7280 imm32 = (imm4H << 4) | imm4L; 7281 add = BitIsSet(opcode, 23); 7282 7283 // if t == 15 then UNPREDICTABLE; 7284 if (t == 15) 7285 return false; 7286 break; 7287 } 7288 7289 default: 7290 return false; 7291 } 7292 7293 // base = Align(PC,4); 7294 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7295 if (!success) 7296 return false; 7297 7298 addr_t base = AlignPC(pc_value); 7299 addr_t address; 7300 7301 // address = if add then (base + imm32) else (base - imm32); 7302 if (add) 7303 address = base + imm32; 7304 else 7305 address = base - imm32; 7306 7307 // data = MemU[address,2]; 7308 RegisterInfo base_reg; 7309 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7310 7311 EmulateInstruction::Context context; 7312 context.type = eContextRegisterLoad; 7313 context.SetRegisterPlusOffset(base_reg, address - base); 7314 7315 uint64_t data = MemURead(context, address, 2, 0, &success); 7316 if (!success) 7317 return false; 7318 7319 // if UnalignedSupport() || address<0> = '0' then 7320 if (UnalignedSupport() || BitIsClear(address, 0)) { 7321 // R[t] = ZeroExtend(data, 32); 7322 context.type = eContextRegisterLoad; 7323 context.SetRegisterPlusOffset(base_reg, address - base); 7324 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7325 data)) 7326 return false; 7327 7328 } else // Can only apply before ARMv7 7329 { 7330 // R[t] = bits(32) UNKNOWN; 7331 WriteBits32Unknown(t); 7332 } 7333 } 7334 return true; 7335 } 7336 7337 // LDRH (literal) calculates an address from a base register value and an offset 7338 // register value, loads a halfword 7339 // from memory, zero-extends it to form a 32-bit word, and writes it to a 7340 // register. The offset register value can be shifted left by 0, 1, 2, or 3 7341 // bits. 7342 bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode, 7343 const ARMEncoding encoding) { 7344 #if 0 7345 if ConditionPassed() then 7346 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7347 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7348 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7349 address = if index then offset_addr else R[n]; 7350 data = MemU[address,2]; 7351 if wback then R[n] = offset_addr; 7352 if UnalignedSupport() || address<0> = '0' then 7353 R[t] = ZeroExtend(data, 32); 7354 else // Can only apply before ARMv7 7355 R[t] = bits(32) UNKNOWN; 7356 #endif 7357 7358 bool success = false; 7359 7360 if (ConditionPassed(opcode)) { 7361 uint32_t t; 7362 uint32_t n; 7363 uint32_t m; 7364 bool index; 7365 bool add; 7366 bool wback; 7367 ARM_ShifterType shift_t; 7368 uint32_t shift_n; 7369 7370 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7371 switch (encoding) { 7372 case eEncodingT1: 7373 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 7374 // in ThumbEE"; 7375 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7376 t = Bits32(opcode, 2, 0); 7377 n = Bits32(opcode, 5, 3); 7378 m = Bits32(opcode, 8, 6); 7379 7380 // index = TRUE; add = TRUE; wback = FALSE; 7381 index = true; 7382 add = true; 7383 wback = false; 7384 7385 // (shift_t, shift_n) = (SRType_LSL, 0); 7386 shift_t = SRType_LSL; 7387 shift_n = 0; 7388 7389 break; 7390 7391 case eEncodingT2: 7392 // if Rn == '1111' then SEE LDRH (literal); 7393 // if Rt == '1111' then SEE "Unallocated memory hints"; 7394 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7395 t = Bits32(opcode, 15, 12); 7396 n = Bits32(opcode, 19, 16); 7397 m = Bits32(opcode, 3, 0); 7398 7399 // index = TRUE; add = TRUE; wback = FALSE; 7400 index = true; 7401 add = true; 7402 wback = false; 7403 7404 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7405 shift_t = SRType_LSL; 7406 shift_n = Bits32(opcode, 5, 4); 7407 7408 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7409 if ((t == 13) || BadReg(m)) 7410 return false; 7411 break; 7412 7413 case eEncodingA1: 7414 // if P == '0' && W == '1' then SEE LDRHT; 7415 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7416 t = Bits32(opcode, 15, 12); 7417 n = Bits32(opcode, 19, 16); 7418 m = Bits32(opcode, 3, 0); 7419 7420 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7421 // (W == '1'); 7422 index = BitIsSet(opcode, 24); 7423 add = BitIsSet(opcode, 23); 7424 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7425 7426 // (shift_t, shift_n) = (SRType_LSL, 0); 7427 shift_t = SRType_LSL; 7428 shift_n = 0; 7429 7430 // if t == 15 || m == 15 then UNPREDICTABLE; 7431 if ((t == 15) || (m == 15)) 7432 return false; 7433 7434 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7435 if (wback && ((n == 15) || (n == t))) 7436 return false; 7437 7438 break; 7439 7440 default: 7441 return false; 7442 } 7443 7444 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7445 7446 uint64_t Rm = 7447 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7448 if (!success) 7449 return false; 7450 7451 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7452 if (!success) 7453 return false; 7454 7455 addr_t offset_addr; 7456 addr_t address; 7457 7458 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7459 uint64_t Rn = 7460 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7461 if (!success) 7462 return false; 7463 7464 if (add) 7465 offset_addr = Rn + offset; 7466 else 7467 offset_addr = Rn - offset; 7468 7469 // address = if index then offset_addr else R[n]; 7470 if (index) 7471 address = offset_addr; 7472 else 7473 address = Rn; 7474 7475 // data = MemU[address,2]; 7476 RegisterInfo base_reg; 7477 RegisterInfo offset_reg; 7478 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7479 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7480 7481 EmulateInstruction::Context context; 7482 context.type = eContextRegisterLoad; 7483 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7484 uint64_t data = MemURead(context, address, 2, 0, &success); 7485 if (!success) 7486 return false; 7487 7488 // if wback then R[n] = offset_addr; 7489 if (wback) { 7490 context.type = eContextAdjustBaseRegister; 7491 context.SetAddress(offset_addr); 7492 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7493 offset_addr)) 7494 return false; 7495 } 7496 7497 // if UnalignedSupport() || address<0> = '0' then 7498 if (UnalignedSupport() || BitIsClear(address, 0)) { 7499 // R[t] = ZeroExtend(data, 32); 7500 context.type = eContextRegisterLoad; 7501 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7502 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7503 data)) 7504 return false; 7505 } else // Can only apply before ARMv7 7506 { 7507 // R[t] = bits(32) UNKNOWN; 7508 WriteBits32Unknown(t); 7509 } 7510 } 7511 return true; 7512 } 7513 7514 // LDRSB (immediate) calculates an address from a base register value and an 7515 // immediate offset, loads a byte from 7516 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7517 // It can use offset, post-indexed, or pre-indexed addressing. 7518 bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode, 7519 const ARMEncoding encoding) { 7520 #if 0 7521 if ConditionPassed() then 7522 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7523 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7524 address = if index then offset_addr else R[n]; 7525 R[t] = SignExtend(MemU[address,1], 32); 7526 if wback then R[n] = offset_addr; 7527 #endif 7528 7529 bool success = false; 7530 7531 if (ConditionPassed(opcode)) { 7532 uint32_t t; 7533 uint32_t n; 7534 uint32_t imm32; 7535 bool index; 7536 bool add; 7537 bool wback; 7538 7539 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7540 switch (encoding) { 7541 case eEncodingT1: 7542 // if Rt == '1111' then SEE PLI; 7543 // if Rn == '1111' then SEE LDRSB (literal); 7544 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7545 t = Bits32(opcode, 15, 12); 7546 n = Bits32(opcode, 19, 16); 7547 imm32 = Bits32(opcode, 11, 0); 7548 7549 // index = TRUE; add = TRUE; wback = FALSE; 7550 index = true; 7551 add = true; 7552 wback = false; 7553 7554 // if t == 13 then UNPREDICTABLE; 7555 if (t == 13) 7556 return false; 7557 7558 break; 7559 7560 case eEncodingT2: 7561 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7562 // if Rn == '1111' then SEE LDRSB (literal); 7563 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7564 // if P == '0' && W == '0' then UNDEFINED; 7565 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7566 return false; 7567 7568 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7569 t = Bits32(opcode, 15, 12); 7570 n = Bits32(opcode, 19, 16); 7571 imm32 = Bits32(opcode, 7, 0); 7572 7573 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7574 index = BitIsSet(opcode, 10); 7575 add = BitIsSet(opcode, 9); 7576 wback = BitIsSet(opcode, 8); 7577 7578 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7579 if (((t == 13) || 7580 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) || 7581 BitIsSet(opcode, 8)))) || 7582 (wback && (n == t))) 7583 return false; 7584 7585 break; 7586 7587 case eEncodingA1: { 7588 // if Rn == '1111' then SEE LDRSB (literal); 7589 // if P == '0' && W == '1' then SEE LDRSBT; 7590 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7591 t = Bits32(opcode, 15, 12); 7592 n = Bits32(opcode, 19, 16); 7593 7594 uint32_t imm4H = Bits32(opcode, 11, 8); 7595 uint32_t imm4L = Bits32(opcode, 3, 0); 7596 imm32 = (imm4H << 4) | imm4L; 7597 7598 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7599 // (W == '1'); 7600 index = BitIsSet(opcode, 24); 7601 add = BitIsSet(opcode, 23); 7602 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7603 7604 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7605 if ((t == 15) || (wback && (n == t))) 7606 return false; 7607 7608 break; 7609 } 7610 7611 default: 7612 return false; 7613 } 7614 7615 uint64_t Rn = ReadCoreReg(n, &success); 7616 if (!success) 7617 return false; 7618 7619 addr_t offset_addr; 7620 addr_t address; 7621 7622 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7623 if (add) 7624 offset_addr = Rn + imm32; 7625 else 7626 offset_addr = Rn - imm32; 7627 7628 // address = if index then offset_addr else R[n]; 7629 if (index) 7630 address = offset_addr; 7631 else 7632 address = Rn; 7633 7634 // R[t] = SignExtend(MemU[address,1], 32); 7635 RegisterInfo base_reg; 7636 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7637 7638 EmulateInstruction::Context context; 7639 context.type = eContextRegisterLoad; 7640 context.SetRegisterPlusOffset(base_reg, address - Rn); 7641 7642 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7643 if (!success) 7644 return false; 7645 7646 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7647 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7648 (uint64_t)signed_data)) 7649 return false; 7650 7651 // if wback then R[n] = offset_addr; 7652 if (wback) { 7653 context.type = eContextAdjustBaseRegister; 7654 context.SetAddress(offset_addr); 7655 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7656 offset_addr)) 7657 return false; 7658 } 7659 } 7660 7661 return true; 7662 } 7663 7664 // LDRSB (literal) calculates an address from the PC value and an immediate 7665 // offset, loads a byte from memory, 7666 // sign-extends it to form a 32-bit word, and writes tit to a register. 7667 bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode, 7668 const ARMEncoding encoding) { 7669 #if 0 7670 if ConditionPassed() then 7671 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7672 base = Align(PC,4); 7673 address = if add then (base + imm32) else (base - imm32); 7674 R[t] = SignExtend(MemU[address,1], 32); 7675 #endif 7676 7677 bool success = false; 7678 7679 if (ConditionPassed(opcode)) { 7680 uint32_t t; 7681 uint32_t imm32; 7682 bool add; 7683 7684 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7685 switch (encoding) { 7686 case eEncodingT1: 7687 // if Rt == '1111' then SEE PLI; 7688 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7689 t = Bits32(opcode, 15, 12); 7690 imm32 = Bits32(opcode, 11, 0); 7691 add = BitIsSet(opcode, 23); 7692 7693 // if t == 13 then UNPREDICTABLE; 7694 if (t == 13) 7695 return false; 7696 7697 break; 7698 7699 case eEncodingA1: { 7700 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7701 t = Bits32(opcode, 15, 12); 7702 uint32_t imm4H = Bits32(opcode, 11, 8); 7703 uint32_t imm4L = Bits32(opcode, 3, 0); 7704 imm32 = (imm4H << 4) | imm4L; 7705 add = BitIsSet(opcode, 23); 7706 7707 // if t == 15 then UNPREDICTABLE; 7708 if (t == 15) 7709 return false; 7710 7711 break; 7712 } 7713 7714 default: 7715 return false; 7716 } 7717 7718 // base = Align(PC,4); 7719 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7720 if (!success) 7721 return false; 7722 uint64_t base = AlignPC(pc_value); 7723 7724 // address = if add then (base + imm32) else (base - imm32); 7725 addr_t address; 7726 if (add) 7727 address = base + imm32; 7728 else 7729 address = base - imm32; 7730 7731 // R[t] = SignExtend(MemU[address,1], 32); 7732 RegisterInfo base_reg; 7733 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7734 7735 EmulateInstruction::Context context; 7736 context.type = eContextRegisterLoad; 7737 context.SetRegisterPlusOffset(base_reg, address - base); 7738 7739 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7740 if (!success) 7741 return false; 7742 7743 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7744 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7745 (uint64_t)signed_data)) 7746 return false; 7747 } 7748 return true; 7749 } 7750 7751 // LDRSB (register) calculates an address from a base register value and an 7752 // offset register value, loadsa byte from 7753 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7754 // The offset register value can be shifted left by 0, 1, 2, or 3 bits. 7755 bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode, 7756 const ARMEncoding encoding) { 7757 #if 0 7758 if ConditionPassed() then 7759 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7760 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7761 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7762 address = if index then offset_addr else R[n]; 7763 R[t] = SignExtend(MemU[address,1], 32); 7764 if wback then R[n] = offset_addr; 7765 #endif 7766 7767 bool success = false; 7768 7769 if (ConditionPassed(opcode)) { 7770 uint32_t t; 7771 uint32_t n; 7772 uint32_t m; 7773 bool index; 7774 bool add; 7775 bool wback; 7776 ARM_ShifterType shift_t; 7777 uint32_t shift_n; 7778 7779 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7780 switch (encoding) { 7781 case eEncodingT1: 7782 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7783 t = Bits32(opcode, 2, 0); 7784 n = Bits32(opcode, 5, 3); 7785 m = Bits32(opcode, 8, 6); 7786 7787 // index = TRUE; add = TRUE; wback = FALSE; 7788 index = true; 7789 add = true; 7790 wback = false; 7791 7792 // (shift_t, shift_n) = (SRType_LSL, 0); 7793 shift_t = SRType_LSL; 7794 shift_n = 0; 7795 7796 break; 7797 7798 case eEncodingT2: 7799 // if Rt == '1111' then SEE PLI; 7800 // if Rn == '1111' then SEE LDRSB (literal); 7801 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7802 t = Bits32(opcode, 15, 12); 7803 n = Bits32(opcode, 19, 16); 7804 m = Bits32(opcode, 3, 0); 7805 7806 // index = TRUE; add = TRUE; wback = FALSE; 7807 index = true; 7808 add = true; 7809 wback = false; 7810 7811 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7812 shift_t = SRType_LSL; 7813 shift_n = Bits32(opcode, 5, 4); 7814 7815 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7816 if ((t == 13) || BadReg(m)) 7817 return false; 7818 break; 7819 7820 case eEncodingA1: 7821 // if P == '0' && W == '1' then SEE LDRSBT; 7822 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7823 t = Bits32(opcode, 15, 12); 7824 n = Bits32(opcode, 19, 16); 7825 m = Bits32(opcode, 3, 0); 7826 7827 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7828 // (W == '1'); 7829 index = BitIsSet(opcode, 24); 7830 add = BitIsSet(opcode, 23); 7831 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7832 7833 // (shift_t, shift_n) = (SRType_LSL, 0); 7834 shift_t = SRType_LSL; 7835 shift_n = 0; 7836 7837 // if t == 15 || m == 15 then UNPREDICTABLE; 7838 if ((t == 15) || (m == 15)) 7839 return false; 7840 7841 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7842 if (wback && ((n == 15) || (n == t))) 7843 return false; 7844 break; 7845 7846 default: 7847 return false; 7848 } 7849 7850 uint64_t Rm = 7851 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7852 if (!success) 7853 return false; 7854 7855 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7856 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7857 if (!success) 7858 return false; 7859 7860 addr_t offset_addr; 7861 addr_t address; 7862 7863 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7864 uint64_t Rn = 7865 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7866 if (!success) 7867 return false; 7868 7869 if (add) 7870 offset_addr = Rn + offset; 7871 else 7872 offset_addr = Rn - offset; 7873 7874 // address = if index then offset_addr else R[n]; 7875 if (index) 7876 address = offset_addr; 7877 else 7878 address = Rn; 7879 7880 // R[t] = SignExtend(MemU[address,1], 32); 7881 RegisterInfo base_reg; 7882 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7883 RegisterInfo offset_reg; 7884 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7885 7886 EmulateInstruction::Context context; 7887 context.type = eContextRegisterLoad; 7888 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7889 7890 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7891 if (!success) 7892 return false; 7893 7894 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7895 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7896 (uint64_t)signed_data)) 7897 return false; 7898 7899 // if wback then R[n] = offset_addr; 7900 if (wback) { 7901 context.type = eContextAdjustBaseRegister; 7902 context.SetAddress(offset_addr); 7903 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7904 offset_addr)) 7905 return false; 7906 } 7907 } 7908 return true; 7909 } 7910 7911 // LDRSH (immediate) calculates an address from a base register value and an 7912 // immediate offset, loads a halfword from 7913 // memory, sign-extends it to form a 32-bit word, and writes it to a register. 7914 // It can use offset, post-indexed, or pre-indexed addressing. 7915 bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode, 7916 const ARMEncoding encoding) { 7917 #if 0 7918 if ConditionPassed() then 7919 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7920 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7921 address = if index then offset_addr else R[n]; 7922 data = MemU[address,2]; 7923 if wback then R[n] = offset_addr; 7924 if UnalignedSupport() || address<0> = '0' then 7925 R[t] = SignExtend(data, 32); 7926 else // Can only apply before ARMv7 7927 R[t] = bits(32) UNKNOWN; 7928 #endif 7929 7930 bool success = false; 7931 7932 if (ConditionPassed(opcode)) { 7933 uint32_t t; 7934 uint32_t n; 7935 uint32_t imm32; 7936 bool index; 7937 bool add; 7938 bool wback; 7939 7940 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7941 switch (encoding) { 7942 case eEncodingT1: 7943 // if Rn == '1111' then SEE LDRSH (literal); 7944 // if Rt == '1111' then SEE "Unallocated memory hints"; 7945 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7946 t = Bits32(opcode, 15, 12); 7947 n = Bits32(opcode, 19, 16); 7948 imm32 = Bits32(opcode, 11, 0); 7949 7950 // index = TRUE; add = TRUE; wback = FALSE; 7951 index = true; 7952 add = true; 7953 wback = false; 7954 7955 // if t == 13 then UNPREDICTABLE; 7956 if (t == 13) 7957 return false; 7958 7959 break; 7960 7961 case eEncodingT2: 7962 // if Rn == '1111' then SEE LDRSH (literal); 7963 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7964 // "Unallocated memory hints"; 7965 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7966 // if P == '0' && W == '0' then UNDEFINED; 7967 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7968 return false; 7969 7970 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7971 t = Bits32(opcode, 15, 12); 7972 n = Bits32(opcode, 19, 16); 7973 imm32 = Bits32(opcode, 7, 0); 7974 7975 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7976 index = BitIsSet(opcode, 10); 7977 add = BitIsSet(opcode, 9); 7978 wback = BitIsSet(opcode, 8); 7979 7980 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7981 if (BadReg(t) || (wback && (n == t))) 7982 return false; 7983 7984 break; 7985 7986 case eEncodingA1: { 7987 // if Rn == '1111' then SEE LDRSH (literal); 7988 // if P == '0' && W == '1' then SEE LDRSHT; 7989 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7990 t = Bits32(opcode, 15, 12); 7991 n = Bits32(opcode, 19, 16); 7992 uint32_t imm4H = Bits32(opcode, 11, 8); 7993 uint32_t imm4L = Bits32(opcode, 3, 0); 7994 imm32 = (imm4H << 4) | imm4L; 7995 7996 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7997 // (W == '1'); 7998 index = BitIsSet(opcode, 24); 7999 add = BitIsSet(opcode, 23); 8000 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8001 8002 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 8003 if ((t == 15) || (wback && (n == t))) 8004 return false; 8005 8006 break; 8007 } 8008 8009 default: 8010 return false; 8011 } 8012 8013 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 8014 uint64_t Rn = 8015 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8016 if (!success) 8017 return false; 8018 8019 addr_t offset_addr; 8020 if (add) 8021 offset_addr = Rn + imm32; 8022 else 8023 offset_addr = Rn - imm32; 8024 8025 // address = if index then offset_addr else R[n]; 8026 addr_t address; 8027 if (index) 8028 address = offset_addr; 8029 else 8030 address = Rn; 8031 8032 // data = MemU[address,2]; 8033 RegisterInfo base_reg; 8034 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8035 8036 EmulateInstruction::Context context; 8037 context.type = eContextRegisterLoad; 8038 context.SetRegisterPlusOffset(base_reg, address - Rn); 8039 8040 uint64_t data = MemURead(context, address, 2, 0, &success); 8041 if (!success) 8042 return false; 8043 8044 // if wback then R[n] = offset_addr; 8045 if (wback) { 8046 context.type = eContextAdjustBaseRegister; 8047 context.SetAddress(offset_addr); 8048 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8049 offset_addr)) 8050 return false; 8051 } 8052 8053 // if UnalignedSupport() || address<0> = '0' then 8054 if (UnalignedSupport() || BitIsClear(address, 0)) { 8055 // R[t] = SignExtend(data, 32); 8056 int64_t signed_data = llvm::SignExtend64<16>(data); 8057 context.type = eContextRegisterLoad; 8058 context.SetRegisterPlusOffset(base_reg, address - Rn); 8059 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8060 (uint64_t)signed_data)) 8061 return false; 8062 } else // Can only apply before ARMv7 8063 { 8064 // R[t] = bits(32) UNKNOWN; 8065 WriteBits32Unknown(t); 8066 } 8067 } 8068 return true; 8069 } 8070 8071 // LDRSH (literal) calculates an address from the PC value and an immediate 8072 // offset, loads a halfword from memory, 8073 // sign-extends it to from a 32-bit word, and writes it to a register. 8074 bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode, 8075 const ARMEncoding encoding) { 8076 #if 0 8077 if ConditionPassed() then 8078 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8079 base = Align(PC,4); 8080 address = if add then (base + imm32) else (base - imm32); 8081 data = MemU[address,2]; 8082 if UnalignedSupport() || address<0> = '0' then 8083 R[t] = SignExtend(data, 32); 8084 else // Can only apply before ARMv7 8085 R[t] = bits(32) UNKNOWN; 8086 #endif 8087 8088 bool success = false; 8089 8090 if (ConditionPassed(opcode)) { 8091 uint32_t t; 8092 uint32_t imm32; 8093 bool add; 8094 8095 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8096 switch (encoding) { 8097 case eEncodingT1: 8098 // if Rt == '1111' then SEE "Unallocated memory hints"; 8099 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 8100 t = Bits32(opcode, 15, 12); 8101 imm32 = Bits32(opcode, 11, 0); 8102 add = BitIsSet(opcode, 23); 8103 8104 // if t == 13 then UNPREDICTABLE; 8105 if (t == 13) 8106 return false; 8107 8108 break; 8109 8110 case eEncodingA1: { 8111 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 8112 t = Bits32(opcode, 15, 12); 8113 uint32_t imm4H = Bits32(opcode, 11, 8); 8114 uint32_t imm4L = Bits32(opcode, 3, 0); 8115 imm32 = (imm4H << 4) | imm4L; 8116 add = BitIsSet(opcode, 23); 8117 8118 // if t == 15 then UNPREDICTABLE; 8119 if (t == 15) 8120 return false; 8121 8122 break; 8123 } 8124 default: 8125 return false; 8126 } 8127 8128 // base = Align(PC,4); 8129 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 8130 if (!success) 8131 return false; 8132 8133 uint64_t base = AlignPC(pc_value); 8134 8135 addr_t address; 8136 // address = if add then (base + imm32) else (base - imm32); 8137 if (add) 8138 address = base + imm32; 8139 else 8140 address = base - imm32; 8141 8142 // data = MemU[address,2]; 8143 RegisterInfo base_reg; 8144 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 8145 8146 EmulateInstruction::Context context; 8147 context.type = eContextRegisterLoad; 8148 context.SetRegisterPlusOffset(base_reg, imm32); 8149 8150 uint64_t data = MemURead(context, address, 2, 0, &success); 8151 if (!success) 8152 return false; 8153 8154 // if UnalignedSupport() || address<0> = '0' then 8155 if (UnalignedSupport() || BitIsClear(address, 0)) { 8156 // R[t] = SignExtend(data, 32); 8157 int64_t signed_data = llvm::SignExtend64<16>(data); 8158 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8159 (uint64_t)signed_data)) 8160 return false; 8161 } else // Can only apply before ARMv7 8162 { 8163 // R[t] = bits(32) UNKNOWN; 8164 WriteBits32Unknown(t); 8165 } 8166 } 8167 return true; 8168 } 8169 8170 // LDRSH (register) calculates an address from a base register value and an 8171 // offset register value, loads a halfword 8172 // from memory, sign-extends it to form a 32-bit word, and writes it to a 8173 // register. The offset register value can be shifted left by 0, 1, 2, or 3 8174 // bits. 8175 bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode, 8176 const ARMEncoding encoding) { 8177 #if 0 8178 if ConditionPassed() then 8179 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8180 offset = Shift(R[m], shift_t, shift_n, APSR.C); 8181 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8182 address = if index then offset_addr else R[n]; 8183 data = MemU[address,2]; 8184 if wback then R[n] = offset_addr; 8185 if UnalignedSupport() || address<0> = '0' then 8186 R[t] = SignExtend(data, 32); 8187 else // Can only apply before ARMv7 8188 R[t] = bits(32) UNKNOWN; 8189 #endif 8190 8191 bool success = false; 8192 8193 if (ConditionPassed(opcode)) { 8194 uint32_t t; 8195 uint32_t n; 8196 uint32_t m; 8197 bool index; 8198 bool add; 8199 bool wback; 8200 ARM_ShifterType shift_t; 8201 uint32_t shift_n; 8202 8203 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8204 switch (encoding) { 8205 case eEncodingT1: 8206 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 8207 // in ThumbEE"; 8208 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8209 t = Bits32(opcode, 2, 0); 8210 n = Bits32(opcode, 5, 3); 8211 m = Bits32(opcode, 8, 6); 8212 8213 // index = TRUE; add = TRUE; wback = FALSE; 8214 index = true; 8215 add = true; 8216 wback = false; 8217 8218 // (shift_t, shift_n) = (SRType_LSL, 0); 8219 shift_t = SRType_LSL; 8220 shift_n = 0; 8221 8222 break; 8223 8224 case eEncodingT2: 8225 // if Rn == '1111' then SEE LDRSH (literal); 8226 // if Rt == '1111' then SEE "Unallocated memory hints"; 8227 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8228 t = Bits32(opcode, 15, 12); 8229 n = Bits32(opcode, 19, 16); 8230 m = Bits32(opcode, 3, 0); 8231 8232 // index = TRUE; add = TRUE; wback = FALSE; 8233 index = true; 8234 add = true; 8235 wback = false; 8236 8237 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 8238 shift_t = SRType_LSL; 8239 shift_n = Bits32(opcode, 5, 4); 8240 8241 // if t == 13 || BadReg(m) then UNPREDICTABLE; 8242 if ((t == 13) || BadReg(m)) 8243 return false; 8244 8245 break; 8246 8247 case eEncodingA1: 8248 // if P == '0' && W == '1' then SEE LDRSHT; 8249 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8250 t = Bits32(opcode, 15, 12); 8251 n = Bits32(opcode, 19, 16); 8252 m = Bits32(opcode, 3, 0); 8253 8254 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8255 // (W == '1'); 8256 index = BitIsSet(opcode, 24); 8257 add = BitIsSet(opcode, 23); 8258 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8259 8260 // (shift_t, shift_n) = (SRType_LSL, 0); 8261 shift_t = SRType_LSL; 8262 shift_n = 0; 8263 8264 // if t == 15 || m == 15 then UNPREDICTABLE; 8265 if ((t == 15) || (m == 15)) 8266 return false; 8267 8268 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 8269 if (wback && ((n == 15) || (n == t))) 8270 return false; 8271 8272 break; 8273 8274 default: 8275 return false; 8276 } 8277 8278 uint64_t Rm = 8279 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8280 if (!success) 8281 return false; 8282 8283 uint64_t Rn = 8284 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8285 if (!success) 8286 return false; 8287 8288 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 8289 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 8290 if (!success) 8291 return false; 8292 8293 addr_t offset_addr; 8294 addr_t address; 8295 8296 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8297 if (add) 8298 offset_addr = Rn + offset; 8299 else 8300 offset_addr = Rn - offset; 8301 8302 // address = if index then offset_addr else R[n]; 8303 if (index) 8304 address = offset_addr; 8305 else 8306 address = Rn; 8307 8308 // data = MemU[address,2]; 8309 RegisterInfo base_reg; 8310 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8311 8312 RegisterInfo offset_reg; 8313 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 8314 8315 EmulateInstruction::Context context; 8316 context.type = eContextRegisterLoad; 8317 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8318 8319 uint64_t data = MemURead(context, address, 2, 0, &success); 8320 if (!success) 8321 return false; 8322 8323 // if wback then R[n] = offset_addr; 8324 if (wback) { 8325 context.type = eContextAdjustBaseRegister; 8326 context.SetAddress(offset_addr); 8327 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8328 offset_addr)) 8329 return false; 8330 } 8331 8332 // if UnalignedSupport() || address<0> = '0' then 8333 if (UnalignedSupport() || BitIsClear(address, 0)) { 8334 // R[t] = SignExtend(data, 32); 8335 context.type = eContextRegisterLoad; 8336 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8337 8338 int64_t signed_data = llvm::SignExtend64<16>(data); 8339 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8340 (uint64_t)signed_data)) 8341 return false; 8342 } else // Can only apply before ARMv7 8343 { 8344 // R[t] = bits(32) UNKNOWN; 8345 WriteBits32Unknown(t); 8346 } 8347 } 8348 return true; 8349 } 8350 8351 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and 8352 // writes the result to the destination 8353 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before 8354 // extracting the 8-bit value. 8355 bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode, 8356 const ARMEncoding encoding) { 8357 #if 0 8358 if ConditionPassed() then 8359 EncodingSpecificOperations(); 8360 rotated = ROR(R[m], rotation); 8361 R[d] = SignExtend(rotated<7:0>, 32); 8362 #endif 8363 8364 bool success = false; 8365 8366 if (ConditionPassed(opcode)) { 8367 uint32_t d; 8368 uint32_t m; 8369 uint32_t rotation; 8370 8371 // EncodingSpecificOperations(); 8372 switch (encoding) { 8373 case eEncodingT1: 8374 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8375 d = Bits32(opcode, 2, 0); 8376 m = Bits32(opcode, 5, 3); 8377 rotation = 0; 8378 8379 break; 8380 8381 case eEncodingT2: 8382 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8383 d = Bits32(opcode, 11, 8); 8384 m = Bits32(opcode, 3, 0); 8385 rotation = Bits32(opcode, 5, 4) << 3; 8386 8387 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8388 if (BadReg(d) || BadReg(m)) 8389 return false; 8390 8391 break; 8392 8393 case eEncodingA1: 8394 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8395 d = Bits32(opcode, 15, 12); 8396 m = Bits32(opcode, 3, 0); 8397 rotation = Bits32(opcode, 11, 10) << 3; 8398 8399 // if d == 15 || m == 15 then UNPREDICTABLE; 8400 if ((d == 15) || (m == 15)) 8401 return false; 8402 8403 break; 8404 8405 default: 8406 return false; 8407 } 8408 8409 uint64_t Rm = 8410 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8411 if (!success) 8412 return false; 8413 8414 // rotated = ROR(R[m], rotation); 8415 uint64_t rotated = ROR(Rm, rotation, &success); 8416 if (!success) 8417 return false; 8418 8419 // R[d] = SignExtend(rotated<7:0>, 32); 8420 int64_t data = llvm::SignExtend64<8>(rotated); 8421 8422 RegisterInfo source_reg; 8423 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8424 8425 EmulateInstruction::Context context; 8426 context.type = eContextRegisterLoad; 8427 context.SetRegister(source_reg); 8428 8429 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8430 (uint64_t)data)) 8431 return false; 8432 } 8433 return true; 8434 } 8435 8436 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and 8437 // writes the result to the destination 8438 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8439 // extracting the 16-bit value. 8440 bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode, 8441 const ARMEncoding encoding) { 8442 #if 0 8443 if ConditionPassed() then 8444 EncodingSpecificOperations(); 8445 rotated = ROR(R[m], rotation); 8446 R[d] = SignExtend(rotated<15:0>, 32); 8447 #endif 8448 8449 bool success = false; 8450 8451 if (ConditionPassed(opcode)) { 8452 uint32_t d; 8453 uint32_t m; 8454 uint32_t rotation; 8455 8456 // EncodingSpecificOperations(); 8457 switch (encoding) { 8458 case eEncodingT1: 8459 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8460 d = Bits32(opcode, 2, 0); 8461 m = Bits32(opcode, 5, 3); 8462 rotation = 0; 8463 8464 break; 8465 8466 case eEncodingT2: 8467 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8468 d = Bits32(opcode, 11, 8); 8469 m = Bits32(opcode, 3, 0); 8470 rotation = Bits32(opcode, 5, 4) << 3; 8471 8472 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8473 if (BadReg(d) || BadReg(m)) 8474 return false; 8475 8476 break; 8477 8478 case eEncodingA1: 8479 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8480 d = Bits32(opcode, 15, 12); 8481 m = Bits32(opcode, 3, 0); 8482 rotation = Bits32(opcode, 11, 10) << 3; 8483 8484 // if d == 15 || m == 15 then UNPREDICTABLE; 8485 if ((d == 15) || (m == 15)) 8486 return false; 8487 8488 break; 8489 8490 default: 8491 return false; 8492 } 8493 8494 uint64_t Rm = 8495 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8496 if (!success) 8497 return false; 8498 8499 // rotated = ROR(R[m], rotation); 8500 uint64_t rotated = ROR(Rm, rotation, &success); 8501 if (!success) 8502 return false; 8503 8504 // R[d] = SignExtend(rotated<15:0>, 32); 8505 RegisterInfo source_reg; 8506 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8507 8508 EmulateInstruction::Context context; 8509 context.type = eContextRegisterLoad; 8510 context.SetRegister(source_reg); 8511 8512 int64_t data = llvm::SignExtend64<16>(rotated); 8513 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8514 (uint64_t)data)) 8515 return false; 8516 } 8517 8518 return true; 8519 } 8520 8521 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and 8522 // writes the result to the destination 8523 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8524 // extracting the 8-bit value. 8525 bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode, 8526 const ARMEncoding encoding) { 8527 #if 0 8528 if ConditionPassed() then 8529 EncodingSpecificOperations(); 8530 rotated = ROR(R[m], rotation); 8531 R[d] = ZeroExtend(rotated<7:0>, 32); 8532 #endif 8533 8534 bool success = false; 8535 8536 if (ConditionPassed(opcode)) { 8537 uint32_t d; 8538 uint32_t m; 8539 uint32_t rotation; 8540 8541 // EncodingSpecificOperations(); 8542 switch (encoding) { 8543 case eEncodingT1: 8544 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8545 d = Bits32(opcode, 2, 0); 8546 m = Bits32(opcode, 5, 3); 8547 rotation = 0; 8548 8549 break; 8550 8551 case eEncodingT2: 8552 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8553 d = Bits32(opcode, 11, 8); 8554 m = Bits32(opcode, 3, 0); 8555 rotation = Bits32(opcode, 5, 4) << 3; 8556 8557 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8558 if (BadReg(d) || BadReg(m)) 8559 return false; 8560 8561 break; 8562 8563 case eEncodingA1: 8564 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8565 d = Bits32(opcode, 15, 12); 8566 m = Bits32(opcode, 3, 0); 8567 rotation = Bits32(opcode, 11, 10) << 3; 8568 8569 // if d == 15 || m == 15 then UNPREDICTABLE; 8570 if ((d == 15) || (m == 15)) 8571 return false; 8572 8573 break; 8574 8575 default: 8576 return false; 8577 } 8578 8579 uint64_t Rm = 8580 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8581 if (!success) 8582 return false; 8583 8584 // rotated = ROR(R[m], rotation); 8585 uint64_t rotated = ROR(Rm, rotation, &success); 8586 if (!success) 8587 return false; 8588 8589 // R[d] = ZeroExtend(rotated<7:0>, 32); 8590 RegisterInfo source_reg; 8591 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8592 8593 EmulateInstruction::Context context; 8594 context.type = eContextRegisterLoad; 8595 context.SetRegister(source_reg); 8596 8597 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8598 Bits32(rotated, 7, 0))) 8599 return false; 8600 } 8601 return true; 8602 } 8603 8604 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and 8605 // writes the result to the destination 8606 // register. You can specify a rotation by 0, 8, 16, or 24 bits before 8607 // extracting the 16-bit value. 8608 bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode, 8609 const ARMEncoding encoding) { 8610 #if 0 8611 if ConditionPassed() then 8612 EncodingSpecificOperations(); 8613 rotated = ROR(R[m], rotation); 8614 R[d] = ZeroExtend(rotated<15:0>, 32); 8615 #endif 8616 8617 bool success = false; 8618 8619 if (ConditionPassed(opcode)) { 8620 uint32_t d; 8621 uint32_t m; 8622 uint32_t rotation; 8623 8624 switch (encoding) { 8625 case eEncodingT1: 8626 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8627 d = Bits32(opcode, 2, 0); 8628 m = Bits32(opcode, 5, 3); 8629 rotation = 0; 8630 8631 break; 8632 8633 case eEncodingT2: 8634 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8635 d = Bits32(opcode, 11, 8); 8636 m = Bits32(opcode, 3, 0); 8637 rotation = Bits32(opcode, 5, 4) << 3; 8638 8639 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8640 if (BadReg(d) || BadReg(m)) 8641 return false; 8642 8643 break; 8644 8645 case eEncodingA1: 8646 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8647 d = Bits32(opcode, 15, 12); 8648 m = Bits32(opcode, 3, 0); 8649 rotation = Bits32(opcode, 11, 10) << 3; 8650 8651 // if d == 15 || m == 15 then UNPREDICTABLE; 8652 if ((d == 15) || (m == 15)) 8653 return false; 8654 8655 break; 8656 8657 default: 8658 return false; 8659 } 8660 8661 uint64_t Rm = 8662 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8663 if (!success) 8664 return false; 8665 8666 // rotated = ROR(R[m], rotation); 8667 uint64_t rotated = ROR(Rm, rotation, &success); 8668 if (!success) 8669 return false; 8670 8671 // R[d] = ZeroExtend(rotated<15:0>, 32); 8672 RegisterInfo source_reg; 8673 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8674 8675 EmulateInstruction::Context context; 8676 context.type = eContextRegisterLoad; 8677 context.SetRegister(source_reg); 8678 8679 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8680 Bits32(rotated, 15, 0))) 8681 return false; 8682 } 8683 return true; 8684 } 8685 8686 // RFE (Return From Exception) loads the PC and the CPSR from the word at the 8687 // specified address and the following 8688 // word respectively. 8689 bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode, 8690 const ARMEncoding encoding) { 8691 #if 0 8692 if ConditionPassed() then 8693 EncodingSpecificOperations(); 8694 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8695 UNPREDICTABLE; 8696 else 8697 address = if increment then R[n] else R[n]-8; 8698 if wordhigher then address = address+4; 8699 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8700 BranchWritePC(MemA[address,4]); 8701 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8702 #endif 8703 8704 bool success = false; 8705 8706 if (ConditionPassed(opcode)) { 8707 uint32_t n; 8708 bool wback; 8709 bool increment; 8710 bool wordhigher; 8711 8712 // EncodingSpecificOperations(); 8713 switch (encoding) { 8714 case eEncodingT1: 8715 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = 8716 // FALSE; 8717 n = Bits32(opcode, 19, 16); 8718 wback = BitIsSet(opcode, 21); 8719 increment = false; 8720 wordhigher = false; 8721 8722 // if n == 15 then UNPREDICTABLE; 8723 if (n == 15) 8724 return false; 8725 8726 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8727 if (InITBlock() && !LastInITBlock()) 8728 return false; 8729 8730 break; 8731 8732 case eEncodingT2: 8733 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8734 n = Bits32(opcode, 19, 16); 8735 wback = BitIsSet(opcode, 21); 8736 increment = true; 8737 wordhigher = false; 8738 8739 // if n == 15 then UNPREDICTABLE; 8740 if (n == 15) 8741 return false; 8742 8743 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8744 if (InITBlock() && !LastInITBlock()) 8745 return false; 8746 8747 break; 8748 8749 case eEncodingA1: 8750 // n = UInt(Rn); 8751 n = Bits32(opcode, 19, 16); 8752 8753 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8754 wback = BitIsSet(opcode, 21); 8755 increment = BitIsSet(opcode, 23); 8756 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23)); 8757 8758 // if n == 15 then UNPREDICTABLE; 8759 if (n == 15) 8760 return false; 8761 8762 break; 8763 8764 default: 8765 return false; 8766 } 8767 8768 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE 8769 // then 8770 if (!CurrentModeIsPrivileged()) 8771 // UNPREDICTABLE; 8772 return false; 8773 else { 8774 uint64_t Rn = 8775 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8776 if (!success) 8777 return false; 8778 8779 addr_t address; 8780 // address = if increment then R[n] else R[n]-8; 8781 if (increment) 8782 address = Rn; 8783 else 8784 address = Rn - 8; 8785 8786 // if wordhigher then address = address+4; 8787 if (wordhigher) 8788 address = address + 4; 8789 8790 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8791 RegisterInfo base_reg; 8792 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8793 8794 EmulateInstruction::Context context; 8795 context.type = eContextReturnFromException; 8796 context.SetRegisterPlusOffset(base_reg, address - Rn); 8797 8798 uint64_t data = MemARead(context, address + 4, 4, 0, &success); 8799 if (!success) 8800 return false; 8801 8802 CPSRWriteByInstr(data, 15, true); 8803 8804 // BranchWritePC(MemA[address,4]); 8805 uint64_t data2 = MemARead(context, address, 4, 0, &success); 8806 if (!success) 8807 return false; 8808 8809 BranchWritePC(context, data2); 8810 8811 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8812 if (wback) { 8813 context.type = eContextAdjustBaseRegister; 8814 if (increment) { 8815 context.SetOffset(8); 8816 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8817 Rn + 8)) 8818 return false; 8819 } else { 8820 context.SetOffset(-8); 8821 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8822 Rn - 8)) 8823 return false; 8824 } 8825 } // if wback 8826 } 8827 } // if ConditionPassed() 8828 return true; 8829 } 8830 8831 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a 8832 // register value and an immediate value, and writes the result to the 8833 // destination register. It can optionally update the condition flags based on 8834 // the result. 8835 bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode, 8836 const ARMEncoding encoding) { 8837 #if 0 8838 // ARM pseudo code... 8839 if ConditionPassed() then 8840 EncodingSpecificOperations(); 8841 result = R[n] EOR imm32; 8842 if d == 15 then // Can only occur for ARM encoding 8843 ALUWritePC(result); // setflags is always FALSE here 8844 else 8845 R[d] = result; 8846 if setflags then 8847 APSR.N = result<31>; 8848 APSR.Z = IsZeroBit(result); 8849 APSR.C = carry; 8850 // APSR.V unchanged 8851 #endif 8852 8853 bool success = false; 8854 8855 if (ConditionPassed(opcode)) { 8856 uint32_t Rd, Rn; 8857 uint32_t 8858 imm32; // the immediate value to be ORed to the value obtained from Rn 8859 bool setflags; 8860 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8861 switch (encoding) { 8862 case eEncodingT1: 8863 Rd = Bits32(opcode, 11, 8); 8864 Rn = Bits32(opcode, 19, 16); 8865 setflags = BitIsSet(opcode, 20); 8866 imm32 = ThumbExpandImm_C( 8867 opcode, APSR_C, 8868 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8869 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8870 if (Rd == 15 && setflags) 8871 return EmulateTEQImm(opcode, eEncodingT1); 8872 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8873 return false; 8874 break; 8875 case eEncodingA1: 8876 Rd = Bits32(opcode, 15, 12); 8877 Rn = Bits32(opcode, 19, 16); 8878 setflags = BitIsSet(opcode, 20); 8879 imm32 = 8880 ARMExpandImm_C(opcode, APSR_C, 8881 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8882 8883 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8884 // instructions; 8885 if (Rd == 15 && setflags) 8886 return EmulateSUBSPcLrEtc(opcode, encoding); 8887 break; 8888 default: 8889 return false; 8890 } 8891 8892 // Read the first operand. 8893 uint32_t val1 = ReadCoreReg(Rn, &success); 8894 if (!success) 8895 return false; 8896 8897 uint32_t result = val1 ^ imm32; 8898 8899 EmulateInstruction::Context context; 8900 context.type = EmulateInstruction::eContextImmediate; 8901 context.SetNoArgs(); 8902 8903 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8904 return false; 8905 } 8906 return true; 8907 } 8908 8909 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a 8910 // register value and an optionally-shifted register value, and writes the 8911 // result to the destination register. It can optionally update the condition 8912 // flags based on the result. 8913 bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode, 8914 const ARMEncoding encoding) { 8915 #if 0 8916 // ARM pseudo code... 8917 if ConditionPassed() then 8918 EncodingSpecificOperations(); 8919 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8920 result = R[n] EOR shifted; 8921 if d == 15 then // Can only occur for ARM encoding 8922 ALUWritePC(result); // setflags is always FALSE here 8923 else 8924 R[d] = result; 8925 if setflags then 8926 APSR.N = result<31>; 8927 APSR.Z = IsZeroBit(result); 8928 APSR.C = carry; 8929 // APSR.V unchanged 8930 #endif 8931 8932 bool success = false; 8933 8934 if (ConditionPassed(opcode)) { 8935 uint32_t Rd, Rn, Rm; 8936 ARM_ShifterType shift_t; 8937 uint32_t shift_n; // the shift applied to the value read from Rm 8938 bool setflags; 8939 uint32_t carry; 8940 switch (encoding) { 8941 case eEncodingT1: 8942 Rd = Rn = Bits32(opcode, 2, 0); 8943 Rm = Bits32(opcode, 5, 3); 8944 setflags = !InITBlock(); 8945 shift_t = SRType_LSL; 8946 shift_n = 0; 8947 break; 8948 case eEncodingT2: 8949 Rd = Bits32(opcode, 11, 8); 8950 Rn = Bits32(opcode, 19, 16); 8951 Rm = Bits32(opcode, 3, 0); 8952 setflags = BitIsSet(opcode, 20); 8953 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8954 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8955 if (Rd == 15 && setflags) 8956 return EmulateTEQReg(opcode, eEncodingT1); 8957 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8958 return false; 8959 break; 8960 case eEncodingA1: 8961 Rd = Bits32(opcode, 15, 12); 8962 Rn = Bits32(opcode, 19, 16); 8963 Rm = Bits32(opcode, 3, 0); 8964 setflags = BitIsSet(opcode, 20); 8965 shift_n = DecodeImmShiftARM(opcode, shift_t); 8966 8967 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8968 // instructions; 8969 if (Rd == 15 && setflags) 8970 return EmulateSUBSPcLrEtc(opcode, encoding); 8971 break; 8972 default: 8973 return false; 8974 } 8975 8976 // Read the first operand. 8977 uint32_t val1 = ReadCoreReg(Rn, &success); 8978 if (!success) 8979 return false; 8980 8981 // Read the second operand. 8982 uint32_t val2 = ReadCoreReg(Rm, &success); 8983 if (!success) 8984 return false; 8985 8986 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8987 if (!success) 8988 return false; 8989 uint32_t result = val1 ^ shifted; 8990 8991 EmulateInstruction::Context context; 8992 context.type = EmulateInstruction::eContextImmediate; 8993 context.SetNoArgs(); 8994 8995 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8996 return false; 8997 } 8998 return true; 8999 } 9000 9001 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value 9002 // and an immediate value, and writes the result to the destination register. 9003 // It can optionally update the condition flags based on the result. 9004 bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode, 9005 const ARMEncoding encoding) { 9006 #if 0 9007 // ARM pseudo code... 9008 if ConditionPassed() then 9009 EncodingSpecificOperations(); 9010 result = R[n] OR imm32; 9011 if d == 15 then // Can only occur for ARM encoding 9012 ALUWritePC(result); // setflags is always FALSE here 9013 else 9014 R[d] = result; 9015 if setflags then 9016 APSR.N = result<31>; 9017 APSR.Z = IsZeroBit(result); 9018 APSR.C = carry; 9019 // APSR.V unchanged 9020 #endif 9021 9022 bool success = false; 9023 9024 if (ConditionPassed(opcode)) { 9025 uint32_t Rd, Rn; 9026 uint32_t 9027 imm32; // the immediate value to be ORed to the value obtained from Rn 9028 bool setflags; 9029 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9030 switch (encoding) { 9031 case eEncodingT1: 9032 Rd = Bits32(opcode, 11, 8); 9033 Rn = Bits32(opcode, 19, 16); 9034 setflags = BitIsSet(opcode, 20); 9035 imm32 = ThumbExpandImm_C( 9036 opcode, APSR_C, 9037 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9038 // if Rn == '1111' then SEE MOV (immediate); 9039 if (Rn == 15) 9040 return EmulateMOVRdImm(opcode, eEncodingT2); 9041 if (BadReg(Rd) || Rn == 13) 9042 return false; 9043 break; 9044 case eEncodingA1: 9045 Rd = Bits32(opcode, 15, 12); 9046 Rn = Bits32(opcode, 19, 16); 9047 setflags = BitIsSet(opcode, 20); 9048 imm32 = 9049 ARMExpandImm_C(opcode, APSR_C, 9050 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9051 9052 if (Rd == 15 && setflags) 9053 return EmulateSUBSPcLrEtc(opcode, encoding); 9054 break; 9055 default: 9056 return false; 9057 } 9058 9059 // Read the first operand. 9060 uint32_t val1 = ReadCoreReg(Rn, &success); 9061 if (!success) 9062 return false; 9063 9064 uint32_t result = val1 | imm32; 9065 9066 EmulateInstruction::Context context; 9067 context.type = EmulateInstruction::eContextImmediate; 9068 context.SetNoArgs(); 9069 9070 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9071 return false; 9072 } 9073 return true; 9074 } 9075 9076 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value 9077 // and an optionally-shifted register value, and writes the result to the 9078 // destination register. It can optionally update the condition flags based on 9079 // the result. 9080 bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode, 9081 const ARMEncoding encoding) { 9082 #if 0 9083 // ARM pseudo code... 9084 if ConditionPassed() then 9085 EncodingSpecificOperations(); 9086 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9087 result = R[n] OR shifted; 9088 if d == 15 then // Can only occur for ARM encoding 9089 ALUWritePC(result); // setflags is always FALSE here 9090 else 9091 R[d] = result; 9092 if setflags then 9093 APSR.N = result<31>; 9094 APSR.Z = IsZeroBit(result); 9095 APSR.C = carry; 9096 // APSR.V unchanged 9097 #endif 9098 9099 bool success = false; 9100 9101 if (ConditionPassed(opcode)) { 9102 uint32_t Rd, Rn, Rm; 9103 ARM_ShifterType shift_t; 9104 uint32_t shift_n; // the shift applied to the value read from Rm 9105 bool setflags; 9106 uint32_t carry; 9107 switch (encoding) { 9108 case eEncodingT1: 9109 Rd = Rn = Bits32(opcode, 2, 0); 9110 Rm = Bits32(opcode, 5, 3); 9111 setflags = !InITBlock(); 9112 shift_t = SRType_LSL; 9113 shift_n = 0; 9114 break; 9115 case eEncodingT2: 9116 Rd = Bits32(opcode, 11, 8); 9117 Rn = Bits32(opcode, 19, 16); 9118 Rm = Bits32(opcode, 3, 0); 9119 setflags = BitIsSet(opcode, 20); 9120 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9121 // if Rn == '1111' then SEE MOV (register); 9122 if (Rn == 15) 9123 return EmulateMOVRdRm(opcode, eEncodingT3); 9124 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 9125 return false; 9126 break; 9127 case eEncodingA1: 9128 Rd = Bits32(opcode, 15, 12); 9129 Rn = Bits32(opcode, 19, 16); 9130 Rm = Bits32(opcode, 3, 0); 9131 setflags = BitIsSet(opcode, 20); 9132 shift_n = DecodeImmShiftARM(opcode, shift_t); 9133 9134 if (Rd == 15 && setflags) 9135 return EmulateSUBSPcLrEtc(opcode, encoding); 9136 break; 9137 default: 9138 return false; 9139 } 9140 9141 // Read the first operand. 9142 uint32_t val1 = ReadCoreReg(Rn, &success); 9143 if (!success) 9144 return false; 9145 9146 // Read the second operand. 9147 uint32_t val2 = ReadCoreReg(Rm, &success); 9148 if (!success) 9149 return false; 9150 9151 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9152 if (!success) 9153 return false; 9154 uint32_t result = val1 | shifted; 9155 9156 EmulateInstruction::Context context; 9157 context.type = EmulateInstruction::eContextImmediate; 9158 context.SetNoArgs(); 9159 9160 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9161 return false; 9162 } 9163 return true; 9164 } 9165 9166 // Reverse Subtract (immediate) subtracts a register value from an immediate 9167 // value, and writes the result to the destination register. It can optionally 9168 // update the condition flags based on the result. 9169 bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode, 9170 const ARMEncoding encoding) { 9171 #if 0 9172 // ARM pseudo code... 9173 if ConditionPassed() then 9174 EncodingSpecificOperations(); 9175 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 9176 if d == 15 then // Can only occur for ARM encoding 9177 ALUWritePC(result); // setflags is always FALSE here 9178 else 9179 R[d] = result; 9180 if setflags then 9181 APSR.N = result<31>; 9182 APSR.Z = IsZeroBit(result); 9183 APSR.C = carry; 9184 APSR.V = overflow; 9185 #endif 9186 9187 bool success = false; 9188 9189 uint32_t Rd; // the destination register 9190 uint32_t Rn; // the first operand 9191 bool setflags; 9192 uint32_t 9193 imm32; // the immediate value to be added to the value obtained from Rn 9194 switch (encoding) { 9195 case eEncodingT1: 9196 Rd = Bits32(opcode, 2, 0); 9197 Rn = Bits32(opcode, 5, 3); 9198 setflags = !InITBlock(); 9199 imm32 = 0; 9200 break; 9201 case eEncodingT2: 9202 Rd = Bits32(opcode, 11, 8); 9203 Rn = Bits32(opcode, 19, 16); 9204 setflags = BitIsSet(opcode, 20); 9205 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9206 if (BadReg(Rd) || BadReg(Rn)) 9207 return false; 9208 break; 9209 case eEncodingA1: 9210 Rd = Bits32(opcode, 15, 12); 9211 Rn = Bits32(opcode, 19, 16); 9212 setflags = BitIsSet(opcode, 20); 9213 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9214 9215 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9216 // instructions; 9217 if (Rd == 15 && setflags) 9218 return EmulateSUBSPcLrEtc(opcode, encoding); 9219 break; 9220 default: 9221 return false; 9222 } 9223 // Read the register value from the operand register Rn. 9224 uint32_t reg_val = ReadCoreReg(Rn, &success); 9225 if (!success) 9226 return false; 9227 9228 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 9229 9230 EmulateInstruction::Context context; 9231 context.type = EmulateInstruction::eContextImmediate; 9232 context.SetNoArgs(); 9233 9234 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9235 res.carry_out, res.overflow); 9236 } 9237 9238 // Reverse Subtract (register) subtracts a register value from an optionally- 9239 // shifted register value, and writes the result to the destination register. 9240 // It can optionally update the condition flags based on the result. 9241 bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode, 9242 const ARMEncoding encoding) { 9243 #if 0 9244 // ARM pseudo code... 9245 if ConditionPassed() then 9246 EncodingSpecificOperations(); 9247 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9248 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 9249 if d == 15 then // Can only occur for ARM encoding 9250 ALUWritePC(result); // setflags is always FALSE here 9251 else 9252 R[d] = result; 9253 if setflags then 9254 APSR.N = result<31>; 9255 APSR.Z = IsZeroBit(result); 9256 APSR.C = carry; 9257 APSR.V = overflow; 9258 #endif 9259 9260 bool success = false; 9261 9262 uint32_t Rd; // the destination register 9263 uint32_t Rn; // the first operand 9264 uint32_t Rm; // the second operand 9265 bool setflags; 9266 ARM_ShifterType shift_t; 9267 uint32_t shift_n; // the shift applied to the value read from Rm 9268 switch (encoding) { 9269 case eEncodingT1: 9270 Rd = Bits32(opcode, 11, 8); 9271 Rn = Bits32(opcode, 19, 16); 9272 Rm = Bits32(opcode, 3, 0); 9273 setflags = BitIsSet(opcode, 20); 9274 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9275 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 9276 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9277 return false; 9278 break; 9279 case eEncodingA1: 9280 Rd = Bits32(opcode, 15, 12); 9281 Rn = Bits32(opcode, 19, 16); 9282 Rm = Bits32(opcode, 3, 0); 9283 setflags = BitIsSet(opcode, 20); 9284 shift_n = DecodeImmShiftARM(opcode, shift_t); 9285 9286 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9287 // instructions; 9288 if (Rd == 15 && setflags) 9289 return EmulateSUBSPcLrEtc(opcode, encoding); 9290 break; 9291 default: 9292 return false; 9293 } 9294 // Read the register value from register Rn. 9295 uint32_t val1 = ReadCoreReg(Rn, &success); 9296 if (!success) 9297 return false; 9298 9299 // Read the register value from register Rm. 9300 uint32_t val2 = ReadCoreReg(Rm, &success); 9301 if (!success) 9302 return false; 9303 9304 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9305 if (!success) 9306 return false; 9307 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 9308 9309 EmulateInstruction::Context context; 9310 context.type = EmulateInstruction::eContextImmediate; 9311 context.SetNoArgs(); 9312 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9313 res.carry_out, res.overflow); 9314 } 9315 9316 // Reverse Subtract with Carry (immediate) subtracts a register value and the 9317 // value of NOT (Carry flag) from an immediate value, and writes the result to 9318 // the destination register. It can optionally update the condition flags based 9319 // on the result. 9320 bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode, 9321 const ARMEncoding encoding) { 9322 #if 0 9323 // ARM pseudo code... 9324 if ConditionPassed() then 9325 EncodingSpecificOperations(); 9326 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 9327 if d == 15 then 9328 ALUWritePC(result); // setflags is always FALSE here 9329 else 9330 R[d] = result; 9331 if setflags then 9332 APSR.N = result<31>; 9333 APSR.Z = IsZeroBit(result); 9334 APSR.C = carry; 9335 APSR.V = overflow; 9336 #endif 9337 9338 bool success = false; 9339 9340 uint32_t Rd; // the destination register 9341 uint32_t Rn; // the first operand 9342 bool setflags; 9343 uint32_t 9344 imm32; // the immediate value to be added to the value obtained from Rn 9345 switch (encoding) { 9346 case eEncodingA1: 9347 Rd = Bits32(opcode, 15, 12); 9348 Rn = Bits32(opcode, 19, 16); 9349 setflags = BitIsSet(opcode, 20); 9350 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9351 9352 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9353 // instructions; 9354 if (Rd == 15 && setflags) 9355 return EmulateSUBSPcLrEtc(opcode, encoding); 9356 break; 9357 default: 9358 return false; 9359 } 9360 // Read the register value from the operand register Rn. 9361 uint32_t reg_val = ReadCoreReg(Rn, &success); 9362 if (!success) 9363 return false; 9364 9365 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 9366 9367 EmulateInstruction::Context context; 9368 context.type = EmulateInstruction::eContextImmediate; 9369 context.SetNoArgs(); 9370 9371 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9372 res.carry_out, res.overflow); 9373 } 9374 9375 // Reverse Subtract with Carry (register) subtracts a register value and the 9376 // value of NOT (Carry flag) from an optionally-shifted register value, and 9377 // writes the result to the destination register. It can optionally update the 9378 // condition flags based on the result. 9379 bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode, 9380 const ARMEncoding encoding) { 9381 #if 0 9382 // ARM pseudo code... 9383 if ConditionPassed() then 9384 EncodingSpecificOperations(); 9385 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9386 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 9387 if d == 15 then 9388 ALUWritePC(result); // setflags is always FALSE here 9389 else 9390 R[d] = result; 9391 if setflags then 9392 APSR.N = result<31>; 9393 APSR.Z = IsZeroBit(result); 9394 APSR.C = carry; 9395 APSR.V = overflow; 9396 #endif 9397 9398 bool success = false; 9399 9400 uint32_t Rd; // the destination register 9401 uint32_t Rn; // the first operand 9402 uint32_t Rm; // the second operand 9403 bool setflags; 9404 ARM_ShifterType shift_t; 9405 uint32_t shift_n; // the shift applied to the value read from Rm 9406 switch (encoding) { 9407 case eEncodingA1: 9408 Rd = Bits32(opcode, 15, 12); 9409 Rn = Bits32(opcode, 19, 16); 9410 Rm = Bits32(opcode, 3, 0); 9411 setflags = BitIsSet(opcode, 20); 9412 shift_n = DecodeImmShiftARM(opcode, shift_t); 9413 9414 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9415 // instructions; 9416 if (Rd == 15 && setflags) 9417 return EmulateSUBSPcLrEtc(opcode, encoding); 9418 break; 9419 default: 9420 return false; 9421 } 9422 // Read the register value from register Rn. 9423 uint32_t val1 = ReadCoreReg(Rn, &success); 9424 if (!success) 9425 return false; 9426 9427 // Read the register value from register Rm. 9428 uint32_t val2 = ReadCoreReg(Rm, &success); 9429 if (!success) 9430 return false; 9431 9432 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9433 if (!success) 9434 return false; 9435 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 9436 9437 EmulateInstruction::Context context; 9438 context.type = EmulateInstruction::eContextImmediate; 9439 context.SetNoArgs(); 9440 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9441 res.carry_out, res.overflow); 9442 } 9443 9444 // Subtract with Carry (immediate) subtracts an immediate value and the value 9445 // of 9446 // NOT (Carry flag) from a register value, and writes the result to the 9447 // destination register. 9448 // It can optionally update the condition flags based on the result. 9449 bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode, 9450 const ARMEncoding encoding) { 9451 #if 0 9452 // ARM pseudo code... 9453 if ConditionPassed() then 9454 EncodingSpecificOperations(); 9455 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 9456 if d == 15 then // Can only occur for ARM encoding 9457 ALUWritePC(result); // setflags is always FALSE here 9458 else 9459 R[d] = result; 9460 if setflags then 9461 APSR.N = result<31>; 9462 APSR.Z = IsZeroBit(result); 9463 APSR.C = carry; 9464 APSR.V = overflow; 9465 #endif 9466 9467 bool success = false; 9468 9469 uint32_t Rd; // the destination register 9470 uint32_t Rn; // the first operand 9471 bool setflags; 9472 uint32_t 9473 imm32; // the immediate value to be added to the value obtained from Rn 9474 switch (encoding) { 9475 case eEncodingT1: 9476 Rd = Bits32(opcode, 11, 8); 9477 Rn = Bits32(opcode, 19, 16); 9478 setflags = BitIsSet(opcode, 20); 9479 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9480 if (BadReg(Rd) || BadReg(Rn)) 9481 return false; 9482 break; 9483 case eEncodingA1: 9484 Rd = Bits32(opcode, 15, 12); 9485 Rn = Bits32(opcode, 19, 16); 9486 setflags = BitIsSet(opcode, 20); 9487 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9488 9489 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9490 // instructions; 9491 if (Rd == 15 && setflags) 9492 return EmulateSUBSPcLrEtc(opcode, encoding); 9493 break; 9494 default: 9495 return false; 9496 } 9497 // Read the register value from the operand register Rn. 9498 uint32_t reg_val = ReadCoreReg(Rn, &success); 9499 if (!success) 9500 return false; 9501 9502 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9503 9504 EmulateInstruction::Context context; 9505 context.type = EmulateInstruction::eContextImmediate; 9506 context.SetNoArgs(); 9507 9508 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9509 res.carry_out, res.overflow); 9510 } 9511 9512 // Subtract with Carry (register) subtracts an optionally-shifted register 9513 // value and the value of 9514 // NOT (Carry flag) from a register value, and writes the result to the 9515 // destination register. 9516 // It can optionally update the condition flags based on the result. 9517 bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode, 9518 const ARMEncoding encoding) { 9519 #if 0 9520 // ARM pseudo code... 9521 if ConditionPassed() then 9522 EncodingSpecificOperations(); 9523 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9524 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9525 if d == 15 then // Can only occur for ARM encoding 9526 ALUWritePC(result); // setflags is always FALSE here 9527 else 9528 R[d] = result; 9529 if setflags then 9530 APSR.N = result<31>; 9531 APSR.Z = IsZeroBit(result); 9532 APSR.C = carry; 9533 APSR.V = overflow; 9534 #endif 9535 9536 bool success = false; 9537 9538 uint32_t Rd; // the destination register 9539 uint32_t Rn; // the first operand 9540 uint32_t Rm; // the second operand 9541 bool setflags; 9542 ARM_ShifterType shift_t; 9543 uint32_t shift_n; // the shift applied to the value read from Rm 9544 switch (encoding) { 9545 case eEncodingT1: 9546 Rd = Rn = Bits32(opcode, 2, 0); 9547 Rm = Bits32(opcode, 5, 3); 9548 setflags = !InITBlock(); 9549 shift_t = SRType_LSL; 9550 shift_n = 0; 9551 break; 9552 case eEncodingT2: 9553 Rd = Bits32(opcode, 11, 8); 9554 Rn = Bits32(opcode, 19, 16); 9555 Rm = Bits32(opcode, 3, 0); 9556 setflags = BitIsSet(opcode, 20); 9557 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9558 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9559 return false; 9560 break; 9561 case eEncodingA1: 9562 Rd = Bits32(opcode, 15, 12); 9563 Rn = Bits32(opcode, 19, 16); 9564 Rm = Bits32(opcode, 3, 0); 9565 setflags = BitIsSet(opcode, 20); 9566 shift_n = DecodeImmShiftARM(opcode, shift_t); 9567 9568 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9569 // instructions; 9570 if (Rd == 15 && setflags) 9571 return EmulateSUBSPcLrEtc(opcode, encoding); 9572 break; 9573 default: 9574 return false; 9575 } 9576 // Read the register value from register Rn. 9577 uint32_t val1 = ReadCoreReg(Rn, &success); 9578 if (!success) 9579 return false; 9580 9581 // Read the register value from register Rm. 9582 uint32_t val2 = ReadCoreReg(Rm, &success); 9583 if (!success) 9584 return false; 9585 9586 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9587 if (!success) 9588 return false; 9589 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9590 9591 EmulateInstruction::Context context; 9592 context.type = EmulateInstruction::eContextImmediate; 9593 context.SetNoArgs(); 9594 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9595 res.carry_out, res.overflow); 9596 } 9597 9598 // This instruction subtracts an immediate value from a register value, and 9599 // writes the result to the destination register. It can optionally update the 9600 // condition flags based on the result. 9601 bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode, 9602 const ARMEncoding encoding) { 9603 #if 0 9604 // ARM pseudo code... 9605 if ConditionPassed() then 9606 EncodingSpecificOperations(); 9607 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9608 R[d] = result; 9609 if setflags then 9610 APSR.N = result<31>; 9611 APSR.Z = IsZeroBit(result); 9612 APSR.C = carry; 9613 APSR.V = overflow; 9614 #endif 9615 9616 bool success = false; 9617 9618 uint32_t Rd; // the destination register 9619 uint32_t Rn; // the first operand 9620 bool setflags; 9621 uint32_t imm32; // the immediate value to be subtracted from the value 9622 // obtained from Rn 9623 switch (encoding) { 9624 case eEncodingT1: 9625 Rd = Bits32(opcode, 2, 0); 9626 Rn = Bits32(opcode, 5, 3); 9627 setflags = !InITBlock(); 9628 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9629 break; 9630 case eEncodingT2: 9631 Rd = Rn = Bits32(opcode, 10, 8); 9632 setflags = !InITBlock(); 9633 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9634 break; 9635 case eEncodingT3: 9636 Rd = Bits32(opcode, 11, 8); 9637 Rn = Bits32(opcode, 19, 16); 9638 setflags = BitIsSet(opcode, 20); 9639 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9640 9641 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9642 if (Rd == 15 && setflags) 9643 return EmulateCMPImm(opcode, eEncodingT2); 9644 9645 // if Rn == '1101' then SEE SUB (SP minus immediate); 9646 if (Rn == 13) 9647 return EmulateSUBSPImm(opcode, eEncodingT2); 9648 9649 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9650 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9651 return false; 9652 break; 9653 case eEncodingT4: 9654 Rd = Bits32(opcode, 11, 8); 9655 Rn = Bits32(opcode, 19, 16); 9656 setflags = BitIsSet(opcode, 20); 9657 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9658 9659 // if Rn == '1111' then SEE ADR; 9660 if (Rn == 15) 9661 return EmulateADR(opcode, eEncodingT2); 9662 9663 // if Rn == '1101' then SEE SUB (SP minus immediate); 9664 if (Rn == 13) 9665 return EmulateSUBSPImm(opcode, eEncodingT3); 9666 9667 if (BadReg(Rd)) 9668 return false; 9669 break; 9670 default: 9671 return false; 9672 } 9673 // Read the register value from the operand register Rn. 9674 uint32_t reg_val = ReadCoreReg(Rn, &success); 9675 if (!success) 9676 return false; 9677 9678 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9679 9680 EmulateInstruction::Context context; 9681 context.type = EmulateInstruction::eContextImmediate; 9682 context.SetNoArgs(); 9683 9684 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9685 res.carry_out, res.overflow); 9686 } 9687 9688 // This instruction subtracts an immediate value from a register value, and 9689 // writes the result to the destination register. It can optionally update the 9690 // condition flags based on the result. 9691 bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode, 9692 const ARMEncoding encoding) { 9693 #if 0 9694 // ARM pseudo code... 9695 if ConditionPassed() then 9696 EncodingSpecificOperations(); 9697 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9698 if d == 15 then 9699 ALUWritePC(result); // setflags is always FALSE here 9700 else 9701 R[d] = result; 9702 if setflags then 9703 APSR.N = result<31>; 9704 APSR.Z = IsZeroBit(result); 9705 APSR.C = carry; 9706 APSR.V = overflow; 9707 #endif 9708 9709 bool success = false; 9710 9711 if (ConditionPassed(opcode)) { 9712 uint32_t Rd; // the destination register 9713 uint32_t Rn; // the first operand 9714 bool setflags; 9715 uint32_t imm32; // the immediate value to be subtracted from the value 9716 // obtained from Rn 9717 switch (encoding) { 9718 case eEncodingA1: 9719 Rd = Bits32(opcode, 15, 12); 9720 Rn = Bits32(opcode, 19, 16); 9721 setflags = BitIsSet(opcode, 20); 9722 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9723 9724 // if Rn == '1111' && S == '0' then SEE ADR; 9725 if (Rn == 15 && !setflags) 9726 return EmulateADR(opcode, eEncodingA2); 9727 9728 // if Rn == '1101' then SEE SUB (SP minus immediate); 9729 if (Rn == 13) 9730 return EmulateSUBSPImm(opcode, eEncodingA1); 9731 9732 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9733 // instructions; 9734 if (Rd == 15 && setflags) 9735 return EmulateSUBSPcLrEtc(opcode, encoding); 9736 break; 9737 default: 9738 return false; 9739 } 9740 // Read the register value from the operand register Rn. 9741 uint32_t reg_val = ReadCoreReg(Rn, &success); 9742 if (!success) 9743 return false; 9744 9745 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9746 9747 EmulateInstruction::Context context; 9748 if (Rd == 13) 9749 context.type = EmulateInstruction::eContextAdjustStackPointer; 9750 else 9751 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9752 9753 RegisterInfo dwarf_reg; 9754 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 9755 int64_t imm32_signed = imm32; 9756 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed); 9757 9758 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9759 res.carry_out, res.overflow)) 9760 return false; 9761 } 9762 return true; 9763 } 9764 9765 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a 9766 // register value and an immediate value. It updates the condition flags based 9767 // on the result, and discards the result. 9768 bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode, 9769 const ARMEncoding encoding) { 9770 #if 0 9771 // ARM pseudo code... 9772 if ConditionPassed() then 9773 EncodingSpecificOperations(); 9774 result = R[n] EOR imm32; 9775 APSR.N = result<31>; 9776 APSR.Z = IsZeroBit(result); 9777 APSR.C = carry; 9778 // APSR.V unchanged 9779 #endif 9780 9781 bool success = false; 9782 9783 if (ConditionPassed(opcode)) { 9784 uint32_t Rn; 9785 uint32_t 9786 imm32; // the immediate value to be ANDed to the value obtained from Rn 9787 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9788 switch (encoding) { 9789 case eEncodingT1: 9790 Rn = Bits32(opcode, 19, 16); 9791 imm32 = ThumbExpandImm_C( 9792 opcode, APSR_C, 9793 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9794 if (BadReg(Rn)) 9795 return false; 9796 break; 9797 case eEncodingA1: 9798 Rn = Bits32(opcode, 19, 16); 9799 imm32 = 9800 ARMExpandImm_C(opcode, APSR_C, 9801 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9802 break; 9803 default: 9804 return false; 9805 } 9806 9807 // Read the first operand. 9808 uint32_t val1 = ReadCoreReg(Rn, &success); 9809 if (!success) 9810 return false; 9811 9812 uint32_t result = val1 ^ imm32; 9813 9814 EmulateInstruction::Context context; 9815 context.type = EmulateInstruction::eContextImmediate; 9816 context.SetNoArgs(); 9817 9818 if (!WriteFlags(context, result, carry)) 9819 return false; 9820 } 9821 return true; 9822 } 9823 9824 // Test Equivalence (register) performs a bitwise exclusive OR operation on a 9825 // register value and an optionally-shifted register value. It updates the 9826 // condition flags based on the result, and discards the result. 9827 bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode, 9828 const ARMEncoding encoding) { 9829 #if 0 9830 // ARM pseudo code... 9831 if ConditionPassed() then 9832 EncodingSpecificOperations(); 9833 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9834 result = R[n] EOR shifted; 9835 APSR.N = result<31>; 9836 APSR.Z = IsZeroBit(result); 9837 APSR.C = carry; 9838 // APSR.V unchanged 9839 #endif 9840 9841 bool success = false; 9842 9843 if (ConditionPassed(opcode)) { 9844 uint32_t Rn, Rm; 9845 ARM_ShifterType shift_t; 9846 uint32_t shift_n; // the shift applied to the value read from Rm 9847 uint32_t carry; 9848 switch (encoding) { 9849 case eEncodingT1: 9850 Rn = Bits32(opcode, 19, 16); 9851 Rm = Bits32(opcode, 3, 0); 9852 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9853 if (BadReg(Rn) || BadReg(Rm)) 9854 return false; 9855 break; 9856 case eEncodingA1: 9857 Rn = Bits32(opcode, 19, 16); 9858 Rm = Bits32(opcode, 3, 0); 9859 shift_n = DecodeImmShiftARM(opcode, shift_t); 9860 break; 9861 default: 9862 return false; 9863 } 9864 9865 // Read the first operand. 9866 uint32_t val1 = ReadCoreReg(Rn, &success); 9867 if (!success) 9868 return false; 9869 9870 // Read the second operand. 9871 uint32_t val2 = ReadCoreReg(Rm, &success); 9872 if (!success) 9873 return false; 9874 9875 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9876 if (!success) 9877 return false; 9878 uint32_t result = val1 ^ shifted; 9879 9880 EmulateInstruction::Context context; 9881 context.type = EmulateInstruction::eContextImmediate; 9882 context.SetNoArgs(); 9883 9884 if (!WriteFlags(context, result, carry)) 9885 return false; 9886 } 9887 return true; 9888 } 9889 9890 // Test (immediate) performs a bitwise AND operation on a register value and an 9891 // immediate value. It updates the condition flags based on the result, and 9892 // discards the result. 9893 bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode, 9894 const ARMEncoding encoding) { 9895 #if 0 9896 // ARM pseudo code... 9897 if ConditionPassed() then 9898 EncodingSpecificOperations(); 9899 result = R[n] AND imm32; 9900 APSR.N = result<31>; 9901 APSR.Z = IsZeroBit(result); 9902 APSR.C = carry; 9903 // APSR.V unchanged 9904 #endif 9905 9906 bool success = false; 9907 9908 if (ConditionPassed(opcode)) { 9909 uint32_t Rn; 9910 uint32_t 9911 imm32; // the immediate value to be ANDed to the value obtained from Rn 9912 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9913 switch (encoding) { 9914 case eEncodingT1: 9915 Rn = Bits32(opcode, 19, 16); 9916 imm32 = ThumbExpandImm_C( 9917 opcode, APSR_C, 9918 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9919 if (BadReg(Rn)) 9920 return false; 9921 break; 9922 case eEncodingA1: 9923 Rn = Bits32(opcode, 19, 16); 9924 imm32 = 9925 ARMExpandImm_C(opcode, APSR_C, 9926 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9927 break; 9928 default: 9929 return false; 9930 } 9931 9932 // Read the first operand. 9933 uint32_t val1 = ReadCoreReg(Rn, &success); 9934 if (!success) 9935 return false; 9936 9937 uint32_t result = val1 & imm32; 9938 9939 EmulateInstruction::Context context; 9940 context.type = EmulateInstruction::eContextImmediate; 9941 context.SetNoArgs(); 9942 9943 if (!WriteFlags(context, result, carry)) 9944 return false; 9945 } 9946 return true; 9947 } 9948 9949 // Test (register) performs a bitwise AND operation on a register value and an 9950 // optionally-shifted register value. It updates the condition flags based on 9951 // the result, and discards the result. 9952 bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode, 9953 const ARMEncoding encoding) { 9954 #if 0 9955 // ARM pseudo code... 9956 if ConditionPassed() then 9957 EncodingSpecificOperations(); 9958 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9959 result = R[n] AND shifted; 9960 APSR.N = result<31>; 9961 APSR.Z = IsZeroBit(result); 9962 APSR.C = carry; 9963 // APSR.V unchanged 9964 #endif 9965 9966 bool success = false; 9967 9968 if (ConditionPassed(opcode)) { 9969 uint32_t Rn, Rm; 9970 ARM_ShifterType shift_t; 9971 uint32_t shift_n; // the shift applied to the value read from Rm 9972 uint32_t carry; 9973 switch (encoding) { 9974 case eEncodingT1: 9975 Rn = Bits32(opcode, 2, 0); 9976 Rm = Bits32(opcode, 5, 3); 9977 shift_t = SRType_LSL; 9978 shift_n = 0; 9979 break; 9980 case eEncodingT2: 9981 Rn = Bits32(opcode, 19, 16); 9982 Rm = Bits32(opcode, 3, 0); 9983 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9984 if (BadReg(Rn) || BadReg(Rm)) 9985 return false; 9986 break; 9987 case eEncodingA1: 9988 Rn = Bits32(opcode, 19, 16); 9989 Rm = Bits32(opcode, 3, 0); 9990 shift_n = DecodeImmShiftARM(opcode, shift_t); 9991 break; 9992 default: 9993 return false; 9994 } 9995 9996 // Read the first operand. 9997 uint32_t val1 = ReadCoreReg(Rn, &success); 9998 if (!success) 9999 return false; 10000 10001 // Read the second operand. 10002 uint32_t val2 = ReadCoreReg(Rm, &success); 10003 if (!success) 10004 return false; 10005 10006 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 10007 if (!success) 10008 return false; 10009 uint32_t result = val1 & shifted; 10010 10011 EmulateInstruction::Context context; 10012 context.type = EmulateInstruction::eContextImmediate; 10013 context.SetNoArgs(); 10014 10015 if (!WriteFlags(context, result, carry)) 10016 return false; 10017 } 10018 return true; 10019 } 10020 10021 // A8.6.216 SUB (SP minus register) 10022 bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode, 10023 const ARMEncoding encoding) { 10024 #if 0 10025 if ConditionPassed() then 10026 EncodingSpecificOperations(); 10027 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10028 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10029 if d == 15 then // Can only occur for ARM encoding 10030 ALUWritePC(result); // setflags is always FALSE here 10031 else 10032 R[d] = result; 10033 if setflags then 10034 APSR.N = result<31>; 10035 APSR.Z = IsZeroBit(result); 10036 APSR.C = carry; 10037 APSR.V = overflow; 10038 #endif 10039 10040 bool success = false; 10041 10042 if (ConditionPassed(opcode)) { 10043 uint32_t d; 10044 uint32_t m; 10045 bool setflags; 10046 ARM_ShifterType shift_t; 10047 uint32_t shift_n; 10048 10049 switch (encoding) { 10050 case eEncodingT1: 10051 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10052 d = Bits32(opcode, 11, 8); 10053 m = Bits32(opcode, 3, 0); 10054 setflags = BitIsSet(opcode, 20); 10055 10056 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10057 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10058 10059 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then 10060 // UNPREDICTABLE; 10061 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 10062 return false; 10063 10064 // if d == 15 || BadReg(m) then UNPREDICTABLE; 10065 if ((d == 15) || BadReg(m)) 10066 return false; 10067 break; 10068 10069 case eEncodingA1: 10070 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10071 d = Bits32(opcode, 15, 12); 10072 m = Bits32(opcode, 3, 0); 10073 setflags = BitIsSet(opcode, 20); 10074 10075 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10076 // instructions; 10077 if (d == 15 && setflags) 10078 EmulateSUBSPcLrEtc(opcode, encoding); 10079 10080 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10081 shift_n = DecodeImmShiftARM(opcode, shift_t); 10082 break; 10083 10084 default: 10085 return false; 10086 } 10087 10088 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10089 uint32_t Rm = ReadCoreReg(m, &success); 10090 if (!success) 10091 return false; 10092 10093 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10094 if (!success) 10095 return false; 10096 10097 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10098 uint32_t sp_val = ReadCoreReg(SP_REG, &success); 10099 if (!success) 10100 return false; 10101 10102 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1); 10103 10104 EmulateInstruction::Context context; 10105 context.type = eContextArithmetic; 10106 RegisterInfo sp_reg; 10107 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 10108 RegisterInfo dwarf_reg; 10109 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 10110 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg); 10111 10112 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10113 res.carry_out, res.overflow)) 10114 return false; 10115 } 10116 return true; 10117 } 10118 10119 // A8.6.7 ADD (register-shifted register) 10120 bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode, 10121 const ARMEncoding encoding) { 10122 #if 0 10123 if ConditionPassed() then 10124 EncodingSpecificOperations(); 10125 shift_n = UInt(R[s]<7:0>); 10126 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10127 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10128 R[d] = result; 10129 if setflags then 10130 APSR.N = result<31>; 10131 APSR.Z = IsZeroBit(result); 10132 APSR.C = carry; 10133 APSR.V = overflow; 10134 #endif 10135 10136 bool success = false; 10137 10138 if (ConditionPassed(opcode)) { 10139 uint32_t d; 10140 uint32_t n; 10141 uint32_t m; 10142 uint32_t s; 10143 bool setflags; 10144 ARM_ShifterType shift_t; 10145 10146 switch (encoding) { 10147 case eEncodingA1: 10148 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 10149 d = Bits32(opcode, 15, 12); 10150 n = Bits32(opcode, 19, 16); 10151 m = Bits32(opcode, 3, 0); 10152 s = Bits32(opcode, 11, 8); 10153 10154 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 10155 setflags = BitIsSet(opcode, 20); 10156 shift_t = DecodeRegShift(Bits32(opcode, 6, 5)); 10157 10158 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 10159 if ((d == 15) || (n == 15) || (m == 15) || (s == 15)) 10160 return false; 10161 break; 10162 10163 default: 10164 return false; 10165 } 10166 10167 // shift_n = UInt(R[s]<7:0>); 10168 uint32_t Rs = ReadCoreReg(s, &success); 10169 if (!success) 10170 return false; 10171 10172 uint32_t shift_n = Bits32(Rs, 7, 0); 10173 10174 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10175 uint32_t Rm = ReadCoreReg(m, &success); 10176 if (!success) 10177 return false; 10178 10179 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10180 if (!success) 10181 return false; 10182 10183 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10184 uint32_t Rn = ReadCoreReg(n, &success); 10185 if (!success) 10186 return false; 10187 10188 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0); 10189 10190 // R[d] = result; 10191 EmulateInstruction::Context context; 10192 context.type = eContextArithmetic; 10193 RegisterInfo reg_n; 10194 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10195 RegisterInfo reg_m; 10196 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10197 10198 context.SetRegisterRegisterOperands(reg_n, reg_m); 10199 10200 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 10201 res.result)) 10202 return false; 10203 10204 // if setflags then 10205 // APSR.N = result<31>; 10206 // APSR.Z = IsZeroBit(result); 10207 // APSR.C = carry; 10208 // APSR.V = overflow; 10209 if (setflags) 10210 return WriteFlags(context, res.result, res.carry_out, res.overflow); 10211 } 10212 return true; 10213 } 10214 10215 // A8.6.213 SUB (register) 10216 bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode, 10217 const ARMEncoding encoding) { 10218 #if 0 10219 if ConditionPassed() then 10220 EncodingSpecificOperations(); 10221 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10222 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10223 if d == 15 then // Can only occur for ARM encoding 10224 ALUWritePC(result); // setflags is always FALSE here 10225 else 10226 R[d] = result; 10227 if setflags then 10228 APSR.N = result<31>; 10229 APSR.Z = IsZeroBit(result); 10230 APSR.C = carry; 10231 APSR.V = overflow; 10232 #endif 10233 10234 bool success = false; 10235 10236 if (ConditionPassed(opcode)) { 10237 uint32_t d; 10238 uint32_t n; 10239 uint32_t m; 10240 bool setflags; 10241 ARM_ShifterType shift_t; 10242 uint32_t shift_n; 10243 10244 switch (encoding) { 10245 case eEncodingT1: 10246 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 10247 d = Bits32(opcode, 2, 0); 10248 n = Bits32(opcode, 5, 3); 10249 m = Bits32(opcode, 8, 6); 10250 setflags = !InITBlock(); 10251 10252 // (shift_t, shift_n) = (SRType_LSL, 0); 10253 shift_t = SRType_LSL; 10254 shift_n = 0; 10255 10256 break; 10257 10258 case eEncodingT2: 10259 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 10260 d = Bits32(opcode, 11, 8); 10261 n = Bits32(opcode, 19, 16); 10262 m = Bits32(opcode, 3, 0); 10263 setflags = BitIsSet(opcode, 20); 10264 10265 // if Rd == "1111" && S == "1" then SEE CMP (register); 10266 if (d == 15 && setflags == 1) 10267 return EmulateCMPImm(opcode, eEncodingT3); 10268 10269 // if Rn == "1101" then SEE SUB (SP minus register); 10270 if (n == 13) 10271 return EmulateSUBSPReg(opcode, eEncodingT1); 10272 10273 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10274 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10275 10276 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then 10277 // UNPREDICTABLE; 10278 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) || 10279 BadReg(m)) 10280 return false; 10281 10282 break; 10283 10284 case eEncodingA1: 10285 // if Rn == '1101' then SEE SUB (SP minus register); 10286 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 10287 d = Bits32(opcode, 15, 12); 10288 n = Bits32(opcode, 19, 16); 10289 m = Bits32(opcode, 3, 0); 10290 setflags = BitIsSet(opcode, 20); 10291 10292 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10293 // instructions; 10294 if ((d == 15) && setflags) 10295 EmulateSUBSPcLrEtc(opcode, encoding); 10296 10297 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10298 shift_n = DecodeImmShiftARM(opcode, shift_t); 10299 10300 break; 10301 10302 default: 10303 return false; 10304 } 10305 10306 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10307 uint32_t Rm = ReadCoreReg(m, &success); 10308 if (!success) 10309 return false; 10310 10311 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10312 if (!success) 10313 return false; 10314 10315 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10316 uint32_t Rn = ReadCoreReg(n, &success); 10317 if (!success) 10318 return false; 10319 10320 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1); 10321 10322 // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result); 10323 // // setflags is always FALSE here else 10324 // R[d] = result; 10325 // if setflags then 10326 // APSR.N = result<31>; 10327 // APSR.Z = IsZeroBit(result); 10328 // APSR.C = carry; 10329 // APSR.V = overflow; 10330 10331 EmulateInstruction::Context context; 10332 context.type = eContextArithmetic; 10333 RegisterInfo reg_n; 10334 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10335 RegisterInfo reg_m; 10336 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10337 context.SetRegisterRegisterOperands(reg_n, reg_m); 10338 10339 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10340 res.carry_out, res.overflow)) 10341 return false; 10342 } 10343 return true; 10344 } 10345 10346 // A8.6.202 STREX 10347 // Store Register Exclusive calculates an address from a base register value 10348 // and an immediate offset, and stores a word from a register to memory if the 10349 // executing processor has exclusive access to the memory addressed. 10350 bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode, 10351 const ARMEncoding encoding) { 10352 #if 0 10353 if ConditionPassed() then 10354 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10355 address = R[n] + imm32; 10356 if ExclusiveMonitorsPass(address,4) then 10357 MemA[address,4] = R[t]; 10358 R[d] = 0; 10359 else 10360 R[d] = 1; 10361 #endif 10362 10363 bool success = false; 10364 10365 if (ConditionPassed(opcode)) { 10366 uint32_t d; 10367 uint32_t t; 10368 uint32_t n; 10369 uint32_t imm32; 10370 const uint32_t addr_byte_size = GetAddressByteSize(); 10371 10372 switch (encoding) { 10373 case eEncodingT1: 10374 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = 10375 // ZeroExtend(imm8:'00', 10376 // 32); 10377 d = Bits32(opcode, 11, 8); 10378 t = Bits32(opcode, 15, 12); 10379 n = Bits32(opcode, 19, 16); 10380 imm32 = Bits32(opcode, 7, 0) << 2; 10381 10382 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 10383 if (BadReg(d) || BadReg(t) || (n == 15)) 10384 return false; 10385 10386 // if d == n || d == t then UNPREDICTABLE; 10387 if ((d == n) || (d == t)) 10388 return false; 10389 10390 break; 10391 10392 case eEncodingA1: 10393 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero 10394 // offset 10395 d = Bits32(opcode, 15, 12); 10396 t = Bits32(opcode, 3, 0); 10397 n = Bits32(opcode, 19, 16); 10398 imm32 = 0; 10399 10400 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 10401 if ((d == 15) || (t == 15) || (n == 15)) 10402 return false; 10403 10404 // if d == n || d == t then UNPREDICTABLE; 10405 if ((d == n) || (d == t)) 10406 return false; 10407 10408 break; 10409 10410 default: 10411 return false; 10412 } 10413 10414 // address = R[n] + imm32; 10415 uint32_t Rn = ReadCoreReg(n, &success); 10416 if (!success) 10417 return false; 10418 10419 addr_t address = Rn + imm32; 10420 10421 RegisterInfo base_reg; 10422 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10423 RegisterInfo data_reg; 10424 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10425 EmulateInstruction::Context context; 10426 context.type = eContextRegisterStore; 10427 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32); 10428 10429 // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass 10430 // (address, addr_byte_size)) -- For now, for the sake of emulation, we 10431 // will say this 10432 // always return 10433 // true. 10434 if (true) { 10435 // MemA[address,4] = R[t]; 10436 uint32_t Rt = 10437 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 10438 if (!success) 10439 return false; 10440 10441 if (!MemAWrite(context, address, Rt, addr_byte_size)) 10442 return false; 10443 10444 // R[d] = 0; 10445 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 10446 return false; 10447 } 10448 #if 0 // unreachable because if true 10449 else 10450 { 10451 // R[d] = 1; 10452 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 10453 return false; 10454 } 10455 #endif // unreachable because if true 10456 } 10457 return true; 10458 } 10459 10460 // A8.6.197 STRB (immediate, ARM) 10461 bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode, 10462 const ARMEncoding encoding) { 10463 #if 0 10464 if ConditionPassed() then 10465 EncodingSpecificOperations(); 10466 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10467 address = if index then offset_addr else R[n]; 10468 MemU[address,1] = R[t]<7:0>; 10469 if wback then R[n] = offset_addr; 10470 #endif 10471 10472 bool success = false; 10473 10474 if (ConditionPassed(opcode)) { 10475 uint32_t t; 10476 uint32_t n; 10477 uint32_t imm32; 10478 bool index; 10479 bool add; 10480 bool wback; 10481 10482 switch (encoding) { 10483 case eEncodingA1: 10484 // if P == '0' && W == '1' then SEE STRBT; 10485 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10486 t = Bits32(opcode, 15, 12); 10487 n = Bits32(opcode, 19, 16); 10488 imm32 = Bits32(opcode, 11, 0); 10489 10490 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10491 index = BitIsSet(opcode, 24); 10492 add = BitIsSet(opcode, 23); 10493 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10494 10495 // if t == 15 then UNPREDICTABLE; 10496 if (t == 15) 10497 return false; 10498 10499 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10500 if (wback && ((n == 15) || (n == t))) 10501 return false; 10502 10503 break; 10504 10505 default: 10506 return false; 10507 } 10508 10509 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10510 uint32_t Rn = ReadCoreReg(n, &success); 10511 if (!success) 10512 return false; 10513 10514 addr_t offset_addr; 10515 if (add) 10516 offset_addr = Rn + imm32; 10517 else 10518 offset_addr = Rn - imm32; 10519 10520 // address = if index then offset_addr else R[n]; 10521 addr_t address; 10522 if (index) 10523 address = offset_addr; 10524 else 10525 address = Rn; 10526 10527 // MemU[address,1] = R[t]<7:0>; 10528 uint32_t Rt = ReadCoreReg(t, &success); 10529 if (!success) 10530 return false; 10531 10532 RegisterInfo base_reg; 10533 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10534 RegisterInfo data_reg; 10535 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10536 EmulateInstruction::Context context; 10537 context.type = eContextRegisterStore; 10538 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10539 10540 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1)) 10541 return false; 10542 10543 // if wback then R[n] = offset_addr; 10544 if (wback) { 10545 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10546 offset_addr)) 10547 return false; 10548 } 10549 } 10550 return true; 10551 } 10552 10553 // A8.6.194 STR (immediate, ARM) 10554 bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode, 10555 const ARMEncoding encoding) { 10556 #if 0 10557 if ConditionPassed() then 10558 EncodingSpecificOperations(); 10559 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10560 address = if index then offset_addr else R[n]; 10561 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10562 if wback then R[n] = offset_addr; 10563 #endif 10564 10565 bool success = false; 10566 10567 if (ConditionPassed(opcode)) { 10568 uint32_t t; 10569 uint32_t n; 10570 uint32_t imm32; 10571 bool index; 10572 bool add; 10573 bool wback; 10574 10575 const uint32_t addr_byte_size = GetAddressByteSize(); 10576 10577 switch (encoding) { 10578 case eEncodingA1: 10579 // if P == '0' && W == '1' then SEE STRT; 10580 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == 10581 // '000000000100' then SEE PUSH; 10582 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10583 t = Bits32(opcode, 15, 12); 10584 n = Bits32(opcode, 19, 16); 10585 imm32 = Bits32(opcode, 11, 0); 10586 10587 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10588 index = BitIsSet(opcode, 24); 10589 add = BitIsSet(opcode, 23); 10590 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10591 10592 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10593 if (wback && ((n == 15) || (n == t))) 10594 return false; 10595 10596 break; 10597 10598 default: 10599 return false; 10600 } 10601 10602 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10603 uint32_t Rn = ReadCoreReg(n, &success); 10604 if (!success) 10605 return false; 10606 10607 addr_t offset_addr; 10608 if (add) 10609 offset_addr = Rn + imm32; 10610 else 10611 offset_addr = Rn - imm32; 10612 10613 // address = if index then offset_addr else R[n]; 10614 addr_t address; 10615 if (index) 10616 address = offset_addr; 10617 else 10618 address = Rn; 10619 10620 RegisterInfo base_reg; 10621 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10622 RegisterInfo data_reg; 10623 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10624 EmulateInstruction::Context context; 10625 context.type = eContextRegisterStore; 10626 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10627 10628 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10629 uint32_t Rt = ReadCoreReg(t, &success); 10630 if (!success) 10631 return false; 10632 10633 if (t == 15) { 10634 uint32_t pc_value = ReadCoreReg(PC_REG, &success); 10635 if (!success) 10636 return false; 10637 10638 if (!MemUWrite(context, address, pc_value, addr_byte_size)) 10639 return false; 10640 } else { 10641 if (!MemUWrite(context, address, Rt, addr_byte_size)) 10642 return false; 10643 } 10644 10645 // if wback then R[n] = offset_addr; 10646 if (wback) { 10647 context.type = eContextAdjustBaseRegister; 10648 context.SetImmediate(offset_addr); 10649 10650 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10651 offset_addr)) 10652 return false; 10653 } 10654 } 10655 return true; 10656 } 10657 10658 // A8.6.66 LDRD (immediate) 10659 // Load Register Dual (immediate) calculates an address from a base register 10660 // value and an immediate offset, loads two words from memory, and writes them 10661 // to two registers. It can use offset, post-indexed, or pre-indexed 10662 // addressing. 10663 bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode, 10664 const ARMEncoding encoding) { 10665 #if 0 10666 if ConditionPassed() then 10667 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10668 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10669 address = if index then offset_addr else R[n]; 10670 R[t] = MemA[address,4]; 10671 R[t2] = MemA[address+4,4]; 10672 if wback then R[n] = offset_addr; 10673 #endif 10674 10675 bool success = false; 10676 10677 if (ConditionPassed(opcode)) { 10678 uint32_t t; 10679 uint32_t t2; 10680 uint32_t n; 10681 uint32_t imm32; 10682 bool index; 10683 bool add; 10684 bool wback; 10685 10686 switch (encoding) { 10687 case eEncodingT1: 10688 // if P == '0' && W == '0' then SEE 'Related encodings'; 10689 // if Rn == '1111' then SEE LDRD (literal); 10690 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10691 // ZeroExtend(imm8:'00', 32); 10692 t = Bits32(opcode, 15, 12); 10693 t2 = Bits32(opcode, 11, 8); 10694 n = Bits32(opcode, 19, 16); 10695 imm32 = Bits32(opcode, 7, 0) << 2; 10696 10697 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10698 index = BitIsSet(opcode, 24); 10699 add = BitIsSet(opcode, 23); 10700 wback = BitIsSet(opcode, 21); 10701 10702 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10703 if (wback && ((n == t) || (n == t2))) 10704 return false; 10705 10706 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10707 if (BadReg(t) || BadReg(t2) || (t == t2)) 10708 return false; 10709 10710 break; 10711 10712 case eEncodingA1: 10713 // if Rn == '1111' then SEE LDRD (literal); 10714 // if Rt<0> == '1' then UNPREDICTABLE; 10715 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10716 // 32); 10717 t = Bits32(opcode, 15, 12); 10718 if (BitIsSet(t, 0)) 10719 return false; 10720 t2 = t + 1; 10721 n = Bits32(opcode, 19, 16); 10722 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10723 10724 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10725 index = BitIsSet(opcode, 24); 10726 add = BitIsSet(opcode, 23); 10727 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10728 10729 // if P == '0' && W == '1' then UNPREDICTABLE; 10730 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10731 return false; 10732 10733 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10734 if (wback && ((n == t) || (n == t2))) 10735 return false; 10736 10737 // if t2 == 15 then UNPREDICTABLE; 10738 if (t2 == 15) 10739 return false; 10740 10741 break; 10742 10743 default: 10744 return false; 10745 } 10746 10747 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10748 uint32_t Rn = ReadCoreReg(n, &success); 10749 if (!success) 10750 return false; 10751 10752 addr_t offset_addr; 10753 if (add) 10754 offset_addr = Rn + imm32; 10755 else 10756 offset_addr = Rn - imm32; 10757 10758 // address = if index then offset_addr else R[n]; 10759 addr_t address; 10760 if (index) 10761 address = offset_addr; 10762 else 10763 address = Rn; 10764 10765 // R[t] = MemA[address,4]; 10766 RegisterInfo base_reg; 10767 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10768 10769 EmulateInstruction::Context context; 10770 if (n == 13) 10771 context.type = eContextPopRegisterOffStack; 10772 else 10773 context.type = eContextRegisterLoad; 10774 context.SetAddress(address); 10775 10776 const uint32_t addr_byte_size = GetAddressByteSize(); 10777 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10778 if (!success) 10779 return false; 10780 10781 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10782 return false; 10783 10784 // R[t2] = MemA[address+4,4]; 10785 context.SetAddress(address + 4); 10786 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10787 if (!success) 10788 return false; 10789 10790 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10791 data)) 10792 return false; 10793 10794 // if wback then R[n] = offset_addr; 10795 if (wback) { 10796 context.type = eContextAdjustBaseRegister; 10797 context.SetAddress(offset_addr); 10798 10799 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10800 offset_addr)) 10801 return false; 10802 } 10803 } 10804 return true; 10805 } 10806 10807 // A8.6.68 LDRD (register) 10808 // Load Register Dual (register) calculates an address from a base register 10809 // value and a register offset, loads two words from memory, and writes them to 10810 // two registers. It can use offset, post-indexed or pre-indexed addressing. 10811 bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode, 10812 const ARMEncoding encoding) { 10813 #if 0 10814 if ConditionPassed() then 10815 EncodingSpecificOperations(); 10816 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10817 address = if index then offset_addr else R[n]; 10818 R[t] = MemA[address,4]; 10819 R[t2] = MemA[address+4,4]; 10820 if wback then R[n] = offset_addr; 10821 #endif 10822 10823 bool success = false; 10824 10825 if (ConditionPassed(opcode)) { 10826 uint32_t t; 10827 uint32_t t2; 10828 uint32_t n; 10829 uint32_t m; 10830 bool index; 10831 bool add; 10832 bool wback; 10833 10834 switch (encoding) { 10835 case eEncodingA1: 10836 // if Rt<0> == '1' then UNPREDICTABLE; 10837 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10838 t = Bits32(opcode, 15, 12); 10839 if (BitIsSet(t, 0)) 10840 return false; 10841 t2 = t + 1; 10842 n = Bits32(opcode, 19, 16); 10843 m = Bits32(opcode, 3, 0); 10844 10845 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10846 index = BitIsSet(opcode, 24); 10847 add = BitIsSet(opcode, 23); 10848 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10849 10850 // if P == '0' && W == '1' then UNPREDICTABLE; 10851 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10852 return false; 10853 10854 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10855 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10856 return false; 10857 10858 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10859 if (wback && ((n == 15) || (n == t) || (n == t2))) 10860 return false; 10861 10862 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10863 if ((ArchVersion() < 6) && wback && (m == n)) 10864 return false; 10865 break; 10866 10867 default: 10868 return false; 10869 } 10870 10871 uint32_t Rn = ReadCoreReg(n, &success); 10872 if (!success) 10873 return false; 10874 RegisterInfo base_reg; 10875 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10876 10877 uint32_t Rm = ReadCoreReg(m, &success); 10878 if (!success) 10879 return false; 10880 RegisterInfo offset_reg; 10881 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10882 10883 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10884 addr_t offset_addr; 10885 if (add) 10886 offset_addr = Rn + Rm; 10887 else 10888 offset_addr = Rn - Rm; 10889 10890 // address = if index then offset_addr else R[n]; 10891 addr_t address; 10892 if (index) 10893 address = offset_addr; 10894 else 10895 address = Rn; 10896 10897 EmulateInstruction::Context context; 10898 if (n == 13) 10899 context.type = eContextPopRegisterOffStack; 10900 else 10901 context.type = eContextRegisterLoad; 10902 context.SetAddress(address); 10903 10904 // R[t] = MemA[address,4]; 10905 const uint32_t addr_byte_size = GetAddressByteSize(); 10906 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10907 if (!success) 10908 return false; 10909 10910 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10911 return false; 10912 10913 // R[t2] = MemA[address+4,4]; 10914 10915 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10916 if (!success) 10917 return false; 10918 10919 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10920 data)) 10921 return false; 10922 10923 // if wback then R[n] = offset_addr; 10924 if (wback) { 10925 context.type = eContextAdjustBaseRegister; 10926 context.SetAddress(offset_addr); 10927 10928 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10929 offset_addr)) 10930 return false; 10931 } 10932 } 10933 return true; 10934 } 10935 10936 // A8.6.200 STRD (immediate) 10937 // Store Register Dual (immediate) calculates an address from a base register 10938 // value and an immediate offset, and stores two words from two registers to 10939 // memory. It can use offset, post-indexed, or pre-indexed addressing. 10940 bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode, 10941 const ARMEncoding encoding) { 10942 #if 0 10943 if ConditionPassed() then 10944 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10945 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10946 address = if index then offset_addr else R[n]; 10947 MemA[address,4] = R[t]; 10948 MemA[address+4,4] = R[t2]; 10949 if wback then R[n] = offset_addr; 10950 #endif 10951 10952 bool success = false; 10953 10954 if (ConditionPassed(opcode)) { 10955 uint32_t t; 10956 uint32_t t2; 10957 uint32_t n; 10958 uint32_t imm32; 10959 bool index; 10960 bool add; 10961 bool wback; 10962 10963 switch (encoding) { 10964 case eEncodingT1: 10965 // if P == '0' && W == '0' then SEE 'Related encodings'; 10966 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10967 // ZeroExtend(imm8:'00', 32); 10968 t = Bits32(opcode, 15, 12); 10969 t2 = Bits32(opcode, 11, 8); 10970 n = Bits32(opcode, 19, 16); 10971 imm32 = Bits32(opcode, 7, 0) << 2; 10972 10973 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10974 index = BitIsSet(opcode, 24); 10975 add = BitIsSet(opcode, 23); 10976 wback = BitIsSet(opcode, 21); 10977 10978 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10979 if (wback && ((n == t) || (n == t2))) 10980 return false; 10981 10982 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10983 if ((n == 15) || BadReg(t) || BadReg(t2)) 10984 return false; 10985 10986 break; 10987 10988 case eEncodingA1: 10989 // if Rt<0> == '1' then UNPREDICTABLE; 10990 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10991 // 32); 10992 t = Bits32(opcode, 15, 12); 10993 if (BitIsSet(t, 0)) 10994 return false; 10995 10996 t2 = t + 1; 10997 n = Bits32(opcode, 19, 16); 10998 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10999 11000 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11001 index = BitIsSet(opcode, 24); 11002 add = BitIsSet(opcode, 23); 11003 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11004 11005 // if P == '0' && W == '1' then UNPREDICTABLE; 11006 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11007 return false; 11008 11009 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11010 if (wback && ((n == 15) || (n == t) || (n == t2))) 11011 return false; 11012 11013 // if t2 == 15 then UNPREDICTABLE; 11014 if (t2 == 15) 11015 return false; 11016 11017 break; 11018 11019 default: 11020 return false; 11021 } 11022 11023 RegisterInfo base_reg; 11024 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11025 11026 uint32_t Rn = ReadCoreReg(n, &success); 11027 if (!success) 11028 return false; 11029 11030 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11031 addr_t offset_addr; 11032 if (add) 11033 offset_addr = Rn + imm32; 11034 else 11035 offset_addr = Rn - imm32; 11036 11037 // address = if index then offset_addr else R[n]; 11038 addr_t address; 11039 if (index) 11040 address = offset_addr; 11041 else 11042 address = Rn; 11043 11044 // MemA[address,4] = R[t]; 11045 RegisterInfo data_reg; 11046 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11047 11048 uint32_t data = ReadCoreReg(t, &success); 11049 if (!success) 11050 return false; 11051 11052 EmulateInstruction::Context context; 11053 if (n == 13) 11054 context.type = eContextPushRegisterOnStack; 11055 else 11056 context.type = eContextRegisterStore; 11057 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11058 11059 const uint32_t addr_byte_size = GetAddressByteSize(); 11060 11061 if (!MemAWrite(context, address, data, addr_byte_size)) 11062 return false; 11063 11064 // MemA[address+4,4] = R[t2]; 11065 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11066 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11067 (address + 4) - Rn); 11068 11069 data = ReadCoreReg(t2, &success); 11070 if (!success) 11071 return false; 11072 11073 if (!MemAWrite(context, address + 4, data, addr_byte_size)) 11074 return false; 11075 11076 // if wback then R[n] = offset_addr; 11077 if (wback) { 11078 if (n == 13) 11079 context.type = eContextAdjustStackPointer; 11080 else 11081 context.type = eContextAdjustBaseRegister; 11082 context.SetAddress(offset_addr); 11083 11084 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11085 offset_addr)) 11086 return false; 11087 } 11088 } 11089 return true; 11090 } 11091 11092 // A8.6.201 STRD (register) 11093 bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode, 11094 const ARMEncoding encoding) { 11095 #if 0 11096 if ConditionPassed() then 11097 EncodingSpecificOperations(); 11098 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11099 address = if index then offset_addr else R[n]; 11100 MemA[address,4] = R[t]; 11101 MemA[address+4,4] = R[t2]; 11102 if wback then R[n] = offset_addr; 11103 #endif 11104 11105 bool success = false; 11106 11107 if (ConditionPassed(opcode)) { 11108 uint32_t t; 11109 uint32_t t2; 11110 uint32_t n; 11111 uint32_t m; 11112 bool index; 11113 bool add; 11114 bool wback; 11115 11116 switch (encoding) { 11117 case eEncodingA1: 11118 // if Rt<0> == '1' then UNPREDICTABLE; 11119 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 11120 t = Bits32(opcode, 15, 12); 11121 if (BitIsSet(t, 0)) 11122 return false; 11123 11124 t2 = t + 1; 11125 n = Bits32(opcode, 19, 16); 11126 m = Bits32(opcode, 3, 0); 11127 11128 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11129 index = BitIsSet(opcode, 24); 11130 add = BitIsSet(opcode, 23); 11131 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11132 11133 // if P == '0' && W == '1' then UNPREDICTABLE; 11134 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11135 return false; 11136 11137 // if t2 == 15 || m == 15 then UNPREDICTABLE; 11138 if ((t2 == 15) || (m == 15)) 11139 return false; 11140 11141 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11142 if (wback && ((n == 15) || (n == t) || (n == t2))) 11143 return false; 11144 11145 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 11146 if ((ArchVersion() < 6) && wback && (m == n)) 11147 return false; 11148 11149 break; 11150 11151 default: 11152 return false; 11153 } 11154 11155 RegisterInfo base_reg; 11156 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11157 RegisterInfo offset_reg; 11158 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 11159 RegisterInfo data_reg; 11160 11161 uint32_t Rn = ReadCoreReg(n, &success); 11162 if (!success) 11163 return false; 11164 11165 uint32_t Rm = ReadCoreReg(m, &success); 11166 if (!success) 11167 return false; 11168 11169 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11170 addr_t offset_addr; 11171 if (add) 11172 offset_addr = Rn + Rm; 11173 else 11174 offset_addr = Rn - Rm; 11175 11176 // address = if index then offset_addr else R[n]; 11177 addr_t address; 11178 if (index) 11179 address = offset_addr; 11180 else 11181 address = Rn; 11182 // MemA[address,4] = R[t]; 11183 uint32_t Rt = ReadCoreReg(t, &success); 11184 if (!success) 11185 return false; 11186 11187 EmulateInstruction::Context context; 11188 if (t == 13) 11189 context.type = eContextPushRegisterOnStack; 11190 else 11191 context.type = eContextRegisterStore; 11192 11193 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11194 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11195 data_reg); 11196 11197 const uint32_t addr_byte_size = GetAddressByteSize(); 11198 11199 if (!MemAWrite(context, address, Rt, addr_byte_size)) 11200 return false; 11201 11202 // MemA[address+4,4] = R[t2]; 11203 uint32_t Rt2 = ReadCoreReg(t2, &success); 11204 if (!success) 11205 return false; 11206 11207 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11208 11209 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11210 data_reg); 11211 11212 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size)) 11213 return false; 11214 11215 // if wback then R[n] = offset_addr; 11216 if (wback) { 11217 context.type = eContextAdjustBaseRegister; 11218 context.SetAddress(offset_addr); 11219 11220 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11221 offset_addr)) 11222 return false; 11223 } 11224 } 11225 return true; 11226 } 11227 11228 // A8.6.319 VLDM 11229 // Vector Load Multiple loads multiple extension registers from consecutive 11230 // memory locations using an address from an ARM core register. 11231 bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode, 11232 const ARMEncoding encoding) { 11233 #if 0 11234 if ConditionPassed() then 11235 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11236 address = if add then R[n] else R[n]-imm32; 11237 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11238 for r = 0 to regs-1 11239 if single_regs then 11240 S[d+r] = MemA[address,4]; address = address+4; 11241 else 11242 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 11243 // Combine the word-aligned words in the correct order for 11244 // current endianness. 11245 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11246 #endif 11247 11248 bool success = false; 11249 11250 if (ConditionPassed(opcode)) { 11251 bool single_regs; 11252 bool add; 11253 bool wback; 11254 uint32_t d; 11255 uint32_t n; 11256 uint32_t imm32; 11257 uint32_t regs; 11258 11259 switch (encoding) { 11260 case eEncodingT1: 11261 case eEncodingA1: 11262 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11263 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11264 // if P == '1' && W == '0' then SEE VLDR; 11265 // if P == U && W == '1' then UNDEFINED; 11266 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11267 return false; 11268 11269 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11270 // !), 101 (DB with !) 11271 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11272 single_regs = false; 11273 add = BitIsSet(opcode, 23); 11274 wback = BitIsSet(opcode, 21); 11275 11276 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11277 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11278 n = Bits32(opcode, 19, 16); 11279 imm32 = Bits32(opcode, 7, 0) << 2; 11280 11281 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 11282 regs = Bits32(opcode, 7, 0) / 2; 11283 11284 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11285 // UNPREDICTABLE; 11286 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 11287 return false; 11288 11289 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11290 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11291 return false; 11292 11293 break; 11294 11295 case eEncodingT2: 11296 case eEncodingA2: 11297 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11298 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11299 // if P == '1' && W == '0' then SEE VLDR; 11300 // if P == U && W == '1' then UNDEFINED; 11301 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11302 return false; 11303 11304 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11305 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11306 // == '1'); d = 11307 // UInt(Vd:D); n = UInt(Rn); 11308 single_regs = true; 11309 add = BitIsSet(opcode, 23); 11310 wback = BitIsSet(opcode, 21); 11311 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11312 n = Bits32(opcode, 19, 16); 11313 11314 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11315 imm32 = Bits32(opcode, 7, 0) << 2; 11316 regs = Bits32(opcode, 7, 0); 11317 11318 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11319 // UNPREDICTABLE; 11320 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11321 return false; 11322 11323 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11324 if ((regs == 0) || ((d + regs) > 32)) 11325 return false; 11326 break; 11327 11328 default: 11329 return false; 11330 } 11331 11332 RegisterInfo base_reg; 11333 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11334 11335 uint32_t Rn = ReadCoreReg(n, &success); 11336 if (!success) 11337 return false; 11338 11339 // address = if add then R[n] else R[n]-imm32; 11340 addr_t address; 11341 if (add) 11342 address = Rn; 11343 else 11344 address = Rn - imm32; 11345 11346 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11347 EmulateInstruction::Context context; 11348 11349 if (wback) { 11350 uint32_t value; 11351 if (add) 11352 value = Rn + imm32; 11353 else 11354 value = Rn - imm32; 11355 11356 context.type = eContextAdjustBaseRegister; 11357 context.SetImmediateSigned(value - Rn); 11358 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11359 value)) 11360 return false; 11361 } 11362 11363 const uint32_t addr_byte_size = GetAddressByteSize(); 11364 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11365 11366 context.type = eContextRegisterLoad; 11367 11368 // for r = 0 to regs-1 11369 for (uint32_t r = 0; r < regs; ++r) { 11370 if (single_regs) { 11371 // S[d+r] = MemA[address,4]; address = address+4; 11372 context.SetRegisterPlusOffset(base_reg, address - Rn); 11373 11374 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11375 if (!success) 11376 return false; 11377 11378 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11379 start_reg + d + r, data)) 11380 return false; 11381 11382 address = address + 4; 11383 } else { 11384 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = 11385 // address+8; 11386 context.SetRegisterPlusOffset(base_reg, address - Rn); 11387 uint32_t word1 = 11388 MemARead(context, address, addr_byte_size, 0, &success); 11389 if (!success) 11390 return false; 11391 11392 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn); 11393 uint32_t word2 = 11394 MemARead(context, address + 4, addr_byte_size, 0, &success); 11395 if (!success) 11396 return false; 11397 11398 address = address + 8; 11399 // // Combine the word-aligned words in the correct order for current 11400 // endianness. 11401 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11402 uint64_t data; 11403 if (GetByteOrder() == eByteOrderBig) { 11404 data = word1; 11405 data = (data << 32) | word2; 11406 } else { 11407 data = word2; 11408 data = (data << 32) | word1; 11409 } 11410 11411 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11412 start_reg + d + r, data)) 11413 return false; 11414 } 11415 } 11416 } 11417 return true; 11418 } 11419 11420 // A8.6.399 VSTM 11421 // Vector Store Multiple stores multiple extension registers to consecutive 11422 // memory locations using an address from an 11423 // ARM core register. 11424 bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode, 11425 const ARMEncoding encoding) { 11426 #if 0 11427 if ConditionPassed() then 11428 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11429 address = if add then R[n] else R[n]-imm32; 11430 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11431 for r = 0 to regs-1 11432 if single_regs then 11433 MemA[address,4] = S[d+r]; address = address+4; 11434 else 11435 // Store as two word-aligned words in the correct order for 11436 // current endianness. 11437 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11438 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11439 address = address+8; 11440 #endif 11441 11442 bool success = false; 11443 11444 if (ConditionPassed(opcode)) { 11445 bool single_regs; 11446 bool add; 11447 bool wback; 11448 uint32_t d; 11449 uint32_t n; 11450 uint32_t imm32; 11451 uint32_t regs; 11452 11453 switch (encoding) { 11454 case eEncodingT1: 11455 case eEncodingA1: 11456 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11457 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11458 // if P == '1' && W == '0' then SEE VSTR; 11459 // if P == U && W == '1' then UNDEFINED; 11460 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11461 return false; 11462 11463 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11464 // !), 101 (DB with !) 11465 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11466 single_regs = false; 11467 add = BitIsSet(opcode, 23); 11468 wback = BitIsSet(opcode, 21); 11469 11470 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11471 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11472 n = Bits32(opcode, 19, 16); 11473 imm32 = Bits32(opcode, 7, 0) << 2; 11474 11475 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11476 regs = Bits32(opcode, 7, 0) / 2; 11477 11478 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11479 // UNPREDICTABLE; 11480 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11481 return false; 11482 11483 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11484 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11485 return false; 11486 11487 break; 11488 11489 case eEncodingT2: 11490 case eEncodingA2: 11491 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11492 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11493 // if P == '1' && W == '0' then SEE VSTR; 11494 // if P == U && W == '1' then UNDEFINED; 11495 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11496 return false; 11497 11498 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11499 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11500 // == '1'); d = 11501 // UInt(Vd:D); n = UInt(Rn); 11502 single_regs = true; 11503 add = BitIsSet(opcode, 23); 11504 wback = BitIsSet(opcode, 21); 11505 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11506 n = Bits32(opcode, 19, 16); 11507 11508 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11509 imm32 = Bits32(opcode, 7, 0) << 2; 11510 regs = Bits32(opcode, 7, 0); 11511 11512 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11513 // UNPREDICTABLE; 11514 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11515 return false; 11516 11517 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11518 if ((regs == 0) || ((d + regs) > 32)) 11519 return false; 11520 11521 break; 11522 11523 default: 11524 return false; 11525 } 11526 11527 RegisterInfo base_reg; 11528 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11529 11530 uint32_t Rn = ReadCoreReg(n, &success); 11531 if (!success) 11532 return false; 11533 11534 // address = if add then R[n] else R[n]-imm32; 11535 addr_t address; 11536 if (add) 11537 address = Rn; 11538 else 11539 address = Rn - imm32; 11540 11541 EmulateInstruction::Context context; 11542 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11543 if (wback) { 11544 uint32_t value; 11545 if (add) 11546 value = Rn + imm32; 11547 else 11548 value = Rn - imm32; 11549 11550 context.type = eContextAdjustBaseRegister; 11551 context.SetRegisterPlusOffset(base_reg, value - Rn); 11552 11553 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11554 value)) 11555 return false; 11556 } 11557 11558 const uint32_t addr_byte_size = GetAddressByteSize(); 11559 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11560 11561 context.type = eContextRegisterStore; 11562 // for r = 0 to regs-1 11563 for (uint32_t r = 0; r < regs; ++r) { 11564 11565 if (single_regs) { 11566 // MemA[address,4] = S[d+r]; address = address+4; 11567 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11568 start_reg + d + r, 0, &success); 11569 if (!success) 11570 return false; 11571 11572 RegisterInfo data_reg; 11573 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11574 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11575 address - Rn); 11576 if (!MemAWrite(context, address, data, addr_byte_size)) 11577 return false; 11578 11579 address = address + 4; 11580 } else { 11581 // // Store as two word-aligned words in the correct order for current 11582 // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else 11583 // D[d+r]<31:0>; 11584 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else 11585 // D[d+r]<63:32>; 11586 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11587 start_reg + d + r, 0, &success); 11588 if (!success) 11589 return false; 11590 11591 RegisterInfo data_reg; 11592 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11593 11594 if (GetByteOrder() == eByteOrderBig) { 11595 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11596 address - Rn); 11597 if (!MemAWrite(context, address, Bits64(data, 63, 32), 11598 addr_byte_size)) 11599 return false; 11600 11601 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11602 (address + 4) - Rn); 11603 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11604 addr_byte_size)) 11605 return false; 11606 } else { 11607 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11608 address - Rn); 11609 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11610 return false; 11611 11612 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11613 (address + 4) - Rn); 11614 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11615 addr_byte_size)) 11616 return false; 11617 } 11618 // address = address+8; 11619 address = address + 8; 11620 } 11621 } 11622 } 11623 return true; 11624 } 11625 11626 // A8.6.320 11627 // This instruction loads a single extension register from memory, using an 11628 // address from an ARM core register, with an optional offset. 11629 bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode, 11630 ARMEncoding encoding) { 11631 #if 0 11632 if ConditionPassed() then 11633 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11634 base = if n == 15 then Align(PC,4) else R[n]; 11635 address = if add then (base + imm32) else (base - imm32); 11636 if single_reg then 11637 S[d] = MemA[address,4]; 11638 else 11639 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11640 // Combine the word-aligned words in the correct order for current 11641 // endianness. 11642 D[d] = if BigEndian() then word1:word2 else word2:word1; 11643 #endif 11644 11645 bool success = false; 11646 11647 if (ConditionPassed(opcode)) { 11648 bool single_reg; 11649 bool add; 11650 uint32_t imm32; 11651 uint32_t d; 11652 uint32_t n; 11653 11654 switch (encoding) { 11655 case eEncodingT1: 11656 case eEncodingA1: 11657 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11658 // 32); 11659 single_reg = false; 11660 add = BitIsSet(opcode, 23); 11661 imm32 = Bits32(opcode, 7, 0) << 2; 11662 11663 // d = UInt(D:Vd); n = UInt(Rn); 11664 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11665 n = Bits32(opcode, 19, 16); 11666 11667 break; 11668 11669 case eEncodingT2: 11670 case eEncodingA2: 11671 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11672 single_reg = true; 11673 add = BitIsSet(opcode, 23); 11674 imm32 = Bits32(opcode, 7, 0) << 2; 11675 11676 // d = UInt(Vd:D); n = UInt(Rn); 11677 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11678 n = Bits32(opcode, 19, 16); 11679 11680 break; 11681 11682 default: 11683 return false; 11684 } 11685 RegisterInfo base_reg; 11686 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11687 11688 uint32_t Rn = ReadCoreReg(n, &success); 11689 if (!success) 11690 return false; 11691 11692 // base = if n == 15 then Align(PC,4) else R[n]; 11693 uint32_t base; 11694 if (n == 15) 11695 base = AlignPC(Rn); 11696 else 11697 base = Rn; 11698 11699 // address = if add then (base + imm32) else (base - imm32); 11700 addr_t address; 11701 if (add) 11702 address = base + imm32; 11703 else 11704 address = base - imm32; 11705 11706 const uint32_t addr_byte_size = GetAddressByteSize(); 11707 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11708 11709 EmulateInstruction::Context context; 11710 context.type = eContextRegisterLoad; 11711 context.SetRegisterPlusOffset(base_reg, address - base); 11712 11713 if (single_reg) { 11714 // S[d] = MemA[address,4]; 11715 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11716 if (!success) 11717 return false; 11718 11719 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11720 data)) 11721 return false; 11722 } else { 11723 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11724 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success); 11725 if (!success) 11726 return false; 11727 11728 context.SetRegisterPlusOffset(base_reg, (address + 4) - base); 11729 uint32_t word2 = 11730 MemARead(context, address + 4, addr_byte_size, 0, &success); 11731 if (!success) 11732 return false; 11733 // // Combine the word-aligned words in the correct order for current 11734 // endianness. 11735 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11736 uint64_t data64; 11737 if (GetByteOrder() == eByteOrderBig) { 11738 data64 = word1; 11739 data64 = (data64 << 32) | word2; 11740 } else { 11741 data64 = word2; 11742 data64 = (data64 << 32) | word1; 11743 } 11744 11745 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11746 data64)) 11747 return false; 11748 } 11749 } 11750 return true; 11751 } 11752 11753 // A8.6.400 VSTR 11754 // This instruction stores a signle extension register to memory, using an 11755 // address from an ARM core register, with an optional offset. 11756 bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode, 11757 ARMEncoding encoding) { 11758 #if 0 11759 if ConditionPassed() then 11760 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11761 address = if add then (R[n] + imm32) else (R[n] - imm32); 11762 if single_reg then 11763 MemA[address,4] = S[d]; 11764 else 11765 // Store as two word-aligned words in the correct order for current 11766 // endianness. 11767 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11768 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11769 #endif 11770 11771 bool success = false; 11772 11773 if (ConditionPassed(opcode)) { 11774 bool single_reg; 11775 bool add; 11776 uint32_t imm32; 11777 uint32_t d; 11778 uint32_t n; 11779 11780 switch (encoding) { 11781 case eEncodingT1: 11782 case eEncodingA1: 11783 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11784 // 32); 11785 single_reg = false; 11786 add = BitIsSet(opcode, 23); 11787 imm32 = Bits32(opcode, 7, 0) << 2; 11788 11789 // d = UInt(D:Vd); n = UInt(Rn); 11790 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11791 n = Bits32(opcode, 19, 16); 11792 11793 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11794 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11795 return false; 11796 11797 break; 11798 11799 case eEncodingT2: 11800 case eEncodingA2: 11801 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11802 single_reg = true; 11803 add = BitIsSet(opcode, 23); 11804 imm32 = Bits32(opcode, 7, 0) << 2; 11805 11806 // d = UInt(Vd:D); n = UInt(Rn); 11807 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11808 n = Bits32(opcode, 19, 16); 11809 11810 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11811 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11812 return false; 11813 11814 break; 11815 11816 default: 11817 return false; 11818 } 11819 11820 RegisterInfo base_reg; 11821 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11822 11823 uint32_t Rn = ReadCoreReg(n, &success); 11824 if (!success) 11825 return false; 11826 11827 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11828 addr_t address; 11829 if (add) 11830 address = Rn + imm32; 11831 else 11832 address = Rn - imm32; 11833 11834 const uint32_t addr_byte_size = GetAddressByteSize(); 11835 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11836 11837 RegisterInfo data_reg; 11838 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg); 11839 EmulateInstruction::Context context; 11840 context.type = eContextRegisterStore; 11841 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11842 11843 if (single_reg) { 11844 // MemA[address,4] = S[d]; 11845 uint32_t data = 11846 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11847 if (!success) 11848 return false; 11849 11850 if (!MemAWrite(context, address, data, addr_byte_size)) 11851 return false; 11852 } else { 11853 // // Store as two word-aligned words in the correct order for current 11854 // endianness. 11855 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11856 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11857 uint64_t data = 11858 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11859 if (!success) 11860 return false; 11861 11862 if (GetByteOrder() == eByteOrderBig) { 11863 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size)) 11864 return false; 11865 11866 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11867 (address + 4) - Rn); 11868 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11869 addr_byte_size)) 11870 return false; 11871 } else { 11872 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11873 return false; 11874 11875 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11876 (address + 4) - Rn); 11877 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11878 addr_byte_size)) 11879 return false; 11880 } 11881 } 11882 } 11883 return true; 11884 } 11885 11886 // A8.6.307 VLDI1 (multiple single elements) This instruction loads elements 11887 // from memory into one, two, three or four registers, without de-interleaving. 11888 // Every element of each register is loaded. 11889 bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode, 11890 ARMEncoding encoding) { 11891 #if 0 11892 if ConditionPassed() then 11893 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11894 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11895 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11896 for r = 0 to regs-1 11897 for e = 0 to elements-1 11898 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11899 address = address + ebytes; 11900 #endif 11901 11902 bool success = false; 11903 11904 if (ConditionPassed(opcode)) { 11905 uint32_t regs; 11906 uint32_t alignment; 11907 uint32_t ebytes; 11908 uint32_t esize; 11909 uint32_t elements; 11910 uint32_t d; 11911 uint32_t n; 11912 uint32_t m; 11913 bool wback; 11914 bool register_index; 11915 11916 switch (encoding) { 11917 case eEncodingT1: 11918 case eEncodingA1: { 11919 // case type of 11920 // when '0111' 11921 // regs = 1; if align<1> == '1' then UNDEFINED; 11922 // when '1010' 11923 // regs = 2; if align == '11' then UNDEFINED; 11924 // when '0110' 11925 // regs = 3; if align<1> == '1' then UNDEFINED; 11926 // when '0010' 11927 // regs = 4; 11928 // otherwise 11929 // SEE 'Related encodings'; 11930 uint32_t type = Bits32(opcode, 11, 8); 11931 uint32_t align = Bits32(opcode, 5, 4); 11932 if (type == 7) // '0111' 11933 { 11934 regs = 1; 11935 if (BitIsSet(align, 1)) 11936 return false; 11937 } else if (type == 10) // '1010' 11938 { 11939 regs = 2; 11940 if (align == 3) 11941 return false; 11942 11943 } else if (type == 6) // '0110' 11944 { 11945 regs = 3; 11946 if (BitIsSet(align, 1)) 11947 return false; 11948 } else if (type == 2) // '0010' 11949 { 11950 regs = 4; 11951 } else 11952 return false; 11953 11954 // alignment = if align == '00' then 1 else 4 << UInt(align); 11955 if (align == 0) 11956 alignment = 1; 11957 else 11958 alignment = 4 << align; 11959 11960 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11961 ebytes = 1 << Bits32(opcode, 7, 6); 11962 esize = 8 * ebytes; 11963 elements = 8 / ebytes; 11964 11965 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11966 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11967 n = Bits32(opcode, 19, 15); 11968 m = Bits32(opcode, 3, 0); 11969 11970 // wback = (m != 15); register_index = (m != 15 && m != 13); 11971 wback = (m != 15); 11972 register_index = ((m != 15) && (m != 13)); 11973 11974 // if d+regs > 32 then UNPREDICTABLE; 11975 if ((d + regs) > 32) 11976 return false; 11977 } break; 11978 11979 default: 11980 return false; 11981 } 11982 11983 RegisterInfo base_reg; 11984 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11985 11986 uint32_t Rn = ReadCoreReg(n, &success); 11987 if (!success) 11988 return false; 11989 11990 // address = R[n]; if (address MOD alignment) != 0 then 11991 // GenerateAlignmentException(); 11992 addr_t address = Rn; 11993 if ((address % alignment) != 0) 11994 return false; 11995 11996 EmulateInstruction::Context context; 11997 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11998 if (wback) { 11999 uint32_t Rm = ReadCoreReg(m, &success); 12000 if (!success) 12001 return false; 12002 12003 uint32_t offset; 12004 if (register_index) 12005 offset = Rm; 12006 else 12007 offset = 8 * regs; 12008 12009 uint32_t value = Rn + offset; 12010 context.type = eContextAdjustBaseRegister; 12011 context.SetRegisterPlusOffset(base_reg, offset); 12012 12013 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12014 value)) 12015 return false; 12016 } 12017 12018 // for r = 0 to regs-1 12019 for (uint32_t r = 0; r < regs; ++r) { 12020 // for e = 0 to elements-1 12021 uint64_t assembled_data = 0; 12022 for (uint32_t e = 0; e < elements; ++e) { 12023 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 12024 context.type = eContextRegisterLoad; 12025 context.SetRegisterPlusOffset(base_reg, address - Rn); 12026 uint64_t data = MemURead(context, address, ebytes, 0, &success); 12027 if (!success) 12028 return false; 12029 12030 assembled_data = 12031 (data << (e * esize)) | 12032 assembled_data; // New data goes to the left of existing data 12033 12034 // address = address + ebytes; 12035 address = address + ebytes; 12036 } 12037 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12038 assembled_data)) 12039 return false; 12040 } 12041 } 12042 return true; 12043 } 12044 12045 // A8.6.308 VLD1 (single element to one lane) 12046 // 12047 bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode, 12048 const ARMEncoding encoding) { 12049 #if 0 12050 if ConditionPassed() then 12051 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12052 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12053 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12054 Elem[D[d],index,esize] = MemU[address,ebytes]; 12055 #endif 12056 12057 bool success = false; 12058 12059 if (ConditionPassed(opcode)) { 12060 uint32_t ebytes; 12061 uint32_t esize; 12062 uint32_t index; 12063 uint32_t alignment; 12064 uint32_t d; 12065 uint32_t n; 12066 uint32_t m; 12067 bool wback; 12068 bool register_index; 12069 12070 switch (encoding) { 12071 case eEncodingT1: 12072 case eEncodingA1: { 12073 uint32_t size = Bits32(opcode, 11, 10); 12074 uint32_t index_align = Bits32(opcode, 7, 4); 12075 // if size == '11' then SEE VLD1 (single element to all lanes); 12076 if (size == 3) 12077 return EmulateVLD1SingleAll(opcode, encoding); 12078 // case size of 12079 if (size == 0) // when '00' 12080 { 12081 // if index_align<0> != '0' then UNDEFINED; 12082 if (BitIsClear(index_align, 0)) 12083 return false; 12084 12085 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12086 ebytes = 1; 12087 esize = 8; 12088 index = Bits32(index_align, 3, 1); 12089 alignment = 1; 12090 } else if (size == 1) // when '01' 12091 { 12092 // if index_align<1> != '0' then UNDEFINED; 12093 if (BitIsClear(index_align, 1)) 12094 return false; 12095 12096 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12097 ebytes = 2; 12098 esize = 16; 12099 index = Bits32(index_align, 3, 2); 12100 12101 // alignment = if index_align<0> == '0' then 1 else 2; 12102 if (BitIsClear(index_align, 0)) 12103 alignment = 1; 12104 else 12105 alignment = 2; 12106 } else if (size == 2) // when '10' 12107 { 12108 // if index_align<2> != '0' then UNDEFINED; 12109 if (BitIsClear(index_align, 2)) 12110 return false; 12111 12112 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12113 // UNDEFINED; 12114 if ((Bits32(index_align, 1, 0) != 0) && 12115 (Bits32(index_align, 1, 0) != 3)) 12116 return false; 12117 12118 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12119 ebytes = 4; 12120 esize = 32; 12121 index = Bit32(index_align, 3); 12122 12123 // alignment = if index_align<1:0> == '00' then 1 else 4; 12124 if (Bits32(index_align, 1, 0) == 0) 12125 alignment = 1; 12126 else 12127 alignment = 4; 12128 } else { 12129 return false; 12130 } 12131 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12132 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12133 n = Bits32(opcode, 19, 16); 12134 m = Bits32(opcode, 3, 0); 12135 12136 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12137 // then UNPREDICTABLE; 12138 wback = (m != 15); 12139 register_index = ((m != 15) && (m != 13)); 12140 12141 if (n == 15) 12142 return false; 12143 12144 } break; 12145 12146 default: 12147 return false; 12148 } 12149 12150 RegisterInfo base_reg; 12151 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12152 12153 uint32_t Rn = ReadCoreReg(n, &success); 12154 if (!success) 12155 return false; 12156 12157 // address = R[n]; if (address MOD alignment) != 0 then 12158 // GenerateAlignmentException(); 12159 addr_t address = Rn; 12160 if ((address % alignment) != 0) 12161 return false; 12162 12163 EmulateInstruction::Context context; 12164 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12165 if (wback) { 12166 uint32_t Rm = ReadCoreReg(m, &success); 12167 if (!success) 12168 return false; 12169 12170 uint32_t offset; 12171 if (register_index) 12172 offset = Rm; 12173 else 12174 offset = ebytes; 12175 12176 uint32_t value = Rn + offset; 12177 12178 context.type = eContextAdjustBaseRegister; 12179 context.SetRegisterPlusOffset(base_reg, offset); 12180 12181 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12182 value)) 12183 return false; 12184 } 12185 12186 // Elem[D[d],index,esize] = MemU[address,ebytes]; 12187 uint32_t element = MemURead(context, address, esize, 0, &success); 12188 if (!success) 12189 return false; 12190 12191 element = element << (index * esize); 12192 12193 uint64_t reg_data = 12194 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12195 if (!success) 12196 return false; 12197 12198 uint64_t all_ones = -1; 12199 uint64_t mask = all_ones 12200 << ((index + 1) * esize); // mask is all 1's to left of 12201 // where 'element' goes, & all 0's 12202 // at element & to the right of element. 12203 if (index > 0) 12204 mask = mask | Bits64(all_ones, (index * esize) - 1, 12205 0); // add 1's to the right of where 'element' goes. 12206 // now mask should be 0's where element goes & 1's everywhere else. 12207 12208 uint64_t masked_reg = 12209 reg_data & mask; // Take original reg value & zero out 'element' bits 12210 reg_data = 12211 masked_reg & element; // Put 'element' into those bits in reg_data. 12212 12213 context.type = eContextRegisterLoad; 12214 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 12215 reg_data)) 12216 return false; 12217 } 12218 return true; 12219 } 12220 12221 // A8.6.391 VST1 (multiple single elements) Vector Store (multiple single 12222 // elements) stores elements to memory from one, two, three, or four registers, 12223 // without interleaving. Every element of each register is stored. 12224 bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode, 12225 ARMEncoding encoding) { 12226 #if 0 12227 if ConditionPassed() then 12228 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12229 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12230 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12231 for r = 0 to regs-1 12232 for e = 0 to elements-1 12233 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12234 address = address + ebytes; 12235 #endif 12236 12237 bool success = false; 12238 12239 if (ConditionPassed(opcode)) { 12240 uint32_t regs; 12241 uint32_t alignment; 12242 uint32_t ebytes; 12243 uint32_t esize; 12244 uint32_t elements; 12245 uint32_t d; 12246 uint32_t n; 12247 uint32_t m; 12248 bool wback; 12249 bool register_index; 12250 12251 switch (encoding) { 12252 case eEncodingT1: 12253 case eEncodingA1: { 12254 uint32_t type = Bits32(opcode, 11, 8); 12255 uint32_t align = Bits32(opcode, 5, 4); 12256 12257 // case type of 12258 if (type == 7) // when '0111' 12259 { 12260 // regs = 1; if align<1> == '1' then UNDEFINED; 12261 regs = 1; 12262 if (BitIsSet(align, 1)) 12263 return false; 12264 } else if (type == 10) // when '1010' 12265 { 12266 // regs = 2; if align == '11' then UNDEFINED; 12267 regs = 2; 12268 if (align == 3) 12269 return false; 12270 } else if (type == 6) // when '0110' 12271 { 12272 // regs = 3; if align<1> == '1' then UNDEFINED; 12273 regs = 3; 12274 if (BitIsSet(align, 1)) 12275 return false; 12276 } else if (type == 2) // when '0010' 12277 // regs = 4; 12278 regs = 4; 12279 else // otherwise 12280 // SEE 'Related encodings'; 12281 return false; 12282 12283 // alignment = if align == '00' then 1 else 4 << UInt(align); 12284 if (align == 0) 12285 alignment = 1; 12286 else 12287 alignment = 4 << align; 12288 12289 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 12290 ebytes = 1 << Bits32(opcode, 7, 6); 12291 esize = 8 * ebytes; 12292 elements = 8 / ebytes; 12293 12294 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12295 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12296 n = Bits32(opcode, 19, 16); 12297 m = Bits32(opcode, 3, 0); 12298 12299 // wback = (m != 15); register_index = (m != 15 && m != 13); 12300 wback = (m != 15); 12301 register_index = ((m != 15) && (m != 13)); 12302 12303 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12304 if ((d + regs) > 32) 12305 return false; 12306 12307 if (n == 15) 12308 return false; 12309 12310 } break; 12311 12312 default: 12313 return false; 12314 } 12315 12316 RegisterInfo base_reg; 12317 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12318 12319 uint32_t Rn = ReadCoreReg(n, &success); 12320 if (!success) 12321 return false; 12322 12323 // address = R[n]; if (address MOD alignment) != 0 then 12324 // GenerateAlignmentException(); 12325 addr_t address = Rn; 12326 if ((address % alignment) != 0) 12327 return false; 12328 12329 EmulateInstruction::Context context; 12330 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12331 if (wback) { 12332 uint32_t Rm = ReadCoreReg(m, &success); 12333 if (!success) 12334 return false; 12335 12336 uint32_t offset; 12337 if (register_index) 12338 offset = Rm; 12339 else 12340 offset = 8 * regs; 12341 12342 context.type = eContextAdjustBaseRegister; 12343 context.SetRegisterPlusOffset(base_reg, offset); 12344 12345 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12346 Rn + offset)) 12347 return false; 12348 } 12349 12350 RegisterInfo data_reg; 12351 context.type = eContextRegisterStore; 12352 // for r = 0 to regs-1 12353 for (uint32_t r = 0; r < regs; ++r) { 12354 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 12355 uint64_t register_data = ReadRegisterUnsigned( 12356 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 12357 if (!success) 12358 return false; 12359 12360 // for e = 0 to elements-1 12361 for (uint32_t e = 0; e < elements; ++e) { 12362 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12363 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize); 12364 12365 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12366 address - Rn); 12367 if (!MemUWrite(context, address, word, ebytes)) 12368 return false; 12369 12370 // address = address + ebytes; 12371 address = address + ebytes; 12372 } 12373 } 12374 } 12375 return true; 12376 } 12377 12378 // A8.6.392 VST1 (single element from one lane) This instruction stores one 12379 // element to memory from one element of a register. 12380 bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode, 12381 ARMEncoding encoding) { 12382 #if 0 12383 if ConditionPassed() then 12384 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12385 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12386 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12387 MemU[address,ebytes] = Elem[D[d],index,esize]; 12388 #endif 12389 12390 bool success = false; 12391 12392 if (ConditionPassed(opcode)) { 12393 uint32_t ebytes; 12394 uint32_t esize; 12395 uint32_t index; 12396 uint32_t alignment; 12397 uint32_t d; 12398 uint32_t n; 12399 uint32_t m; 12400 bool wback; 12401 bool register_index; 12402 12403 switch (encoding) { 12404 case eEncodingT1: 12405 case eEncodingA1: { 12406 uint32_t size = Bits32(opcode, 11, 10); 12407 uint32_t index_align = Bits32(opcode, 7, 4); 12408 12409 // if size == '11' then UNDEFINED; 12410 if (size == 3) 12411 return false; 12412 12413 // case size of 12414 if (size == 0) // when '00' 12415 { 12416 // if index_align<0> != '0' then UNDEFINED; 12417 if (BitIsClear(index_align, 0)) 12418 return false; 12419 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12420 ebytes = 1; 12421 esize = 8; 12422 index = Bits32(index_align, 3, 1); 12423 alignment = 1; 12424 } else if (size == 1) // when '01' 12425 { 12426 // if index_align<1> != '0' then UNDEFINED; 12427 if (BitIsClear(index_align, 1)) 12428 return false; 12429 12430 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12431 ebytes = 2; 12432 esize = 16; 12433 index = Bits32(index_align, 3, 2); 12434 12435 // alignment = if index_align<0> == '0' then 1 else 2; 12436 if (BitIsClear(index_align, 0)) 12437 alignment = 1; 12438 else 12439 alignment = 2; 12440 } else if (size == 2) // when '10' 12441 { 12442 // if index_align<2> != '0' then UNDEFINED; 12443 if (BitIsClear(index_align, 2)) 12444 return false; 12445 12446 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12447 // UNDEFINED; 12448 if ((Bits32(index_align, 1, 0) != 0) && 12449 (Bits32(index_align, 1, 0) != 3)) 12450 return false; 12451 12452 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12453 ebytes = 4; 12454 esize = 32; 12455 index = Bit32(index_align, 3); 12456 12457 // alignment = if index_align<1:0> == '00' then 1 else 4; 12458 if (Bits32(index_align, 1, 0) == 0) 12459 alignment = 1; 12460 else 12461 alignment = 4; 12462 } else { 12463 return false; 12464 } 12465 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12466 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12467 n = Bits32(opcode, 19, 16); 12468 m = Bits32(opcode, 3, 0); 12469 12470 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12471 // then UNPREDICTABLE; 12472 wback = (m != 15); 12473 register_index = ((m != 15) && (m != 13)); 12474 12475 if (n == 15) 12476 return false; 12477 } break; 12478 12479 default: 12480 return false; 12481 } 12482 12483 RegisterInfo base_reg; 12484 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12485 12486 uint32_t Rn = ReadCoreReg(n, &success); 12487 if (!success) 12488 return false; 12489 12490 // address = R[n]; if (address MOD alignment) != 0 then 12491 // GenerateAlignmentException(); 12492 addr_t address = Rn; 12493 if ((address % alignment) != 0) 12494 return false; 12495 12496 EmulateInstruction::Context context; 12497 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12498 if (wback) { 12499 uint32_t Rm = ReadCoreReg(m, &success); 12500 if (!success) 12501 return false; 12502 12503 uint32_t offset; 12504 if (register_index) 12505 offset = Rm; 12506 else 12507 offset = ebytes; 12508 12509 context.type = eContextAdjustBaseRegister; 12510 context.SetRegisterPlusOffset(base_reg, offset); 12511 12512 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12513 Rn + offset)) 12514 return false; 12515 } 12516 12517 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12518 uint64_t register_data = 12519 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12520 if (!success) 12521 return false; 12522 12523 uint64_t word = 12524 Bits64(register_data, ((index + 1) * esize) - 1, index * esize); 12525 12526 RegisterInfo data_reg; 12527 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12528 context.type = eContextRegisterStore; 12529 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 12530 12531 if (!MemUWrite(context, address, word, ebytes)) 12532 return false; 12533 } 12534 return true; 12535 } 12536 12537 // A8.6.309 VLD1 (single element to all lanes) This instruction loads one 12538 // element from memory into every element of one or two vectors. 12539 bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode, 12540 const ARMEncoding encoding) { 12541 #if 0 12542 if ConditionPassed() then 12543 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12544 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12545 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12546 replicated_element = Replicate(MemU[address,ebytes], elements); 12547 for r = 0 to regs-1 12548 D[d+r] = replicated_element; 12549 #endif 12550 12551 bool success = false; 12552 12553 if (ConditionPassed(opcode)) { 12554 uint32_t ebytes; 12555 uint32_t elements; 12556 uint32_t regs; 12557 uint32_t alignment; 12558 uint32_t d; 12559 uint32_t n; 12560 uint32_t m; 12561 bool wback; 12562 bool register_index; 12563 12564 switch (encoding) { 12565 case eEncodingT1: 12566 case eEncodingA1: { 12567 // if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12568 uint32_t size = Bits32(opcode, 7, 6); 12569 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4))) 12570 return false; 12571 12572 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' 12573 // then 1 else 2; 12574 ebytes = 1 << size; 12575 elements = 8 / ebytes; 12576 if (BitIsClear(opcode, 5)) 12577 regs = 1; 12578 else 12579 regs = 2; 12580 12581 // alignment = if a == '0' then 1 else ebytes; 12582 if (BitIsClear(opcode, 4)) 12583 alignment = 1; 12584 else 12585 alignment = ebytes; 12586 12587 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12588 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12589 n = Bits32(opcode, 19, 16); 12590 m = Bits32(opcode, 3, 0); 12591 12592 // wback = (m != 15); register_index = (m != 15 && m != 13); 12593 wback = (m != 15); 12594 register_index = ((m != 15) && (m != 13)); 12595 12596 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12597 if ((d + regs) > 32) 12598 return false; 12599 12600 if (n == 15) 12601 return false; 12602 } break; 12603 12604 default: 12605 return false; 12606 } 12607 12608 RegisterInfo base_reg; 12609 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12610 12611 uint32_t Rn = ReadCoreReg(n, &success); 12612 if (!success) 12613 return false; 12614 12615 // address = R[n]; if (address MOD alignment) != 0 then 12616 // GenerateAlignmentException(); 12617 addr_t address = Rn; 12618 if ((address % alignment) != 0) 12619 return false; 12620 12621 EmulateInstruction::Context context; 12622 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12623 if (wback) { 12624 uint32_t Rm = ReadCoreReg(m, &success); 12625 if (!success) 12626 return false; 12627 12628 uint32_t offset; 12629 if (register_index) 12630 offset = Rm; 12631 else 12632 offset = ebytes; 12633 12634 context.type = eContextAdjustBaseRegister; 12635 context.SetRegisterPlusOffset(base_reg, offset); 12636 12637 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12638 Rn + offset)) 12639 return false; 12640 } 12641 12642 // replicated_element = Replicate(MemU[address,ebytes], elements); 12643 12644 context.type = eContextRegisterLoad; 12645 uint64_t word = MemURead(context, address, ebytes, 0, &success); 12646 if (!success) 12647 return false; 12648 12649 uint64_t replicated_element = 0; 12650 uint32_t esize = ebytes * 8; 12651 for (uint32_t e = 0; e < elements; ++e) 12652 replicated_element = 12653 (replicated_element << esize) | Bits64(word, esize - 1, 0); 12654 12655 // for r = 0 to regs-1 12656 for (uint32_t r = 0; r < regs; ++r) { 12657 // D[d+r] = replicated_element; 12658 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12659 replicated_element)) 12660 return false; 12661 } 12662 } 12663 return true; 12664 } 12665 12666 // B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const? 12667 // instruction provides an exception return without the use of the stack. It 12668 // subtracts the immediate constant from the LR, branches to the resulting 12669 // address, and also copies the SPSR to the CPSR. 12670 bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode, 12671 const ARMEncoding encoding) { 12672 #if 0 12673 if ConditionPassed() then 12674 EncodingSpecificOperations(); 12675 if CurrentInstrSet() == InstrSet_ThumbEE then 12676 UNPREDICTABLE; 12677 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12678 case opcode of 12679 when '0000' result = R[n] AND operand2; // AND 12680 when '0001' result = R[n] EOR operand2; // EOR 12681 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12682 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12683 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12684 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12685 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12686 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12687 when '1100' result = R[n] OR operand2; // ORR 12688 when '1101' result = operand2; // MOV 12689 when '1110' result = R[n] AND NOT(operand2); // BIC 12690 when '1111' result = NOT(operand2); // MVN 12691 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12692 BranchWritePC(result); 12693 #endif 12694 12695 bool success = false; 12696 12697 if (ConditionPassed(opcode)) { 12698 uint32_t n; 12699 uint32_t m; 12700 uint32_t imm32; 12701 bool register_form; 12702 ARM_ShifterType shift_t; 12703 uint32_t shift_n; 12704 uint32_t code; 12705 12706 switch (encoding) { 12707 case eEncodingT1: 12708 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14; 12709 // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; 12710 // // = SUB 12711 n = 14; 12712 imm32 = Bits32(opcode, 7, 0); 12713 register_form = false; 12714 code = 2; 12715 12716 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12717 if (InITBlock() && !LastInITBlock()) 12718 return false; 12719 12720 break; 12721 12722 case eEncodingA1: 12723 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12724 n = Bits32(opcode, 19, 16); 12725 imm32 = ARMExpandImm(opcode); 12726 register_form = false; 12727 code = Bits32(opcode, 24, 21); 12728 12729 break; 12730 12731 case eEncodingA2: 12732 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12733 n = Bits32(opcode, 19, 16); 12734 m = Bits32(opcode, 3, 0); 12735 register_form = true; 12736 12737 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12738 shift_n = DecodeImmShiftARM(opcode, shift_t); 12739 12740 break; 12741 12742 default: 12743 return false; 12744 } 12745 12746 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) 12747 // else imm32; 12748 uint32_t operand2; 12749 if (register_form) { 12750 uint32_t Rm = ReadCoreReg(m, &success); 12751 if (!success) 12752 return false; 12753 12754 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success); 12755 if (!success) 12756 return false; 12757 } else { 12758 operand2 = imm32; 12759 } 12760 12761 uint32_t Rn = ReadCoreReg(n, &success); 12762 if (!success) 12763 return false; 12764 12765 AddWithCarryResult result; 12766 12767 // case opcode of 12768 switch (code) { 12769 case 0: // when '0000' 12770 // result = R[n] AND operand2; // AND 12771 result.result = Rn & operand2; 12772 break; 12773 12774 case 1: // when '0001' 12775 // result = R[n] EOR operand2; // EOR 12776 result.result = Rn ^ operand2; 12777 break; 12778 12779 case 2: // when '0010' 12780 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12781 result = AddWithCarry(Rn, ~(operand2), 1); 12782 break; 12783 12784 case 3: // when '0011' 12785 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12786 result = AddWithCarry(~(Rn), operand2, 1); 12787 break; 12788 12789 case 4: // when '0100' 12790 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12791 result = AddWithCarry(Rn, operand2, 0); 12792 break; 12793 12794 case 5: // when '0101' 12795 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12796 result = AddWithCarry(Rn, operand2, APSR_C); 12797 break; 12798 12799 case 6: // when '0110' 12800 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12801 result = AddWithCarry(Rn, ~(operand2), APSR_C); 12802 break; 12803 12804 case 7: // when '0111' 12805 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12806 result = AddWithCarry(~(Rn), operand2, APSR_C); 12807 break; 12808 12809 case 10: // when '1100' 12810 // result = R[n] OR operand2; // ORR 12811 result.result = Rn | operand2; 12812 break; 12813 12814 case 11: // when '1101' 12815 // result = operand2; // MOV 12816 result.result = operand2; 12817 break; 12818 12819 case 12: // when '1110' 12820 // result = R[n] AND NOT(operand2); // BIC 12821 result.result = Rn & ~(operand2); 12822 break; 12823 12824 case 15: // when '1111' 12825 // result = NOT(operand2); // MVN 12826 result.result = ~(operand2); 12827 break; 12828 12829 default: 12830 return false; 12831 } 12832 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12833 12834 // For now, in emulation mode, we don't have access to the SPSR, so we will 12835 // use the CPSR instead, and hope for the best. 12836 uint32_t spsr = 12837 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12838 if (!success) 12839 return false; 12840 12841 CPSRWriteByInstr(spsr, 15, true); 12842 12843 // BranchWritePC(result); 12844 EmulateInstruction::Context context; 12845 context.type = eContextAdjustPC; 12846 context.SetImmediate(result.result); 12847 12848 BranchWritePC(context, result.result); 12849 } 12850 return true; 12851 } 12852 12853 EmulateInstructionARM::ARMOpcode * 12854 EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode, 12855 uint32_t arm_isa) { 12856 static ARMOpcode g_arm_opcodes[] = { 12857 // Prologue instructions 12858 12859 // push register(s) 12860 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12861 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 12862 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12863 &EmulateInstructionARM::EmulatePUSH, "push <register>"}, 12864 12865 // set r7 to point to a stack offset 12866 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12867 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"}, 12868 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12869 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12870 // copy the stack pointer to ip 12871 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, 12872 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"}, 12873 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12874 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"}, 12875 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12876 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12877 12878 // adjust the stack pointer 12879 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12880 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12881 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12882 &EmulateInstructionARM::EmulateSUBSPReg, 12883 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 12884 12885 // push one register 12886 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12887 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12888 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"}, 12889 12890 // vector push consecutive extension register(s) 12891 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12892 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12893 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12894 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12895 12896 // Epilogue instructions 12897 12898 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12899 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12900 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12901 &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12902 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12903 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12904 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12905 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12906 12907 // Supervisor Call (previously Software Interrupt) 12908 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12909 &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12910 12911 // Branch instructions 12912 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and 12913 // "bl <label>". 12914 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, 12915 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12916 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12917 &EmulateInstructionARM::EmulateB, "b #imm24"}, 12918 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12919 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12920 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, 12921 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12922 // for example, "bx lr" 12923 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, 12924 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12925 // bxj 12926 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, 12927 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12928 12929 // Data-processing instructions 12930 // adc (immediate) 12931 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12932 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12933 // adc (register) 12934 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12935 &EmulateInstructionARM::EmulateADCReg, 12936 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12937 // add (immediate) 12938 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12939 &EmulateInstructionARM::EmulateADDImmARM, 12940 "add{s}<c> <Rd>, <Rn>, #const"}, 12941 // add (register) 12942 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12943 &EmulateInstructionARM::EmulateADDReg, 12944 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12945 // add (register-shifted register) 12946 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, 12947 &EmulateInstructionARM::EmulateADDRegShift, 12948 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12949 // adr 12950 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12951 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12952 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, 12953 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12954 // and (immediate) 12955 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12956 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12957 // and (register) 12958 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12959 &EmulateInstructionARM::EmulateANDReg, 12960 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12961 // bic (immediate) 12962 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12963 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12964 // bic (register) 12965 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12966 &EmulateInstructionARM::EmulateBICReg, 12967 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12968 // eor (immediate) 12969 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12970 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12971 // eor (register) 12972 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12973 &EmulateInstructionARM::EmulateEORReg, 12974 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12975 // orr (immediate) 12976 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12977 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12978 // orr (register) 12979 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12980 &EmulateInstructionARM::EmulateORRReg, 12981 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12982 // rsb (immediate) 12983 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12984 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12985 // rsb (register) 12986 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12987 &EmulateInstructionARM::EmulateRSBReg, 12988 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12989 // rsc (immediate) 12990 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12991 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12992 // rsc (register) 12993 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12994 &EmulateInstructionARM::EmulateRSCReg, 12995 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12996 // sbc (immediate) 12997 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12998 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12999 // sbc (register) 13000 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13001 &EmulateInstructionARM::EmulateSBCReg, 13002 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13003 // sub (immediate, ARM) 13004 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13005 &EmulateInstructionARM::EmulateSUBImmARM, 13006 "sub{s}<c> <Rd>, <Rn>, #<const>"}, 13007 // sub (sp minus immediate) 13008 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13009 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 13010 // sub (register) 13011 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13012 &EmulateInstructionARM::EmulateSUBReg, 13013 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 13014 // teq (immediate) 13015 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13016 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 13017 // teq (register) 13018 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13019 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13020 // tst (immediate) 13021 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13022 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 13023 // tst (register) 13024 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13025 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 13026 13027 // mov (immediate) 13028 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13029 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 13030 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 13031 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"}, 13032 // mov (register) 13033 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13034 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 13035 // mvn (immediate) 13036 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13037 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 13038 // mvn (register) 13039 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13040 &EmulateInstructionARM::EmulateMVNReg, 13041 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 13042 // cmn (immediate) 13043 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13044 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13045 // cmn (register) 13046 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13047 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13048 // cmp (immediate) 13049 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13050 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 13051 // cmp (register) 13052 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13053 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 13054 // asr (immediate) 13055 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, 13056 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 13057 // asr (register) 13058 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13059 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 13060 // lsl (immediate) 13061 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13062 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 13063 // lsl (register) 13064 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, 13065 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 13066 // lsr (immediate) 13067 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, 13068 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 13069 // lsr (register) 13070 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13071 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 13072 // rrx is a special case encoding of ror (immediate) 13073 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13074 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 13075 // ror (immediate) 13076 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13077 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 13078 // ror (register) 13079 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, 13080 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 13081 // mul 13082 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, 13083 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"}, 13084 13085 // subs pc, lr and related instructions 13086 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13087 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13088 "<opc>S<c> PC,#<const> | <Rn>,#<const>"}, 13089 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, 13090 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13091 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"}, 13092 13093 // Load instructions 13094 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13095 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13096 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13097 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"}, 13098 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13099 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13100 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13101 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"}, 13102 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13103 &EmulateInstructionARM::EmulateLDRImmediateARM, 13104 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"}, 13105 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13106 &EmulateInstructionARM::EmulateLDRRegister, 13107 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"}, 13108 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13109 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 13110 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13111 &EmulateInstructionARM::EmulateLDRBRegister, 13112 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"}, 13113 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13114 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13115 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13116 &EmulateInstructionARM::EmulateLDRHRegister, 13117 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13118 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13119 &EmulateInstructionARM::EmulateLDRSBImmediate, 13120 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"}, 13121 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13122 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"}, 13123 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13124 &EmulateInstructionARM::EmulateLDRSBRegister, 13125 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13126 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13127 &EmulateInstructionARM::EmulateLDRSHImmediate, 13128 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 13129 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13130 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13131 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13132 &EmulateInstructionARM::EmulateLDRSHRegister, 13133 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13134 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13135 &EmulateInstructionARM::EmulateLDRDImmediate, 13136 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 13137 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13138 &EmulateInstructionARM::EmulateLDRDRegister, 13139 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13140 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13141 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13142 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13143 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13144 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13145 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13146 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13147 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13148 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13149 &EmulateInstructionARM::EmulateVLD1Multiple, 13150 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13151 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13152 &EmulateInstructionARM::EmulateVLD1Single, 13153 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13154 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13155 &EmulateInstructionARM::EmulateVLD1SingleAll, 13156 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13157 13158 // Store instructions 13159 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13160 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13161 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13162 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"}, 13163 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13164 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13165 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13166 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"}, 13167 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13168 &EmulateInstructionARM::EmulateSTRRegister, 13169 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"}, 13170 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13171 &EmulateInstructionARM::EmulateSTRHRegister, 13172 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"}, 13173 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13174 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 13175 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13176 &EmulateInstructionARM::EmulateSTRBImmARM, 13177 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13178 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13179 &EmulateInstructionARM::EmulateSTRImmARM, 13180 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13181 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13182 &EmulateInstructionARM::EmulateSTRDImm, 13183 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 13184 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13185 &EmulateInstructionARM::EmulateSTRDReg, 13186 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13187 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13188 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13189 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13190 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13191 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13192 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 13193 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13194 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 13195 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13196 &EmulateInstructionARM::EmulateVST1Multiple, 13197 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13198 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13199 &EmulateInstructionARM::EmulateVST1Single, 13200 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13201 13202 // Other instructions 13203 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13204 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13205 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13206 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"}, 13207 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13208 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13209 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13210 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"}, 13211 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13212 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"} 13213 13214 }; 13215 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 13216 13217 for (size_t i = 0; i < k_num_arm_opcodes; ++i) { 13218 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 13219 (g_arm_opcodes[i].variants & arm_isa) != 0) 13220 return &g_arm_opcodes[i]; 13221 } 13222 return nullptr; 13223 } 13224 13225 EmulateInstructionARM::ARMOpcode * 13226 EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode, 13227 uint32_t arm_isa) { 13228 13229 static ARMOpcode g_thumb_opcodes[] = { 13230 // Prologue instructions 13231 13232 // push register(s) 13233 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, 13234 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 13235 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13236 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"}, 13237 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13238 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"}, 13239 13240 // set r7 to point to a stack offset 13241 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13242 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"}, 13243 // copy the stack pointer to r7 13244 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, 13245 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"}, 13246 // move from high register to low register (comes after "mov r7, sp" to 13247 // resolve ambiguity) 13248 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, 13249 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"}, 13250 13251 // PC-relative load into register (see also EmulateADDSPRm) 13252 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13253 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 13254 13255 // adjust the stack pointer 13256 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, 13257 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 13258 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13259 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 13260 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13261 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 13262 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13263 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 13264 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13265 &EmulateInstructionARM::EmulateSUBSPReg, 13266 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 13267 13268 // vector push consecutive extension register(s) 13269 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13270 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 13271 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13272 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 13273 13274 // Epilogue instructions 13275 13276 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13277 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 13278 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13279 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 13280 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13281 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 13282 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13283 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"}, 13284 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13285 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"}, 13286 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13287 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 13288 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13289 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 13290 13291 // Supervisor Call (previously Software Interrupt) 13292 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13293 &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 13294 13295 // If Then makes up to four following instructions conditional. 13296 // The next 5 opcode _must_ come before the if then instruction 13297 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13298 &EmulateInstructionARM::EmulateNop, "nop"}, 13299 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13300 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 13301 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13302 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 13303 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13304 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 13305 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13306 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 13307 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13308 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 13309 13310 // Branch instructions 13311 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 13312 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13313 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 13314 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13315 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 13316 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13317 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 13318 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13319 &EmulateInstructionARM::EmulateB, 13320 "b<c>.w #imm8 (outside or last in IT)"}, 13321 // J1 == J2 == 1 13322 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, 13323 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 13324 // J1 == J2 == 1 13325 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, 13326 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 13327 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, 13328 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 13329 // for example, "bx lr" 13330 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, 13331 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 13332 // bxj 13333 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, 13334 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 13335 // compare and branch 13336 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13337 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 13338 // table branch byte 13339 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13340 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 13341 // table branch halfword 13342 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13343 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 13344 13345 // Data-processing instructions 13346 // adc (immediate) 13347 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13348 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 13349 // adc (register) 13350 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, 13351 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 13352 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13353 &EmulateInstructionARM::EmulateADCReg, 13354 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13355 // add (register) 13356 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13357 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 13358 // Make sure "add sp, <Rm>" comes before this instruction, so there's no 13359 // ambiguity decoding the two. 13360 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, 13361 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 13362 // adr 13363 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13364 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13365 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13366 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 13367 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13368 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13369 // and (immediate) 13370 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13371 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 13372 // and (register) 13373 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13374 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 13375 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13376 &EmulateInstructionARM::EmulateANDReg, 13377 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13378 // bic (immediate) 13379 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13380 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 13381 // bic (register) 13382 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, 13383 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 13384 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13385 &EmulateInstructionARM::EmulateBICReg, 13386 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13387 // eor (immediate) 13388 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13389 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 13390 // eor (register) 13391 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, 13392 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 13393 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13394 &EmulateInstructionARM::EmulateEORReg, 13395 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13396 // orr (immediate) 13397 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13398 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 13399 // orr (register) 13400 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, 13401 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 13402 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13403 &EmulateInstructionARM::EmulateORRReg, 13404 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13405 // rsb (immediate) 13406 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, 13407 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 13408 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13409 &EmulateInstructionARM::EmulateRSBImm, 13410 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 13411 // rsb (register) 13412 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13413 &EmulateInstructionARM::EmulateRSBReg, 13414 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13415 // sbc (immediate) 13416 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13417 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13418 // sbc (register) 13419 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, 13420 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 13421 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13422 &EmulateInstructionARM::EmulateSBCReg, 13423 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13424 // add (immediate, Thumb) 13425 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13426 &EmulateInstructionARM::EmulateADDImmThumb, 13427 "adds|add<c> <Rd>,<Rn>,#<imm3>"}, 13428 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13429 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"}, 13430 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13431 &EmulateInstructionARM::EmulateADDImmThumb, 13432 "add{s}<c>.w <Rd>,<Rn>,#<const>"}, 13433 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13434 &EmulateInstructionARM::EmulateADDImmThumb, 13435 "addw<c> <Rd>,<Rn>,#<imm12>"}, 13436 // sub (immediate, Thumb) 13437 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13438 &EmulateInstructionARM::EmulateSUBImmThumb, 13439 "subs|sub<c> <Rd>, <Rn> #imm3"}, 13440 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, 13441 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 13442 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13443 &EmulateInstructionARM::EmulateSUBImmThumb, 13444 "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 13445 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13446 &EmulateInstructionARM::EmulateSUBImmThumb, 13447 "subw<c> <Rd>, <Rn>, #imm12"}, 13448 // sub (sp minus immediate) 13449 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13450 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 13451 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13452 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 13453 // sub (register) 13454 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13455 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 13456 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13457 &EmulateInstructionARM::EmulateSUBReg, 13458 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 13459 // teq (immediate) 13460 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13461 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 13462 // teq (register) 13463 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13464 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13465 // tst (immediate) 13466 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13467 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 13468 // tst (register) 13469 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, 13470 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 13471 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13472 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 13473 13474 // move from high register to high register 13475 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, 13476 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 13477 // move from low register to low register 13478 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13479 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 13480 // mov{s}<c>.w <Rd>, <Rm> 13481 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13482 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 13483 // move immediate 13484 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13485 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 13486 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13487 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 13488 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13489 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 13490 // mvn (immediate) 13491 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13492 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 13493 // mvn (register) 13494 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13495 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 13496 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13497 &EmulateInstructionARM::EmulateMVNReg, 13498 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 13499 // cmn (immediate) 13500 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13501 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13502 // cmn (register) 13503 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13504 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 13505 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13506 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13507 // cmp (immediate) 13508 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13509 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 13510 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13511 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 13512 // cmp (register) (Rn and Rm both from r0-r7) 13513 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, 13514 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13515 // cmp (register) (Rn and Rm not both from r0-r7) 13516 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, 13517 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13518 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, 13519 &EmulateInstructionARM::EmulateCMPReg, 13520 "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 13521 // asr (immediate) 13522 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13523 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 13524 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13525 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 13526 // asr (register) 13527 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, 13528 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 13529 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13530 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13531 // lsl (immediate) 13532 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13533 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 13534 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13535 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 13536 // lsl (register) 13537 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13538 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 13539 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13540 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13541 // lsr (immediate) 13542 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13543 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 13544 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13545 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 13546 // lsr (register) 13547 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13548 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 13549 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13550 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13551 // rrx is a special case encoding of ror (immediate) 13552 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13553 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 13554 // ror (immediate) 13555 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13556 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 13557 // ror (register) 13558 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13559 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 13560 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13561 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13562 // mul 13563 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13564 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"}, 13565 // mul 13566 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13567 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"}, 13568 13569 // subs pc, lr and related instructions 13570 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13571 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"}, 13572 13573 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE 13574 // LDM.. Instructions in this table; 13575 // otherwise the wrong instructions will be selected. 13576 13577 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13578 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"}, 13579 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13580 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"}, 13581 13582 // Load instructions 13583 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13584 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13585 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13586 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"}, 13587 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13588 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13589 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13590 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 13591 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13592 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 13593 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13594 &EmulateInstructionARM::EmulateLDRRtRnImm, 13595 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 13596 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13597 &EmulateInstructionARM::EmulateLDRRtRnImm, 13598 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 13599 // Thumb2 PC-relative load into register 13600 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13601 &EmulateInstructionARM::EmulateLDRRtPCRelative, 13602 "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 13603 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13604 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"}, 13605 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13606 &EmulateInstructionARM::EmulateLDRRegister, 13607 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"}, 13608 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13609 &EmulateInstructionARM::EmulateLDRBImmediate, 13610 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"}, 13611 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13612 &EmulateInstructionARM::EmulateLDRBImmediate, 13613 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13614 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13615 &EmulateInstructionARM::EmulateLDRBImmediate, 13616 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"}, 13617 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13618 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"}, 13619 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13620 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"}, 13621 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13622 &EmulateInstructionARM::EmulateLDRBRegister, 13623 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13624 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13625 &EmulateInstructionARM::EmulateLDRHImmediate, 13626 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"}, 13627 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13628 &EmulateInstructionARM::EmulateLDRHImmediate, 13629 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13630 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13631 &EmulateInstructionARM::EmulateLDRHImmediate, 13632 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"}, 13633 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13634 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13635 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13636 &EmulateInstructionARM::EmulateLDRHRegister, 13637 "ldrh<c> <Rt>, [<Rn>,<Rm>]"}, 13638 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13639 &EmulateInstructionARM::EmulateLDRHRegister, 13640 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13641 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13642 &EmulateInstructionARM::EmulateLDRSBImmediate, 13643 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"}, 13644 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13645 &EmulateInstructionARM::EmulateLDRSBImmediate, 13646 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13647 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13648 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"}, 13649 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13650 &EmulateInstructionARM::EmulateLDRSBRegister, 13651 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"}, 13652 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13653 &EmulateInstructionARM::EmulateLDRSBRegister, 13654 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13655 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13656 &EmulateInstructionARM::EmulateLDRSHImmediate, 13657 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"}, 13658 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13659 &EmulateInstructionARM::EmulateLDRSHImmediate, 13660 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13661 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13662 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13663 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13664 &EmulateInstructionARM::EmulateLDRSHRegister, 13665 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"}, 13666 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13667 &EmulateInstructionARM::EmulateLDRSHRegister, 13668 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13669 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13670 &EmulateInstructionARM::EmulateLDRDImmediate, 13671 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 13672 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13673 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13674 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13675 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13676 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13677 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13678 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13679 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 13680 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13681 &EmulateInstructionARM::EmulateVLD1Multiple, 13682 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13683 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13684 &EmulateInstructionARM::EmulateVLD1Single, 13685 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13686 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13687 &EmulateInstructionARM::EmulateVLD1SingleAll, 13688 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13689 13690 // Store instructions 13691 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13692 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13693 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13694 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"}, 13695 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13696 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13697 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13698 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"}, 13699 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13700 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"}, 13701 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13702 &EmulateInstructionARM::EmulateSTRThumb, 13703 "str<c>.w <Rt>, [<Rn>,#<imm12>]"}, 13704 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13705 &EmulateInstructionARM::EmulateSTRThumb, 13706 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"}, 13707 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13708 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"}, 13709 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13710 &EmulateInstructionARM::EmulateSTRRegister, 13711 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"}, 13712 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13713 &EmulateInstructionARM::EmulateSTRBThumb, 13714 "strb<c> <Rt>, [<Rn>, #<imm5>]"}, 13715 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13716 &EmulateInstructionARM::EmulateSTRBThumb, 13717 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"}, 13718 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13719 &EmulateInstructionARM::EmulateSTRBThumb, 13720 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"}, 13721 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13722 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"}, 13723 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13724 &EmulateInstructionARM::EmulateSTRHRegister, 13725 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13726 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13727 &EmulateInstructionARM::EmulateSTREX, 13728 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"}, 13729 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13730 &EmulateInstructionARM::EmulateSTRDImm, 13731 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 13732 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13733 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13734 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13735 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13736 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13737 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13738 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13739 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13740 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13741 &EmulateInstructionARM::EmulateVST1Multiple, 13742 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13743 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13744 &EmulateInstructionARM::EmulateVST1Single, 13745 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13746 13747 // Other instructions 13748 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13749 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"}, 13750 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, 13751 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13752 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13753 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"}, 13754 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13755 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13756 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13757 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"}, 13758 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13759 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13760 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13761 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"}, 13762 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13763 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13764 }; 13765 13766 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 13767 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) { 13768 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 13769 (g_thumb_opcodes[i].variants & arm_isa) != 0) 13770 return &g_thumb_opcodes[i]; 13771 } 13772 return nullptr; 13773 } 13774 13775 bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) { 13776 m_arch = arch; 13777 m_arm_isa = 0; 13778 const char *arch_cstr = arch.GetArchitectureName(); 13779 if (arch_cstr) { 13780 if (0 == ::strcasecmp(arch_cstr, "armv4t")) 13781 m_arm_isa = ARMv4T; 13782 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) 13783 m_arm_isa = ARMv5TEJ; 13784 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) 13785 m_arm_isa = ARMv5TE; 13786 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) 13787 m_arm_isa = ARMv5T; 13788 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) 13789 m_arm_isa = ARMv6K; 13790 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) 13791 m_arm_isa = ARMv6T2; 13792 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) 13793 m_arm_isa = ARMv7S; 13794 else if (0 == ::strcasecmp(arch_cstr, "arm")) 13795 m_arm_isa = ARMvAll; 13796 else if (0 == ::strcasecmp(arch_cstr, "thumb")) 13797 m_arm_isa = ARMvAll; 13798 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5)) 13799 m_arm_isa = ARMv4; 13800 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5)) 13801 m_arm_isa = ARMv6; 13802 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5)) 13803 m_arm_isa = ARMv7; 13804 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5)) 13805 m_arm_isa = ARMv8; 13806 } 13807 return m_arm_isa != 0; 13808 } 13809 13810 bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode, 13811 const Address &inst_addr, 13812 Target *target) { 13813 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { 13814 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || 13815 m_arch.IsAlwaysThumbInstructions()) 13816 m_opcode_mode = eModeThumb; 13817 else { 13818 AddressClass addr_class = inst_addr.GetAddressClass(); 13819 13820 if ((addr_class == AddressClass::eCode) || 13821 (addr_class == AddressClass::eUnknown)) 13822 m_opcode_mode = eModeARM; 13823 else if (addr_class == AddressClass::eCodeAlternateISA) 13824 m_opcode_mode = eModeThumb; 13825 else 13826 return false; 13827 } 13828 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions()) 13829 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13830 else 13831 m_opcode_cpsr = CPSR_MODE_USR; 13832 return true; 13833 } 13834 return false; 13835 } 13836 13837 bool EmulateInstructionARM::ReadInstruction() { 13838 bool success = false; 13839 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric, 13840 LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13841 if (success) { 13842 addr_t pc = 13843 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 13844 LLDB_INVALID_ADDRESS, &success); 13845 if (success) { 13846 Context read_inst_context; 13847 read_inst_context.type = eContextReadOpcode; 13848 read_inst_context.SetNoArgs(); 13849 13850 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) { 13851 m_opcode_mode = eModeThumb; 13852 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13853 13854 if (success) { 13855 if ((thumb_opcode & 0xe000) != 0xe000 || 13856 ((thumb_opcode & 0x1800u) == 0)) { 13857 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder()); 13858 } else { 13859 m_opcode.SetOpcode32( 13860 (thumb_opcode << 16) | 13861 MemARead(read_inst_context, pc + 2, 2, 0, &success), 13862 GetByteOrder()); 13863 } 13864 } 13865 } else { 13866 m_opcode_mode = eModeARM; 13867 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success), 13868 GetByteOrder()); 13869 } 13870 13871 if (!m_ignore_conditions) { 13872 // If we are not ignoreing the conditions then init the it session from 13873 // the current value of cpsr. 13874 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | 13875 Bits32(m_opcode_cpsr, 26, 25); 13876 if (it != 0) 13877 m_it_session.InitIT(it); 13878 } 13879 } 13880 } 13881 if (!success) { 13882 m_opcode_mode = eModeInvalid; 13883 m_addr = LLDB_INVALID_ADDRESS; 13884 } 13885 return success; 13886 } 13887 13888 uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; } 13889 13890 bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) { 13891 // If we are ignoring conditions, then always return true. this allows us to 13892 // iterate over disassembly code and still emulate an instruction even if we 13893 // don't have all the right bits set in the CPSR register... 13894 if (m_ignore_conditions) 13895 return true; 13896 13897 const uint32_t cond = CurrentCond(opcode); 13898 if (cond == UINT32_MAX) 13899 return false; 13900 13901 bool result = false; 13902 switch (UnsignedBits(cond, 3, 1)) { 13903 case 0: 13904 if (m_opcode_cpsr == 0) 13905 result = true; 13906 else 13907 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13908 break; 13909 case 1: 13910 if (m_opcode_cpsr == 0) 13911 result = true; 13912 else 13913 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13914 break; 13915 case 2: 13916 if (m_opcode_cpsr == 0) 13917 result = true; 13918 else 13919 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13920 break; 13921 case 3: 13922 if (m_opcode_cpsr == 0) 13923 result = true; 13924 else 13925 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13926 break; 13927 case 4: 13928 if (m_opcode_cpsr == 0) 13929 result = true; 13930 else 13931 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && 13932 ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13933 break; 13934 case 5: 13935 if (m_opcode_cpsr == 0) 13936 result = true; 13937 else { 13938 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13939 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13940 result = n == v; 13941 } 13942 break; 13943 case 6: 13944 if (m_opcode_cpsr == 0) 13945 result = true; 13946 else { 13947 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13948 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13949 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13950 } 13951 break; 13952 case 7: 13953 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13954 // opcodes different meanings, but always means execution happens. 13955 return true; 13956 } 13957 13958 if (cond & 1) 13959 result = !result; 13960 return result; 13961 } 13962 13963 uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) { 13964 switch (m_opcode_mode) { 13965 case eModeInvalid: 13966 break; 13967 13968 case eModeARM: 13969 return UnsignedBits(opcode, 31, 28); 13970 13971 case eModeThumb: 13972 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13973 // 'cond' field of the encoding. 13974 { 13975 const uint32_t byte_size = m_opcode.GetByteSize(); 13976 if (byte_size == 2) { 13977 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 13978 return Bits32(opcode, 11, 8); 13979 } else if (byte_size == 4) { 13980 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 && 13981 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) { 13982 return Bits32(opcode, 25, 22); 13983 } 13984 } else 13985 // We have an invalid thumb instruction, let's bail out. 13986 break; 13987 13988 return m_it_session.GetCond(); 13989 } 13990 } 13991 return UINT32_MAX; // Return invalid value 13992 } 13993 13994 bool EmulateInstructionARM::InITBlock() { 13995 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13996 } 13997 13998 bool EmulateInstructionARM::LastInITBlock() { 13999 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 14000 } 14001 14002 bool EmulateInstructionARM::BadMode(uint32_t mode) { 14003 14004 switch (mode) { 14005 case 16: 14006 return false; // '10000' 14007 case 17: 14008 return false; // '10001' 14009 case 18: 14010 return false; // '10010' 14011 case 19: 14012 return false; // '10011' 14013 case 22: 14014 return false; // '10110' 14015 case 23: 14016 return false; // '10111' 14017 case 27: 14018 return false; // '11011' 14019 case 31: 14020 return false; // '11111' 14021 default: 14022 return true; 14023 } 14024 return true; 14025 } 14026 14027 bool EmulateInstructionARM::CurrentModeIsPrivileged() { 14028 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0); 14029 14030 if (BadMode(mode)) 14031 return false; 14032 14033 if (mode == 16) 14034 return false; 14035 14036 return true; 14037 } 14038 14039 void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask, 14040 bool affect_execstate) { 14041 bool privileged = CurrentModeIsPrivileged(); 14042 14043 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20; 14044 14045 if (BitIsSet(bytemask, 3)) { 14046 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27); 14047 if (affect_execstate) 14048 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24); 14049 } 14050 14051 if (BitIsSet(bytemask, 2)) { 14052 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16); 14053 } 14054 14055 if (BitIsSet(bytemask, 1)) { 14056 if (affect_execstate) 14057 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10); 14058 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9); 14059 if (privileged) 14060 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8); 14061 } 14062 14063 if (BitIsSet(bytemask, 0)) { 14064 if (privileged) 14065 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6); 14066 if (affect_execstate) 14067 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5); 14068 if (privileged) 14069 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0); 14070 } 14071 14072 m_opcode_cpsr = tmp_cpsr; 14073 } 14074 14075 bool EmulateInstructionARM::BranchWritePC(const Context &context, 14076 uint32_t addr) { 14077 addr_t target; 14078 14079 // Check the current instruction set. 14080 if (CurrentInstrSet() == eModeARM) 14081 target = addr & 0xfffffffc; 14082 else 14083 target = addr & 0xfffffffe; 14084 14085 return WriteRegisterUnsigned(context, eRegisterKindGeneric, 14086 LLDB_REGNUM_GENERIC_PC, target); 14087 } 14088 14089 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by 14090 // inspecting addr. 14091 bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) { 14092 addr_t target; 14093 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 14094 // we want to record it and issue a WriteRegister callback so the clients can 14095 // track the mode changes accordingly. 14096 bool cpsr_changed = false; 14097 14098 if (BitIsSet(addr, 0)) { 14099 if (CurrentInstrSet() != eModeThumb) { 14100 SelectInstrSet(eModeThumb); 14101 cpsr_changed = true; 14102 } 14103 target = addr & 0xfffffffe; 14104 context.SetISA(eModeThumb); 14105 } else if (BitIsClear(addr, 1)) { 14106 if (CurrentInstrSet() != eModeARM) { 14107 SelectInstrSet(eModeARM); 14108 cpsr_changed = true; 14109 } 14110 target = addr & 0xfffffffc; 14111 context.SetISA(eModeARM); 14112 } else 14113 return false; // address<1:0> == '10' => UNPREDICTABLE 14114 14115 if (cpsr_changed) { 14116 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14117 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14118 return false; 14119 } 14120 return WriteRegisterUnsigned(context, eRegisterKindGeneric, 14121 LLDB_REGNUM_GENERIC_PC, target); 14122 } 14123 14124 // Dispatches to either BXWritePC or BranchWritePC based on architecture 14125 // versions. 14126 bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) { 14127 if (ArchVersion() >= ARMv5T) 14128 return BXWritePC(context, addr); 14129 else 14130 return BranchWritePC((const Context)context, addr); 14131 } 14132 14133 // Dispatches to either BXWritePC or BranchWritePC based on architecture 14134 // versions and current instruction set. 14135 bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) { 14136 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 14137 return BXWritePC(context, addr); 14138 else 14139 return BranchWritePC((const Context)context, addr); 14140 } 14141 14142 EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() { 14143 return m_opcode_mode; 14144 } 14145 14146 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 14147 // ReadInstruction() is performed. This function has a side effect of updating 14148 // the m_new_inst_cpsr member variable if necessary. 14149 bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) { 14150 m_new_inst_cpsr = m_opcode_cpsr; 14151 switch (arm_or_thumb) { 14152 default: 14153 return false; 14154 case eModeARM: 14155 // Clear the T bit. 14156 m_new_inst_cpsr &= ~MASK_CPSR_T; 14157 break; 14158 case eModeThumb: 14159 // Set the T bit. 14160 m_new_inst_cpsr |= MASK_CPSR_T; 14161 break; 14162 } 14163 return true; 14164 } 14165 14166 // This function returns TRUE if the processor currently provides support for 14167 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 14168 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 14169 bool EmulateInstructionARM::UnalignedSupport() { 14170 return (ArchVersion() >= ARMv7); 14171 } 14172 14173 // The main addition and subtraction instructions can produce status 14174 // information about both unsigned carry and signed overflow conditions. This 14175 // status information can be used to synthesize multi-word additions and 14176 // subtractions. 14177 EmulateInstructionARM::AddWithCarryResult 14178 EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) { 14179 uint32_t result; 14180 uint8_t carry_out; 14181 uint8_t overflow; 14182 14183 uint64_t unsigned_sum = x + y + carry_in; 14184 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 14185 14186 result = UnsignedBits(unsigned_sum, 31, 0); 14187 // carry_out = (result == unsigned_sum ? 0 : 1); 14188 overflow = ((int32_t)result == signed_sum ? 0 : 1); 14189 14190 if (carry_in) 14191 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0; 14192 else 14193 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0; 14194 14195 AddWithCarryResult res = {result, carry_out, overflow}; 14196 return res; 14197 } 14198 14199 uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) { 14200 lldb::RegisterKind reg_kind; 14201 uint32_t reg_num; 14202 switch (num) { 14203 case SP_REG: 14204 reg_kind = eRegisterKindGeneric; 14205 reg_num = LLDB_REGNUM_GENERIC_SP; 14206 break; 14207 case LR_REG: 14208 reg_kind = eRegisterKindGeneric; 14209 reg_num = LLDB_REGNUM_GENERIC_RA; 14210 break; 14211 case PC_REG: 14212 reg_kind = eRegisterKindGeneric; 14213 reg_num = LLDB_REGNUM_GENERIC_PC; 14214 break; 14215 default: 14216 if (num < SP_REG) { 14217 reg_kind = eRegisterKindDWARF; 14218 reg_num = dwarf_r0 + num; 14219 } else { 14220 // assert(0 && "Invalid register number"); 14221 *success = false; 14222 return UINT32_MAX; 14223 } 14224 break; 14225 } 14226 14227 // Read our register. 14228 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success); 14229 14230 // When executing an ARM instruction , PC reads as the address of the current 14231 // instruction plus 8. When executing a Thumb instruction , PC reads as the 14232 // address of the current instruction plus 4. 14233 if (num == 15) { 14234 if (CurrentInstrSet() == eModeARM) 14235 val += 8; 14236 else 14237 val += 4; 14238 } 14239 14240 return val; 14241 } 14242 14243 // Write the result to the ARM core register Rd, and optionally update the 14244 // condition flags based on the result. 14245 // 14246 // This helper method tries to encapsulate the following pseudocode from the 14247 // ARM Architecture Reference Manual: 14248 // 14249 // if d == 15 then // Can only occur for encoding A1 14250 // ALUWritePC(result); // setflags is always FALSE here 14251 // else 14252 // R[d] = result; 14253 // if setflags then 14254 // APSR.N = result<31>; 14255 // APSR.Z = IsZeroBit(result); 14256 // APSR.C = carry; 14257 // // APSR.V unchanged 14258 // 14259 // In the above case, the API client does not pass in the overflow arg, which 14260 // defaults to ~0u. 14261 bool EmulateInstructionARM::WriteCoreRegOptionalFlags( 14262 Context &context, const uint32_t result, const uint32_t Rd, bool setflags, 14263 const uint32_t carry, const uint32_t overflow) { 14264 if (Rd == 15) { 14265 if (!ALUWritePC(context, result)) 14266 return false; 14267 } else { 14268 lldb::RegisterKind reg_kind; 14269 uint32_t reg_num; 14270 switch (Rd) { 14271 case SP_REG: 14272 reg_kind = eRegisterKindGeneric; 14273 reg_num = LLDB_REGNUM_GENERIC_SP; 14274 break; 14275 case LR_REG: 14276 reg_kind = eRegisterKindGeneric; 14277 reg_num = LLDB_REGNUM_GENERIC_RA; 14278 break; 14279 default: 14280 reg_kind = eRegisterKindDWARF; 14281 reg_num = dwarf_r0 + Rd; 14282 } 14283 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result)) 14284 return false; 14285 if (setflags) 14286 return WriteFlags(context, result, carry, overflow); 14287 } 14288 return true; 14289 } 14290 14291 // This helper method tries to encapsulate the following pseudocode from the 14292 // ARM Architecture Reference Manual: 14293 // 14294 // APSR.N = result<31>; 14295 // APSR.Z = IsZeroBit(result); 14296 // APSR.C = carry; 14297 // APSR.V = overflow 14298 // 14299 // Default arguments can be specified for carry and overflow parameters, which 14300 // means not to update the respective flags. 14301 bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result, 14302 const uint32_t carry, 14303 const uint32_t overflow) { 14304 m_new_inst_cpsr = m_opcode_cpsr; 14305 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 14306 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 14307 if (carry != ~0u) 14308 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 14309 if (overflow != ~0u) 14310 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 14311 if (m_new_inst_cpsr != m_opcode_cpsr) { 14312 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14313 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14314 return false; 14315 } 14316 return true; 14317 } 14318 14319 bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) { 14320 ARMOpcode *opcode_data = nullptr; 14321 14322 if (m_opcode_mode == eModeThumb) 14323 opcode_data = 14324 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14325 else if (m_opcode_mode == eModeARM) 14326 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14327 14328 const bool auto_advance_pc = 14329 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 14330 m_ignore_conditions = 14331 evaluate_options & eEmulateInstructionOptionIgnoreConditions; 14332 14333 bool success = false; 14334 if (m_opcode_cpsr == 0 || !m_ignore_conditions) { 14335 m_opcode_cpsr = 14336 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 14337 } 14338 14339 // Only return false if we are unable to read the CPSR if we care about 14340 // conditions 14341 if (!success && !m_ignore_conditions) 14342 return false; 14343 14344 uint32_t orig_pc_value = 0; 14345 if (auto_advance_pc) { 14346 orig_pc_value = 14347 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14348 if (!success) 14349 return false; 14350 } 14351 14352 // Call the Emulate... function if we managed to decode the opcode. 14353 if (opcode_data) { 14354 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(), 14355 opcode_data->encoding); 14356 if (!success) 14357 return false; 14358 } 14359 14360 // Advance the ITSTATE bits to their values for the next instruction if we 14361 // haven't just executed an IT instruction what initialized it. 14362 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() && 14363 (opcode_data == nullptr || 14364 opcode_data->callback != &EmulateInstructionARM::EmulateIT)) 14365 m_it_session.ITAdvance(); 14366 14367 if (auto_advance_pc) { 14368 uint32_t after_pc_value = 14369 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14370 if (!success) 14371 return false; 14372 14373 if (auto_advance_pc && (after_pc_value == orig_pc_value)) { 14374 after_pc_value += m_opcode.GetByteSize(); 14375 14376 EmulateInstruction::Context context; 14377 context.type = eContextAdvancePC; 14378 context.SetNoArgs(); 14379 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc, 14380 after_pc_value)) 14381 return false; 14382 } 14383 } 14384 return true; 14385 } 14386 14387 EmulateInstruction::InstructionCondition 14388 EmulateInstructionARM::GetInstructionCondition() { 14389 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32()); 14390 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX) 14391 return EmulateInstruction::UnconditionalCondition; 14392 return cond; 14393 } 14394 14395 bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, 14396 OptionValueDictionary *test_data) { 14397 if (!test_data) { 14398 out_stream->Printf("TestEmulation: Missing test data.\n"); 14399 return false; 14400 } 14401 14402 static ConstString opcode_key("opcode"); 14403 static ConstString before_key("before_state"); 14404 static ConstString after_key("after_state"); 14405 14406 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key); 14407 14408 uint32_t test_opcode; 14409 if ((value_sp.get() == nullptr) || 14410 (value_sp->GetType() != OptionValue::eTypeUInt64)) { 14411 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n"); 14412 return false; 14413 } 14414 test_opcode = value_sp->GetUInt64Value(); 14415 14416 if (arch.GetTriple().getArch() == llvm::Triple::thumb || 14417 arch.IsAlwaysThumbInstructions()) { 14418 m_opcode_mode = eModeThumb; 14419 if (test_opcode < 0x10000) 14420 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder()); 14421 else 14422 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14423 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) { 14424 m_opcode_mode = eModeARM; 14425 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14426 } else { 14427 out_stream->Printf("TestEmulation: Invalid arch.\n"); 14428 return false; 14429 } 14430 14431 EmulationStateARM before_state; 14432 EmulationStateARM after_state; 14433 14434 value_sp = test_data->GetValueForKey(before_key); 14435 if ((value_sp.get() == nullptr) || 14436 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14437 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n"); 14438 return false; 14439 } 14440 14441 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary(); 14442 if (!before_state.LoadStateFromDictionary(state_dictionary)) { 14443 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n"); 14444 return false; 14445 } 14446 14447 value_sp = test_data->GetValueForKey(after_key); 14448 if ((value_sp.get() == nullptr) || 14449 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14450 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n"); 14451 return false; 14452 } 14453 14454 state_dictionary = value_sp->GetAsDictionary(); 14455 if (!after_state.LoadStateFromDictionary(state_dictionary)) { 14456 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n"); 14457 return false; 14458 } 14459 14460 SetBaton((void *)&before_state); 14461 SetCallbacks(&EmulationStateARM::ReadPseudoMemory, 14462 &EmulationStateARM::WritePseudoMemory, 14463 &EmulationStateARM::ReadPseudoRegister, 14464 &EmulationStateARM::WritePseudoRegister); 14465 14466 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 14467 if (!success) { 14468 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n"); 14469 return false; 14470 } 14471 14472 success = before_state.CompareState(after_state); 14473 if (!success) 14474 out_stream->Printf( 14475 "TestEmulation: 'before' and 'after' states do not match.\n"); 14476 14477 return success; 14478 } 14479 // 14480 // 14481 // const char * 14482 // EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 14483 //{ 14484 // if (reg_kind == eRegisterKindGeneric) 14485 // { 14486 // switch (reg_num) 14487 // { 14488 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 14489 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 14490 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 14491 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 14492 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 14493 // default: return NULL; 14494 // } 14495 // } 14496 // else if (reg_kind == eRegisterKindDWARF) 14497 // { 14498 // return GetARMDWARFRegisterName (reg_num); 14499 // } 14500 // return NULL; 14501 //} 14502 // 14503 bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { 14504 unwind_plan.Clear(); 14505 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 14506 14507 UnwindPlan::RowSP row(new UnwindPlan::Row); 14508 14509 // Our previous Call Frame Address is the stack pointer 14510 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0); 14511 14512 unwind_plan.AppendRow(row); 14513 unwind_plan.SetSourceName("EmulateInstructionARM"); 14514 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 14515 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 14516 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 14517 unwind_plan.SetReturnAddressRegister(dwarf_lr); 14518 return true; 14519 } 14520