EmulateInstructionARM.cpp revision 321369
1//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include <stdlib.h> 11 12#include "EmulateInstructionARM.h" 13#include "EmulationStateARM.h" 14#include "lldb/Core/Address.h" 15#include "lldb/Core/ArchSpec.h" 16#include "lldb/Core/PluginManager.h" 17#include "lldb/Host/PosixApi.h" 18#include "lldb/Interpreter/OptionValueArray.h" 19#include "lldb/Interpreter/OptionValueDictionary.h" 20#include "lldb/Symbol/UnwindPlan.h" 21#include "lldb/Utility/ConstString.h" 22#include "lldb/Utility/Stream.h" 23 24#include "Plugins/Process/Utility/ARMDefines.h" 25#include "Plugins/Process/Utility/ARMUtils.h" 26#include "Utility/ARM_DWARF_Registers.h" 27 28#include "llvm/ADT/STLExtras.h" 29#include "llvm/Support/MathExtras.h" // for SignExtend32 template function 30 // and countTrailingZeros function 31 32using namespace lldb; 33using namespace lldb_private; 34 35// Convenient macro definitions. 36#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 37#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 38 39#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 40 41//---------------------------------------------------------------------- 42// 43// ITSession implementation 44// 45//---------------------------------------------------------------------- 46 47static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo ®_info) { 48 ::memset(®_info, 0, sizeof(RegisterInfo)); 49 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); 50 51 if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) { 52 reg_info.byte_size = 16; 53 reg_info.format = eFormatVectorOfUInt8; 54 reg_info.encoding = eEncodingVector; 55 } 56 57 if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) { 58 reg_info.byte_size = 8; 59 reg_info.format = eFormatFloat; 60 reg_info.encoding = eEncodingIEEE754; 61 } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) { 62 reg_info.byte_size = 4; 63 reg_info.format = eFormatFloat; 64 reg_info.encoding = eEncodingIEEE754; 65 } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) { 66 reg_info.byte_size = 12; 67 reg_info.format = eFormatFloat; 68 reg_info.encoding = eEncodingIEEE754; 69 } else { 70 reg_info.byte_size = 4; 71 reg_info.format = eFormatHex; 72 reg_info.encoding = eEncodingUint; 73 } 74 75 reg_info.kinds[eRegisterKindDWARF] = reg_num; 76 77 switch (reg_num) { 78 case dwarf_r0: 79 reg_info.name = "r0"; 80 break; 81 case dwarf_r1: 82 reg_info.name = "r1"; 83 break; 84 case dwarf_r2: 85 reg_info.name = "r2"; 86 break; 87 case dwarf_r3: 88 reg_info.name = "r3"; 89 break; 90 case dwarf_r4: 91 reg_info.name = "r4"; 92 break; 93 case dwarf_r5: 94 reg_info.name = "r5"; 95 break; 96 case dwarf_r6: 97 reg_info.name = "r6"; 98 break; 99 case dwarf_r7: 100 reg_info.name = "r7"; 101 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; 102 break; 103 case dwarf_r8: 104 reg_info.name = "r8"; 105 break; 106 case dwarf_r9: 107 reg_info.name = "r9"; 108 break; 109 case dwarf_r10: 110 reg_info.name = "r10"; 111 break; 112 case dwarf_r11: 113 reg_info.name = "r11"; 114 break; 115 case dwarf_r12: 116 reg_info.name = "r12"; 117 break; 118 case dwarf_sp: 119 reg_info.name = "sp"; 120 reg_info.alt_name = "r13"; 121 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; 122 break; 123 case dwarf_lr: 124 reg_info.name = "lr"; 125 reg_info.alt_name = "r14"; 126 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; 127 break; 128 case dwarf_pc: 129 reg_info.name = "pc"; 130 reg_info.alt_name = "r15"; 131 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; 132 break; 133 case dwarf_cpsr: 134 reg_info.name = "cpsr"; 135 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; 136 break; 137 138 case dwarf_s0: 139 reg_info.name = "s0"; 140 break; 141 case dwarf_s1: 142 reg_info.name = "s1"; 143 break; 144 case dwarf_s2: 145 reg_info.name = "s2"; 146 break; 147 case dwarf_s3: 148 reg_info.name = "s3"; 149 break; 150 case dwarf_s4: 151 reg_info.name = "s4"; 152 break; 153 case dwarf_s5: 154 reg_info.name = "s5"; 155 break; 156 case dwarf_s6: 157 reg_info.name = "s6"; 158 break; 159 case dwarf_s7: 160 reg_info.name = "s7"; 161 break; 162 case dwarf_s8: 163 reg_info.name = "s8"; 164 break; 165 case dwarf_s9: 166 reg_info.name = "s9"; 167 break; 168 case dwarf_s10: 169 reg_info.name = "s10"; 170 break; 171 case dwarf_s11: 172 reg_info.name = "s11"; 173 break; 174 case dwarf_s12: 175 reg_info.name = "s12"; 176 break; 177 case dwarf_s13: 178 reg_info.name = "s13"; 179 break; 180 case dwarf_s14: 181 reg_info.name = "s14"; 182 break; 183 case dwarf_s15: 184 reg_info.name = "s15"; 185 break; 186 case dwarf_s16: 187 reg_info.name = "s16"; 188 break; 189 case dwarf_s17: 190 reg_info.name = "s17"; 191 break; 192 case dwarf_s18: 193 reg_info.name = "s18"; 194 break; 195 case dwarf_s19: 196 reg_info.name = "s19"; 197 break; 198 case dwarf_s20: 199 reg_info.name = "s20"; 200 break; 201 case dwarf_s21: 202 reg_info.name = "s21"; 203 break; 204 case dwarf_s22: 205 reg_info.name = "s22"; 206 break; 207 case dwarf_s23: 208 reg_info.name = "s23"; 209 break; 210 case dwarf_s24: 211 reg_info.name = "s24"; 212 break; 213 case dwarf_s25: 214 reg_info.name = "s25"; 215 break; 216 case dwarf_s26: 217 reg_info.name = "s26"; 218 break; 219 case dwarf_s27: 220 reg_info.name = "s27"; 221 break; 222 case dwarf_s28: 223 reg_info.name = "s28"; 224 break; 225 case dwarf_s29: 226 reg_info.name = "s29"; 227 break; 228 case dwarf_s30: 229 reg_info.name = "s30"; 230 break; 231 case dwarf_s31: 232 reg_info.name = "s31"; 233 break; 234 235 // FPA Registers 0-7 236 case dwarf_f0: 237 reg_info.name = "f0"; 238 break; 239 case dwarf_f1: 240 reg_info.name = "f1"; 241 break; 242 case dwarf_f2: 243 reg_info.name = "f2"; 244 break; 245 case dwarf_f3: 246 reg_info.name = "f3"; 247 break; 248 case dwarf_f4: 249 reg_info.name = "f4"; 250 break; 251 case dwarf_f5: 252 reg_info.name = "f5"; 253 break; 254 case dwarf_f6: 255 reg_info.name = "f6"; 256 break; 257 case dwarf_f7: 258 reg_info.name = "f7"; 259 break; 260 261 // Intel wireless MMX general purpose registers 0 - 7 262 // XScale accumulator register 0 - 7 (they do overlap with wCGR0 - wCGR7) 263 case dwarf_wCGR0: 264 reg_info.name = "wCGR0/ACC0"; 265 break; 266 case dwarf_wCGR1: 267 reg_info.name = "wCGR1/ACC1"; 268 break; 269 case dwarf_wCGR2: 270 reg_info.name = "wCGR2/ACC2"; 271 break; 272 case dwarf_wCGR3: 273 reg_info.name = "wCGR3/ACC3"; 274 break; 275 case dwarf_wCGR4: 276 reg_info.name = "wCGR4/ACC4"; 277 break; 278 case dwarf_wCGR5: 279 reg_info.name = "wCGR5/ACC5"; 280 break; 281 case dwarf_wCGR6: 282 reg_info.name = "wCGR6/ACC6"; 283 break; 284 case dwarf_wCGR7: 285 reg_info.name = "wCGR7/ACC7"; 286 break; 287 288 // Intel wireless MMX data registers 0 - 15 289 case dwarf_wR0: 290 reg_info.name = "wR0"; 291 break; 292 case dwarf_wR1: 293 reg_info.name = "wR1"; 294 break; 295 case dwarf_wR2: 296 reg_info.name = "wR2"; 297 break; 298 case dwarf_wR3: 299 reg_info.name = "wR3"; 300 break; 301 case dwarf_wR4: 302 reg_info.name = "wR4"; 303 break; 304 case dwarf_wR5: 305 reg_info.name = "wR5"; 306 break; 307 case dwarf_wR6: 308 reg_info.name = "wR6"; 309 break; 310 case dwarf_wR7: 311 reg_info.name = "wR7"; 312 break; 313 case dwarf_wR8: 314 reg_info.name = "wR8"; 315 break; 316 case dwarf_wR9: 317 reg_info.name = "wR9"; 318 break; 319 case dwarf_wR10: 320 reg_info.name = "wR10"; 321 break; 322 case dwarf_wR11: 323 reg_info.name = "wR11"; 324 break; 325 case dwarf_wR12: 326 reg_info.name = "wR12"; 327 break; 328 case dwarf_wR13: 329 reg_info.name = "wR13"; 330 break; 331 case dwarf_wR14: 332 reg_info.name = "wR14"; 333 break; 334 case dwarf_wR15: 335 reg_info.name = "wR15"; 336 break; 337 338 case dwarf_spsr: 339 reg_info.name = "spsr"; 340 break; 341 case dwarf_spsr_fiq: 342 reg_info.name = "spsr_fiq"; 343 break; 344 case dwarf_spsr_irq: 345 reg_info.name = "spsr_irq"; 346 break; 347 case dwarf_spsr_abt: 348 reg_info.name = "spsr_abt"; 349 break; 350 case dwarf_spsr_und: 351 reg_info.name = "spsr_und"; 352 break; 353 case dwarf_spsr_svc: 354 reg_info.name = "spsr_svc"; 355 break; 356 357 case dwarf_r8_usr: 358 reg_info.name = "r8_usr"; 359 break; 360 case dwarf_r9_usr: 361 reg_info.name = "r9_usr"; 362 break; 363 case dwarf_r10_usr: 364 reg_info.name = "r10_usr"; 365 break; 366 case dwarf_r11_usr: 367 reg_info.name = "r11_usr"; 368 break; 369 case dwarf_r12_usr: 370 reg_info.name = "r12_usr"; 371 break; 372 case dwarf_r13_usr: 373 reg_info.name = "r13_usr"; 374 break; 375 case dwarf_r14_usr: 376 reg_info.name = "r14_usr"; 377 break; 378 case dwarf_r8_fiq: 379 reg_info.name = "r8_fiq"; 380 break; 381 case dwarf_r9_fiq: 382 reg_info.name = "r9_fiq"; 383 break; 384 case dwarf_r10_fiq: 385 reg_info.name = "r10_fiq"; 386 break; 387 case dwarf_r11_fiq: 388 reg_info.name = "r11_fiq"; 389 break; 390 case dwarf_r12_fiq: 391 reg_info.name = "r12_fiq"; 392 break; 393 case dwarf_r13_fiq: 394 reg_info.name = "r13_fiq"; 395 break; 396 case dwarf_r14_fiq: 397 reg_info.name = "r14_fiq"; 398 break; 399 case dwarf_r13_irq: 400 reg_info.name = "r13_irq"; 401 break; 402 case dwarf_r14_irq: 403 reg_info.name = "r14_irq"; 404 break; 405 case dwarf_r13_abt: 406 reg_info.name = "r13_abt"; 407 break; 408 case dwarf_r14_abt: 409 reg_info.name = "r14_abt"; 410 break; 411 case dwarf_r13_und: 412 reg_info.name = "r13_und"; 413 break; 414 case dwarf_r14_und: 415 reg_info.name = "r14_und"; 416 break; 417 case dwarf_r13_svc: 418 reg_info.name = "r13_svc"; 419 break; 420 case dwarf_r14_svc: 421 reg_info.name = "r14_svc"; 422 break; 423 424 // Intel wireless MMX control register in co-processor 0 - 7 425 case dwarf_wC0: 426 reg_info.name = "wC0"; 427 break; 428 case dwarf_wC1: 429 reg_info.name = "wC1"; 430 break; 431 case dwarf_wC2: 432 reg_info.name = "wC2"; 433 break; 434 case dwarf_wC3: 435 reg_info.name = "wC3"; 436 break; 437 case dwarf_wC4: 438 reg_info.name = "wC4"; 439 break; 440 case dwarf_wC5: 441 reg_info.name = "wC5"; 442 break; 443 case dwarf_wC6: 444 reg_info.name = "wC6"; 445 break; 446 case dwarf_wC7: 447 reg_info.name = "wC7"; 448 break; 449 450 // VFP-v3/Neon 451 case dwarf_d0: 452 reg_info.name = "d0"; 453 break; 454 case dwarf_d1: 455 reg_info.name = "d1"; 456 break; 457 case dwarf_d2: 458 reg_info.name = "d2"; 459 break; 460 case dwarf_d3: 461 reg_info.name = "d3"; 462 break; 463 case dwarf_d4: 464 reg_info.name = "d4"; 465 break; 466 case dwarf_d5: 467 reg_info.name = "d5"; 468 break; 469 case dwarf_d6: 470 reg_info.name = "d6"; 471 break; 472 case dwarf_d7: 473 reg_info.name = "d7"; 474 break; 475 case dwarf_d8: 476 reg_info.name = "d8"; 477 break; 478 case dwarf_d9: 479 reg_info.name = "d9"; 480 break; 481 case dwarf_d10: 482 reg_info.name = "d10"; 483 break; 484 case dwarf_d11: 485 reg_info.name = "d11"; 486 break; 487 case dwarf_d12: 488 reg_info.name = "d12"; 489 break; 490 case dwarf_d13: 491 reg_info.name = "d13"; 492 break; 493 case dwarf_d14: 494 reg_info.name = "d14"; 495 break; 496 case dwarf_d15: 497 reg_info.name = "d15"; 498 break; 499 case dwarf_d16: 500 reg_info.name = "d16"; 501 break; 502 case dwarf_d17: 503 reg_info.name = "d17"; 504 break; 505 case dwarf_d18: 506 reg_info.name = "d18"; 507 break; 508 case dwarf_d19: 509 reg_info.name = "d19"; 510 break; 511 case dwarf_d20: 512 reg_info.name = "d20"; 513 break; 514 case dwarf_d21: 515 reg_info.name = "d21"; 516 break; 517 case dwarf_d22: 518 reg_info.name = "d22"; 519 break; 520 case dwarf_d23: 521 reg_info.name = "d23"; 522 break; 523 case dwarf_d24: 524 reg_info.name = "d24"; 525 break; 526 case dwarf_d25: 527 reg_info.name = "d25"; 528 break; 529 case dwarf_d26: 530 reg_info.name = "d26"; 531 break; 532 case dwarf_d27: 533 reg_info.name = "d27"; 534 break; 535 case dwarf_d28: 536 reg_info.name = "d28"; 537 break; 538 case dwarf_d29: 539 reg_info.name = "d29"; 540 break; 541 case dwarf_d30: 542 reg_info.name = "d30"; 543 break; 544 case dwarf_d31: 545 reg_info.name = "d31"; 546 break; 547 548 // NEON 128-bit vector registers (overlays the d registers) 549 case dwarf_q0: 550 reg_info.name = "q0"; 551 break; 552 case dwarf_q1: 553 reg_info.name = "q1"; 554 break; 555 case dwarf_q2: 556 reg_info.name = "q2"; 557 break; 558 case dwarf_q3: 559 reg_info.name = "q3"; 560 break; 561 case dwarf_q4: 562 reg_info.name = "q4"; 563 break; 564 case dwarf_q5: 565 reg_info.name = "q5"; 566 break; 567 case dwarf_q6: 568 reg_info.name = "q6"; 569 break; 570 case dwarf_q7: 571 reg_info.name = "q7"; 572 break; 573 case dwarf_q8: 574 reg_info.name = "q8"; 575 break; 576 case dwarf_q9: 577 reg_info.name = "q9"; 578 break; 579 case dwarf_q10: 580 reg_info.name = "q10"; 581 break; 582 case dwarf_q11: 583 reg_info.name = "q11"; 584 break; 585 case dwarf_q12: 586 reg_info.name = "q12"; 587 break; 588 case dwarf_q13: 589 reg_info.name = "q13"; 590 break; 591 case dwarf_q14: 592 reg_info.name = "q14"; 593 break; 594 case dwarf_q15: 595 reg_info.name = "q15"; 596 break; 597 598 default: 599 return false; 600 } 601 return true; 602} 603 604// A8.6.50 605// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 606static uint32_t CountITSize(uint32_t ITMask) { 607 // First count the trailing zeros of the IT mask. 608 uint32_t TZ = llvm::countTrailingZeros(ITMask); 609 if (TZ > 3) { 610#ifdef LLDB_CONFIGURATION_DEBUG 611 printf("Encoding error: IT Mask '0000'\n"); 612#endif 613 return 0; 614 } 615 return (4 - TZ); 616} 617 618// Init ITState. Note that at least one bit is always 1 in mask. 619bool ITSession::InitIT(uint32_t bits7_0) { 620 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 621 if (ITCounter == 0) 622 return false; 623 624 // A8.6.50 IT 625 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 626 if (FirstCond == 0xF) { 627#ifdef LLDB_CONFIGURATION_DEBUG 628 printf("Encoding error: IT FirstCond '1111'\n"); 629#endif 630 return false; 631 } 632 if (FirstCond == 0xE && ITCounter != 1) { 633#ifdef LLDB_CONFIGURATION_DEBUG 634 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 635#endif 636 return false; 637 } 638 639 ITState = bits7_0; 640 return true; 641} 642 643// Update ITState if necessary. 644void ITSession::ITAdvance() { 645 // assert(ITCounter); 646 --ITCounter; 647 if (ITCounter == 0) 648 ITState = 0; 649 else { 650 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 651 SetBits32(ITState, 4, 0, NewITState4_0); 652 } 653} 654 655// Return true if we're inside an IT Block. 656bool ITSession::InITBlock() { return ITCounter != 0; } 657 658// Return true if we're the last instruction inside an IT Block. 659bool ITSession::LastInITBlock() { return ITCounter == 1; } 660 661// Get condition bits for the current thumb instruction. 662uint32_t ITSession::GetCond() { 663 if (InITBlock()) 664 return Bits32(ITState, 7, 4); 665 else 666 return COND_AL; 667} 668 669// ARM constants used during decoding 670#define REG_RD 0 671#define LDM_REGLIST 1 672#define SP_REG 13 673#define LR_REG 14 674#define PC_REG 15 675#define PC_REGLIST_BIT 0x8000 676 677#define ARMv4 (1u << 0) 678#define ARMv4T (1u << 1) 679#define ARMv5T (1u << 2) 680#define ARMv5TE (1u << 3) 681#define ARMv5TEJ (1u << 4) 682#define ARMv6 (1u << 5) 683#define ARMv6K (1u << 6) 684#define ARMv6T2 (1u << 7) 685#define ARMv7 (1u << 8) 686#define ARMv7S (1u << 9) 687#define ARMv8 (1u << 10) 688#define ARMvAll (0xffffffffu) 689 690#define ARMV4T_ABOVE \ 691 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \ 692 ARMv7S | ARMv8) 693#define ARMV5_ABOVE \ 694 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \ 695 ARMv8) 696#define ARMV5TE_ABOVE \ 697 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 698#define ARMV5J_ABOVE \ 699 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 700#define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 701#define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 702#define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8) 703 704#define No_VFP 0 705#define VFPv1 (1u << 1) 706#define VFPv2 (1u << 2) 707#define VFPv3 (1u << 3) 708#define AdvancedSIMD (1u << 4) 709 710#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 711#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 712#define VFPv2v3 (VFPv2 | VFPv3) 713 714//---------------------------------------------------------------------- 715// 716// EmulateInstructionARM implementation 717// 718//---------------------------------------------------------------------- 719 720void EmulateInstructionARM::Initialize() { 721 PluginManager::RegisterPlugin(GetPluginNameStatic(), 722 GetPluginDescriptionStatic(), CreateInstance); 723} 724 725void EmulateInstructionARM::Terminate() { 726 PluginManager::UnregisterPlugin(CreateInstance); 727} 728 729ConstString EmulateInstructionARM::GetPluginNameStatic() { 730 static ConstString g_name("arm"); 731 return g_name; 732} 733 734const char *EmulateInstructionARM::GetPluginDescriptionStatic() { 735 return "Emulate instructions for the ARM architecture."; 736} 737 738EmulateInstruction * 739EmulateInstructionARM::CreateInstance(const ArchSpec &arch, 740 InstructionType inst_type) { 741 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic( 742 inst_type)) { 743 if (arch.GetTriple().getArch() == llvm::Triple::arm) { 744 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap( 745 new EmulateInstructionARM(arch)); 746 747 if (emulate_insn_ap.get()) 748 return emulate_insn_ap.release(); 749 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) { 750 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap( 751 new EmulateInstructionARM(arch)); 752 753 if (emulate_insn_ap.get()) 754 return emulate_insn_ap.release(); 755 } 756 } 757 758 return NULL; 759} 760 761bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) { 762 if (arch.GetTriple().getArch() == llvm::Triple::arm) 763 return true; 764 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 765 return true; 766 767 return false; 768} 769 770// Write "bits (32) UNKNOWN" to memory address "address". Helper function for 771// many ARM instructions. 772bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) { 773 EmulateInstruction::Context context; 774 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 775 context.SetNoArgs(); 776 777 uint32_t random_data = rand(); 778 const uint32_t addr_byte_size = GetAddressByteSize(); 779 780 if (!MemAWrite(context, address, random_data, addr_byte_size)) 781 return false; 782 783 return true; 784} 785 786// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM 787// instructions. 788bool EmulateInstructionARM::WriteBits32Unknown(int n) { 789 EmulateInstruction::Context context; 790 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 791 context.SetNoArgs(); 792 793 bool success; 794 uint32_t data = 795 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 796 797 if (!success) 798 return false; 799 800 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data)) 801 return false; 802 803 return true; 804} 805 806bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind, 807 uint32_t reg_num, 808 RegisterInfo ®_info) { 809 if (reg_kind == eRegisterKindGeneric) { 810 switch (reg_num) { 811 case LLDB_REGNUM_GENERIC_PC: 812 reg_kind = eRegisterKindDWARF; 813 reg_num = dwarf_pc; 814 break; 815 case LLDB_REGNUM_GENERIC_SP: 816 reg_kind = eRegisterKindDWARF; 817 reg_num = dwarf_sp; 818 break; 819 case LLDB_REGNUM_GENERIC_FP: 820 reg_kind = eRegisterKindDWARF; 821 reg_num = dwarf_r7; 822 break; 823 case LLDB_REGNUM_GENERIC_RA: 824 reg_kind = eRegisterKindDWARF; 825 reg_num = dwarf_lr; 826 break; 827 case LLDB_REGNUM_GENERIC_FLAGS: 828 reg_kind = eRegisterKindDWARF; 829 reg_num = dwarf_cpsr; 830 break; 831 default: 832 return false; 833 } 834 } 835 836 if (reg_kind == eRegisterKindDWARF) 837 return GetARMDWARFRegisterInfo(reg_num, reg_info); 838 return false; 839} 840 841uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const { 842 if (m_arch.GetTriple().isAndroid()) 843 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android 844 bool is_apple = false; 845 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 846 is_apple = true; 847 switch (m_arch.GetTriple().getOS()) { 848 case llvm::Triple::Darwin: 849 case llvm::Triple::MacOSX: 850 case llvm::Triple::IOS: 851 case llvm::Triple::TvOS: 852 case llvm::Triple::WatchOS: 853 is_apple = true; 854 break; 855 default: 856 break; 857 } 858 859 /* On Apple iOS et al, the frame pointer register is always r7. 860 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 861 */ 862 863 uint32_t fp_regnum = 11; 864 865 if (is_apple) 866 fp_regnum = 7; 867 868 if (m_opcode_mode == eModeThumb) 869 fp_regnum = 7; 870 871 return fp_regnum; 872} 873 874uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const { 875 bool is_apple = false; 876 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 877 is_apple = true; 878 switch (m_arch.GetTriple().getOS()) { 879 case llvm::Triple::Darwin: 880 case llvm::Triple::MacOSX: 881 case llvm::Triple::IOS: 882 is_apple = true; 883 break; 884 default: 885 break; 886 } 887 888 /* On Apple iOS et al, the frame pointer register is always r7. 889 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 890 */ 891 892 uint32_t fp_regnum = dwarf_r11; 893 894 if (is_apple) 895 fp_regnum = dwarf_r7; 896 897 if (m_opcode_mode == eModeThumb) 898 fp_regnum = dwarf_r7; 899 900 return fp_regnum; 901} 902 903// Push Multiple Registers stores multiple registers to the stack, storing to 904// consecutive memory locations ending just below the address in SP, and updates 905// SP to point to the start of the stored data. 906bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode, 907 const ARMEncoding encoding) { 908#if 0 909 // ARM pseudo code... 910 if (ConditionPassed()) 911 { 912 EncodingSpecificOperations(); 913 NullCheckIfThumbEE(13); 914 address = SP - 4*BitCount(registers); 915 916 for (i = 0 to 14) 917 { 918 if (registers<i> == '1') 919 { 920 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 921 MemA[address,4] = bits(32) UNKNOWN; 922 else 923 MemA[address,4] = R[i]; 924 address = address + 4; 925 } 926 } 927 928 if (registers<15> == '1') // Only possible for encoding A1 or A2 929 MemA[address,4] = PCStoreValue(); 930 931 SP = SP - 4*BitCount(registers); 932 } 933#endif 934 935 bool success = false; 936 if (ConditionPassed(opcode)) { 937 const uint32_t addr_byte_size = GetAddressByteSize(); 938 const addr_t sp = ReadCoreReg(SP_REG, &success); 939 if (!success) 940 return false; 941 uint32_t registers = 0; 942 uint32_t Rt; // the source register 943 switch (encoding) { 944 case eEncodingT1: 945 registers = Bits32(opcode, 7, 0); 946 // The M bit represents LR. 947 if (Bit32(opcode, 8)) 948 registers |= (1u << 14); 949 // if BitCount(registers) < 1 then UNPREDICTABLE; 950 if (BitCount(registers) < 1) 951 return false; 952 break; 953 case eEncodingT2: 954 // Ignore bits 15 & 13. 955 registers = Bits32(opcode, 15, 0) & ~0xa000; 956 // if BitCount(registers) < 2 then UNPREDICTABLE; 957 if (BitCount(registers) < 2) 958 return false; 959 break; 960 case eEncodingT3: 961 Rt = Bits32(opcode, 15, 12); 962 // if BadReg(t) then UNPREDICTABLE; 963 if (BadReg(Rt)) 964 return false; 965 registers = (1u << Rt); 966 break; 967 case eEncodingA1: 968 registers = Bits32(opcode, 15, 0); 969 // Instead of return false, let's handle the following case as well, 970 // which amounts to pushing one reg onto the full descending stacks. 971 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 972 break; 973 case eEncodingA2: 974 Rt = Bits32(opcode, 15, 12); 975 // if t == 13 then UNPREDICTABLE; 976 if (Rt == dwarf_sp) 977 return false; 978 registers = (1u << Rt); 979 break; 980 default: 981 return false; 982 } 983 addr_t sp_offset = addr_byte_size * BitCount(registers); 984 addr_t addr = sp - sp_offset; 985 uint32_t i; 986 987 EmulateInstruction::Context context; 988 context.type = EmulateInstruction::eContextPushRegisterOnStack; 989 RegisterInfo reg_info; 990 RegisterInfo sp_reg; 991 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 992 for (i = 0; i < 15; ++i) { 993 if (BitIsSet(registers, i)) { 994 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info); 995 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 996 uint32_t reg_value = ReadCoreReg(i, &success); 997 if (!success) 998 return false; 999 if (!MemAWrite(context, addr, reg_value, addr_byte_size)) 1000 return false; 1001 addr += addr_byte_size; 1002 } 1003 } 1004 1005 if (BitIsSet(registers, 15)) { 1006 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info); 1007 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 1008 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1009 if (!success) 1010 return false; 1011 if (!MemAWrite(context, addr, pc, addr_byte_size)) 1012 return false; 1013 } 1014 1015 context.type = EmulateInstruction::eContextAdjustStackPointer; 1016 context.SetImmediateSigned(-sp_offset); 1017 1018 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1019 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1020 return false; 1021 } 1022 return true; 1023} 1024 1025// Pop Multiple Registers loads multiple registers from the stack, loading from 1026// consecutive memory locations staring at the address in SP, and updates 1027// SP to point just above the loaded data. 1028bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode, 1029 const ARMEncoding encoding) { 1030#if 0 1031 // ARM pseudo code... 1032 if (ConditionPassed()) 1033 { 1034 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 1035 address = SP; 1036 for i = 0 to 14 1037 if registers<i> == '1' then 1038 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 1039 if registers<15> == '1' then 1040 if UnalignedAllowed then 1041 LoadWritePC(MemU[address,4]); 1042 else 1043 LoadWritePC(MemA[address,4]); 1044 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 1045 if registers<13> == '1' then SP = bits(32) UNKNOWN; 1046 } 1047#endif 1048 1049 bool success = false; 1050 1051 if (ConditionPassed(opcode)) { 1052 const uint32_t addr_byte_size = GetAddressByteSize(); 1053 const addr_t sp = ReadCoreReg(SP_REG, &success); 1054 if (!success) 1055 return false; 1056 uint32_t registers = 0; 1057 uint32_t Rt; // the destination register 1058 switch (encoding) { 1059 case eEncodingT1: 1060 registers = Bits32(opcode, 7, 0); 1061 // The P bit represents PC. 1062 if (Bit32(opcode, 8)) 1063 registers |= (1u << 15); 1064 // if BitCount(registers) < 1 then UNPREDICTABLE; 1065 if (BitCount(registers) < 1) 1066 return false; 1067 break; 1068 case eEncodingT2: 1069 // Ignore bit 13. 1070 registers = Bits32(opcode, 15, 0) & ~0x2000; 1071 // if BitCount(registers) < 2 || (P == '1' && M == '1') then 1072 // UNPREDICTABLE; 1073 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 1074 return false; 1075 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 1076 // UNPREDICTABLE; 1077 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 1078 return false; 1079 break; 1080 case eEncodingT3: 1081 Rt = Bits32(opcode, 15, 12); 1082 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then 1083 // UNPREDICTABLE; 1084 if (Rt == 13) 1085 return false; 1086 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1087 return false; 1088 registers = (1u << Rt); 1089 break; 1090 case eEncodingA1: 1091 registers = Bits32(opcode, 15, 0); 1092 // Instead of return false, let's handle the following case as well, 1093 // which amounts to popping one reg from the full descending stacks. 1094 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 1095 1096 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 1097 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 1098 return false; 1099 break; 1100 case eEncodingA2: 1101 Rt = Bits32(opcode, 15, 12); 1102 // if t == 13 then UNPREDICTABLE; 1103 if (Rt == dwarf_sp) 1104 return false; 1105 registers = (1u << Rt); 1106 break; 1107 default: 1108 return false; 1109 } 1110 addr_t sp_offset = addr_byte_size * BitCount(registers); 1111 addr_t addr = sp; 1112 uint32_t i, data; 1113 1114 EmulateInstruction::Context context; 1115 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1116 1117 RegisterInfo sp_reg; 1118 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1119 1120 for (i = 0; i < 15; ++i) { 1121 if (BitIsSet(registers, i)) { 1122 context.SetAddress(addr); 1123 data = MemARead(context, addr, 4, 0, &success); 1124 if (!success) 1125 return false; 1126 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 1127 data)) 1128 return false; 1129 addr += addr_byte_size; 1130 } 1131 } 1132 1133 if (BitIsSet(registers, 15)) { 1134 context.SetRegisterPlusOffset(sp_reg, addr - sp); 1135 data = MemARead(context, addr, 4, 0, &success); 1136 if (!success) 1137 return false; 1138 // In ARMv5T and above, this is an interworking branch. 1139 if (!LoadWritePC(context, data)) 1140 return false; 1141 // addr += addr_byte_size; 1142 } 1143 1144 context.type = EmulateInstruction::eContextAdjustStackPointer; 1145 context.SetImmediateSigned(sp_offset); 1146 1147 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1148 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1149 return false; 1150 } 1151 return true; 1152} 1153 1154// Set r7 or ip to point to saved value residing within the stack. 1155// ADD (SP plus immediate) 1156bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode, 1157 const ARMEncoding encoding) { 1158#if 0 1159 // ARM pseudo code... 1160 if (ConditionPassed()) 1161 { 1162 EncodingSpecificOperations(); 1163 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1164 if d == 15 then 1165 ALUWritePC(result); // setflags is always FALSE here 1166 else 1167 R[d] = result; 1168 if setflags then 1169 APSR.N = result<31>; 1170 APSR.Z = IsZeroBit(result); 1171 APSR.C = carry; 1172 APSR.V = overflow; 1173 } 1174#endif 1175 1176 bool success = false; 1177 1178 if (ConditionPassed(opcode)) { 1179 const addr_t sp = ReadCoreReg(SP_REG, &success); 1180 if (!success) 1181 return false; 1182 uint32_t Rd; // the destination register 1183 uint32_t imm32; 1184 switch (encoding) { 1185 case eEncodingT1: 1186 Rd = 7; 1187 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 1188 break; 1189 case eEncodingA1: 1190 Rd = Bits32(opcode, 15, 12); 1191 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1192 break; 1193 default: 1194 return false; 1195 } 1196 addr_t sp_offset = imm32; 1197 addr_t addr = sp + sp_offset; // a pointer to the stack area 1198 1199 EmulateInstruction::Context context; 1200 if (Rd == GetFramePointerRegisterNumber()) 1201 context.type = eContextSetFramePointer; 1202 else 1203 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1204 RegisterInfo sp_reg; 1205 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1206 context.SetRegisterPlusOffset(sp_reg, sp_offset); 1207 1208 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, 1209 addr)) 1210 return false; 1211 } 1212 return true; 1213} 1214 1215// Set r7 or ip to the current stack pointer. 1216// MOV (register) 1217bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode, 1218 const ARMEncoding encoding) { 1219#if 0 1220 // ARM pseudo code... 1221 if (ConditionPassed()) 1222 { 1223 EncodingSpecificOperations(); 1224 result = R[m]; 1225 if d == 15 then 1226 ALUWritePC(result); // setflags is always FALSE here 1227 else 1228 R[d] = result; 1229 if setflags then 1230 APSR.N = result<31>; 1231 APSR.Z = IsZeroBit(result); 1232 // APSR.C unchanged 1233 // APSR.V unchanged 1234 } 1235#endif 1236 1237 bool success = false; 1238 1239 if (ConditionPassed(opcode)) { 1240 const addr_t sp = ReadCoreReg(SP_REG, &success); 1241 if (!success) 1242 return false; 1243 uint32_t Rd; // the destination register 1244 switch (encoding) { 1245 case eEncodingT1: 1246 Rd = 7; 1247 break; 1248 case eEncodingA1: 1249 Rd = 12; 1250 break; 1251 default: 1252 return false; 1253 } 1254 1255 EmulateInstruction::Context context; 1256 if (Rd == GetFramePointerRegisterNumber()) 1257 context.type = EmulateInstruction::eContextSetFramePointer; 1258 else 1259 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1260 RegisterInfo sp_reg; 1261 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1262 context.SetRegisterPlusOffset(sp_reg, 0); 1263 1264 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 1265 return false; 1266 } 1267 return true; 1268} 1269 1270// Move from high register (r8-r15) to low register (r0-r7). 1271// MOV (register) 1272bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode, 1273 const ARMEncoding encoding) { 1274 return EmulateMOVRdRm(opcode, encoding); 1275} 1276 1277// Move from register to register. 1278// MOV (register) 1279bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode, 1280 const ARMEncoding encoding) { 1281#if 0 1282 // ARM pseudo code... 1283 if (ConditionPassed()) 1284 { 1285 EncodingSpecificOperations(); 1286 result = R[m]; 1287 if d == 15 then 1288 ALUWritePC(result); // setflags is always FALSE here 1289 else 1290 R[d] = result; 1291 if setflags then 1292 APSR.N = result<31>; 1293 APSR.Z = IsZeroBit(result); 1294 // APSR.C unchanged 1295 // APSR.V unchanged 1296 } 1297#endif 1298 1299 bool success = false; 1300 1301 if (ConditionPassed(opcode)) { 1302 uint32_t Rm; // the source register 1303 uint32_t Rd; // the destination register 1304 bool setflags; 1305 switch (encoding) { 1306 case eEncodingT1: 1307 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1308 Rm = Bits32(opcode, 6, 3); 1309 setflags = false; 1310 if (Rd == 15 && InITBlock() && !LastInITBlock()) 1311 return false; 1312 break; 1313 case eEncodingT2: 1314 Rd = Bits32(opcode, 2, 0); 1315 Rm = Bits32(opcode, 5, 3); 1316 setflags = true; 1317 if (InITBlock()) 1318 return false; 1319 break; 1320 case eEncodingT3: 1321 Rd = Bits32(opcode, 11, 8); 1322 Rm = Bits32(opcode, 3, 0); 1323 setflags = BitIsSet(opcode, 20); 1324 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1325 if (setflags && (BadReg(Rd) || BadReg(Rm))) 1326 return false; 1327 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then 1328 // UNPREDICTABLE; 1329 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 1330 return false; 1331 break; 1332 case eEncodingA1: 1333 Rd = Bits32(opcode, 15, 12); 1334 Rm = Bits32(opcode, 3, 0); 1335 setflags = BitIsSet(opcode, 20); 1336 1337 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1338 // instructions; 1339 if (Rd == 15 && setflags) 1340 return EmulateSUBSPcLrEtc(opcode, encoding); 1341 break; 1342 default: 1343 return false; 1344 } 1345 uint32_t result = ReadCoreReg(Rm, &success); 1346 if (!success) 1347 return false; 1348 1349 // The context specifies that Rm is to be moved into Rd. 1350 EmulateInstruction::Context context; 1351 if (Rd == 13) 1352 context.type = EmulateInstruction::eContextAdjustStackPointer; 1353 else 1354 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1355 RegisterInfo dwarf_reg; 1356 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1357 context.SetRegisterPlusOffset(dwarf_reg, 0); 1358 1359 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 1360 return false; 1361 } 1362 return true; 1363} 1364 1365// Move (immediate) writes an immediate value to the destination register. It 1366// can optionally update the condition flags based on the value. 1367// MOV (immediate) 1368bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode, 1369 const ARMEncoding encoding) { 1370#if 0 1371 // ARM pseudo code... 1372 if (ConditionPassed()) 1373 { 1374 EncodingSpecificOperations(); 1375 result = imm32; 1376 if d == 15 then // Can only occur for ARM encoding 1377 ALUWritePC(result); // setflags is always FALSE here 1378 else 1379 R[d] = result; 1380 if setflags then 1381 APSR.N = result<31>; 1382 APSR.Z = IsZeroBit(result); 1383 APSR.C = carry; 1384 // APSR.V unchanged 1385 } 1386#endif 1387 1388 if (ConditionPassed(opcode)) { 1389 uint32_t Rd; // the destination register 1390 uint32_t imm32; // the immediate value to be written to Rd 1391 uint32_t carry = 1392 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 1393 // for setflags == false, this value is a don't care 1394 // initialized to 0 to silence the static analyzer 1395 bool setflags; 1396 switch (encoding) { 1397 case eEncodingT1: 1398 Rd = Bits32(opcode, 10, 8); 1399 setflags = !InITBlock(); 1400 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 1401 carry = APSR_C; 1402 1403 break; 1404 1405 case eEncodingT2: 1406 Rd = Bits32(opcode, 11, 8); 1407 setflags = BitIsSet(opcode, 20); 1408 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1409 if (BadReg(Rd)) 1410 return false; 1411 1412 break; 1413 1414 case eEncodingT3: { 1415 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 1416 // 32); 1417 Rd = Bits32(opcode, 11, 8); 1418 setflags = false; 1419 uint32_t imm4 = Bits32(opcode, 19, 16); 1420 uint32_t imm3 = Bits32(opcode, 14, 12); 1421 uint32_t i = Bit32(opcode, 26); 1422 uint32_t imm8 = Bits32(opcode, 7, 0); 1423 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 1424 1425 // if BadReg(d) then UNPREDICTABLE; 1426 if (BadReg(Rd)) 1427 return false; 1428 } break; 1429 1430 case eEncodingA1: 1431 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = 1432 // ARMExpandImm_C(imm12, APSR.C); 1433 Rd = Bits32(opcode, 15, 12); 1434 setflags = BitIsSet(opcode, 20); 1435 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1436 1437 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1438 // instructions; 1439 if ((Rd == 15) && setflags) 1440 return EmulateSUBSPcLrEtc(opcode, encoding); 1441 1442 break; 1443 1444 case eEncodingA2: { 1445 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 1446 Rd = Bits32(opcode, 15, 12); 1447 setflags = false; 1448 uint32_t imm4 = Bits32(opcode, 19, 16); 1449 uint32_t imm12 = Bits32(opcode, 11, 0); 1450 imm32 = (imm4 << 12) | imm12; 1451 1452 // if d == 15 then UNPREDICTABLE; 1453 if (Rd == 15) 1454 return false; 1455 } break; 1456 1457 default: 1458 return false; 1459 } 1460 uint32_t result = imm32; 1461 1462 // The context specifies that an immediate is to be moved into Rd. 1463 EmulateInstruction::Context context; 1464 context.type = EmulateInstruction::eContextImmediate; 1465 context.SetNoArgs(); 1466 1467 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1468 return false; 1469 } 1470 return true; 1471} 1472 1473// MUL multiplies two register values. The least significant 32 bits of the 1474// result are written to the destination 1475// register. These 32 bits do not depend on whether the source register values 1476// are considered to be signed values or 1477// unsigned values. 1478// 1479// Optionally, it can update the condition flags based on the result. In the 1480// Thumb instruction set, this option is 1481// limited to only a few forms of the instruction. 1482bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode, 1483 const ARMEncoding encoding) { 1484#if 0 1485 if ConditionPassed() then 1486 EncodingSpecificOperations(); 1487 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1488 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1489 result = operand1 * operand2; 1490 R[d] = result<31:0>; 1491 if setflags then 1492 APSR.N = result<31>; 1493 APSR.Z = IsZeroBit(result); 1494 if ArchVersion() == 4 then 1495 APSR.C = bit UNKNOWN; 1496 // else APSR.C unchanged 1497 // APSR.V always unchanged 1498#endif 1499 1500 if (ConditionPassed(opcode)) { 1501 uint32_t d; 1502 uint32_t n; 1503 uint32_t m; 1504 bool setflags; 1505 1506 // EncodingSpecificOperations(); 1507 switch (encoding) { 1508 case eEncodingT1: 1509 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 1510 d = Bits32(opcode, 2, 0); 1511 n = Bits32(opcode, 5, 3); 1512 m = Bits32(opcode, 2, 0); 1513 setflags = !InITBlock(); 1514 1515 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1516 if ((ArchVersion() < ARMv6) && (d == n)) 1517 return false; 1518 1519 break; 1520 1521 case eEncodingT2: 1522 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 1523 d = Bits32(opcode, 11, 8); 1524 n = Bits32(opcode, 19, 16); 1525 m = Bits32(opcode, 3, 0); 1526 setflags = false; 1527 1528 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 1529 if (BadReg(d) || BadReg(n) || BadReg(m)) 1530 return false; 1531 1532 break; 1533 1534 case eEncodingA1: 1535 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 1536 d = Bits32(opcode, 19, 16); 1537 n = Bits32(opcode, 3, 0); 1538 m = Bits32(opcode, 11, 8); 1539 setflags = BitIsSet(opcode, 20); 1540 1541 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1542 if ((d == 15) || (n == 15) || (m == 15)) 1543 return false; 1544 1545 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1546 if ((ArchVersion() < ARMv6) && (d == n)) 1547 return false; 1548 1549 break; 1550 1551 default: 1552 return false; 1553 } 1554 1555 bool success = false; 1556 1557 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final 1558 // results 1559 uint64_t operand1 = 1560 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1561 if (!success) 1562 return false; 1563 1564 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final 1565 // results 1566 uint64_t operand2 = 1567 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1568 if (!success) 1569 return false; 1570 1571 // result = operand1 * operand2; 1572 uint64_t result = operand1 * operand2; 1573 1574 // R[d] = result<31:0>; 1575 RegisterInfo op1_reg; 1576 RegisterInfo op2_reg; 1577 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1578 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1579 1580 EmulateInstruction::Context context; 1581 context.type = eContextArithmetic; 1582 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 1583 1584 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 1585 (0x0000ffff & result))) 1586 return false; 1587 1588 // if setflags then 1589 if (setflags) { 1590 // APSR.N = result<31>; 1591 // APSR.Z = IsZeroBit(result); 1592 m_new_inst_cpsr = m_opcode_cpsr; 1593 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31)); 1594 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1595 if (m_new_inst_cpsr != m_opcode_cpsr) { 1596 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1597 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1598 return false; 1599 } 1600 1601 // if ArchVersion() == 4 then 1602 // APSR.C = bit UNKNOWN; 1603 } 1604 } 1605 return true; 1606} 1607 1608// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to 1609// the destination register. 1610// It can optionally update the condition flags based on the value. 1611bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode, 1612 const ARMEncoding encoding) { 1613#if 0 1614 // ARM pseudo code... 1615 if (ConditionPassed()) 1616 { 1617 EncodingSpecificOperations(); 1618 result = NOT(imm32); 1619 if d == 15 then // Can only occur for ARM encoding 1620 ALUWritePC(result); // setflags is always FALSE here 1621 else 1622 R[d] = result; 1623 if setflags then 1624 APSR.N = result<31>; 1625 APSR.Z = IsZeroBit(result); 1626 APSR.C = carry; 1627 // APSR.V unchanged 1628 } 1629#endif 1630 1631 if (ConditionPassed(opcode)) { 1632 uint32_t Rd; // the destination register 1633 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1634 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1635 bool setflags; 1636 switch (encoding) { 1637 case eEncodingT1: 1638 Rd = Bits32(opcode, 11, 8); 1639 setflags = BitIsSet(opcode, 20); 1640 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1641 break; 1642 case eEncodingA1: 1643 Rd = Bits32(opcode, 15, 12); 1644 setflags = BitIsSet(opcode, 20); 1645 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1646 1647 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1648 // instructions; 1649 if (Rd == 15 && setflags) 1650 return EmulateSUBSPcLrEtc(opcode, encoding); 1651 break; 1652 default: 1653 return false; 1654 } 1655 uint32_t result = ~imm32; 1656 1657 // The context specifies that an immediate is to be moved into Rd. 1658 EmulateInstruction::Context context; 1659 context.type = EmulateInstruction::eContextImmediate; 1660 context.SetNoArgs(); 1661 1662 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1663 return false; 1664 } 1665 return true; 1666} 1667 1668// Bitwise NOT (register) writes the bitwise inverse of a register value to the 1669// destination register. 1670// It can optionally update the condition flags based on the result. 1671bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode, 1672 const ARMEncoding encoding) { 1673#if 0 1674 // ARM pseudo code... 1675 if (ConditionPassed()) 1676 { 1677 EncodingSpecificOperations(); 1678 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1679 result = NOT(shifted); 1680 if d == 15 then // Can only occur for ARM encoding 1681 ALUWritePC(result); // setflags is always FALSE here 1682 else 1683 R[d] = result; 1684 if setflags then 1685 APSR.N = result<31>; 1686 APSR.Z = IsZeroBit(result); 1687 APSR.C = carry; 1688 // APSR.V unchanged 1689 } 1690#endif 1691 1692 if (ConditionPassed(opcode)) { 1693 uint32_t Rm; // the source register 1694 uint32_t Rd; // the destination register 1695 ARM_ShifterType shift_t; 1696 uint32_t shift_n; // the shift applied to the value read from Rm 1697 bool setflags; 1698 uint32_t carry; // the carry bit after the shift operation 1699 switch (encoding) { 1700 case eEncodingT1: 1701 Rd = Bits32(opcode, 2, 0); 1702 Rm = Bits32(opcode, 5, 3); 1703 setflags = !InITBlock(); 1704 shift_t = SRType_LSL; 1705 shift_n = 0; 1706 if (InITBlock()) 1707 return false; 1708 break; 1709 case eEncodingT2: 1710 Rd = Bits32(opcode, 11, 8); 1711 Rm = Bits32(opcode, 3, 0); 1712 setflags = BitIsSet(opcode, 20); 1713 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1714 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1715 if (BadReg(Rd) || BadReg(Rm)) 1716 return false; 1717 break; 1718 case eEncodingA1: 1719 Rd = Bits32(opcode, 15, 12); 1720 Rm = Bits32(opcode, 3, 0); 1721 setflags = BitIsSet(opcode, 20); 1722 shift_n = DecodeImmShiftARM(opcode, shift_t); 1723 break; 1724 default: 1725 return false; 1726 } 1727 bool success = false; 1728 uint32_t value = ReadCoreReg(Rm, &success); 1729 if (!success) 1730 return false; 1731 1732 uint32_t shifted = 1733 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1734 if (!success) 1735 return false; 1736 uint32_t result = ~shifted; 1737 1738 // The context specifies that an immediate is to be moved into Rd. 1739 EmulateInstruction::Context context; 1740 context.type = EmulateInstruction::eContextImmediate; 1741 context.SetNoArgs(); 1742 1743 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1744 return false; 1745 } 1746 return true; 1747} 1748 1749// PC relative immediate load into register, possibly followed by ADD (SP plus 1750// register). 1751// LDR (literal) 1752bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode, 1753 const ARMEncoding encoding) { 1754#if 0 1755 // ARM pseudo code... 1756 if (ConditionPassed()) 1757 { 1758 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1759 base = Align(PC,4); 1760 address = if add then (base + imm32) else (base - imm32); 1761 data = MemU[address,4]; 1762 if t == 15 then 1763 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1764 elsif UnalignedSupport() || address<1:0> = '00' then 1765 R[t] = data; 1766 else // Can only apply before ARMv7 1767 if CurrentInstrSet() == InstrSet_ARM then 1768 R[t] = ROR(data, 8*UInt(address<1:0>)); 1769 else 1770 R[t] = bits(32) UNKNOWN; 1771 } 1772#endif 1773 1774 if (ConditionPassed(opcode)) { 1775 bool success = false; 1776 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1777 if (!success) 1778 return false; 1779 1780 // PC relative immediate load context 1781 EmulateInstruction::Context context; 1782 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1783 RegisterInfo pc_reg; 1784 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 1785 context.SetRegisterPlusOffset(pc_reg, 0); 1786 1787 uint32_t Rt; // the destination register 1788 uint32_t imm32; // immediate offset from the PC 1789 bool add; // +imm32 or -imm32? 1790 addr_t base; // the base address 1791 addr_t address; // the PC relative address 1792 uint32_t data; // the literal data value from the PC relative load 1793 switch (encoding) { 1794 case eEncodingT1: 1795 Rt = Bits32(opcode, 10, 8); 1796 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1797 add = true; 1798 break; 1799 case eEncodingT2: 1800 Rt = Bits32(opcode, 15, 12); 1801 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1802 add = BitIsSet(opcode, 23); 1803 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1804 return false; 1805 break; 1806 default: 1807 return false; 1808 } 1809 1810 base = Align(pc, 4); 1811 if (add) 1812 address = base + imm32; 1813 else 1814 address = base - imm32; 1815 1816 context.SetRegisterPlusOffset(pc_reg, address - base); 1817 data = MemURead(context, address, 4, 0, &success); 1818 if (!success) 1819 return false; 1820 1821 if (Rt == 15) { 1822 if (Bits32(address, 1, 0) == 0) { 1823 // In ARMv5T and above, this is an interworking branch. 1824 if (!LoadWritePC(context, data)) 1825 return false; 1826 } else 1827 return false; 1828 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 1829 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 1830 data)) 1831 return false; 1832 } else // We don't handle ARM for now. 1833 return false; 1834 } 1835 return true; 1836} 1837 1838// An add operation to adjust the SP. 1839// ADD (SP plus immediate) 1840bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode, 1841 const ARMEncoding encoding) { 1842#if 0 1843 // ARM pseudo code... 1844 if (ConditionPassed()) 1845 { 1846 EncodingSpecificOperations(); 1847 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1848 if d == 15 then // Can only occur for ARM encoding 1849 ALUWritePC(result); // setflags is always FALSE here 1850 else 1851 R[d] = result; 1852 if setflags then 1853 APSR.N = result<31>; 1854 APSR.Z = IsZeroBit(result); 1855 APSR.C = carry; 1856 APSR.V = overflow; 1857 } 1858#endif 1859 1860 bool success = false; 1861 1862 if (ConditionPassed(opcode)) { 1863 const addr_t sp = ReadCoreReg(SP_REG, &success); 1864 if (!success) 1865 return false; 1866 uint32_t imm32; // the immediate operand 1867 uint32_t d; 1868 bool setflags; 1869 switch (encoding) { 1870 case eEncodingT1: 1871 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1872 d = Bits32(opcode, 10, 8); 1873 imm32 = (Bits32(opcode, 7, 0) << 2); 1874 setflags = false; 1875 break; 1876 1877 case eEncodingT2: 1878 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1879 d = 13; 1880 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1881 setflags = false; 1882 break; 1883 1884 case eEncodingT3: 1885 // d = UInt(Rd); setflags = (S == "1"); imm32 = 1886 // ThumbExpandImm(i:imm3:imm8); 1887 d = Bits32(opcode, 11, 8); 1888 imm32 = ThumbExpandImm(opcode); 1889 setflags = Bit32(opcode, 20); 1890 1891 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 1892 if (d == 15 && setflags == 1) 1893 return false; // CMN (immediate) not yet supported 1894 1895 // if d == 15 && S == "0" then UNPREDICTABLE; 1896 if (d == 15 && setflags == 0) 1897 return false; 1898 break; 1899 1900 case eEncodingT4: { 1901 // if Rn == '1111' then SEE ADR; 1902 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 1903 d = Bits32(opcode, 11, 8); 1904 setflags = false; 1905 uint32_t i = Bit32(opcode, 26); 1906 uint32_t imm3 = Bits32(opcode, 14, 12); 1907 uint32_t imm8 = Bits32(opcode, 7, 0); 1908 imm32 = (i << 11) | (imm3 << 8) | imm8; 1909 1910 // if d == 15 then UNPREDICTABLE; 1911 if (d == 15) 1912 return false; 1913 } break; 1914 1915 default: 1916 return false; 1917 } 1918 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 1919 AddWithCarryResult res = AddWithCarry(sp, imm32, 0); 1920 1921 EmulateInstruction::Context context; 1922 if (d == 13) 1923 context.type = EmulateInstruction::eContextAdjustStackPointer; 1924 else 1925 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1926 1927 RegisterInfo sp_reg; 1928 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1929 context.SetRegisterPlusOffset(sp_reg, res.result - sp); 1930 1931 if (d == 15) { 1932 if (!ALUWritePC(context, res.result)) 1933 return false; 1934 } else { 1935 // R[d] = result; 1936 // if setflags then 1937 // APSR.N = result<31>; 1938 // APSR.Z = IsZeroBit(result); 1939 // APSR.C = carry; 1940 // APSR.V = overflow; 1941 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 1942 res.carry_out, res.overflow)) 1943 return false; 1944 } 1945 } 1946 return true; 1947} 1948 1949// An add operation to adjust the SP. 1950// ADD (SP plus register) 1951bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode, 1952 const ARMEncoding encoding) { 1953#if 0 1954 // ARM pseudo code... 1955 if (ConditionPassed()) 1956 { 1957 EncodingSpecificOperations(); 1958 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1959 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1960 if d == 15 then 1961 ALUWritePC(result); // setflags is always FALSE here 1962 else 1963 R[d] = result; 1964 if setflags then 1965 APSR.N = result<31>; 1966 APSR.Z = IsZeroBit(result); 1967 APSR.C = carry; 1968 APSR.V = overflow; 1969 } 1970#endif 1971 1972 bool success = false; 1973 1974 if (ConditionPassed(opcode)) { 1975 const addr_t sp = ReadCoreReg(SP_REG, &success); 1976 if (!success) 1977 return false; 1978 uint32_t Rm; // the second operand 1979 switch (encoding) { 1980 case eEncodingT2: 1981 Rm = Bits32(opcode, 6, 3); 1982 break; 1983 default: 1984 return false; 1985 } 1986 int32_t reg_value = ReadCoreReg(Rm, &success); 1987 if (!success) 1988 return false; 1989 1990 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1991 1992 EmulateInstruction::Context context; 1993 context.type = eContextArithmetic; 1994 RegisterInfo sp_reg; 1995 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1996 1997 RegisterInfo other_reg; 1998 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1999 context.SetRegisterRegisterOperands(sp_reg, other_reg); 2000 2001 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2002 LLDB_REGNUM_GENERIC_SP, addr)) 2003 return false; 2004 } 2005 return true; 2006} 2007 2008// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 2009// at a PC-relative address, and changes instruction set from ARM to Thumb, or 2010// from Thumb to ARM. 2011// BLX (immediate) 2012bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode, 2013 const ARMEncoding encoding) { 2014#if 0 2015 // ARM pseudo code... 2016 if (ConditionPassed()) 2017 { 2018 EncodingSpecificOperations(); 2019 if CurrentInstrSet() == InstrSet_ARM then 2020 LR = PC - 4; 2021 else 2022 LR = PC<31:1> : '1'; 2023 if targetInstrSet == InstrSet_ARM then 2024 targetAddress = Align(PC,4) + imm32; 2025 else 2026 targetAddress = PC + imm32; 2027 SelectInstrSet(targetInstrSet); 2028 BranchWritePC(targetAddress); 2029 } 2030#endif 2031 2032 bool success = true; 2033 2034 if (ConditionPassed(opcode)) { 2035 EmulateInstruction::Context context; 2036 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2037 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2038 if (!success) 2039 return false; 2040 addr_t lr; // next instruction address 2041 addr_t target; // target address 2042 int32_t imm32; // PC-relative offset 2043 switch (encoding) { 2044 case eEncodingT1: { 2045 lr = pc | 1u; // return address 2046 uint32_t S = Bit32(opcode, 26); 2047 uint32_t imm10 = Bits32(opcode, 25, 16); 2048 uint32_t J1 = Bit32(opcode, 13); 2049 uint32_t J2 = Bit32(opcode, 11); 2050 uint32_t imm11 = Bits32(opcode, 10, 0); 2051 uint32_t I1 = !(J1 ^ S); 2052 uint32_t I2 = !(J2 ^ S); 2053 uint32_t imm25 = 2054 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2055 imm32 = llvm::SignExtend32<25>(imm25); 2056 target = pc + imm32; 2057 SelectInstrSet(eModeThumb); 2058 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2059 if (InITBlock() && !LastInITBlock()) 2060 return false; 2061 break; 2062 } 2063 case eEncodingT2: { 2064 lr = pc | 1u; // return address 2065 uint32_t S = Bit32(opcode, 26); 2066 uint32_t imm10H = Bits32(opcode, 25, 16); 2067 uint32_t J1 = Bit32(opcode, 13); 2068 uint32_t J2 = Bit32(opcode, 11); 2069 uint32_t imm10L = Bits32(opcode, 10, 1); 2070 uint32_t I1 = !(J1 ^ S); 2071 uint32_t I2 = !(J2 ^ S); 2072 uint32_t imm25 = 2073 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 2074 imm32 = llvm::SignExtend32<25>(imm25); 2075 target = Align(pc, 4) + imm32; 2076 SelectInstrSet(eModeARM); 2077 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32); 2078 if (InITBlock() && !LastInITBlock()) 2079 return false; 2080 break; 2081 } 2082 case eEncodingA1: 2083 lr = pc - 4; // return address 2084 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2085 target = Align(pc, 4) + imm32; 2086 SelectInstrSet(eModeARM); 2087 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2088 break; 2089 case eEncodingA2: 2090 lr = pc - 4; // return address 2091 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | 2092 Bits32(opcode, 24, 24) << 1); 2093 target = pc + imm32; 2094 SelectInstrSet(eModeThumb); 2095 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32); 2096 break; 2097 default: 2098 return false; 2099 } 2100 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2101 LLDB_REGNUM_GENERIC_RA, lr)) 2102 return false; 2103 if (!BranchWritePC(context, target)) 2104 return false; 2105 if (m_opcode_cpsr != m_new_inst_cpsr) 2106 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2107 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2108 return false; 2109 } 2110 return true; 2111} 2112 2113// Branch with Link and Exchange (register) calls a subroutine at an address and 2114// instruction set specified by a register. 2115// BLX (register) 2116bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode, 2117 const ARMEncoding encoding) { 2118#if 0 2119 // ARM pseudo code... 2120 if (ConditionPassed()) 2121 { 2122 EncodingSpecificOperations(); 2123 target = R[m]; 2124 if CurrentInstrSet() == InstrSet_ARM then 2125 next_instr_addr = PC - 4; 2126 LR = next_instr_addr; 2127 else 2128 next_instr_addr = PC - 2; 2129 LR = next_instr_addr<31:1> : '1'; 2130 BXWritePC(target); 2131 } 2132#endif 2133 2134 bool success = false; 2135 2136 if (ConditionPassed(opcode)) { 2137 EmulateInstruction::Context context; 2138 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2139 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2140 addr_t lr; // next instruction address 2141 if (!success) 2142 return false; 2143 uint32_t Rm; // the register with the target address 2144 switch (encoding) { 2145 case eEncodingT1: 2146 lr = (pc - 2) | 1u; // return address 2147 Rm = Bits32(opcode, 6, 3); 2148 // if m == 15 then UNPREDICTABLE; 2149 if (Rm == 15) 2150 return false; 2151 if (InITBlock() && !LastInITBlock()) 2152 return false; 2153 break; 2154 case eEncodingA1: 2155 lr = pc - 4; // return address 2156 Rm = Bits32(opcode, 3, 0); 2157 // if m == 15 then UNPREDICTABLE; 2158 if (Rm == 15) 2159 return false; 2160 break; 2161 default: 2162 return false; 2163 } 2164 addr_t target = ReadCoreReg(Rm, &success); 2165 if (!success) 2166 return false; 2167 RegisterInfo dwarf_reg; 2168 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2169 context.SetRegister(dwarf_reg); 2170 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2171 LLDB_REGNUM_GENERIC_RA, lr)) 2172 return false; 2173 if (!BXWritePC(context, target)) 2174 return false; 2175 } 2176 return true; 2177} 2178 2179// Branch and Exchange causes a branch to an address and instruction set 2180// specified by a register. 2181bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode, 2182 const ARMEncoding encoding) { 2183#if 0 2184 // ARM pseudo code... 2185 if (ConditionPassed()) 2186 { 2187 EncodingSpecificOperations(); 2188 BXWritePC(R[m]); 2189 } 2190#endif 2191 2192 if (ConditionPassed(opcode)) { 2193 EmulateInstruction::Context context; 2194 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2195 uint32_t Rm; // the register with the target address 2196 switch (encoding) { 2197 case eEncodingT1: 2198 Rm = Bits32(opcode, 6, 3); 2199 if (InITBlock() && !LastInITBlock()) 2200 return false; 2201 break; 2202 case eEncodingA1: 2203 Rm = Bits32(opcode, 3, 0); 2204 break; 2205 default: 2206 return false; 2207 } 2208 bool success = false; 2209 addr_t target = ReadCoreReg(Rm, &success); 2210 if (!success) 2211 return false; 2212 2213 RegisterInfo dwarf_reg; 2214 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2215 context.SetRegister(dwarf_reg); 2216 if (!BXWritePC(context, target)) 2217 return false; 2218 } 2219 return true; 2220} 2221 2222// Branch and Exchange Jazelle attempts to change to Jazelle state. If the 2223// attempt fails, it branches to an 2224// address and instruction set specified by a register as though it were a BX 2225// instruction. 2226// 2227// TODO: Emulate Jazelle architecture? 2228// We currently assume that switching to Jazelle state fails, thus 2229// treating BXJ as a BX operation. 2230bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode, 2231 const ARMEncoding encoding) { 2232#if 0 2233 // ARM pseudo code... 2234 if (ConditionPassed()) 2235 { 2236 EncodingSpecificOperations(); 2237 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 2238 BXWritePC(R[m]); 2239 else 2240 if JazelleAcceptsExecution() then 2241 SwitchToJazelleExecution(); 2242 else 2243 SUBARCHITECTURE_DEFINED handler call; 2244 } 2245#endif 2246 2247 if (ConditionPassed(opcode)) { 2248 EmulateInstruction::Context context; 2249 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2250 uint32_t Rm; // the register with the target address 2251 switch (encoding) { 2252 case eEncodingT1: 2253 Rm = Bits32(opcode, 19, 16); 2254 if (BadReg(Rm)) 2255 return false; 2256 if (InITBlock() && !LastInITBlock()) 2257 return false; 2258 break; 2259 case eEncodingA1: 2260 Rm = Bits32(opcode, 3, 0); 2261 if (Rm == 15) 2262 return false; 2263 break; 2264 default: 2265 return false; 2266 } 2267 bool success = false; 2268 addr_t target = ReadCoreReg(Rm, &success); 2269 if (!success) 2270 return false; 2271 2272 RegisterInfo dwarf_reg; 2273 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2274 context.SetRegister(dwarf_reg); 2275 if (!BXWritePC(context, target)) 2276 return false; 2277 } 2278 return true; 2279} 2280 2281// Set r7 to point to some ip offset. 2282// SUB (immediate) 2283bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode, 2284 const ARMEncoding encoding) { 2285#if 0 2286 // ARM pseudo code... 2287 if (ConditionPassed()) 2288 { 2289 EncodingSpecificOperations(); 2290 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2291 if d == 15 then // Can only occur for ARM encoding 2292 ALUWritePC(result); // setflags is always FALSE here 2293 else 2294 R[d] = result; 2295 if setflags then 2296 APSR.N = result<31>; 2297 APSR.Z = IsZeroBit(result); 2298 APSR.C = carry; 2299 APSR.V = overflow; 2300 } 2301#endif 2302 2303 if (ConditionPassed(opcode)) { 2304 bool success = false; 2305 const addr_t ip = ReadCoreReg(12, &success); 2306 if (!success) 2307 return false; 2308 uint32_t imm32; 2309 switch (encoding) { 2310 case eEncodingA1: 2311 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2312 break; 2313 default: 2314 return false; 2315 } 2316 addr_t ip_offset = imm32; 2317 addr_t addr = ip - ip_offset; // the adjusted ip value 2318 2319 EmulateInstruction::Context context; 2320 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2321 RegisterInfo dwarf_reg; 2322 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg); 2323 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset); 2324 2325 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr)) 2326 return false; 2327 } 2328 return true; 2329} 2330 2331// Set ip to point to some stack offset. 2332// SUB (SP minus immediate) 2333bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode, 2334 const ARMEncoding encoding) { 2335#if 0 2336 // ARM pseudo code... 2337 if (ConditionPassed()) 2338 { 2339 EncodingSpecificOperations(); 2340 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2341 if d == 15 then // Can only occur for ARM encoding 2342 ALUWritePC(result); // setflags is always FALSE here 2343 else 2344 R[d] = result; 2345 if setflags then 2346 APSR.N = result<31>; 2347 APSR.Z = IsZeroBit(result); 2348 APSR.C = carry; 2349 APSR.V = overflow; 2350 } 2351#endif 2352 2353 if (ConditionPassed(opcode)) { 2354 bool success = false; 2355 const addr_t sp = ReadCoreReg(SP_REG, &success); 2356 if (!success) 2357 return false; 2358 uint32_t imm32; 2359 switch (encoding) { 2360 case eEncodingA1: 2361 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2362 break; 2363 default: 2364 return false; 2365 } 2366 addr_t sp_offset = imm32; 2367 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 2368 2369 EmulateInstruction::Context context; 2370 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2371 RegisterInfo dwarf_reg; 2372 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 2373 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset); 2374 2375 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr)) 2376 return false; 2377 } 2378 return true; 2379} 2380 2381// This instruction subtracts an immediate value from the SP value, and writes 2382// the result to the destination register. 2383// 2384// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local 2385// storage. 2386bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode, 2387 const ARMEncoding encoding) { 2388#if 0 2389 // ARM pseudo code... 2390 if (ConditionPassed()) 2391 { 2392 EncodingSpecificOperations(); 2393 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2394 if d == 15 then // Can only occur for ARM encoding 2395 ALUWritePC(result); // setflags is always FALSE here 2396 else 2397 R[d] = result; 2398 if setflags then 2399 APSR.N = result<31>; 2400 APSR.Z = IsZeroBit(result); 2401 APSR.C = carry; 2402 APSR.V = overflow; 2403 } 2404#endif 2405 2406 bool success = false; 2407 if (ConditionPassed(opcode)) { 2408 const addr_t sp = ReadCoreReg(SP_REG, &success); 2409 if (!success) 2410 return false; 2411 2412 uint32_t Rd; 2413 bool setflags; 2414 uint32_t imm32; 2415 switch (encoding) { 2416 case eEncodingT1: 2417 Rd = 13; 2418 setflags = false; 2419 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 2420 break; 2421 case eEncodingT2: 2422 Rd = Bits32(opcode, 11, 8); 2423 setflags = BitIsSet(opcode, 20); 2424 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2425 if (Rd == 15 && setflags) 2426 return EmulateCMPImm(opcode, eEncodingT2); 2427 if (Rd == 15 && !setflags) 2428 return false; 2429 break; 2430 case eEncodingT3: 2431 Rd = Bits32(opcode, 11, 8); 2432 setflags = false; 2433 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 2434 if (Rd == 15) 2435 return false; 2436 break; 2437 case eEncodingA1: 2438 Rd = Bits32(opcode, 15, 12); 2439 setflags = BitIsSet(opcode, 20); 2440 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2441 2442 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 2443 // instructions; 2444 if (Rd == 15 && setflags) 2445 return EmulateSUBSPcLrEtc(opcode, encoding); 2446 break; 2447 default: 2448 return false; 2449 } 2450 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 2451 2452 EmulateInstruction::Context context; 2453 if (Rd == 13) { 2454 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting 2455 // to negate it, or the wrong 2456 // value gets passed down to context.SetImmediateSigned. 2457 context.type = EmulateInstruction::eContextAdjustStackPointer; 2458 context.SetImmediateSigned(-imm64); // the stack pointer offset 2459 } else { 2460 context.type = EmulateInstruction::eContextImmediate; 2461 context.SetNoArgs(); 2462 } 2463 2464 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 2465 res.carry_out, res.overflow)) 2466 return false; 2467 } 2468 return true; 2469} 2470 2471// A store operation to the stack that also updates the SP. 2472bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode, 2473 const ARMEncoding encoding) { 2474#if 0 2475 // ARM pseudo code... 2476 if (ConditionPassed()) 2477 { 2478 EncodingSpecificOperations(); 2479 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2480 address = if index then offset_addr else R[n]; 2481 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 2482 if wback then R[n] = offset_addr; 2483 } 2484#endif 2485 2486 bool success = false; 2487 if (ConditionPassed(opcode)) { 2488 const uint32_t addr_byte_size = GetAddressByteSize(); 2489 const addr_t sp = ReadCoreReg(SP_REG, &success); 2490 if (!success) 2491 return false; 2492 uint32_t Rt; // the source register 2493 uint32_t imm12; 2494 uint32_t 2495 Rn; // This function assumes Rn is the SP, but we should verify that. 2496 2497 bool index; 2498 bool add; 2499 bool wback; 2500 switch (encoding) { 2501 case eEncodingA1: 2502 Rt = Bits32(opcode, 15, 12); 2503 imm12 = Bits32(opcode, 11, 0); 2504 Rn = Bits32(opcode, 19, 16); 2505 2506 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 2507 return false; 2508 2509 index = BitIsSet(opcode, 24); 2510 add = BitIsSet(opcode, 23); 2511 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 2512 2513 if (wback && ((Rn == 15) || (Rn == Rt))) 2514 return false; 2515 break; 2516 default: 2517 return false; 2518 } 2519 addr_t offset_addr; 2520 if (add) 2521 offset_addr = sp + imm12; 2522 else 2523 offset_addr = sp - imm12; 2524 2525 addr_t addr; 2526 if (index) 2527 addr = offset_addr; 2528 else 2529 addr = sp; 2530 2531 EmulateInstruction::Context context; 2532 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2533 RegisterInfo sp_reg; 2534 RegisterInfo dwarf_reg; 2535 2536 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2537 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2538 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2539 if (Rt != 15) { 2540 uint32_t reg_value = ReadCoreReg(Rt, &success); 2541 if (!success) 2542 return false; 2543 if (!MemUWrite(context, addr, reg_value, addr_byte_size)) 2544 return false; 2545 } else { 2546 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2547 if (!success) 2548 return false; 2549 if (!MemUWrite(context, addr, pc, addr_byte_size)) 2550 return false; 2551 } 2552 2553 if (wback) { 2554 context.type = EmulateInstruction::eContextAdjustStackPointer; 2555 context.SetImmediateSigned(addr - sp); 2556 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2557 LLDB_REGNUM_GENERIC_SP, offset_addr)) 2558 return false; 2559 } 2560 } 2561 return true; 2562} 2563 2564// Vector Push stores multiple extension registers to the stack. 2565// It also updates SP to point to the start of the stored data. 2566bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode, 2567 const ARMEncoding encoding) { 2568#if 0 2569 // ARM pseudo code... 2570 if (ConditionPassed()) 2571 { 2572 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2573 address = SP - imm32; 2574 SP = SP - imm32; 2575 if single_regs then 2576 for r = 0 to regs-1 2577 MemA[address,4] = S[d+r]; address = address+4; 2578 else 2579 for r = 0 to regs-1 2580 // Store as two word-aligned words in the correct order for current endianness. 2581 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2582 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2583 address = address+8; 2584 } 2585#endif 2586 2587 bool success = false; 2588 if (ConditionPassed(opcode)) { 2589 const uint32_t addr_byte_size = GetAddressByteSize(); 2590 const addr_t sp = ReadCoreReg(SP_REG, &success); 2591 if (!success) 2592 return false; 2593 bool single_regs; 2594 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2595 uint32_t imm32; // stack offset 2596 uint32_t regs; // number of registers 2597 switch (encoding) { 2598 case eEncodingT1: 2599 case eEncodingA1: 2600 single_regs = false; 2601 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2602 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2603 // If UInt(imm8) is odd, see "FSTMX". 2604 regs = Bits32(opcode, 7, 0) / 2; 2605 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2606 if (regs == 0 || regs > 16 || (d + regs) > 32) 2607 return false; 2608 break; 2609 case eEncodingT2: 2610 case eEncodingA2: 2611 single_regs = true; 2612 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2613 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2614 regs = Bits32(opcode, 7, 0); 2615 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2616 if (regs == 0 || regs > 16 || (d + regs) > 32) 2617 return false; 2618 break; 2619 default: 2620 return false; 2621 } 2622 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2623 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2624 addr_t sp_offset = imm32; 2625 addr_t addr = sp - sp_offset; 2626 uint32_t i; 2627 2628 EmulateInstruction::Context context; 2629 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2630 2631 RegisterInfo dwarf_reg; 2632 RegisterInfo sp_reg; 2633 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2634 for (i = 0; i < regs; ++i) { 2635 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2636 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2637 // uint64_t to accommodate 64-bit registers. 2638 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success); 2639 if (!success) 2640 return false; 2641 if (!MemAWrite(context, addr, reg_value, reg_byte_size)) 2642 return false; 2643 addr += reg_byte_size; 2644 } 2645 2646 context.type = EmulateInstruction::eContextAdjustStackPointer; 2647 context.SetImmediateSigned(-sp_offset); 2648 2649 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2650 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2651 return false; 2652 } 2653 return true; 2654} 2655 2656// Vector Pop loads multiple extension registers from the stack. 2657// It also updates SP to point just above the loaded data. 2658bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode, 2659 const ARMEncoding encoding) { 2660#if 0 2661 // ARM pseudo code... 2662 if (ConditionPassed()) 2663 { 2664 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2665 address = SP; 2666 SP = SP + imm32; 2667 if single_regs then 2668 for r = 0 to regs-1 2669 S[d+r] = MemA[address,4]; address = address+4; 2670 else 2671 for r = 0 to regs-1 2672 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2673 // Combine the word-aligned words in the correct order for current endianness. 2674 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2675 } 2676#endif 2677 2678 bool success = false; 2679 if (ConditionPassed(opcode)) { 2680 const uint32_t addr_byte_size = GetAddressByteSize(); 2681 const addr_t sp = ReadCoreReg(SP_REG, &success); 2682 if (!success) 2683 return false; 2684 bool single_regs; 2685 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2686 uint32_t imm32; // stack offset 2687 uint32_t regs; // number of registers 2688 switch (encoding) { 2689 case eEncodingT1: 2690 case eEncodingA1: 2691 single_regs = false; 2692 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2693 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2694 // If UInt(imm8) is odd, see "FLDMX". 2695 regs = Bits32(opcode, 7, 0) / 2; 2696 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2697 if (regs == 0 || regs > 16 || (d + regs) > 32) 2698 return false; 2699 break; 2700 case eEncodingT2: 2701 case eEncodingA2: 2702 single_regs = true; 2703 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2704 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2705 regs = Bits32(opcode, 7, 0); 2706 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2707 if (regs == 0 || regs > 16 || (d + regs) > 32) 2708 return false; 2709 break; 2710 default: 2711 return false; 2712 } 2713 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2714 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2715 addr_t sp_offset = imm32; 2716 addr_t addr = sp; 2717 uint32_t i; 2718 uint64_t data; // uint64_t to accommodate 64-bit registers. 2719 2720 EmulateInstruction::Context context; 2721 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2722 2723 RegisterInfo dwarf_reg; 2724 RegisterInfo sp_reg; 2725 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2726 for (i = 0; i < regs; ++i) { 2727 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2728 context.SetAddress(addr); 2729 data = MemARead(context, addr, reg_byte_size, 0, &success); 2730 if (!success) 2731 return false; 2732 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2733 return false; 2734 addr += reg_byte_size; 2735 } 2736 2737 context.type = EmulateInstruction::eContextAdjustStackPointer; 2738 context.SetImmediateSigned(sp_offset); 2739 2740 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2741 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2742 return false; 2743 } 2744 return true; 2745} 2746 2747// SVC (previously SWI) 2748bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode, 2749 const ARMEncoding encoding) { 2750#if 0 2751 // ARM pseudo code... 2752 if (ConditionPassed()) 2753 { 2754 EncodingSpecificOperations(); 2755 CallSupervisor(); 2756 } 2757#endif 2758 2759 bool success = false; 2760 2761 if (ConditionPassed(opcode)) { 2762 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2763 addr_t lr; // next instruction address 2764 if (!success) 2765 return false; 2766 uint32_t imm32; // the immediate constant 2767 uint32_t mode; // ARM or Thumb mode 2768 switch (encoding) { 2769 case eEncodingT1: 2770 lr = (pc + 2) | 1u; // return address 2771 imm32 = Bits32(opcode, 7, 0); 2772 mode = eModeThumb; 2773 break; 2774 case eEncodingA1: 2775 lr = pc + 4; // return address 2776 imm32 = Bits32(opcode, 23, 0); 2777 mode = eModeARM; 2778 break; 2779 default: 2780 return false; 2781 } 2782 2783 EmulateInstruction::Context context; 2784 context.type = EmulateInstruction::eContextSupervisorCall; 2785 context.SetISAAndImmediate(mode, imm32); 2786 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2787 LLDB_REGNUM_GENERIC_RA, lr)) 2788 return false; 2789 } 2790 return true; 2791} 2792 2793// If Then makes up to four following instructions (the IT block) conditional. 2794bool EmulateInstructionARM::EmulateIT(const uint32_t opcode, 2795 const ARMEncoding encoding) { 2796#if 0 2797 // ARM pseudo code... 2798 EncodingSpecificOperations(); 2799 ITSTATE.IT<7:0> = firstcond:mask; 2800#endif 2801 2802 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2803 return true; 2804} 2805 2806bool EmulateInstructionARM::EmulateNop(const uint32_t opcode, 2807 const ARMEncoding encoding) { 2808 // NOP, nothing to do... 2809 return true; 2810} 2811 2812// Branch causes a branch to a target address. 2813bool EmulateInstructionARM::EmulateB(const uint32_t opcode, 2814 const ARMEncoding encoding) { 2815#if 0 2816 // ARM pseudo code... 2817 if (ConditionPassed()) 2818 { 2819 EncodingSpecificOperations(); 2820 BranchWritePC(PC + imm32); 2821 } 2822#endif 2823 2824 bool success = false; 2825 2826 if (ConditionPassed(opcode)) { 2827 EmulateInstruction::Context context; 2828 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2829 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2830 if (!success) 2831 return false; 2832 addr_t target; // target address 2833 int32_t imm32; // PC-relative offset 2834 switch (encoding) { 2835 case eEncodingT1: 2836 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2837 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2838 target = pc + imm32; 2839 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2840 break; 2841 case eEncodingT2: 2842 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2843 target = pc + imm32; 2844 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2845 break; 2846 case eEncodingT3: 2847 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2848 { 2849 if (Bits32(opcode, 25, 23) == 7) 2850 return false; // See Branches and miscellaneous control on page 2851 // A6-235. 2852 2853 uint32_t S = Bit32(opcode, 26); 2854 uint32_t imm6 = Bits32(opcode, 21, 16); 2855 uint32_t J1 = Bit32(opcode, 13); 2856 uint32_t J2 = Bit32(opcode, 11); 2857 uint32_t imm11 = Bits32(opcode, 10, 0); 2858 uint32_t imm21 = 2859 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2860 imm32 = llvm::SignExtend32<21>(imm21); 2861 target = pc + imm32; 2862 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2863 break; 2864 } 2865 case eEncodingT4: { 2866 uint32_t S = Bit32(opcode, 26); 2867 uint32_t imm10 = Bits32(opcode, 25, 16); 2868 uint32_t J1 = Bit32(opcode, 13); 2869 uint32_t J2 = Bit32(opcode, 11); 2870 uint32_t imm11 = Bits32(opcode, 10, 0); 2871 uint32_t I1 = !(J1 ^ S); 2872 uint32_t I2 = !(J2 ^ S); 2873 uint32_t imm25 = 2874 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2875 imm32 = llvm::SignExtend32<25>(imm25); 2876 target = pc + imm32; 2877 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2878 break; 2879 } 2880 case eEncodingA1: 2881 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2882 target = pc + imm32; 2883 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2884 break; 2885 default: 2886 return false; 2887 } 2888 if (!BranchWritePC(context, target)) 2889 return false; 2890 } 2891 return true; 2892} 2893 2894// Compare and Branch on Nonzero and Compare and Branch on Zero compare the 2895// value in a register with 2896// zero and conditionally branch forward a constant value. They do not affect 2897// the condition flags. 2898// CBNZ, CBZ 2899bool EmulateInstructionARM::EmulateCB(const uint32_t opcode, 2900 const ARMEncoding encoding) { 2901#if 0 2902 // ARM pseudo code... 2903 EncodingSpecificOperations(); 2904 if nonzero ^ IsZero(R[n]) then 2905 BranchWritePC(PC + imm32); 2906#endif 2907 2908 bool success = false; 2909 2910 // Read the register value from the operand register Rn. 2911 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2912 if (!success) 2913 return false; 2914 2915 EmulateInstruction::Context context; 2916 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2917 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2918 if (!success) 2919 return false; 2920 2921 addr_t target; // target address 2922 uint32_t imm32; // PC-relative offset to branch forward 2923 bool nonzero; 2924 switch (encoding) { 2925 case eEncodingT1: 2926 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2927 nonzero = BitIsSet(opcode, 11); 2928 target = pc + imm32; 2929 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2930 break; 2931 default: 2932 return false; 2933 } 2934 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2935 if (!BranchWritePC(context, target)) 2936 return false; 2937 2938 return true; 2939} 2940 2941// Table Branch Byte causes a PC-relative forward branch using a table of single 2942// byte offsets. 2943// A base register provides a pointer to the table, and a second register 2944// supplies an index into the table. 2945// The branch length is twice the value of the byte returned from the table. 2946// 2947// Table Branch Halfword causes a PC-relative forward branch using a table of 2948// single halfword offsets. 2949// A base register provides a pointer to the table, and a second register 2950// supplies an index into the table. 2951// The branch length is twice the value of the halfword returned from the table. 2952// TBB, TBH 2953bool EmulateInstructionARM::EmulateTB(const uint32_t opcode, 2954 const ARMEncoding encoding) { 2955#if 0 2956 // ARM pseudo code... 2957 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2958 if is_tbh then 2959 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2960 else 2961 halfwords = UInt(MemU[R[n]+R[m], 1]); 2962 BranchWritePC(PC + 2*halfwords); 2963#endif 2964 2965 bool success = false; 2966 2967 if (ConditionPassed(opcode)) { 2968 uint32_t Rn; // the base register which contains the address of the table of 2969 // branch lengths 2970 uint32_t Rm; // the index register which contains an integer pointing to a 2971 // byte/halfword in the table 2972 bool is_tbh; // true if table branch halfword 2973 switch (encoding) { 2974 case eEncodingT1: 2975 Rn = Bits32(opcode, 19, 16); 2976 Rm = Bits32(opcode, 3, 0); 2977 is_tbh = BitIsSet(opcode, 4); 2978 if (Rn == 13 || BadReg(Rm)) 2979 return false; 2980 if (InITBlock() && !LastInITBlock()) 2981 return false; 2982 break; 2983 default: 2984 return false; 2985 } 2986 2987 // Read the address of the table from the operand register Rn. 2988 // The PC can be used, in which case the table immediately follows this 2989 // instruction. 2990 uint32_t base = ReadCoreReg(Rn, &success); 2991 if (!success) 2992 return false; 2993 2994 // the table index 2995 uint32_t index = ReadCoreReg(Rm, &success); 2996 if (!success) 2997 return false; 2998 2999 // the offsetted table address 3000 addr_t addr = base + (is_tbh ? index * 2 : index); 3001 3002 // PC-relative offset to branch forward 3003 EmulateInstruction::Context context; 3004 context.type = EmulateInstruction::eContextTableBranchReadMemory; 3005 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 3006 if (!success) 3007 return false; 3008 3009 const uint32_t pc = ReadCoreReg(PC_REG, &success); 3010 if (!success) 3011 return false; 3012 3013 // target address 3014 addr_t target = pc + offset; 3015 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 3016 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset); 3017 3018 if (!BranchWritePC(context, target)) 3019 return false; 3020 } 3021 3022 return true; 3023} 3024 3025// This instruction adds an immediate value to a register value, and writes the 3026// result to the destination register. 3027// It can optionally update the condition flags based on the result. 3028bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode, 3029 const ARMEncoding encoding) { 3030#if 0 3031 if ConditionPassed() then 3032 EncodingSpecificOperations(); 3033 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3034 R[d] = result; 3035 if setflags then 3036 APSR.N = result<31>; 3037 APSR.Z = IsZeroBit(result); 3038 APSR.C = carry; 3039 APSR.V = overflow; 3040#endif 3041 3042 bool success = false; 3043 3044 if (ConditionPassed(opcode)) { 3045 uint32_t d; 3046 uint32_t n; 3047 bool setflags; 3048 uint32_t imm32; 3049 uint32_t carry_out; 3050 3051 // EncodingSpecificOperations(); 3052 switch (encoding) { 3053 case eEncodingT1: 3054 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = 3055 // ZeroExtend(imm3, 32); 3056 d = Bits32(opcode, 2, 0); 3057 n = Bits32(opcode, 5, 3); 3058 setflags = !InITBlock(); 3059 imm32 = Bits32(opcode, 8, 6); 3060 3061 break; 3062 3063 case eEncodingT2: 3064 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = 3065 // ZeroExtend(imm8, 32); 3066 d = Bits32(opcode, 10, 8); 3067 n = Bits32(opcode, 10, 8); 3068 setflags = !InITBlock(); 3069 imm32 = Bits32(opcode, 7, 0); 3070 3071 break; 3072 3073 case eEncodingT3: 3074 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 3075 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = 3076 // ThumbExpandImm(i:imm3:imm8); 3077 d = Bits32(opcode, 11, 8); 3078 n = Bits32(opcode, 19, 16); 3079 setflags = BitIsSet(opcode, 20); 3080 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out); 3081 3082 // if Rn == '1101' then SEE ADD (SP plus immediate); 3083 if (n == 13) 3084 return EmulateADDSPImm(opcode, eEncodingT3); 3085 3086 // if BadReg(d) || n == 15 then UNPREDICTABLE; 3087 if (BadReg(d) || (n == 15)) 3088 return false; 3089 3090 break; 3091 3092 case eEncodingT4: { 3093 // if Rn == '1111' then SEE ADR; 3094 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = 3095 // ZeroExtend(i:imm3:imm8, 32); 3096 d = Bits32(opcode, 11, 8); 3097 n = Bits32(opcode, 19, 16); 3098 setflags = false; 3099 uint32_t i = Bit32(opcode, 26); 3100 uint32_t imm3 = Bits32(opcode, 14, 12); 3101 uint32_t imm8 = Bits32(opcode, 7, 0); 3102 imm32 = (i << 11) | (imm3 << 8) | imm8; 3103 3104 // if Rn == '1101' then SEE ADD (SP plus immediate); 3105 if (n == 13) 3106 return EmulateADDSPImm(opcode, eEncodingT4); 3107 3108 // if BadReg(d) then UNPREDICTABLE; 3109 if (BadReg(d)) 3110 return false; 3111 3112 break; 3113 } 3114 3115 default: 3116 return false; 3117 } 3118 3119 uint64_t Rn = 3120 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3121 if (!success) 3122 return false; 3123 3124 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3125 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0); 3126 3127 RegisterInfo reg_n; 3128 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 3129 3130 EmulateInstruction::Context context; 3131 context.type = eContextArithmetic; 3132 context.SetRegisterPlusOffset(reg_n, imm32); 3133 3134 // R[d] = result; 3135 // if setflags then 3136 // APSR.N = result<31>; 3137 // APSR.Z = IsZeroBit(result); 3138 // APSR.C = carry; 3139 // APSR.V = overflow; 3140 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 3141 res.carry_out, res.overflow)) 3142 return false; 3143 } 3144 return true; 3145} 3146 3147// This instruction adds an immediate value to a register value, and writes the 3148// result to the destination 3149// register. It can optionally update the condition flags based on the result. 3150bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode, 3151 const ARMEncoding encoding) { 3152#if 0 3153 // ARM pseudo code... 3154 if ConditionPassed() then 3155 EncodingSpecificOperations(); 3156 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3157 if d == 15 then 3158 ALUWritePC(result); // setflags is always FALSE here 3159 else 3160 R[d] = result; 3161 if setflags then 3162 APSR.N = result<31>; 3163 APSR.Z = IsZeroBit(result); 3164 APSR.C = carry; 3165 APSR.V = overflow; 3166#endif 3167 3168 bool success = false; 3169 3170 if (ConditionPassed(opcode)) { 3171 uint32_t Rd, Rn; 3172 uint32_t 3173 imm32; // the immediate value to be added to the value obtained from Rn 3174 bool setflags; 3175 switch (encoding) { 3176 case eEncodingA1: 3177 Rd = Bits32(opcode, 15, 12); 3178 Rn = Bits32(opcode, 19, 16); 3179 setflags = BitIsSet(opcode, 20); 3180 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3181 break; 3182 default: 3183 return false; 3184 } 3185 3186 // Read the first operand. 3187 uint32_t val1 = ReadCoreReg(Rn, &success); 3188 if (!success) 3189 return false; 3190 3191 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 3192 3193 EmulateInstruction::Context context; 3194 if (Rd == 13) 3195 context.type = EmulateInstruction::eContextAdjustStackPointer; 3196 else if (Rd == GetFramePointerRegisterNumber()) 3197 context.type = EmulateInstruction::eContextSetFramePointer; 3198 else 3199 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3200 3201 RegisterInfo dwarf_reg; 3202 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 3203 context.SetRegisterPlusOffset(dwarf_reg, imm32); 3204 3205 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3206 res.carry_out, res.overflow)) 3207 return false; 3208 } 3209 return true; 3210} 3211 3212// This instruction adds a register value and an optionally-shifted register 3213// value, and writes the result 3214// to the destination register. It can optionally update the condition flags 3215// based on the result. 3216bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode, 3217 const ARMEncoding encoding) { 3218#if 0 3219 // ARM pseudo code... 3220 if ConditionPassed() then 3221 EncodingSpecificOperations(); 3222 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3223 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3224 if d == 15 then 3225 ALUWritePC(result); // setflags is always FALSE here 3226 else 3227 R[d] = result; 3228 if setflags then 3229 APSR.N = result<31>; 3230 APSR.Z = IsZeroBit(result); 3231 APSR.C = carry; 3232 APSR.V = overflow; 3233#endif 3234 3235 bool success = false; 3236 3237 if (ConditionPassed(opcode)) { 3238 uint32_t Rd, Rn, Rm; 3239 ARM_ShifterType shift_t; 3240 uint32_t shift_n; // the shift applied to the value read from Rm 3241 bool setflags; 3242 switch (encoding) { 3243 case eEncodingT1: 3244 Rd = Bits32(opcode, 2, 0); 3245 Rn = Bits32(opcode, 5, 3); 3246 Rm = Bits32(opcode, 8, 6); 3247 setflags = !InITBlock(); 3248 shift_t = SRType_LSL; 3249 shift_n = 0; 3250 break; 3251 case eEncodingT2: 3252 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3253 Rm = Bits32(opcode, 6, 3); 3254 setflags = false; 3255 shift_t = SRType_LSL; 3256 shift_n = 0; 3257 if (Rn == 15 && Rm == 15) 3258 return false; 3259 if (Rd == 15 && InITBlock() && !LastInITBlock()) 3260 return false; 3261 break; 3262 case eEncodingA1: 3263 Rd = Bits32(opcode, 15, 12); 3264 Rn = Bits32(opcode, 19, 16); 3265 Rm = Bits32(opcode, 3, 0); 3266 setflags = BitIsSet(opcode, 20); 3267 shift_n = DecodeImmShiftARM(opcode, shift_t); 3268 break; 3269 default: 3270 return false; 3271 } 3272 3273 // Read the first operand. 3274 uint32_t val1 = ReadCoreReg(Rn, &success); 3275 if (!success) 3276 return false; 3277 3278 // Read the second operand. 3279 uint32_t val2 = ReadCoreReg(Rm, &success); 3280 if (!success) 3281 return false; 3282 3283 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3284 if (!success) 3285 return false; 3286 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3287 3288 EmulateInstruction::Context context; 3289 context.type = eContextArithmetic; 3290 RegisterInfo op1_reg; 3291 RegisterInfo op2_reg; 3292 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 3293 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 3294 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 3295 3296 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3297 res.carry_out, res.overflow)) 3298 return false; 3299 } 3300 return true; 3301} 3302 3303// Compare Negative (immediate) adds a register value and an immediate value. 3304// It updates the condition flags based on the result, and discards the result. 3305bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode, 3306 const ARMEncoding encoding) { 3307#if 0 3308 // ARM pseudo code... 3309 if ConditionPassed() then 3310 EncodingSpecificOperations(); 3311 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3312 APSR.N = result<31>; 3313 APSR.Z = IsZeroBit(result); 3314 APSR.C = carry; 3315 APSR.V = overflow; 3316#endif 3317 3318 bool success = false; 3319 3320 uint32_t Rn; // the first operand 3321 uint32_t imm32; // the immediate value to be compared with 3322 switch (encoding) { 3323 case eEncodingT1: 3324 Rn = Bits32(opcode, 19, 16); 3325 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3326 if (Rn == 15) 3327 return false; 3328 break; 3329 case eEncodingA1: 3330 Rn = Bits32(opcode, 19, 16); 3331 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3332 break; 3333 default: 3334 return false; 3335 } 3336 // Read the register value from the operand register Rn. 3337 uint32_t reg_val = ReadCoreReg(Rn, &success); 3338 if (!success) 3339 return false; 3340 3341 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 3342 3343 EmulateInstruction::Context context; 3344 context.type = EmulateInstruction::eContextImmediate; 3345 context.SetNoArgs(); 3346 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3347 return false; 3348 3349 return true; 3350} 3351 3352// Compare Negative (register) adds a register value and an optionally-shifted 3353// register value. 3354// It updates the condition flags based on the result, and discards the result. 3355bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode, 3356 const ARMEncoding encoding) { 3357#if 0 3358 // ARM pseudo code... 3359 if ConditionPassed() then 3360 EncodingSpecificOperations(); 3361 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3362 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3363 APSR.N = result<31>; 3364 APSR.Z = IsZeroBit(result); 3365 APSR.C = carry; 3366 APSR.V = overflow; 3367#endif 3368 3369 bool success = false; 3370 3371 uint32_t Rn; // the first operand 3372 uint32_t Rm; // the second operand 3373 ARM_ShifterType shift_t; 3374 uint32_t shift_n; // the shift applied to the value read from Rm 3375 switch (encoding) { 3376 case eEncodingT1: 3377 Rn = Bits32(opcode, 2, 0); 3378 Rm = Bits32(opcode, 5, 3); 3379 shift_t = SRType_LSL; 3380 shift_n = 0; 3381 break; 3382 case eEncodingT2: 3383 Rn = Bits32(opcode, 19, 16); 3384 Rm = Bits32(opcode, 3, 0); 3385 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3386 // if n == 15 || BadReg(m) then UNPREDICTABLE; 3387 if (Rn == 15 || BadReg(Rm)) 3388 return false; 3389 break; 3390 case eEncodingA1: 3391 Rn = Bits32(opcode, 19, 16); 3392 Rm = Bits32(opcode, 3, 0); 3393 shift_n = DecodeImmShiftARM(opcode, shift_t); 3394 break; 3395 default: 3396 return false; 3397 } 3398 // Read the register value from register Rn. 3399 uint32_t val1 = ReadCoreReg(Rn, &success); 3400 if (!success) 3401 return false; 3402 3403 // Read the register value from register Rm. 3404 uint32_t val2 = ReadCoreReg(Rm, &success); 3405 if (!success) 3406 return false; 3407 3408 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3409 if (!success) 3410 return false; 3411 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3412 3413 EmulateInstruction::Context context; 3414 context.type = EmulateInstruction::eContextImmediate; 3415 context.SetNoArgs(); 3416 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3417 return false; 3418 3419 return true; 3420} 3421 3422// Compare (immediate) subtracts an immediate value from a register value. 3423// It updates the condition flags based on the result, and discards the result. 3424bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode, 3425 const ARMEncoding encoding) { 3426#if 0 3427 // ARM pseudo code... 3428 if ConditionPassed() then 3429 EncodingSpecificOperations(); 3430 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 3431 APSR.N = result<31>; 3432 APSR.Z = IsZeroBit(result); 3433 APSR.C = carry; 3434 APSR.V = overflow; 3435#endif 3436 3437 bool success = false; 3438 3439 uint32_t Rn; // the first operand 3440 uint32_t imm32; // the immediate value to be compared with 3441 switch (encoding) { 3442 case eEncodingT1: 3443 Rn = Bits32(opcode, 10, 8); 3444 imm32 = Bits32(opcode, 7, 0); 3445 break; 3446 case eEncodingT2: 3447 Rn = Bits32(opcode, 19, 16); 3448 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3449 if (Rn == 15) 3450 return false; 3451 break; 3452 case eEncodingA1: 3453 Rn = Bits32(opcode, 19, 16); 3454 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3455 break; 3456 default: 3457 return false; 3458 } 3459 // Read the register value from the operand register Rn. 3460 uint32_t reg_val = ReadCoreReg(Rn, &success); 3461 if (!success) 3462 return false; 3463 3464 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 3465 3466 EmulateInstruction::Context context; 3467 context.type = EmulateInstruction::eContextImmediate; 3468 context.SetNoArgs(); 3469 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3470 return false; 3471 3472 return true; 3473} 3474 3475// Compare (register) subtracts an optionally-shifted register value from a 3476// register value. 3477// It updates the condition flags based on the result, and discards the result. 3478bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode, 3479 const ARMEncoding encoding) { 3480#if 0 3481 // ARM pseudo code... 3482 if ConditionPassed() then 3483 EncodingSpecificOperations(); 3484 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3485 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 3486 APSR.N = result<31>; 3487 APSR.Z = IsZeroBit(result); 3488 APSR.C = carry; 3489 APSR.V = overflow; 3490#endif 3491 3492 bool success = false; 3493 3494 uint32_t Rn; // the first operand 3495 uint32_t Rm; // the second operand 3496 ARM_ShifterType shift_t; 3497 uint32_t shift_n; // the shift applied to the value read from Rm 3498 switch (encoding) { 3499 case eEncodingT1: 3500 Rn = Bits32(opcode, 2, 0); 3501 Rm = Bits32(opcode, 5, 3); 3502 shift_t = SRType_LSL; 3503 shift_n = 0; 3504 break; 3505 case eEncodingT2: 3506 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3507 Rm = Bits32(opcode, 6, 3); 3508 shift_t = SRType_LSL; 3509 shift_n = 0; 3510 if (Rn < 8 && Rm < 8) 3511 return false; 3512 if (Rn == 15 || Rm == 15) 3513 return false; 3514 break; 3515 case eEncodingT3: 3516 Rn = Bits32(opcode, 19, 16); 3517 Rm = Bits32(opcode, 3, 0); 3518 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3519 if (Rn == 15 || BadReg(Rm)) 3520 return false; 3521 break; 3522 case eEncodingA1: 3523 Rn = Bits32(opcode, 19, 16); 3524 Rm = Bits32(opcode, 3, 0); 3525 shift_n = DecodeImmShiftARM(opcode, shift_t); 3526 break; 3527 default: 3528 return false; 3529 } 3530 // Read the register value from register Rn. 3531 uint32_t val1 = ReadCoreReg(Rn, &success); 3532 if (!success) 3533 return false; 3534 3535 // Read the register value from register Rm. 3536 uint32_t val2 = ReadCoreReg(Rm, &success); 3537 if (!success) 3538 return false; 3539 3540 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3541 if (!success) 3542 return false; 3543 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3544 3545 EmulateInstruction::Context context; 3546 context.type = EmulateInstruction::eContextImmediate; 3547 context.SetNoArgs(); 3548 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3549 return false; 3550 3551 return true; 3552} 3553 3554// Arithmetic Shift Right (immediate) shifts a register value right by an 3555// immediate number of bits, 3556// shifting in copies of its sign bit, and writes the result to the destination 3557// register. It can 3558// optionally update the condition flags based on the result. 3559bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode, 3560 const ARMEncoding encoding) { 3561#if 0 3562 // ARM pseudo code... 3563 if ConditionPassed() then 3564 EncodingSpecificOperations(); 3565 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3566 if d == 15 then // Can only occur for ARM encoding 3567 ALUWritePC(result); // setflags is always FALSE here 3568 else 3569 R[d] = result; 3570 if setflags then 3571 APSR.N = result<31>; 3572 APSR.Z = IsZeroBit(result); 3573 APSR.C = carry; 3574 // APSR.V unchanged 3575#endif 3576 3577 return EmulateShiftImm(opcode, encoding, SRType_ASR); 3578} 3579 3580// Arithmetic Shift Right (register) shifts a register value right by a variable 3581// number of bits, 3582// shifting in copies of its sign bit, and writes the result to the destination 3583// register. 3584// The variable number of bits is read from the bottom byte of a register. It 3585// can optionally update 3586// the condition flags based on the result. 3587bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode, 3588 const ARMEncoding encoding) { 3589#if 0 3590 // ARM pseudo code... 3591 if ConditionPassed() then 3592 EncodingSpecificOperations(); 3593 shift_n = UInt(R[m]<7:0>); 3594 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3595 R[d] = result; 3596 if setflags then 3597 APSR.N = result<31>; 3598 APSR.Z = IsZeroBit(result); 3599 APSR.C = carry; 3600 // APSR.V unchanged 3601#endif 3602 3603 return EmulateShiftReg(opcode, encoding, SRType_ASR); 3604} 3605 3606// Logical Shift Left (immediate) shifts a register value left by an immediate 3607// number of bits, 3608// shifting in zeros, and writes the result to the destination register. It can 3609// optionally 3610// update the condition flags based on the result. 3611bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode, 3612 const ARMEncoding encoding) { 3613#if 0 3614 // ARM pseudo code... 3615 if ConditionPassed() then 3616 EncodingSpecificOperations(); 3617 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3618 if d == 15 then // Can only occur for ARM encoding 3619 ALUWritePC(result); // setflags is always FALSE here 3620 else 3621 R[d] = result; 3622 if setflags then 3623 APSR.N = result<31>; 3624 APSR.Z = IsZeroBit(result); 3625 APSR.C = carry; 3626 // APSR.V unchanged 3627#endif 3628 3629 return EmulateShiftImm(opcode, encoding, SRType_LSL); 3630} 3631 3632// Logical Shift Left (register) shifts a register value left by a variable 3633// number of bits, 3634// shifting in zeros, and writes the result to the destination register. The 3635// variable number 3636// of bits is read from the bottom byte of a register. It can optionally update 3637// the condition 3638// flags based on the result. 3639bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode, 3640 const ARMEncoding encoding) { 3641#if 0 3642 // ARM pseudo code... 3643 if ConditionPassed() then 3644 EncodingSpecificOperations(); 3645 shift_n = UInt(R[m]<7:0>); 3646 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 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 EmulateShiftReg(opcode, encoding, SRType_LSL); 3656} 3657 3658// Logical Shift Right (immediate) shifts a register value right by an immediate 3659// number of bits, 3660// shifting in zeros, and writes the result to the destination register. It can 3661// optionally 3662// update the condition flags based on the result. 3663bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode, 3664 const ARMEncoding encoding) { 3665#if 0 3666 // ARM pseudo code... 3667 if ConditionPassed() then 3668 EncodingSpecificOperations(); 3669 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3670 if d == 15 then // Can only occur for ARM encoding 3671 ALUWritePC(result); // setflags is always FALSE here 3672 else 3673 R[d] = result; 3674 if setflags then 3675 APSR.N = result<31>; 3676 APSR.Z = IsZeroBit(result); 3677 APSR.C = carry; 3678 // APSR.V unchanged 3679#endif 3680 3681 return EmulateShiftImm(opcode, encoding, SRType_LSR); 3682} 3683 3684// Logical Shift Right (register) shifts a register value right by a variable 3685// number of bits, 3686// shifting in zeros, and writes the result to the destination register. The 3687// variable number 3688// of bits is read from the bottom byte of a register. It can optionally update 3689// the condition 3690// flags based on the result. 3691bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode, 3692 const ARMEncoding encoding) { 3693#if 0 3694 // ARM pseudo code... 3695 if ConditionPassed() then 3696 EncodingSpecificOperations(); 3697 shift_n = UInt(R[m]<7:0>); 3698 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3699 R[d] = result; 3700 if setflags then 3701 APSR.N = result<31>; 3702 APSR.Z = IsZeroBit(result); 3703 APSR.C = carry; 3704 // APSR.V unchanged 3705#endif 3706 3707 return EmulateShiftReg(opcode, encoding, SRType_LSR); 3708} 3709 3710// Rotate Right (immediate) provides the value of the contents of a register 3711// rotated by a constant value. 3712// The bits that are rotated off the right end are inserted into the vacated bit 3713// positions on the left. 3714// It can optionally update the condition flags based on the result. 3715bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode, 3716 const ARMEncoding encoding) { 3717#if 0 3718 // ARM pseudo code... 3719 if ConditionPassed() then 3720 EncodingSpecificOperations(); 3721 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3722 if d == 15 then // Can only occur for ARM encoding 3723 ALUWritePC(result); // setflags is always FALSE here 3724 else 3725 R[d] = result; 3726 if setflags then 3727 APSR.N = result<31>; 3728 APSR.Z = IsZeroBit(result); 3729 APSR.C = carry; 3730 // APSR.V unchanged 3731#endif 3732 3733 return EmulateShiftImm(opcode, encoding, SRType_ROR); 3734} 3735 3736// Rotate Right (register) provides the value of the contents of a register 3737// rotated by a variable number of bits. 3738// The bits that are rotated off the right end are inserted into the vacated bit 3739// positions on the left. 3740// The variable number of bits is read from the bottom byte of a register. It 3741// can optionally update the condition 3742// flags based on the result. 3743bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode, 3744 const ARMEncoding encoding) { 3745#if 0 3746 // ARM pseudo code... 3747 if ConditionPassed() then 3748 EncodingSpecificOperations(); 3749 shift_n = UInt(R[m]<7:0>); 3750 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3751 R[d] = result; 3752 if setflags then 3753 APSR.N = result<31>; 3754 APSR.Z = IsZeroBit(result); 3755 APSR.C = carry; 3756 // APSR.V unchanged 3757#endif 3758 3759 return EmulateShiftReg(opcode, encoding, SRType_ROR); 3760} 3761 3762// Rotate Right with Extend provides the value of the contents of a register 3763// shifted right by one place, 3764// with the carry flag shifted into bit [31]. 3765// 3766// RRX can optionally update the condition flags based on the result. 3767// In that case, bit [0] is shifted into the carry flag. 3768bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode, 3769 const ARMEncoding encoding) { 3770#if 0 3771 // ARM pseudo code... 3772 if ConditionPassed() then 3773 EncodingSpecificOperations(); 3774 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3775 if d == 15 then // Can only occur for ARM encoding 3776 ALUWritePC(result); // setflags is always FALSE here 3777 else 3778 R[d] = result; 3779 if setflags then 3780 APSR.N = result<31>; 3781 APSR.Z = IsZeroBit(result); 3782 APSR.C = carry; 3783 // APSR.V unchanged 3784#endif 3785 3786 return EmulateShiftImm(opcode, encoding, SRType_RRX); 3787} 3788 3789bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode, 3790 const ARMEncoding encoding, 3791 ARM_ShifterType shift_type) { 3792 // assert(shift_type == SRType_ASR 3793 // || shift_type == SRType_LSL 3794 // || shift_type == SRType_LSR 3795 // || shift_type == SRType_ROR 3796 // || shift_type == SRType_RRX); 3797 3798 bool success = false; 3799 3800 if (ConditionPassed(opcode)) { 3801 uint32_t Rd; // the destination register 3802 uint32_t Rm; // the first operand register 3803 uint32_t imm5; // encoding for the shift amount 3804 uint32_t carry; // the carry bit after the shift operation 3805 bool setflags; 3806 3807 // Special case handling! 3808 // A8.6.139 ROR (immediate) -- Encoding T1 3809 ARMEncoding use_encoding = encoding; 3810 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) { 3811 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding 3812 // to 3813 // have the same decoding of bit fields as the other Thumb2 shift 3814 // operations. 3815 use_encoding = eEncodingT2; 3816 } 3817 3818 switch (use_encoding) { 3819 case eEncodingT1: 3820 // Due to the above special case handling! 3821 if (shift_type == SRType_ROR) 3822 return false; 3823 3824 Rd = Bits32(opcode, 2, 0); 3825 Rm = Bits32(opcode, 5, 3); 3826 setflags = !InITBlock(); 3827 imm5 = Bits32(opcode, 10, 6); 3828 break; 3829 case eEncodingT2: 3830 // A8.6.141 RRX 3831 // There's no imm form of RRX instructions. 3832 if (shift_type == SRType_RRX) 3833 return false; 3834 3835 Rd = Bits32(opcode, 11, 8); 3836 Rm = Bits32(opcode, 3, 0); 3837 setflags = BitIsSet(opcode, 20); 3838 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3839 if (BadReg(Rd) || BadReg(Rm)) 3840 return false; 3841 break; 3842 case eEncodingA1: 3843 Rd = Bits32(opcode, 15, 12); 3844 Rm = Bits32(opcode, 3, 0); 3845 setflags = BitIsSet(opcode, 20); 3846 imm5 = Bits32(opcode, 11, 7); 3847 break; 3848 default: 3849 return false; 3850 } 3851 3852 // A8.6.139 ROR (immediate) 3853 if (shift_type == SRType_ROR && imm5 == 0) 3854 shift_type = SRType_RRX; 3855 3856 // Get the first operand. 3857 uint32_t value = ReadCoreReg(Rm, &success); 3858 if (!success) 3859 return false; 3860 3861 // Decode the shift amount if not RRX. 3862 uint32_t amt = 3863 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3864 3865 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3866 if (!success) 3867 return false; 3868 3869 // The context specifies that an immediate is to be moved into Rd. 3870 EmulateInstruction::Context context; 3871 context.type = EmulateInstruction::eContextImmediate; 3872 context.SetNoArgs(); 3873 3874 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3875 return false; 3876 } 3877 return true; 3878} 3879 3880bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode, 3881 const ARMEncoding encoding, 3882 ARM_ShifterType shift_type) { 3883 // assert(shift_type == SRType_ASR 3884 // || shift_type == SRType_LSL 3885 // || shift_type == SRType_LSR 3886 // || shift_type == SRType_ROR); 3887 3888 bool success = false; 3889 3890 if (ConditionPassed(opcode)) { 3891 uint32_t Rd; // the destination register 3892 uint32_t Rn; // the first operand register 3893 uint32_t 3894 Rm; // the register whose bottom byte contains the amount to shift by 3895 uint32_t carry; // the carry bit after the shift operation 3896 bool setflags; 3897 switch (encoding) { 3898 case eEncodingT1: 3899 Rd = Bits32(opcode, 2, 0); 3900 Rn = Rd; 3901 Rm = Bits32(opcode, 5, 3); 3902 setflags = !InITBlock(); 3903 break; 3904 case eEncodingT2: 3905 Rd = Bits32(opcode, 11, 8); 3906 Rn = Bits32(opcode, 19, 16); 3907 Rm = Bits32(opcode, 3, 0); 3908 setflags = BitIsSet(opcode, 20); 3909 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3910 return false; 3911 break; 3912 case eEncodingA1: 3913 Rd = Bits32(opcode, 15, 12); 3914 Rn = Bits32(opcode, 3, 0); 3915 Rm = Bits32(opcode, 11, 8); 3916 setflags = BitIsSet(opcode, 20); 3917 if (Rd == 15 || Rn == 15 || Rm == 15) 3918 return false; 3919 break; 3920 default: 3921 return false; 3922 } 3923 3924 // Get the first operand. 3925 uint32_t value = ReadCoreReg(Rn, &success); 3926 if (!success) 3927 return false; 3928 // Get the Rm register content. 3929 uint32_t val = ReadCoreReg(Rm, &success); 3930 if (!success) 3931 return false; 3932 3933 // Get the shift amount. 3934 uint32_t amt = Bits32(val, 7, 0); 3935 3936 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3937 if (!success) 3938 return false; 3939 3940 // The context specifies that an immediate is to be moved into Rd. 3941 EmulateInstruction::Context context; 3942 context.type = EmulateInstruction::eContextImmediate; 3943 context.SetNoArgs(); 3944 3945 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3946 return false; 3947 } 3948 return true; 3949} 3950 3951// LDM loads multiple registers from consecutive memory locations, using an 3952// address from a base register. Optionally the address just above the highest 3953// of those locations 3954// can be written back to the base register. 3955bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode, 3956 const ARMEncoding encoding) { 3957#if 0 3958 // ARM pseudo code... 3959 if ConditionPassed() 3960 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3961 address = R[n]; 3962 3963 for i = 0 to 14 3964 if registers<i> == '1' then 3965 R[i] = MemA[address, 4]; address = address + 4; 3966 if registers<15> == '1' then 3967 LoadWritePC (MemA[address, 4]); 3968 3969 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3970 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3971 3972#endif 3973 3974 bool success = false; 3975 if (ConditionPassed(opcode)) { 3976 uint32_t n; 3977 uint32_t registers = 0; 3978 bool wback; 3979 const uint32_t addr_byte_size = GetAddressByteSize(); 3980 switch (encoding) { 3981 case eEncodingT1: 3982 // n = UInt(Rn); registers = '00000000':register_list; wback = 3983 // (registers<n> == '0'); 3984 n = Bits32(opcode, 10, 8); 3985 registers = Bits32(opcode, 7, 0); 3986 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3987 wback = BitIsClear(registers, n); 3988 // if BitCount(registers) < 1 then UNPREDICTABLE; 3989 if (BitCount(registers) < 1) 3990 return false; 3991 break; 3992 case eEncodingT2: 3993 // if W == '1' && Rn == '1101' then SEE POP; 3994 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3995 n = Bits32(opcode, 19, 16); 3996 registers = Bits32(opcode, 15, 0); 3997 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3998 wback = BitIsSet(opcode, 21); 3999 4000 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 4001 // UNPREDICTABLE; 4002 if ((n == 15) || (BitCount(registers) < 2) || 4003 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 4004 return false; 4005 4006 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 4007 // UNPREDICTABLE; 4008 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 4009 return false; 4010 4011 // if wback && registers<n> == '1' then UNPREDICTABLE; 4012 if (wback && BitIsSet(registers, n)) 4013 return false; 4014 break; 4015 4016 case eEncodingA1: 4017 n = Bits32(opcode, 19, 16); 4018 registers = Bits32(opcode, 15, 0); 4019 wback = BitIsSet(opcode, 21); 4020 if ((n == 15) || (BitCount(registers) < 1)) 4021 return false; 4022 break; 4023 default: 4024 return false; 4025 } 4026 4027 int32_t offset = 0; 4028 const addr_t base_address = 4029 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4030 if (!success) 4031 return false; 4032 4033 EmulateInstruction::Context context; 4034 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4035 RegisterInfo dwarf_reg; 4036 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4037 context.SetRegisterPlusOffset(dwarf_reg, offset); 4038 4039 for (int i = 0; i < 14; ++i) { 4040 if (BitIsSet(registers, i)) { 4041 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4042 context.SetRegisterPlusOffset(dwarf_reg, offset); 4043 if (wback && (n == 13)) // Pop Instruction 4044 { 4045 context.type = EmulateInstruction::eContextPopRegisterOffStack; 4046 context.SetAddress(base_address + offset); 4047 } 4048 4049 // R[i] = MemA [address, 4]; address = address + 4; 4050 uint32_t data = MemARead(context, base_address + offset, addr_byte_size, 4051 0, &success); 4052 if (!success) 4053 return false; 4054 4055 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4056 data)) 4057 return false; 4058 4059 offset += addr_byte_size; 4060 } 4061 } 4062 4063 if (BitIsSet(registers, 15)) { 4064 // LoadWritePC (MemA [address, 4]); 4065 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4066 context.SetRegisterPlusOffset(dwarf_reg, offset); 4067 uint32_t data = 4068 MemARead(context, base_address + offset, addr_byte_size, 0, &success); 4069 if (!success) 4070 return false; 4071 // In ARMv5T and above, this is an interworking branch. 4072 if (!LoadWritePC(context, data)) 4073 return false; 4074 } 4075 4076 if (wback && BitIsClear(registers, n)) { 4077 // R[n] = R[n] + 4 * BitCount (registers) 4078 int32_t offset = addr_byte_size * BitCount(registers); 4079 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4080 context.SetRegisterPlusOffset(dwarf_reg, offset); 4081 4082 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4083 base_address + offset)) 4084 return false; 4085 } 4086 if (wback && BitIsSet(registers, n)) 4087 // R[n] bits(32) UNKNOWN; 4088 return WriteBits32Unknown(n); 4089 } 4090 return true; 4091} 4092 4093// LDMDA loads multiple registers from consecutive memory locations using an 4094// address from a base register. 4095// The consecutive memory locations end at this address and the address just 4096// below the lowest of those locations 4097// can optionally be written back to the base register. 4098bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode, 4099 const ARMEncoding encoding) { 4100#if 0 4101 // ARM pseudo code... 4102 if ConditionPassed() then 4103 EncodingSpecificOperations(); 4104 address = R[n] - 4*BitCount(registers) + 4; 4105 4106 for i = 0 to 14 4107 if registers<i> == '1' then 4108 R[i] = MemA[address,4]; address = address + 4; 4109 4110 if registers<15> == '1' then 4111 LoadWritePC(MemA[address,4]); 4112 4113 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4114 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4115#endif 4116 4117 bool success = false; 4118 4119 if (ConditionPassed(opcode)) { 4120 uint32_t n; 4121 uint32_t registers = 0; 4122 bool wback; 4123 const uint32_t addr_byte_size = GetAddressByteSize(); 4124 4125 // EncodingSpecificOperations(); 4126 switch (encoding) { 4127 case eEncodingA1: 4128 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4129 n = Bits32(opcode, 19, 16); 4130 registers = Bits32(opcode, 15, 0); 4131 wback = BitIsSet(opcode, 21); 4132 4133 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4134 if ((n == 15) || (BitCount(registers) < 1)) 4135 return false; 4136 4137 break; 4138 4139 default: 4140 return false; 4141 } 4142 // address = R[n] - 4*BitCount(registers) + 4; 4143 4144 int32_t offset = 0; 4145 addr_t Rn = ReadCoreReg(n, &success); 4146 4147 if (!success) 4148 return false; 4149 4150 addr_t address = 4151 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size; 4152 4153 EmulateInstruction::Context context; 4154 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4155 RegisterInfo dwarf_reg; 4156 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4157 context.SetRegisterPlusOffset(dwarf_reg, offset); 4158 4159 // for i = 0 to 14 4160 for (int i = 0; i < 14; ++i) { 4161 // if registers<i> == '1' then 4162 if (BitIsSet(registers, i)) { 4163 // R[i] = MemA[address,4]; address = address + 4; 4164 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4165 uint32_t data = 4166 MemARead(context, address + offset, addr_byte_size, 0, &success); 4167 if (!success) 4168 return false; 4169 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4170 data)) 4171 return false; 4172 offset += addr_byte_size; 4173 } 4174 } 4175 4176 // if registers<15> == '1' then 4177 // LoadWritePC(MemA[address,4]); 4178 if (BitIsSet(registers, 15)) { 4179 context.SetRegisterPlusOffset(dwarf_reg, offset); 4180 uint32_t data = 4181 MemARead(context, address + offset, addr_byte_size, 0, &success); 4182 if (!success) 4183 return false; 4184 // In ARMv5T and above, this is an interworking branch. 4185 if (!LoadWritePC(context, data)) 4186 return false; 4187 } 4188 4189 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4190 if (wback && BitIsClear(registers, n)) { 4191 if (!success) 4192 return false; 4193 4194 offset = (addr_byte_size * BitCount(registers)) * -1; 4195 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4196 context.SetImmediateSigned(offset); 4197 addr_t addr = Rn + offset; 4198 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4199 addr)) 4200 return false; 4201 } 4202 4203 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4204 if (wback && BitIsSet(registers, n)) 4205 return WriteBits32Unknown(n); 4206 } 4207 return true; 4208} 4209 4210// LDMDB loads multiple registers from consecutive memory locations using an 4211// address from a base register. The 4212// consecutive memory locations end just below this address, and the address of 4213// the lowest of those locations can 4214// be optionally written back to the base register. 4215bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode, 4216 const ARMEncoding encoding) { 4217#if 0 4218 // ARM pseudo code... 4219 if ConditionPassed() then 4220 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4221 address = R[n] - 4*BitCount(registers); 4222 4223 for i = 0 to 14 4224 if registers<i> == '1' then 4225 R[i] = MemA[address,4]; address = address + 4; 4226 if registers<15> == '1' then 4227 LoadWritePC(MemA[address,4]); 4228 4229 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4230 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 4231#endif 4232 4233 bool success = false; 4234 4235 if (ConditionPassed(opcode)) { 4236 uint32_t n; 4237 uint32_t registers = 0; 4238 bool wback; 4239 const uint32_t addr_byte_size = GetAddressByteSize(); 4240 switch (encoding) { 4241 case eEncodingT1: 4242 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 4243 n = Bits32(opcode, 19, 16); 4244 registers = Bits32(opcode, 15, 0); 4245 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 4246 wback = BitIsSet(opcode, 21); 4247 4248 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 4249 // UNPREDICTABLE; 4250 if ((n == 15) || (BitCount(registers) < 2) || 4251 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 4252 return false; 4253 4254 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 4255 // UNPREDICTABLE; 4256 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 4257 return false; 4258 4259 // if wback && registers<n> == '1' then UNPREDICTABLE; 4260 if (wback && BitIsSet(registers, n)) 4261 return false; 4262 4263 break; 4264 4265 case eEncodingA1: 4266 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4267 n = Bits32(opcode, 19, 16); 4268 registers = Bits32(opcode, 15, 0); 4269 wback = BitIsSet(opcode, 21); 4270 4271 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4272 if ((n == 15) || (BitCount(registers) < 1)) 4273 return false; 4274 4275 break; 4276 4277 default: 4278 return false; 4279 } 4280 4281 // address = R[n] - 4*BitCount(registers); 4282 4283 int32_t offset = 0; 4284 addr_t Rn = 4285 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4286 4287 if (!success) 4288 return false; 4289 4290 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4291 EmulateInstruction::Context context; 4292 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4293 RegisterInfo dwarf_reg; 4294 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4295 context.SetRegisterPlusOffset(dwarf_reg, Rn - address); 4296 4297 for (int i = 0; i < 14; ++i) { 4298 if (BitIsSet(registers, i)) { 4299 // R[i] = MemA[address,4]; address = address + 4; 4300 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4301 uint32_t data = 4302 MemARead(context, address + offset, addr_byte_size, 0, &success); 4303 if (!success) 4304 return false; 4305 4306 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4307 data)) 4308 return false; 4309 4310 offset += addr_byte_size; 4311 } 4312 } 4313 4314 // if registers<15> == '1' then 4315 // LoadWritePC(MemA[address,4]); 4316 if (BitIsSet(registers, 15)) { 4317 context.SetRegisterPlusOffset(dwarf_reg, offset); 4318 uint32_t data = 4319 MemARead(context, address + offset, addr_byte_size, 0, &success); 4320 if (!success) 4321 return false; 4322 // In ARMv5T and above, this is an interworking branch. 4323 if (!LoadWritePC(context, data)) 4324 return false; 4325 } 4326 4327 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4328 if (wback && BitIsClear(registers, n)) { 4329 if (!success) 4330 return false; 4331 4332 offset = (addr_byte_size * BitCount(registers)) * -1; 4333 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4334 context.SetImmediateSigned(offset); 4335 addr_t addr = Rn + offset; 4336 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4337 addr)) 4338 return false; 4339 } 4340 4341 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4342 // possible for encoding A1 4343 if (wback && BitIsSet(registers, n)) 4344 return WriteBits32Unknown(n); 4345 } 4346 return true; 4347} 4348 4349// LDMIB loads multiple registers from consecutive memory locations using an 4350// address from a base register. The 4351// consecutive memory locations start just above this address, and thea ddress 4352// of the last of those locations can 4353// optinoally be written back to the base register. 4354bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode, 4355 const ARMEncoding encoding) { 4356#if 0 4357 if ConditionPassed() then 4358 EncodingSpecificOperations(); 4359 address = R[n] + 4; 4360 4361 for i = 0 to 14 4362 if registers<i> == '1' then 4363 R[i] = MemA[address,4]; address = address + 4; 4364 if registers<15> == '1' then 4365 LoadWritePC(MemA[address,4]); 4366 4367 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4368 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4369#endif 4370 4371 bool success = false; 4372 4373 if (ConditionPassed(opcode)) { 4374 uint32_t n; 4375 uint32_t registers = 0; 4376 bool wback; 4377 const uint32_t addr_byte_size = GetAddressByteSize(); 4378 switch (encoding) { 4379 case eEncodingA1: 4380 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4381 n = Bits32(opcode, 19, 16); 4382 registers = Bits32(opcode, 15, 0); 4383 wback = BitIsSet(opcode, 21); 4384 4385 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4386 if ((n == 15) || (BitCount(registers) < 1)) 4387 return false; 4388 4389 break; 4390 default: 4391 return false; 4392 } 4393 // address = R[n] + 4; 4394 4395 int32_t offset = 0; 4396 addr_t Rn = 4397 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4398 4399 if (!success) 4400 return false; 4401 4402 addr_t address = Rn + addr_byte_size; 4403 4404 EmulateInstruction::Context context; 4405 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4406 RegisterInfo dwarf_reg; 4407 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4408 context.SetRegisterPlusOffset(dwarf_reg, offset); 4409 4410 for (int i = 0; i < 14; ++i) { 4411 if (BitIsSet(registers, i)) { 4412 // R[i] = MemA[address,4]; address = address + 4; 4413 4414 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size); 4415 uint32_t data = 4416 MemARead(context, address + offset, addr_byte_size, 0, &success); 4417 if (!success) 4418 return false; 4419 4420 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4421 data)) 4422 return false; 4423 4424 offset += addr_byte_size; 4425 } 4426 } 4427 4428 // if registers<15> == '1' then 4429 // LoadWritePC(MemA[address,4]); 4430 if (BitIsSet(registers, 15)) { 4431 context.SetRegisterPlusOffset(dwarf_reg, offset); 4432 uint32_t data = 4433 MemARead(context, address + offset, addr_byte_size, 0, &success); 4434 if (!success) 4435 return false; 4436 // In ARMv5T and above, this is an interworking branch. 4437 if (!LoadWritePC(context, data)) 4438 return false; 4439 } 4440 4441 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4442 if (wback && BitIsClear(registers, n)) { 4443 if (!success) 4444 return false; 4445 4446 offset = addr_byte_size * BitCount(registers); 4447 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4448 context.SetImmediateSigned(offset); 4449 addr_t addr = Rn + offset; 4450 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4451 addr)) 4452 return false; 4453 } 4454 4455 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4456 // possible for encoding A1 4457 if (wback && BitIsSet(registers, n)) 4458 return WriteBits32Unknown(n); 4459 } 4460 return true; 4461} 4462 4463// Load Register (immediate) calculates an address from a base register value 4464// and 4465// an immediate offset, loads a word from memory, and writes to a register. 4466// LDR (immediate, Thumb) 4467bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode, 4468 const ARMEncoding encoding) { 4469#if 0 4470 // ARM pseudo code... 4471 if (ConditionPassed()) 4472 { 4473 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 4474 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4475 address = if index then offset_addr else R[n]; 4476 data = MemU[address,4]; 4477 if wback then R[n] = offset_addr; 4478 if t == 15 then 4479 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 4480 elsif UnalignedSupport() || address<1:0> = '00' then 4481 R[t] = data; 4482 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 4483 } 4484#endif 4485 4486 bool success = false; 4487 4488 if (ConditionPassed(opcode)) { 4489 uint32_t Rt; // the destination register 4490 uint32_t Rn; // the base register 4491 uint32_t imm32; // the immediate offset used to form the address 4492 addr_t offset_addr; // the offset address 4493 addr_t address; // the calculated address 4494 uint32_t data; // the literal data value from memory load 4495 bool add, index, wback; 4496 switch (encoding) { 4497 case eEncodingT1: 4498 Rt = Bits32(opcode, 2, 0); 4499 Rn = Bits32(opcode, 5, 3); 4500 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 4501 // index = TRUE; add = TRUE; wback = FALSE 4502 add = true; 4503 index = true; 4504 wback = false; 4505 4506 break; 4507 4508 case eEncodingT2: 4509 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4510 Rt = Bits32(opcode, 10, 8); 4511 Rn = 13; 4512 imm32 = Bits32(opcode, 7, 0) << 2; 4513 4514 // index = TRUE; add = TRUE; wback = FALSE; 4515 index = true; 4516 add = true; 4517 wback = false; 4518 4519 break; 4520 4521 case eEncodingT3: 4522 // if Rn == '1111' then SEE LDR (literal); 4523 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4524 Rt = Bits32(opcode, 15, 12); 4525 Rn = Bits32(opcode, 19, 16); 4526 imm32 = Bits32(opcode, 11, 0); 4527 4528 // index = TRUE; add = TRUE; wback = FALSE; 4529 index = true; 4530 add = true; 4531 wback = false; 4532 4533 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4534 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4535 return false; 4536 4537 break; 4538 4539 case eEncodingT4: 4540 // if Rn == '1111' then SEE LDR (literal); 4541 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4542 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == 4543 // '00000100' then SEE POP; 4544 // if P == '0' && W == '0' then UNDEFINED; 4545 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 4546 return false; 4547 4548 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4549 Rt = Bits32(opcode, 15, 12); 4550 Rn = Bits32(opcode, 19, 16); 4551 imm32 = Bits32(opcode, 7, 0); 4552 4553 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4554 index = BitIsSet(opcode, 10); 4555 add = BitIsSet(opcode, 9); 4556 wback = BitIsSet(opcode, 8); 4557 4558 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) 4559 // then UNPREDICTABLE; 4560 if ((wback && (Rn == Rt)) || 4561 ((Rt == 15) && InITBlock() && !LastInITBlock())) 4562 return false; 4563 4564 break; 4565 4566 default: 4567 return false; 4568 } 4569 uint32_t base = ReadCoreReg(Rn, &success); 4570 if (!success) 4571 return false; 4572 if (add) 4573 offset_addr = base + imm32; 4574 else 4575 offset_addr = base - imm32; 4576 4577 address = (index ? offset_addr : base); 4578 4579 RegisterInfo base_reg; 4580 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4581 if (wback) { 4582 EmulateInstruction::Context ctx; 4583 if (Rn == 13) { 4584 ctx.type = eContextAdjustStackPointer; 4585 ctx.SetImmediateSigned((int32_t)(offset_addr - base)); 4586 } else if (Rn == GetFramePointerRegisterNumber()) { 4587 ctx.type = eContextSetFramePointer; 4588 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4589 } else { 4590 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4591 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4592 } 4593 4594 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn, 4595 offset_addr)) 4596 return false; 4597 } 4598 4599 // Prepare to write to the Rt register. 4600 EmulateInstruction::Context context; 4601 context.type = EmulateInstruction::eContextRegisterLoad; 4602 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4603 4604 // Read memory from the address. 4605 data = MemURead(context, address, 4, 0, &success); 4606 if (!success) 4607 return false; 4608 4609 if (Rt == 15) { 4610 if (Bits32(address, 1, 0) == 0) { 4611 if (!LoadWritePC(context, data)) 4612 return false; 4613 } else 4614 return false; 4615 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 4616 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 4617 data)) 4618 return false; 4619 } else 4620 WriteBits32Unknown(Rt); 4621 } 4622 return true; 4623} 4624 4625// STM (Store Multiple Increment After) stores multiple registers to consecutive 4626// memory locations using an address 4627// from a base register. The consecutive memory locations start at this 4628// address, and the address just above the last 4629// of those locations can optionally be written back to the base register. 4630bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode, 4631 const ARMEncoding encoding) { 4632#if 0 4633 if ConditionPassed() then 4634 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4635 address = R[n]; 4636 4637 for i = 0 to 14 4638 if registers<i> == '1' then 4639 if i == n && wback && i != LowestSetBit(registers) then 4640 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4641 else 4642 MemA[address,4] = R[i]; 4643 address = address + 4; 4644 4645 if registers<15> == '1' then // Only possible for encoding A1 4646 MemA[address,4] = PCStoreValue(); 4647 if wback then R[n] = R[n] + 4*BitCount(registers); 4648#endif 4649 4650 bool success = false; 4651 4652 if (ConditionPassed(opcode)) { 4653 uint32_t n; 4654 uint32_t registers = 0; 4655 bool wback; 4656 const uint32_t addr_byte_size = GetAddressByteSize(); 4657 4658 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4659 switch (encoding) { 4660 case eEncodingT1: 4661 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4662 n = Bits32(opcode, 10, 8); 4663 registers = Bits32(opcode, 7, 0); 4664 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4665 wback = true; 4666 4667 // if BitCount(registers) < 1 then UNPREDICTABLE; 4668 if (BitCount(registers) < 1) 4669 return false; 4670 4671 break; 4672 4673 case eEncodingT2: 4674 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4675 n = Bits32(opcode, 19, 16); 4676 registers = Bits32(opcode, 15, 0); 4677 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4678 wback = BitIsSet(opcode, 21); 4679 4680 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4681 if ((n == 15) || (BitCount(registers) < 2)) 4682 return false; 4683 4684 // if wback && registers<n> == '1' then UNPREDICTABLE; 4685 if (wback && BitIsSet(registers, n)) 4686 return false; 4687 4688 break; 4689 4690 case eEncodingA1: 4691 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4692 n = Bits32(opcode, 19, 16); 4693 registers = Bits32(opcode, 15, 0); 4694 wback = BitIsSet(opcode, 21); 4695 4696 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4697 if ((n == 15) || (BitCount(registers) < 1)) 4698 return false; 4699 4700 break; 4701 4702 default: 4703 return false; 4704 } 4705 4706 // address = R[n]; 4707 int32_t offset = 0; 4708 const addr_t address = 4709 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4710 if (!success) 4711 return false; 4712 4713 EmulateInstruction::Context context; 4714 context.type = EmulateInstruction::eContextRegisterStore; 4715 RegisterInfo base_reg; 4716 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4717 4718 // for i = 0 to 14 4719 uint32_t lowest_set_bit = 14; 4720 for (uint32_t i = 0; i < 14; ++i) { 4721 // if registers<i> == '1' then 4722 if (BitIsSet(registers, i)) { 4723 if (i < lowest_set_bit) 4724 lowest_set_bit = i; 4725 // if i == n && wback && i != LowestSetBit(registers) then 4726 if ((i == n) && wback && (i != lowest_set_bit)) 4727 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings 4728 // T1 and A1 4729 WriteBits32UnknownToMemory(address + offset); 4730 else { 4731 // MemA[address,4] = R[i]; 4732 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4733 0, &success); 4734 if (!success) 4735 return false; 4736 4737 RegisterInfo data_reg; 4738 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4739 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 4740 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4741 return false; 4742 } 4743 4744 // address = address + 4; 4745 offset += addr_byte_size; 4746 } 4747 } 4748 4749 // if registers<15> == '1' then // Only possible for encoding A1 4750 // MemA[address,4] = PCStoreValue(); 4751 if (BitIsSet(registers, 15)) { 4752 RegisterInfo pc_reg; 4753 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4754 context.SetRegisterPlusOffset(pc_reg, 8); 4755 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4756 if (!success) 4757 return false; 4758 4759 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4760 return false; 4761 } 4762 4763 // if wback then R[n] = R[n] + 4*BitCount(registers); 4764 if (wback) { 4765 offset = addr_byte_size * BitCount(registers); 4766 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4767 context.SetImmediateSigned(offset); 4768 addr_t data = address + offset; 4769 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4770 data)) 4771 return false; 4772 } 4773 } 4774 return true; 4775} 4776 4777// STMDA (Store Multiple Decrement After) stores multiple registers to 4778// consecutive memory locations using an address 4779// from a base register. The consecutive memory locations end at this address, 4780// and the address just below the lowest 4781// of those locations can optionally be written back to the base register. 4782bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode, 4783 const ARMEncoding encoding) { 4784#if 0 4785 if ConditionPassed() then 4786 EncodingSpecificOperations(); 4787 address = R[n] - 4*BitCount(registers) + 4; 4788 4789 for i = 0 to 14 4790 if registers<i> == '1' then 4791 if i == n && wback && i != LowestSetBit(registers) then 4792 MemA[address,4] = bits(32) UNKNOWN; 4793 else 4794 MemA[address,4] = R[i]; 4795 address = address + 4; 4796 4797 if registers<15> == '1' then 4798 MemA[address,4] = PCStoreValue(); 4799 4800 if wback then R[n] = R[n] - 4*BitCount(registers); 4801#endif 4802 4803 bool success = false; 4804 4805 if (ConditionPassed(opcode)) { 4806 uint32_t n; 4807 uint32_t registers = 0; 4808 bool wback; 4809 const uint32_t addr_byte_size = GetAddressByteSize(); 4810 4811 // EncodingSpecificOperations(); 4812 switch (encoding) { 4813 case eEncodingA1: 4814 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4815 n = Bits32(opcode, 19, 16); 4816 registers = Bits32(opcode, 15, 0); 4817 wback = BitIsSet(opcode, 21); 4818 4819 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4820 if ((n == 15) || (BitCount(registers) < 1)) 4821 return false; 4822 break; 4823 default: 4824 return false; 4825 } 4826 4827 // address = R[n] - 4*BitCount(registers) + 4; 4828 int32_t offset = 0; 4829 addr_t Rn = ReadCoreReg(n, &success); 4830 if (!success) 4831 return false; 4832 4833 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4; 4834 4835 EmulateInstruction::Context context; 4836 context.type = EmulateInstruction::eContextRegisterStore; 4837 RegisterInfo base_reg; 4838 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4839 4840 // for i = 0 to 14 4841 uint32_t lowest_bit_set = 14; 4842 for (uint32_t i = 0; i < 14; ++i) { 4843 // if registers<i> == '1' then 4844 if (BitIsSet(registers, i)) { 4845 if (i < lowest_bit_set) 4846 lowest_bit_set = i; 4847 // if i == n && wback && i != LowestSetBit(registers) then 4848 if ((i == n) && wback && (i != lowest_bit_set)) 4849 // MemA[address,4] = bits(32) UNKNOWN; 4850 WriteBits32UnknownToMemory(address + offset); 4851 else { 4852 // MemA[address,4] = R[i]; 4853 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4854 0, &success); 4855 if (!success) 4856 return false; 4857 4858 RegisterInfo data_reg; 4859 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4860 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4861 Rn - (address + offset)); 4862 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4863 return false; 4864 } 4865 4866 // address = address + 4; 4867 offset += addr_byte_size; 4868 } 4869 } 4870 4871 // if registers<15> == '1' then 4872 // MemA[address,4] = PCStoreValue(); 4873 if (BitIsSet(registers, 15)) { 4874 RegisterInfo pc_reg; 4875 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4876 context.SetRegisterPlusOffset(pc_reg, 8); 4877 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4878 if (!success) 4879 return false; 4880 4881 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4882 return false; 4883 } 4884 4885 // if wback then R[n] = R[n] - 4*BitCount(registers); 4886 if (wback) { 4887 offset = (addr_byte_size * BitCount(registers)) * -1; 4888 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4889 context.SetImmediateSigned(offset); 4890 addr_t data = Rn + offset; 4891 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4892 data)) 4893 return false; 4894 } 4895 } 4896 return true; 4897} 4898 4899// STMDB (Store Multiple Decrement Before) stores multiple registers to 4900// consecutive memory locations using an address 4901// from a base register. The consecutive memory locations end just below this 4902// address, and the address of the first of 4903// those locations can optionally be written back to the base register. 4904bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode, 4905 const ARMEncoding encoding) { 4906#if 0 4907 if ConditionPassed() then 4908 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4909 address = R[n] - 4*BitCount(registers); 4910 4911 for i = 0 to 14 4912 if registers<i> == '1' then 4913 if i == n && wback && i != LowestSetBit(registers) then 4914 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4915 else 4916 MemA[address,4] = R[i]; 4917 address = address + 4; 4918 4919 if registers<15> == '1' then // Only possible for encoding A1 4920 MemA[address,4] = PCStoreValue(); 4921 4922 if wback then R[n] = R[n] - 4*BitCount(registers); 4923#endif 4924 4925 bool success = false; 4926 4927 if (ConditionPassed(opcode)) { 4928 uint32_t n; 4929 uint32_t registers = 0; 4930 bool wback; 4931 const uint32_t addr_byte_size = GetAddressByteSize(); 4932 4933 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4934 switch (encoding) { 4935 case eEncodingT1: 4936 // if W == '1' && Rn == '1101' then SEE PUSH; 4937 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) { 4938 // See PUSH 4939 } 4940 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4941 n = Bits32(opcode, 19, 16); 4942 registers = Bits32(opcode, 15, 0); 4943 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4944 wback = BitIsSet(opcode, 21); 4945 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4946 if ((n == 15) || BitCount(registers) < 2) 4947 return false; 4948 // if wback && registers<n> == '1' then UNPREDICTABLE; 4949 if (wback && BitIsSet(registers, n)) 4950 return false; 4951 break; 4952 4953 case eEncodingA1: 4954 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE 4955 // PUSH; 4956 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) && 4957 BitCount(Bits32(opcode, 15, 0)) >= 2) { 4958 // See Push 4959 } 4960 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4961 n = Bits32(opcode, 19, 16); 4962 registers = Bits32(opcode, 15, 0); 4963 wback = BitIsSet(opcode, 21); 4964 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4965 if ((n == 15) || BitCount(registers) < 1) 4966 return false; 4967 break; 4968 4969 default: 4970 return false; 4971 } 4972 4973 // address = R[n] - 4*BitCount(registers); 4974 4975 int32_t offset = 0; 4976 addr_t Rn = 4977 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4978 if (!success) 4979 return false; 4980 4981 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4982 4983 EmulateInstruction::Context context; 4984 context.type = EmulateInstruction::eContextRegisterStore; 4985 RegisterInfo base_reg; 4986 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4987 4988 // for i = 0 to 14 4989 uint32_t lowest_set_bit = 14; 4990 for (uint32_t i = 0; i < 14; ++i) { 4991 // if registers<i> == '1' then 4992 if (BitIsSet(registers, i)) { 4993 if (i < lowest_set_bit) 4994 lowest_set_bit = i; 4995 // if i == n && wback && i != LowestSetBit(registers) then 4996 if ((i == n) && wback && (i != lowest_set_bit)) 4997 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding 4998 // A1 4999 WriteBits32UnknownToMemory(address + offset); 5000 else { 5001 // MemA[address,4] = R[i]; 5002 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5003 0, &success); 5004 if (!success) 5005 return false; 5006 5007 RegisterInfo data_reg; 5008 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5009 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5010 Rn - (address + offset)); 5011 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5012 return false; 5013 } 5014 5015 // address = address + 4; 5016 offset += addr_byte_size; 5017 } 5018 } 5019 5020 // if registers<15> == '1' then // Only possible for encoding A1 5021 // MemA[address,4] = PCStoreValue(); 5022 if (BitIsSet(registers, 15)) { 5023 RegisterInfo pc_reg; 5024 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5025 context.SetRegisterPlusOffset(pc_reg, 8); 5026 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5027 if (!success) 5028 return false; 5029 5030 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5031 return false; 5032 } 5033 5034 // if wback then R[n] = R[n] - 4*BitCount(registers); 5035 if (wback) { 5036 offset = (addr_byte_size * BitCount(registers)) * -1; 5037 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5038 context.SetImmediateSigned(offset); 5039 addr_t data = Rn + offset; 5040 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5041 data)) 5042 return false; 5043 } 5044 } 5045 return true; 5046} 5047 5048// STMIB (Store Multiple Increment Before) stores multiple registers to 5049// consecutive memory locations using an address 5050// from a base register. The consecutive memory locations start just above this 5051// address, and the address of the last 5052// of those locations can optionally be written back to the base register. 5053bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode, 5054 const ARMEncoding encoding) { 5055#if 0 5056 if ConditionPassed() then 5057 EncodingSpecificOperations(); 5058 address = R[n] + 4; 5059 5060 for i = 0 to 14 5061 if registers<i> == '1' then 5062 if i == n && wback && i != LowestSetBit(registers) then 5063 MemA[address,4] = bits(32) UNKNOWN; 5064 else 5065 MemA[address,4] = R[i]; 5066 address = address + 4; 5067 5068 if registers<15> == '1' then 5069 MemA[address,4] = PCStoreValue(); 5070 5071 if wback then R[n] = R[n] + 4*BitCount(registers); 5072#endif 5073 5074 bool success = false; 5075 5076 if (ConditionPassed(opcode)) { 5077 uint32_t n; 5078 uint32_t registers = 0; 5079 bool wback; 5080 const uint32_t addr_byte_size = GetAddressByteSize(); 5081 5082 // EncodingSpecificOperations(); 5083 switch (encoding) { 5084 case eEncodingA1: 5085 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 5086 n = Bits32(opcode, 19, 16); 5087 registers = Bits32(opcode, 15, 0); 5088 wback = BitIsSet(opcode, 21); 5089 5090 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 5091 if ((n == 15) && (BitCount(registers) < 1)) 5092 return false; 5093 break; 5094 default: 5095 return false; 5096 } 5097 // address = R[n] + 4; 5098 5099 int32_t offset = 0; 5100 addr_t Rn = ReadCoreReg(n, &success); 5101 if (!success) 5102 return false; 5103 5104 addr_t address = Rn + addr_byte_size; 5105 5106 EmulateInstruction::Context context; 5107 context.type = EmulateInstruction::eContextRegisterStore; 5108 RegisterInfo base_reg; 5109 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5110 5111 uint32_t lowest_set_bit = 14; 5112 // for i = 0 to 14 5113 for (uint32_t i = 0; i < 14; ++i) { 5114 // if registers<i> == '1' then 5115 if (BitIsSet(registers, i)) { 5116 if (i < lowest_set_bit) 5117 lowest_set_bit = i; 5118 // if i == n && wback && i != LowestSetBit(registers) then 5119 if ((i == n) && wback && (i != lowest_set_bit)) 5120 // MemA[address,4] = bits(32) UNKNOWN; 5121 WriteBits32UnknownToMemory(address + offset); 5122 // else 5123 else { 5124 // MemA[address,4] = R[i]; 5125 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5126 0, &success); 5127 if (!success) 5128 return false; 5129 5130 RegisterInfo data_reg; 5131 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5132 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5133 offset + addr_byte_size); 5134 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5135 return false; 5136 } 5137 5138 // address = address + 4; 5139 offset += addr_byte_size; 5140 } 5141 } 5142 5143 // if registers<15> == '1' then 5144 // MemA[address,4] = PCStoreValue(); 5145 if (BitIsSet(registers, 15)) { 5146 RegisterInfo pc_reg; 5147 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5148 context.SetRegisterPlusOffset(pc_reg, 8); 5149 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5150 if (!success) 5151 return false; 5152 5153 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5154 return false; 5155 } 5156 5157 // if wback then R[n] = R[n] + 4*BitCount(registers); 5158 if (wback) { 5159 offset = addr_byte_size * BitCount(registers); 5160 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5161 context.SetImmediateSigned(offset); 5162 addr_t data = Rn + offset; 5163 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5164 data)) 5165 return false; 5166 } 5167 } 5168 return true; 5169} 5170 5171// STR (store immediate) calculates an address from a base register value and an 5172// immediate offset, and stores a word 5173// from a register to memory. It can use offset, post-indexed, or pre-indexed 5174// addressing. 5175bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode, 5176 const ARMEncoding encoding) { 5177#if 0 5178 if ConditionPassed() then 5179 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5180 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5181 address = if index then offset_addr else R[n]; 5182 if UnalignedSupport() || address<1:0> == '00' then 5183 MemU[address,4] = R[t]; 5184 else // Can only occur before ARMv7 5185 MemU[address,4] = bits(32) UNKNOWN; 5186 if wback then R[n] = offset_addr; 5187#endif 5188 5189 bool success = false; 5190 5191 if (ConditionPassed(opcode)) { 5192 const uint32_t addr_byte_size = GetAddressByteSize(); 5193 5194 uint32_t t; 5195 uint32_t n; 5196 uint32_t imm32; 5197 bool index; 5198 bool add; 5199 bool wback; 5200 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5201 switch (encoding) { 5202 case eEncodingT1: 5203 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 5204 t = Bits32(opcode, 2, 0); 5205 n = Bits32(opcode, 5, 3); 5206 imm32 = Bits32(opcode, 10, 6) << 2; 5207 5208 // index = TRUE; add = TRUE; wback = FALSE; 5209 index = true; 5210 add = false; 5211 wback = false; 5212 break; 5213 5214 case eEncodingT2: 5215 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 5216 t = Bits32(opcode, 10, 8); 5217 n = 13; 5218 imm32 = Bits32(opcode, 7, 0) << 2; 5219 5220 // index = TRUE; add = TRUE; wback = FALSE; 5221 index = true; 5222 add = true; 5223 wback = false; 5224 break; 5225 5226 case eEncodingT3: 5227 // if Rn == '1111' then UNDEFINED; 5228 if (Bits32(opcode, 19, 16) == 15) 5229 return false; 5230 5231 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5232 t = Bits32(opcode, 15, 12); 5233 n = Bits32(opcode, 19, 16); 5234 imm32 = Bits32(opcode, 11, 0); 5235 5236 // index = TRUE; add = TRUE; wback = FALSE; 5237 index = true; 5238 add = true; 5239 wback = false; 5240 5241 // if t == 15 then UNPREDICTABLE; 5242 if (t == 15) 5243 return false; 5244 break; 5245 5246 case eEncodingT4: 5247 // if P == '1' && U == '1' && W == '0' then SEE STRT; 5248 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == 5249 // '00000100' then SEE PUSH; 5250 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5251 if ((Bits32(opcode, 19, 16) == 15) || 5252 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))) 5253 return false; 5254 5255 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5256 t = Bits32(opcode, 15, 12); 5257 n = Bits32(opcode, 19, 16); 5258 imm32 = Bits32(opcode, 7, 0); 5259 5260 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5261 index = BitIsSet(opcode, 10); 5262 add = BitIsSet(opcode, 9); 5263 wback = BitIsSet(opcode, 8); 5264 5265 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 5266 if ((t == 15) || (wback && (n == t))) 5267 return false; 5268 break; 5269 5270 default: 5271 return false; 5272 } 5273 5274 addr_t offset_addr; 5275 addr_t address; 5276 5277 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5278 uint32_t base_address = ReadCoreReg(n, &success); 5279 if (!success) 5280 return false; 5281 5282 if (add) 5283 offset_addr = base_address + imm32; 5284 else 5285 offset_addr = base_address - imm32; 5286 5287 // address = if index then offset_addr else R[n]; 5288 if (index) 5289 address = offset_addr; 5290 else 5291 address = base_address; 5292 5293 EmulateInstruction::Context context; 5294 if (n == 13) 5295 context.type = eContextPushRegisterOnStack; 5296 else 5297 context.type = eContextRegisterStore; 5298 5299 RegisterInfo base_reg; 5300 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5301 5302 // if UnalignedSupport() || address<1:0> == '00' then 5303 if (UnalignedSupport() || 5304 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 5305 // MemU[address,4] = R[t]; 5306 uint32_t data = 5307 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5308 if (!success) 5309 return false; 5310 5311 RegisterInfo data_reg; 5312 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5313 int32_t offset = address - base_address; 5314 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 5315 if (!MemUWrite(context, address, data, addr_byte_size)) 5316 return false; 5317 } else { 5318 // MemU[address,4] = bits(32) UNKNOWN; 5319 WriteBits32UnknownToMemory(address); 5320 } 5321 5322 // if wback then R[n] = offset_addr; 5323 if (wback) { 5324 if (n == 13) 5325 context.type = eContextAdjustStackPointer; 5326 else 5327 context.type = eContextAdjustBaseRegister; 5328 context.SetAddress(offset_addr); 5329 5330 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5331 offset_addr)) 5332 return false; 5333 } 5334 } 5335 return true; 5336} 5337 5338// STR (Store Register) calculates an address from a base register value and an 5339// offset register value, stores a 5340// word from a register to memory. The offset register value can optionally be 5341// shifted. 5342bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode, 5343 const ARMEncoding encoding) { 5344#if 0 5345 if ConditionPassed() then 5346 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5347 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5348 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5349 address = if index then offset_addr else R[n]; 5350 if t == 15 then // Only possible for encoding A1 5351 data = PCStoreValue(); 5352 else 5353 data = R[t]; 5354 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 5355 MemU[address,4] = data; 5356 else // Can only occur before ARMv7 5357 MemU[address,4] = bits(32) UNKNOWN; 5358 if wback then R[n] = offset_addr; 5359#endif 5360 5361 bool success = false; 5362 5363 if (ConditionPassed(opcode)) { 5364 const uint32_t addr_byte_size = GetAddressByteSize(); 5365 5366 uint32_t t; 5367 uint32_t n; 5368 uint32_t m; 5369 ARM_ShifterType shift_t; 5370 uint32_t shift_n; 5371 bool index; 5372 bool add; 5373 bool wback; 5374 5375 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5376 switch (encoding) { 5377 case eEncodingT1: 5378 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5379 // in ThumbEE"; 5380 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5381 t = Bits32(opcode, 2, 0); 5382 n = Bits32(opcode, 5, 3); 5383 m = Bits32(opcode, 8, 6); 5384 5385 // index = TRUE; add = TRUE; wback = FALSE; 5386 index = true; 5387 add = true; 5388 wback = false; 5389 5390 // (shift_t, shift_n) = (SRType_LSL, 0); 5391 shift_t = SRType_LSL; 5392 shift_n = 0; 5393 break; 5394 5395 case eEncodingT2: 5396 // if Rn == '1111' then UNDEFINED; 5397 if (Bits32(opcode, 19, 16) == 15) 5398 return false; 5399 5400 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5401 t = Bits32(opcode, 15, 12); 5402 n = Bits32(opcode, 19, 16); 5403 m = Bits32(opcode, 3, 0); 5404 5405 // index = TRUE; add = TRUE; wback = FALSE; 5406 index = true; 5407 add = true; 5408 wback = false; 5409 5410 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5411 shift_t = SRType_LSL; 5412 shift_n = Bits32(opcode, 5, 4); 5413 5414 // if t == 15 || BadReg(m) then UNPREDICTABLE; 5415 if ((t == 15) || (BadReg(m))) 5416 return false; 5417 break; 5418 5419 case eEncodingA1: { 5420 // if P == '0' && W == '1' then SEE STRT; 5421 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5422 t = Bits32(opcode, 15, 12); 5423 n = Bits32(opcode, 19, 16); 5424 m = Bits32(opcode, 3, 0); 5425 5426 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5427 // (W == '1'); 5428 index = BitIsSet(opcode, 24); 5429 add = BitIsSet(opcode, 23); 5430 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5431 5432 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5433 uint32_t typ = Bits32(opcode, 6, 5); 5434 uint32_t imm5 = Bits32(opcode, 11, 7); 5435 shift_n = DecodeImmShift(typ, imm5, shift_t); 5436 5437 // if m == 15 then UNPREDICTABLE; 5438 if (m == 15) 5439 return false; 5440 5441 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5442 if (wback && ((n == 15) || (n == t))) 5443 return false; 5444 5445 break; 5446 } 5447 default: 5448 return false; 5449 } 5450 5451 addr_t offset_addr; 5452 addr_t address; 5453 int32_t offset = 0; 5454 5455 addr_t base_address = 5456 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5457 if (!success) 5458 return false; 5459 5460 uint32_t Rm_data = 5461 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5462 if (!success) 5463 return false; 5464 5465 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5466 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success); 5467 if (!success) 5468 return false; 5469 5470 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5471 if (add) 5472 offset_addr = base_address + offset; 5473 else 5474 offset_addr = base_address - offset; 5475 5476 // address = if index then offset_addr else R[n]; 5477 if (index) 5478 address = offset_addr; 5479 else 5480 address = base_address; 5481 5482 uint32_t data; 5483 // if t == 15 then // Only possible for encoding A1 5484 if (t == 15) 5485 // data = PCStoreValue(); 5486 data = ReadCoreReg(PC_REG, &success); 5487 else 5488 // data = R[t]; 5489 data = 5490 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5491 5492 if (!success) 5493 return false; 5494 5495 EmulateInstruction::Context context; 5496 context.type = eContextRegisterStore; 5497 5498 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == 5499 // InstrSet_ARM then 5500 if (UnalignedSupport() || 5501 (BitIsClear(address, 1) && BitIsClear(address, 0)) || 5502 CurrentInstrSet() == eModeARM) { 5503 // MemU[address,4] = data; 5504 5505 RegisterInfo base_reg; 5506 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5507 5508 RegisterInfo data_reg; 5509 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5510 5511 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5512 address - base_address); 5513 if (!MemUWrite(context, address, data, addr_byte_size)) 5514 return false; 5515 5516 } else 5517 // MemU[address,4] = bits(32) UNKNOWN; 5518 WriteBits32UnknownToMemory(address); 5519 5520 // if wback then R[n] = offset_addr; 5521 if (wback) { 5522 context.type = eContextRegisterLoad; 5523 context.SetAddress(offset_addr); 5524 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5525 offset_addr)) 5526 return false; 5527 } 5528 } 5529 return true; 5530} 5531 5532bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode, 5533 const ARMEncoding encoding) { 5534#if 0 5535 if ConditionPassed() then 5536 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5537 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5538 address = if index then offset_addr else R[n]; 5539 MemU[address,1] = R[t]<7:0>; 5540 if wback then R[n] = offset_addr; 5541#endif 5542 5543 bool success = false; 5544 5545 if (ConditionPassed(opcode)) { 5546 uint32_t t; 5547 uint32_t n; 5548 uint32_t imm32; 5549 bool index; 5550 bool add; 5551 bool wback; 5552 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5553 switch (encoding) { 5554 case eEncodingT1: 5555 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5556 t = Bits32(opcode, 2, 0); 5557 n = Bits32(opcode, 5, 3); 5558 imm32 = Bits32(opcode, 10, 6); 5559 5560 // index = TRUE; add = TRUE; wback = FALSE; 5561 index = true; 5562 add = true; 5563 wback = false; 5564 break; 5565 5566 case eEncodingT2: 5567 // if Rn == '1111' then UNDEFINED; 5568 if (Bits32(opcode, 19, 16) == 15) 5569 return false; 5570 5571 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5572 t = Bits32(opcode, 15, 12); 5573 n = Bits32(opcode, 19, 16); 5574 imm32 = Bits32(opcode, 11, 0); 5575 5576 // index = TRUE; add = TRUE; wback = FALSE; 5577 index = true; 5578 add = true; 5579 wback = false; 5580 5581 // if BadReg(t) then UNPREDICTABLE; 5582 if (BadReg(t)) 5583 return false; 5584 break; 5585 5586 case eEncodingT3: 5587 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5588 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5589 if (Bits32(opcode, 19, 16) == 15) 5590 return false; 5591 5592 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5593 t = Bits32(opcode, 15, 12); 5594 n = Bits32(opcode, 19, 16); 5595 imm32 = Bits32(opcode, 7, 0); 5596 5597 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5598 index = BitIsSet(opcode, 10); 5599 add = BitIsSet(opcode, 9); 5600 wback = BitIsSet(opcode, 8); 5601 5602 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5603 if ((BadReg(t)) || (wback && (n == t))) 5604 return false; 5605 break; 5606 5607 default: 5608 return false; 5609 } 5610 5611 addr_t offset_addr; 5612 addr_t address; 5613 addr_t base_address = 5614 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5615 if (!success) 5616 return false; 5617 5618 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5619 if (add) 5620 offset_addr = base_address + imm32; 5621 else 5622 offset_addr = base_address - imm32; 5623 5624 // address = if index then offset_addr else R[n]; 5625 if (index) 5626 address = offset_addr; 5627 else 5628 address = base_address; 5629 5630 // MemU[address,1] = R[t]<7:0> 5631 RegisterInfo base_reg; 5632 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5633 5634 RegisterInfo data_reg; 5635 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5636 5637 EmulateInstruction::Context context; 5638 context.type = eContextRegisterStore; 5639 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5640 address - base_address); 5641 5642 uint32_t data = 5643 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5644 if (!success) 5645 return false; 5646 5647 data = Bits32(data, 7, 0); 5648 5649 if (!MemUWrite(context, address, data, 1)) 5650 return false; 5651 5652 // if wback then R[n] = offset_addr; 5653 if (wback) { 5654 context.type = eContextRegisterLoad; 5655 context.SetAddress(offset_addr); 5656 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5657 offset_addr)) 5658 return false; 5659 } 5660 } 5661 5662 return true; 5663} 5664 5665// STRH (register) calculates an address from a base register value and an 5666// offset register value, and stores a 5667// halfword from a register to memory. The offset register value can be shifted 5668// left by 0, 1, 2, or 3 bits. 5669bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode, 5670 const ARMEncoding encoding) { 5671#if 0 5672 if ConditionPassed() then 5673 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5674 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5675 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5676 address = if index then offset_addr else R[n]; 5677 if UnalignedSupport() || address<0> == '0' then 5678 MemU[address,2] = R[t]<15:0>; 5679 else // Can only occur before ARMv7 5680 MemU[address,2] = bits(16) UNKNOWN; 5681 if wback then R[n] = offset_addr; 5682#endif 5683 5684 bool success = false; 5685 5686 if (ConditionPassed(opcode)) { 5687 uint32_t t; 5688 uint32_t n; 5689 uint32_t m; 5690 bool index; 5691 bool add; 5692 bool wback; 5693 ARM_ShifterType shift_t; 5694 uint32_t shift_n; 5695 5696 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5697 switch (encoding) { 5698 case eEncodingT1: 5699 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5700 // in ThumbEE"; 5701 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5702 t = Bits32(opcode, 2, 0); 5703 n = Bits32(opcode, 5, 3); 5704 m = Bits32(opcode, 8, 6); 5705 5706 // index = TRUE; add = TRUE; wback = FALSE; 5707 index = true; 5708 add = true; 5709 wback = false; 5710 5711 // (shift_t, shift_n) = (SRType_LSL, 0); 5712 shift_t = SRType_LSL; 5713 shift_n = 0; 5714 5715 break; 5716 5717 case eEncodingT2: 5718 // if Rn == '1111' then UNDEFINED; 5719 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5720 t = Bits32(opcode, 15, 12); 5721 n = Bits32(opcode, 19, 16); 5722 m = Bits32(opcode, 3, 0); 5723 if (n == 15) 5724 return false; 5725 5726 // index = TRUE; add = TRUE; wback = FALSE; 5727 index = true; 5728 add = true; 5729 wback = false; 5730 5731 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5732 shift_t = SRType_LSL; 5733 shift_n = Bits32(opcode, 5, 4); 5734 5735 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5736 if (BadReg(t) || BadReg(m)) 5737 return false; 5738 5739 break; 5740 5741 case eEncodingA1: 5742 // if P == '0' && W == '1' then SEE STRHT; 5743 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5744 t = Bits32(opcode, 15, 12); 5745 n = Bits32(opcode, 19, 16); 5746 m = Bits32(opcode, 3, 0); 5747 5748 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5749 // (W == '1'); 5750 index = BitIsSet(opcode, 24); 5751 add = BitIsSet(opcode, 23); 5752 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5753 5754 // (shift_t, shift_n) = (SRType_LSL, 0); 5755 shift_t = SRType_LSL; 5756 shift_n = 0; 5757 5758 // if t == 15 || m == 15 then UNPREDICTABLE; 5759 if ((t == 15) || (m == 15)) 5760 return false; 5761 5762 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5763 if (wback && ((n == 15) || (n == t))) 5764 return false; 5765 5766 break; 5767 5768 default: 5769 return false; 5770 } 5771 5772 uint32_t Rm = ReadCoreReg(m, &success); 5773 if (!success) 5774 return false; 5775 5776 uint32_t Rn = ReadCoreReg(n, &success); 5777 if (!success) 5778 return false; 5779 5780 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5781 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 5782 if (!success) 5783 return false; 5784 5785 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5786 addr_t offset_addr; 5787 if (add) 5788 offset_addr = Rn + offset; 5789 else 5790 offset_addr = Rn - offset; 5791 5792 // address = if index then offset_addr else R[n]; 5793 addr_t address; 5794 if (index) 5795 address = offset_addr; 5796 else 5797 address = Rn; 5798 5799 EmulateInstruction::Context context; 5800 context.type = eContextRegisterStore; 5801 RegisterInfo base_reg; 5802 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5803 RegisterInfo offset_reg; 5804 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5805 5806 // if UnalignedSupport() || address<0> == '0' then 5807 if (UnalignedSupport() || BitIsClear(address, 0)) { 5808 // MemU[address,2] = R[t]<15:0>; 5809 uint32_t Rt = ReadCoreReg(t, &success); 5810 if (!success) 5811 return false; 5812 5813 EmulateInstruction::Context context; 5814 context.type = eContextRegisterStore; 5815 RegisterInfo base_reg; 5816 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5817 RegisterInfo offset_reg; 5818 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5819 RegisterInfo data_reg; 5820 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5821 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 5822 data_reg); 5823 5824 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2)) 5825 return false; 5826 } else // Can only occur before ARMv7 5827 { 5828 // MemU[address,2] = bits(16) UNKNOWN; 5829 } 5830 5831 // if wback then R[n] = offset_addr; 5832 if (wback) { 5833 context.type = eContextAdjustBaseRegister; 5834 context.SetAddress(offset_addr); 5835 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5836 offset_addr)) 5837 return false; 5838 } 5839 } 5840 5841 return true; 5842} 5843 5844// Add with Carry (immediate) adds an immediate value and the carry flag value 5845// to a register value, 5846// and writes the result to the destination register. It can optionally update 5847// the condition flags 5848// based on the result. 5849bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode, 5850 const ARMEncoding encoding) { 5851#if 0 5852 // ARM pseudo code... 5853 if ConditionPassed() then 5854 EncodingSpecificOperations(); 5855 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5856 if d == 15 then // Can only occur for ARM encoding 5857 ALUWritePC(result); // setflags is always FALSE here 5858 else 5859 R[d] = result; 5860 if setflags then 5861 APSR.N = result<31>; 5862 APSR.Z = IsZeroBit(result); 5863 APSR.C = carry; 5864 APSR.V = overflow; 5865#endif 5866 5867 bool success = false; 5868 5869 if (ConditionPassed(opcode)) { 5870 uint32_t Rd, Rn; 5871 uint32_t 5872 imm32; // the immediate value to be added to the value obtained from Rn 5873 bool setflags; 5874 switch (encoding) { 5875 case eEncodingT1: 5876 Rd = Bits32(opcode, 11, 8); 5877 Rn = Bits32(opcode, 19, 16); 5878 setflags = BitIsSet(opcode, 20); 5879 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5880 if (BadReg(Rd) || BadReg(Rn)) 5881 return false; 5882 break; 5883 case eEncodingA1: 5884 Rd = Bits32(opcode, 15, 12); 5885 Rn = Bits32(opcode, 19, 16); 5886 setflags = BitIsSet(opcode, 20); 5887 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5888 5889 if (Rd == 15 && setflags) 5890 return EmulateSUBSPcLrEtc(opcode, encoding); 5891 break; 5892 default: 5893 return false; 5894 } 5895 5896 // Read the first operand. 5897 int32_t val1 = ReadCoreReg(Rn, &success); 5898 if (!success) 5899 return false; 5900 5901 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5902 5903 EmulateInstruction::Context context; 5904 context.type = EmulateInstruction::eContextImmediate; 5905 context.SetNoArgs(); 5906 5907 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5908 res.carry_out, res.overflow)) 5909 return false; 5910 } 5911 return true; 5912} 5913 5914// Add with Carry (register) adds a register value, the carry flag value, and an 5915// optionally-shifted 5916// register value, and writes the result to the destination register. It can 5917// optionally update the 5918// condition flags based on the result. 5919bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode, 5920 const ARMEncoding encoding) { 5921#if 0 5922 // ARM pseudo code... 5923 if ConditionPassed() then 5924 EncodingSpecificOperations(); 5925 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5926 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5927 if d == 15 then // Can only occur for ARM encoding 5928 ALUWritePC(result); // setflags is always FALSE here 5929 else 5930 R[d] = result; 5931 if setflags then 5932 APSR.N = result<31>; 5933 APSR.Z = IsZeroBit(result); 5934 APSR.C = carry; 5935 APSR.V = overflow; 5936#endif 5937 5938 bool success = false; 5939 5940 if (ConditionPassed(opcode)) { 5941 uint32_t Rd, Rn, Rm; 5942 ARM_ShifterType shift_t; 5943 uint32_t shift_n; // the shift applied to the value read from Rm 5944 bool setflags; 5945 switch (encoding) { 5946 case eEncodingT1: 5947 Rd = Rn = Bits32(opcode, 2, 0); 5948 Rm = Bits32(opcode, 5, 3); 5949 setflags = !InITBlock(); 5950 shift_t = SRType_LSL; 5951 shift_n = 0; 5952 break; 5953 case eEncodingT2: 5954 Rd = Bits32(opcode, 11, 8); 5955 Rn = Bits32(opcode, 19, 16); 5956 Rm = Bits32(opcode, 3, 0); 5957 setflags = BitIsSet(opcode, 20); 5958 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5959 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5960 return false; 5961 break; 5962 case eEncodingA1: 5963 Rd = Bits32(opcode, 15, 12); 5964 Rn = Bits32(opcode, 19, 16); 5965 Rm = Bits32(opcode, 3, 0); 5966 setflags = BitIsSet(opcode, 20); 5967 shift_n = DecodeImmShiftARM(opcode, shift_t); 5968 5969 if (Rd == 15 && setflags) 5970 return EmulateSUBSPcLrEtc(opcode, encoding); 5971 break; 5972 default: 5973 return false; 5974 } 5975 5976 // Read the first operand. 5977 int32_t val1 = ReadCoreReg(Rn, &success); 5978 if (!success) 5979 return false; 5980 5981 // Read the second operand. 5982 int32_t val2 = ReadCoreReg(Rm, &success); 5983 if (!success) 5984 return false; 5985 5986 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5987 if (!success) 5988 return false; 5989 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5990 5991 EmulateInstruction::Context context; 5992 context.type = EmulateInstruction::eContextImmediate; 5993 context.SetNoArgs(); 5994 5995 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5996 res.carry_out, res.overflow)) 5997 return false; 5998 } 5999 return true; 6000} 6001 6002// This instruction adds an immediate value to the PC value to form a 6003// PC-relative address, 6004// and writes the result to the destination register. 6005bool EmulateInstructionARM::EmulateADR(const uint32_t opcode, 6006 const ARMEncoding encoding) { 6007#if 0 6008 // ARM pseudo code... 6009 if ConditionPassed() then 6010 EncodingSpecificOperations(); 6011 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 6012 if d == 15 then // Can only occur for ARM encodings 6013 ALUWritePC(result); 6014 else 6015 R[d] = result; 6016#endif 6017 6018 bool success = false; 6019 6020 if (ConditionPassed(opcode)) { 6021 uint32_t Rd; 6022 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 6023 bool add; 6024 switch (encoding) { 6025 case eEncodingT1: 6026 Rd = Bits32(opcode, 10, 8); 6027 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 6028 add = true; 6029 break; 6030 case eEncodingT2: 6031 case eEncodingT3: 6032 Rd = Bits32(opcode, 11, 8); 6033 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 6034 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 6035 if (BadReg(Rd)) 6036 return false; 6037 break; 6038 case eEncodingA1: 6039 case eEncodingA2: 6040 Rd = Bits32(opcode, 15, 12); 6041 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 6042 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 6043 break; 6044 default: 6045 return false; 6046 } 6047 6048 // Read the PC value. 6049 uint32_t pc = ReadCoreReg(PC_REG, &success); 6050 if (!success) 6051 return false; 6052 6053 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 6054 6055 EmulateInstruction::Context context; 6056 context.type = EmulateInstruction::eContextImmediate; 6057 context.SetNoArgs(); 6058 6059 if (!WriteCoreReg(context, result, Rd)) 6060 return false; 6061 } 6062 return true; 6063} 6064 6065// This instruction performs a bitwise AND of a register value and an immediate 6066// value, and writes the result 6067// to the destination register. It can optionally update the condition flags 6068// based on the result. 6069bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode, 6070 const ARMEncoding encoding) { 6071#if 0 6072 // ARM pseudo code... 6073 if ConditionPassed() then 6074 EncodingSpecificOperations(); 6075 result = R[n] AND imm32; 6076 if d == 15 then // Can only occur for ARM encoding 6077 ALUWritePC(result); // setflags is always FALSE here 6078 else 6079 R[d] = result; 6080 if setflags then 6081 APSR.N = result<31>; 6082 APSR.Z = IsZeroBit(result); 6083 APSR.C = carry; 6084 // APSR.V unchanged 6085#endif 6086 6087 bool success = false; 6088 6089 if (ConditionPassed(opcode)) { 6090 uint32_t Rd, Rn; 6091 uint32_t 6092 imm32; // the immediate value to be ANDed to the value obtained from Rn 6093 bool setflags; 6094 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6095 switch (encoding) { 6096 case eEncodingT1: 6097 Rd = Bits32(opcode, 11, 8); 6098 Rn = Bits32(opcode, 19, 16); 6099 setflags = BitIsSet(opcode, 20); 6100 imm32 = ThumbExpandImm_C( 6101 opcode, APSR_C, 6102 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6103 // if Rd == '1111' && S == '1' then SEE TST (immediate); 6104 if (Rd == 15 && setflags) 6105 return EmulateTSTImm(opcode, eEncodingT1); 6106 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 6107 return false; 6108 break; 6109 case eEncodingA1: 6110 Rd = Bits32(opcode, 15, 12); 6111 Rn = Bits32(opcode, 19, 16); 6112 setflags = BitIsSet(opcode, 20); 6113 imm32 = 6114 ARMExpandImm_C(opcode, APSR_C, 6115 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6116 6117 if (Rd == 15 && setflags) 6118 return EmulateSUBSPcLrEtc(opcode, encoding); 6119 break; 6120 default: 6121 return false; 6122 } 6123 6124 // Read the first operand. 6125 uint32_t val1 = ReadCoreReg(Rn, &success); 6126 if (!success) 6127 return false; 6128 6129 uint32_t result = val1 & imm32; 6130 6131 EmulateInstruction::Context context; 6132 context.type = EmulateInstruction::eContextImmediate; 6133 context.SetNoArgs(); 6134 6135 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6136 return false; 6137 } 6138 return true; 6139} 6140 6141// This instruction performs a bitwise AND of a register value and an 6142// optionally-shifted register value, 6143// and writes the result to the destination register. It can optionally update 6144// the condition flags 6145// based on the result. 6146bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode, 6147 const ARMEncoding encoding) { 6148#if 0 6149 // ARM pseudo code... 6150 if ConditionPassed() then 6151 EncodingSpecificOperations(); 6152 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6153 result = R[n] AND shifted; 6154 if d == 15 then // Can only occur for ARM encoding 6155 ALUWritePC(result); // setflags is always FALSE here 6156 else 6157 R[d] = result; 6158 if setflags then 6159 APSR.N = result<31>; 6160 APSR.Z = IsZeroBit(result); 6161 APSR.C = carry; 6162 // APSR.V unchanged 6163#endif 6164 6165 bool success = false; 6166 6167 if (ConditionPassed(opcode)) { 6168 uint32_t Rd, Rn, Rm; 6169 ARM_ShifterType shift_t; 6170 uint32_t shift_n; // the shift applied to the value read from Rm 6171 bool setflags; 6172 uint32_t carry; 6173 switch (encoding) { 6174 case eEncodingT1: 6175 Rd = Rn = Bits32(opcode, 2, 0); 6176 Rm = Bits32(opcode, 5, 3); 6177 setflags = !InITBlock(); 6178 shift_t = SRType_LSL; 6179 shift_n = 0; 6180 break; 6181 case eEncodingT2: 6182 Rd = Bits32(opcode, 11, 8); 6183 Rn = Bits32(opcode, 19, 16); 6184 Rm = Bits32(opcode, 3, 0); 6185 setflags = BitIsSet(opcode, 20); 6186 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6187 // if Rd == '1111' && S == '1' then SEE TST (register); 6188 if (Rd == 15 && setflags) 6189 return EmulateTSTReg(opcode, eEncodingT2); 6190 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 6191 return false; 6192 break; 6193 case eEncodingA1: 6194 Rd = Bits32(opcode, 15, 12); 6195 Rn = Bits32(opcode, 19, 16); 6196 Rm = Bits32(opcode, 3, 0); 6197 setflags = BitIsSet(opcode, 20); 6198 shift_n = DecodeImmShiftARM(opcode, shift_t); 6199 6200 if (Rd == 15 && setflags) 6201 return EmulateSUBSPcLrEtc(opcode, encoding); 6202 break; 6203 default: 6204 return false; 6205 } 6206 6207 // Read the first operand. 6208 uint32_t val1 = ReadCoreReg(Rn, &success); 6209 if (!success) 6210 return false; 6211 6212 // Read the second operand. 6213 uint32_t val2 = ReadCoreReg(Rm, &success); 6214 if (!success) 6215 return false; 6216 6217 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6218 if (!success) 6219 return false; 6220 uint32_t result = val1 & shifted; 6221 6222 EmulateInstruction::Context context; 6223 context.type = EmulateInstruction::eContextImmediate; 6224 context.SetNoArgs(); 6225 6226 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6227 return false; 6228 } 6229 return true; 6230} 6231 6232// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and 6233// the complement of an 6234// immediate value, and writes the result to the destination register. It can 6235// optionally update the 6236// condition flags based on the result. 6237bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode, 6238 const ARMEncoding encoding) { 6239#if 0 6240 // ARM pseudo code... 6241 if ConditionPassed() then 6242 EncodingSpecificOperations(); 6243 result = R[n] AND NOT(imm32); 6244 if d == 15 then // Can only occur for ARM encoding 6245 ALUWritePC(result); // setflags is always FALSE here 6246 else 6247 R[d] = result; 6248 if setflags then 6249 APSR.N = result<31>; 6250 APSR.Z = IsZeroBit(result); 6251 APSR.C = carry; 6252 // APSR.V unchanged 6253#endif 6254 6255 bool success = false; 6256 6257 if (ConditionPassed(opcode)) { 6258 uint32_t Rd, Rn; 6259 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to 6260 // the value obtained from Rn 6261 bool setflags; 6262 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6263 switch (encoding) { 6264 case eEncodingT1: 6265 Rd = Bits32(opcode, 11, 8); 6266 Rn = Bits32(opcode, 19, 16); 6267 setflags = BitIsSet(opcode, 20); 6268 imm32 = ThumbExpandImm_C( 6269 opcode, APSR_C, 6270 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6271 if (BadReg(Rd) || BadReg(Rn)) 6272 return false; 6273 break; 6274 case eEncodingA1: 6275 Rd = Bits32(opcode, 15, 12); 6276 Rn = Bits32(opcode, 19, 16); 6277 setflags = BitIsSet(opcode, 20); 6278 imm32 = 6279 ARMExpandImm_C(opcode, APSR_C, 6280 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6281 6282 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6283 // instructions; 6284 if (Rd == 15 && setflags) 6285 return EmulateSUBSPcLrEtc(opcode, encoding); 6286 break; 6287 default: 6288 return false; 6289 } 6290 6291 // Read the first operand. 6292 uint32_t val1 = ReadCoreReg(Rn, &success); 6293 if (!success) 6294 return false; 6295 6296 uint32_t result = val1 & ~imm32; 6297 6298 EmulateInstruction::Context context; 6299 context.type = EmulateInstruction::eContextImmediate; 6300 context.SetNoArgs(); 6301 6302 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6303 return false; 6304 } 6305 return true; 6306} 6307 6308// Bitwise Bit Clear (register) performs a bitwise AND of a register value and 6309// the complement of an 6310// optionally-shifted register value, and writes the result to the destination 6311// register. 6312// It can optionally update the condition flags based on the result. 6313bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode, 6314 const ARMEncoding encoding) { 6315#if 0 6316 // ARM pseudo code... 6317 if ConditionPassed() then 6318 EncodingSpecificOperations(); 6319 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6320 result = R[n] AND NOT(shifted); 6321 if d == 15 then // Can only occur for ARM encoding 6322 ALUWritePC(result); // setflags is always FALSE here 6323 else 6324 R[d] = result; 6325 if setflags then 6326 APSR.N = result<31>; 6327 APSR.Z = IsZeroBit(result); 6328 APSR.C = carry; 6329 // APSR.V unchanged 6330#endif 6331 6332 bool success = false; 6333 6334 if (ConditionPassed(opcode)) { 6335 uint32_t Rd, Rn, Rm; 6336 ARM_ShifterType shift_t; 6337 uint32_t shift_n; // the shift applied to the value read from Rm 6338 bool setflags; 6339 uint32_t carry; 6340 switch (encoding) { 6341 case eEncodingT1: 6342 Rd = Rn = Bits32(opcode, 2, 0); 6343 Rm = Bits32(opcode, 5, 3); 6344 setflags = !InITBlock(); 6345 shift_t = SRType_LSL; 6346 shift_n = 0; 6347 break; 6348 case eEncodingT2: 6349 Rd = Bits32(opcode, 11, 8); 6350 Rn = Bits32(opcode, 19, 16); 6351 Rm = Bits32(opcode, 3, 0); 6352 setflags = BitIsSet(opcode, 20); 6353 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6354 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 6355 return false; 6356 break; 6357 case eEncodingA1: 6358 Rd = Bits32(opcode, 15, 12); 6359 Rn = Bits32(opcode, 19, 16); 6360 Rm = Bits32(opcode, 3, 0); 6361 setflags = BitIsSet(opcode, 20); 6362 shift_n = DecodeImmShiftARM(opcode, shift_t); 6363 6364 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6365 // instructions; 6366 if (Rd == 15 && setflags) 6367 return EmulateSUBSPcLrEtc(opcode, encoding); 6368 break; 6369 default: 6370 return false; 6371 } 6372 6373 // Read the first operand. 6374 uint32_t val1 = ReadCoreReg(Rn, &success); 6375 if (!success) 6376 return false; 6377 6378 // Read the second operand. 6379 uint32_t val2 = ReadCoreReg(Rm, &success); 6380 if (!success) 6381 return false; 6382 6383 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6384 if (!success) 6385 return false; 6386 uint32_t result = val1 & ~shifted; 6387 6388 EmulateInstruction::Context context; 6389 context.type = EmulateInstruction::eContextImmediate; 6390 context.SetNoArgs(); 6391 6392 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6393 return false; 6394 } 6395 return true; 6396} 6397 6398// LDR (immediate, ARM) calculates an address from a base register value and an 6399// immediate offset, loads a word 6400// from memory, and writes it to a register. It can use offset, post-indexed, 6401// or pre-indexed addressing. 6402bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode, 6403 const ARMEncoding encoding) { 6404#if 0 6405 if ConditionPassed() then 6406 EncodingSpecificOperations(); 6407 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6408 address = if index then offset_addr else R[n]; 6409 data = MemU[address,4]; 6410 if wback then R[n] = offset_addr; 6411 if t == 15 then 6412 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6413 elsif UnalignedSupport() || address<1:0> = '00' then 6414 R[t] = data; 6415 else // Can only apply before ARMv7 6416 R[t] = ROR(data, 8*UInt(address<1:0>)); 6417#endif 6418 6419 bool success = false; 6420 6421 if (ConditionPassed(opcode)) { 6422 const uint32_t addr_byte_size = GetAddressByteSize(); 6423 6424 uint32_t t; 6425 uint32_t n; 6426 uint32_t imm32; 6427 bool index; 6428 bool add; 6429 bool wback; 6430 6431 switch (encoding) { 6432 case eEncodingA1: 6433 // if Rn == '1111' then SEE LDR (literal); 6434 // if P == '0' && W == '1' then SEE LDRT; 6435 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == 6436 // '000000000100' then SEE POP; 6437 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6438 t = Bits32(opcode, 15, 12); 6439 n = Bits32(opcode, 19, 16); 6440 imm32 = Bits32(opcode, 11, 0); 6441 6442 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6443 // (W == '1'); 6444 index = BitIsSet(opcode, 24); 6445 add = BitIsSet(opcode, 23); 6446 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6447 6448 // if wback && n == t then UNPREDICTABLE; 6449 if (wback && (n == t)) 6450 return false; 6451 6452 break; 6453 6454 default: 6455 return false; 6456 } 6457 6458 addr_t address; 6459 addr_t offset_addr; 6460 addr_t base_address = ReadCoreReg(n, &success); 6461 if (!success) 6462 return false; 6463 6464 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6465 if (add) 6466 offset_addr = base_address + imm32; 6467 else 6468 offset_addr = base_address - imm32; 6469 6470 // address = if index then offset_addr else R[n]; 6471 if (index) 6472 address = offset_addr; 6473 else 6474 address = base_address; 6475 6476 // data = MemU[address,4]; 6477 6478 RegisterInfo base_reg; 6479 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6480 6481 EmulateInstruction::Context context; 6482 context.type = eContextRegisterLoad; 6483 context.SetRegisterPlusOffset(base_reg, address - base_address); 6484 6485 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6486 if (!success) 6487 return false; 6488 6489 // if wback then R[n] = offset_addr; 6490 if (wback) { 6491 context.type = eContextAdjustBaseRegister; 6492 context.SetAddress(offset_addr); 6493 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6494 offset_addr)) 6495 return false; 6496 } 6497 6498 // if t == 15 then 6499 if (t == 15) { 6500 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6501 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6502 // LoadWritePC (data); 6503 context.type = eContextRegisterLoad; 6504 context.SetRegisterPlusOffset(base_reg, address - base_address); 6505 LoadWritePC(context, data); 6506 } else 6507 return false; 6508 } 6509 // elsif UnalignedSupport() || address<1:0> = '00' then 6510 else if (UnalignedSupport() || 6511 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6512 // R[t] = data; 6513 context.type = eContextRegisterLoad; 6514 context.SetRegisterPlusOffset(base_reg, address - base_address); 6515 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6516 data)) 6517 return false; 6518 } 6519 // else // Can only apply before ARMv7 6520 else { 6521 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6522 data = ROR(data, Bits32(address, 1, 0), &success); 6523 if (!success) 6524 return false; 6525 context.type = eContextRegisterLoad; 6526 context.SetImmediate(data); 6527 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6528 data)) 6529 return false; 6530 } 6531 } 6532 return true; 6533} 6534 6535// LDR (register) calculates an address from a base register value and an offset 6536// register value, loads a word 6537// from memory, and writes it to a register. The offset register value can 6538// optionally be shifted. 6539bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode, 6540 const ARMEncoding encoding) { 6541#if 0 6542 if ConditionPassed() then 6543 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6544 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6545 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6546 address = if index then offset_addr else R[n]; 6547 data = MemU[address,4]; 6548 if wback then R[n] = offset_addr; 6549 if t == 15 then 6550 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6551 elsif UnalignedSupport() || address<1:0> = '00' then 6552 R[t] = data; 6553 else // Can only apply before ARMv7 6554 if CurrentInstrSet() == InstrSet_ARM then 6555 R[t] = ROR(data, 8*UInt(address<1:0>)); 6556 else 6557 R[t] = bits(32) UNKNOWN; 6558#endif 6559 6560 bool success = false; 6561 6562 if (ConditionPassed(opcode)) { 6563 const uint32_t addr_byte_size = GetAddressByteSize(); 6564 6565 uint32_t t; 6566 uint32_t n; 6567 uint32_t m; 6568 bool index; 6569 bool add; 6570 bool wback; 6571 ARM_ShifterType shift_t; 6572 uint32_t shift_n; 6573 6574 switch (encoding) { 6575 case eEncodingT1: 6576 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 6577 // in ThumbEE"; 6578 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6579 t = Bits32(opcode, 2, 0); 6580 n = Bits32(opcode, 5, 3); 6581 m = Bits32(opcode, 8, 6); 6582 6583 // index = TRUE; add = TRUE; wback = FALSE; 6584 index = true; 6585 add = true; 6586 wback = false; 6587 6588 // (shift_t, shift_n) = (SRType_LSL, 0); 6589 shift_t = SRType_LSL; 6590 shift_n = 0; 6591 6592 break; 6593 6594 case eEncodingT2: 6595 // if Rn == '1111' then SEE LDR (literal); 6596 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6597 t = Bits32(opcode, 15, 12); 6598 n = Bits32(opcode, 19, 16); 6599 m = Bits32(opcode, 3, 0); 6600 6601 // index = TRUE; add = TRUE; wback = FALSE; 6602 index = true; 6603 add = true; 6604 wback = false; 6605 6606 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6607 shift_t = SRType_LSL; 6608 shift_n = Bits32(opcode, 5, 4); 6609 6610 // if BadReg(m) then UNPREDICTABLE; 6611 if (BadReg(m)) 6612 return false; 6613 6614 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6615 if ((t == 15) && InITBlock() && !LastInITBlock()) 6616 return false; 6617 6618 break; 6619 6620 case eEncodingA1: { 6621 // if P == '0' && W == '1' then SEE LDRT; 6622 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6623 t = Bits32(opcode, 15, 12); 6624 n = Bits32(opcode, 19, 16); 6625 m = Bits32(opcode, 3, 0); 6626 6627 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6628 // (W == '1'); 6629 index = BitIsSet(opcode, 24); 6630 add = BitIsSet(opcode, 23); 6631 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6632 6633 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6634 uint32_t type = Bits32(opcode, 6, 5); 6635 uint32_t imm5 = Bits32(opcode, 11, 7); 6636 shift_n = DecodeImmShift(type, imm5, shift_t); 6637 6638 // if m == 15 then UNPREDICTABLE; 6639 if (m == 15) 6640 return false; 6641 6642 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6643 if (wback && ((n == 15) || (n == t))) 6644 return false; 6645 } break; 6646 6647 default: 6648 return false; 6649 } 6650 6651 uint32_t Rm = 6652 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6653 if (!success) 6654 return false; 6655 6656 uint32_t Rn = 6657 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6658 if (!success) 6659 return false; 6660 6661 addr_t offset_addr; 6662 addr_t address; 6663 6664 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an 6665 // application level alias for the CPSR". 6666 addr_t offset = 6667 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success); 6668 if (!success) 6669 return false; 6670 6671 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6672 if (add) 6673 offset_addr = Rn + offset; 6674 else 6675 offset_addr = Rn - offset; 6676 6677 // address = if index then offset_addr else R[n]; 6678 if (index) 6679 address = offset_addr; 6680 else 6681 address = Rn; 6682 6683 // data = MemU[address,4]; 6684 RegisterInfo base_reg; 6685 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6686 6687 EmulateInstruction::Context context; 6688 context.type = eContextRegisterLoad; 6689 context.SetRegisterPlusOffset(base_reg, address - Rn); 6690 6691 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6692 if (!success) 6693 return false; 6694 6695 // if wback then R[n] = offset_addr; 6696 if (wback) { 6697 context.type = eContextAdjustBaseRegister; 6698 context.SetAddress(offset_addr); 6699 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6700 offset_addr)) 6701 return false; 6702 } 6703 6704 // if t == 15 then 6705 if (t == 15) { 6706 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6707 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6708 context.type = eContextRegisterLoad; 6709 context.SetRegisterPlusOffset(base_reg, address - Rn); 6710 LoadWritePC(context, data); 6711 } else 6712 return false; 6713 } 6714 // elsif UnalignedSupport() || address<1:0> = '00' then 6715 else if (UnalignedSupport() || 6716 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6717 // R[t] = data; 6718 context.type = eContextRegisterLoad; 6719 context.SetRegisterPlusOffset(base_reg, address - Rn); 6720 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6721 data)) 6722 return false; 6723 } else // Can only apply before ARMv7 6724 { 6725 // if CurrentInstrSet() == InstrSet_ARM then 6726 if (CurrentInstrSet() == eModeARM) { 6727 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6728 data = ROR(data, Bits32(address, 1, 0), &success); 6729 if (!success) 6730 return false; 6731 context.type = eContextRegisterLoad; 6732 context.SetImmediate(data); 6733 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6734 data)) 6735 return false; 6736 } else { 6737 // R[t] = bits(32) UNKNOWN; 6738 WriteBits32Unknown(t); 6739 } 6740 } 6741 } 6742 return true; 6743} 6744 6745// LDRB (immediate, Thumb) 6746bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode, 6747 const ARMEncoding encoding) { 6748#if 0 6749 if ConditionPassed() then 6750 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6751 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6752 address = if index then offset_addr else R[n]; 6753 R[t] = ZeroExtend(MemU[address,1], 32); 6754 if wback then R[n] = offset_addr; 6755#endif 6756 6757 bool success = false; 6758 6759 if (ConditionPassed(opcode)) { 6760 uint32_t t; 6761 uint32_t n; 6762 uint32_t imm32; 6763 bool index; 6764 bool add; 6765 bool wback; 6766 6767 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6768 switch (encoding) { 6769 case eEncodingT1: 6770 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6771 t = Bits32(opcode, 2, 0); 6772 n = Bits32(opcode, 5, 3); 6773 imm32 = Bits32(opcode, 10, 6); 6774 6775 // index = TRUE; add = TRUE; wback = FALSE; 6776 index = true; 6777 add = true; 6778 wback = false; 6779 6780 break; 6781 6782 case eEncodingT2: 6783 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6784 t = Bits32(opcode, 15, 12); 6785 n = Bits32(opcode, 19, 16); 6786 imm32 = Bits32(opcode, 11, 0); 6787 6788 // index = TRUE; add = TRUE; wback = FALSE; 6789 index = true; 6790 add = true; 6791 wback = false; 6792 6793 // if Rt == '1111' then SEE PLD; 6794 if (t == 15) 6795 return false; // PLD is not implemented yet 6796 6797 // if Rn == '1111' then SEE LDRB (literal); 6798 if (n == 15) 6799 return EmulateLDRBLiteral(opcode, eEncodingT1); 6800 6801 // if t == 13 then UNPREDICTABLE; 6802 if (t == 13) 6803 return false; 6804 6805 break; 6806 6807 case eEncodingT3: 6808 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6809 // if P == '0' && W == '0' then UNDEFINED; 6810 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 6811 return false; 6812 6813 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6814 t = Bits32(opcode, 15, 12); 6815 n = Bits32(opcode, 19, 16); 6816 imm32 = Bits32(opcode, 7, 0); 6817 6818 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6819 index = BitIsSet(opcode, 10); 6820 add = BitIsSet(opcode, 9); 6821 wback = BitIsSet(opcode, 8); 6822 6823 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6824 if (t == 15) 6825 return false; // PLD is not implemented yet 6826 6827 // if Rn == '1111' then SEE LDRB (literal); 6828 if (n == 15) 6829 return EmulateLDRBLiteral(opcode, eEncodingT1); 6830 6831 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6832 if (BadReg(t) || (wback && (n == t))) 6833 return false; 6834 6835 break; 6836 6837 default: 6838 return false; 6839 } 6840 6841 uint32_t Rn = 6842 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6843 if (!success) 6844 return false; 6845 6846 addr_t address; 6847 addr_t offset_addr; 6848 6849 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6850 if (add) 6851 offset_addr = Rn + imm32; 6852 else 6853 offset_addr = Rn - imm32; 6854 6855 // address = if index then offset_addr else R[n]; 6856 if (index) 6857 address = offset_addr; 6858 else 6859 address = Rn; 6860 6861 // R[t] = ZeroExtend(MemU[address,1], 32); 6862 RegisterInfo base_reg; 6863 RegisterInfo data_reg; 6864 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6865 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6866 6867 EmulateInstruction::Context context; 6868 context.type = eContextRegisterLoad; 6869 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 6870 6871 uint64_t data = MemURead(context, address, 1, 0, &success); 6872 if (!success) 6873 return false; 6874 6875 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6876 return false; 6877 6878 // if wback then R[n] = offset_addr; 6879 if (wback) { 6880 context.type = eContextAdjustBaseRegister; 6881 context.SetAddress(offset_addr); 6882 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6883 offset_addr)) 6884 return false; 6885 } 6886 } 6887 return true; 6888} 6889 6890// LDRB (literal) calculates an address from the PC value and an immediate 6891// offset, loads a byte from memory, 6892// zero-extends it to form a 32-bit word and writes it to a register. 6893bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode, 6894 const ARMEncoding encoding) { 6895#if 0 6896 if ConditionPassed() then 6897 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6898 base = Align(PC,4); 6899 address = if add then (base + imm32) else (base - imm32); 6900 R[t] = ZeroExtend(MemU[address,1], 32); 6901#endif 6902 6903 bool success = false; 6904 6905 if (ConditionPassed(opcode)) { 6906 uint32_t t; 6907 uint32_t imm32; 6908 bool add; 6909 switch (encoding) { 6910 case eEncodingT1: 6911 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6912 t = Bits32(opcode, 15, 12); 6913 imm32 = Bits32(opcode, 11, 0); 6914 add = BitIsSet(opcode, 23); 6915 6916 // if Rt == '1111' then SEE PLD; 6917 if (t == 15) 6918 return false; // PLD is not implemented yet 6919 6920 // if t == 13 then UNPREDICTABLE; 6921 if (t == 13) 6922 return false; 6923 6924 break; 6925 6926 case eEncodingA1: 6927 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6928 t = Bits32(opcode, 15, 12); 6929 imm32 = Bits32(opcode, 11, 0); 6930 add = BitIsSet(opcode, 23); 6931 6932 // if t == 15 then UNPREDICTABLE; 6933 if (t == 15) 6934 return false; 6935 break; 6936 6937 default: 6938 return false; 6939 } 6940 6941 // base = Align(PC,4); 6942 uint32_t pc_val = ReadCoreReg(PC_REG, &success); 6943 if (!success) 6944 return false; 6945 6946 uint32_t base = AlignPC(pc_val); 6947 6948 addr_t address; 6949 // address = if add then (base + imm32) else (base - imm32); 6950 if (add) 6951 address = base + imm32; 6952 else 6953 address = base - imm32; 6954 6955 // R[t] = ZeroExtend(MemU[address,1], 32); 6956 EmulateInstruction::Context context; 6957 context.type = eContextRelativeBranchImmediate; 6958 context.SetImmediate(address - base); 6959 6960 uint64_t data = MemURead(context, address, 1, 0, &success); 6961 if (!success) 6962 return false; 6963 6964 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6965 return false; 6966 } 6967 return true; 6968} 6969 6970// LDRB (register) calculates an address from a base register value and an 6971// offset rigister value, loads a byte from 6972// memory, zero-extends it to form a 32-bit word, and writes it to a register. 6973// The offset register value can 6974// optionally be shifted. 6975bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode, 6976 const ARMEncoding encoding) { 6977#if 0 6978 if ConditionPassed() then 6979 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6980 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6981 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6982 address = if index then offset_addr else R[n]; 6983 R[t] = ZeroExtend(MemU[address,1],32); 6984 if wback then R[n] = offset_addr; 6985#endif 6986 6987 bool success = false; 6988 6989 if (ConditionPassed(opcode)) { 6990 uint32_t t; 6991 uint32_t n; 6992 uint32_t m; 6993 bool index; 6994 bool add; 6995 bool wback; 6996 ARM_ShifterType shift_t; 6997 uint32_t shift_n; 6998 6999 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7000 switch (encoding) { 7001 case eEncodingT1: 7002 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7003 t = Bits32(opcode, 2, 0); 7004 n = Bits32(opcode, 5, 3); 7005 m = Bits32(opcode, 8, 6); 7006 7007 // index = TRUE; add = TRUE; wback = FALSE; 7008 index = true; 7009 add = true; 7010 wback = false; 7011 7012 // (shift_t, shift_n) = (SRType_LSL, 0); 7013 shift_t = SRType_LSL; 7014 shift_n = 0; 7015 break; 7016 7017 case eEncodingT2: 7018 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7019 t = Bits32(opcode, 15, 12); 7020 n = Bits32(opcode, 19, 16); 7021 m = Bits32(opcode, 3, 0); 7022 7023 // index = TRUE; add = TRUE; wback = FALSE; 7024 index = true; 7025 add = true; 7026 wback = false; 7027 7028 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7029 shift_t = SRType_LSL; 7030 shift_n = Bits32(opcode, 5, 4); 7031 7032 // if Rt == '1111' then SEE PLD; 7033 if (t == 15) 7034 return false; // PLD is not implemented yet 7035 7036 // if Rn == '1111' then SEE LDRB (literal); 7037 if (n == 15) 7038 return EmulateLDRBLiteral(opcode, eEncodingT1); 7039 7040 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7041 if ((t == 13) || BadReg(m)) 7042 return false; 7043 break; 7044 7045 case eEncodingA1: { 7046 // if P == '0' && W == '1' then SEE LDRBT; 7047 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7048 t = Bits32(opcode, 15, 12); 7049 n = Bits32(opcode, 19, 16); 7050 m = Bits32(opcode, 3, 0); 7051 7052 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7053 // (W == '1'); 7054 index = BitIsSet(opcode, 24); 7055 add = BitIsSet(opcode, 23); 7056 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7057 7058 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 7059 uint32_t type = Bits32(opcode, 6, 5); 7060 uint32_t imm5 = Bits32(opcode, 11, 7); 7061 shift_n = DecodeImmShift(type, imm5, shift_t); 7062 7063 // if t == 15 || m == 15 then UNPREDICTABLE; 7064 if ((t == 15) || (m == 15)) 7065 return false; 7066 7067 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7068 if (wback && ((n == 15) || (n == t))) 7069 return false; 7070 } break; 7071 7072 default: 7073 return false; 7074 } 7075 7076 addr_t offset_addr; 7077 addr_t address; 7078 7079 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7080 uint32_t Rm = 7081 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7082 if (!success) 7083 return false; 7084 7085 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7086 if (!success) 7087 return false; 7088 7089 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7090 uint32_t Rn = 7091 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7092 if (!success) 7093 return false; 7094 7095 if (add) 7096 offset_addr = Rn + offset; 7097 else 7098 offset_addr = Rn - offset; 7099 7100 // address = if index then offset_addr else R[n]; 7101 if (index) 7102 address = offset_addr; 7103 else 7104 address = Rn; 7105 7106 // R[t] = ZeroExtend(MemU[address,1],32); 7107 RegisterInfo base_reg; 7108 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7109 7110 EmulateInstruction::Context context; 7111 context.type = eContextRegisterLoad; 7112 context.SetRegisterPlusOffset(base_reg, address - Rn); 7113 7114 uint64_t data = MemURead(context, address, 1, 0, &success); 7115 if (!success) 7116 return false; 7117 7118 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7119 return false; 7120 7121 // if wback then R[n] = offset_addr; 7122 if (wback) { 7123 context.type = eContextAdjustBaseRegister; 7124 context.SetAddress(offset_addr); 7125 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7126 offset_addr)) 7127 return false; 7128 } 7129 } 7130 return true; 7131} 7132 7133// LDRH (immediate, Thumb) calculates an address from a base register value and 7134// an immediate offset, loads a 7135// halfword from memory, zero-extends it to form a 32-bit word, and writes it to 7136// a register. It can use offset, 7137// post-indexed, or pre-indexed addressing. 7138bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode, 7139 const ARMEncoding encoding) { 7140#if 0 7141 if ConditionPassed() then 7142 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7143 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7144 address = if index then offset_addr else R[n]; 7145 data = MemU[address,2]; 7146 if wback then R[n] = offset_addr; 7147 if UnalignedSupport() || address<0> = '0' then 7148 R[t] = ZeroExtend(data, 32); 7149 else // Can only apply before ARMv7 7150 R[t] = bits(32) UNKNOWN; 7151#endif 7152 7153 bool success = false; 7154 7155 if (ConditionPassed(opcode)) { 7156 uint32_t t; 7157 uint32_t n; 7158 uint32_t imm32; 7159 bool index; 7160 bool add; 7161 bool wback; 7162 7163 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7164 switch (encoding) { 7165 case eEncodingT1: 7166 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 7167 t = Bits32(opcode, 2, 0); 7168 n = Bits32(opcode, 5, 3); 7169 imm32 = Bits32(opcode, 10, 6) << 1; 7170 7171 // index = TRUE; add = TRUE; wback = FALSE; 7172 index = true; 7173 add = true; 7174 wback = false; 7175 7176 break; 7177 7178 case eEncodingT2: 7179 // if Rt == '1111' then SEE "Unallocated memory hints"; 7180 // if Rn == '1111' then SEE LDRH (literal); 7181 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7182 t = Bits32(opcode, 15, 12); 7183 n = Bits32(opcode, 19, 16); 7184 imm32 = Bits32(opcode, 11, 0); 7185 7186 // index = TRUE; add = TRUE; wback = FALSE; 7187 index = true; 7188 add = true; 7189 wback = false; 7190 7191 // if t == 13 then UNPREDICTABLE; 7192 if (t == 13) 7193 return false; 7194 break; 7195 7196 case eEncodingT3: 7197 // if Rn == '1111' then SEE LDRH (literal); 7198 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7199 // "Unallocated memory hints"; 7200 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 7201 // if P == '0' && W == '0' then UNDEFINED; 7202 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7203 return false; 7204 7205 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7206 t = Bits32(opcode, 15, 12); 7207 n = Bits32(opcode, 19, 16); 7208 imm32 = Bits32(opcode, 7, 0); 7209 7210 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7211 index = BitIsSet(opcode, 10); 7212 add = BitIsSet(opcode, 9); 7213 wback = BitIsSet(opcode, 8); 7214 7215 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7216 if (BadReg(t) || (wback && (n == t))) 7217 return false; 7218 break; 7219 7220 default: 7221 return false; 7222 } 7223 7224 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7225 uint32_t Rn = 7226 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7227 if (!success) 7228 return false; 7229 7230 addr_t offset_addr; 7231 addr_t address; 7232 7233 if (add) 7234 offset_addr = Rn + imm32; 7235 else 7236 offset_addr = Rn - imm32; 7237 7238 // address = if index then offset_addr else R[n]; 7239 if (index) 7240 address = offset_addr; 7241 else 7242 address = Rn; 7243 7244 // data = MemU[address,2]; 7245 RegisterInfo base_reg; 7246 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7247 7248 EmulateInstruction::Context context; 7249 context.type = eContextRegisterLoad; 7250 context.SetRegisterPlusOffset(base_reg, address - Rn); 7251 7252 uint64_t data = MemURead(context, address, 2, 0, &success); 7253 if (!success) 7254 return false; 7255 7256 // if wback then R[n] = offset_addr; 7257 if (wback) { 7258 context.type = eContextAdjustBaseRegister; 7259 context.SetAddress(offset_addr); 7260 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7261 offset_addr)) 7262 return false; 7263 } 7264 7265 // if UnalignedSupport() || address<0> = '0' then 7266 if (UnalignedSupport() || BitIsClear(address, 0)) { 7267 // R[t] = ZeroExtend(data, 32); 7268 context.type = eContextRegisterLoad; 7269 context.SetRegisterPlusOffset(base_reg, address - Rn); 7270 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7271 data)) 7272 return false; 7273 } else // Can only apply before ARMv7 7274 { 7275 // R[t] = bits(32) UNKNOWN; 7276 WriteBits32Unknown(t); 7277 } 7278 } 7279 return true; 7280} 7281 7282// LDRH (literal) caculates an address from the PC value and an immediate 7283// offset, loads a halfword from memory, 7284// zero-extends it to form a 32-bit word, and writes it to a register. 7285bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode, 7286 const ARMEncoding encoding) { 7287#if 0 7288 if ConditionPassed() then 7289 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7290 base = Align(PC,4); 7291 address = if add then (base + imm32) else (base - imm32); 7292 data = MemU[address,2]; 7293 if UnalignedSupport() || address<0> = '0' then 7294 R[t] = ZeroExtend(data, 32); 7295 else // Can only apply before ARMv7 7296 R[t] = bits(32) UNKNOWN; 7297#endif 7298 7299 bool success = false; 7300 7301 if (ConditionPassed(opcode)) { 7302 uint32_t t; 7303 uint32_t imm32; 7304 bool add; 7305 7306 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7307 switch (encoding) { 7308 case eEncodingT1: 7309 // if Rt == '1111' then SEE "Unallocated memory hints"; 7310 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7311 t = Bits32(opcode, 15, 12); 7312 imm32 = Bits32(opcode, 11, 0); 7313 add = BitIsSet(opcode, 23); 7314 7315 // if t == 13 then UNPREDICTABLE; 7316 if (t == 13) 7317 return false; 7318 7319 break; 7320 7321 case eEncodingA1: { 7322 uint32_t imm4H = Bits32(opcode, 11, 8); 7323 uint32_t imm4L = Bits32(opcode, 3, 0); 7324 7325 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7326 t = Bits32(opcode, 15, 12); 7327 imm32 = (imm4H << 4) | imm4L; 7328 add = BitIsSet(opcode, 23); 7329 7330 // if t == 15 then UNPREDICTABLE; 7331 if (t == 15) 7332 return false; 7333 break; 7334 } 7335 7336 default: 7337 return false; 7338 } 7339 7340 // base = Align(PC,4); 7341 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7342 if (!success) 7343 return false; 7344 7345 addr_t base = AlignPC(pc_value); 7346 addr_t address; 7347 7348 // address = if add then (base + imm32) else (base - imm32); 7349 if (add) 7350 address = base + imm32; 7351 else 7352 address = base - imm32; 7353 7354 // data = MemU[address,2]; 7355 RegisterInfo base_reg; 7356 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7357 7358 EmulateInstruction::Context context; 7359 context.type = eContextRegisterLoad; 7360 context.SetRegisterPlusOffset(base_reg, address - base); 7361 7362 uint64_t data = MemURead(context, address, 2, 0, &success); 7363 if (!success) 7364 return false; 7365 7366 // if UnalignedSupport() || address<0> = '0' then 7367 if (UnalignedSupport() || BitIsClear(address, 0)) { 7368 // R[t] = ZeroExtend(data, 32); 7369 context.type = eContextRegisterLoad; 7370 context.SetRegisterPlusOffset(base_reg, address - base); 7371 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7372 data)) 7373 return false; 7374 7375 } else // Can only apply before ARMv7 7376 { 7377 // R[t] = bits(32) UNKNOWN; 7378 WriteBits32Unknown(t); 7379 } 7380 } 7381 return true; 7382} 7383 7384// LDRH (literal) calculates an address from a base register value and an offset 7385// register value, loads a halfword 7386// from memory, zero-extends it to form a 32-bit word, and writes it to a 7387// register. The offset register value can 7388// be shifted left by 0, 1, 2, or 3 bits. 7389bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode, 7390 const ARMEncoding encoding) { 7391#if 0 7392 if ConditionPassed() then 7393 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7394 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7395 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7396 address = if index then offset_addr else R[n]; 7397 data = MemU[address,2]; 7398 if wback then R[n] = offset_addr; 7399 if UnalignedSupport() || address<0> = '0' then 7400 R[t] = ZeroExtend(data, 32); 7401 else // Can only apply before ARMv7 7402 R[t] = bits(32) UNKNOWN; 7403#endif 7404 7405 bool success = false; 7406 7407 if (ConditionPassed(opcode)) { 7408 uint32_t t; 7409 uint32_t n; 7410 uint32_t m; 7411 bool index; 7412 bool add; 7413 bool wback; 7414 ARM_ShifterType shift_t; 7415 uint32_t shift_n; 7416 7417 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7418 switch (encoding) { 7419 case eEncodingT1: 7420 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 7421 // in ThumbEE"; 7422 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7423 t = Bits32(opcode, 2, 0); 7424 n = Bits32(opcode, 5, 3); 7425 m = Bits32(opcode, 8, 6); 7426 7427 // index = TRUE; add = TRUE; wback = FALSE; 7428 index = true; 7429 add = true; 7430 wback = false; 7431 7432 // (shift_t, shift_n) = (SRType_LSL, 0); 7433 shift_t = SRType_LSL; 7434 shift_n = 0; 7435 7436 break; 7437 7438 case eEncodingT2: 7439 // if Rn == '1111' then SEE LDRH (literal); 7440 // if Rt == '1111' then SEE "Unallocated memory hints"; 7441 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7442 t = Bits32(opcode, 15, 12); 7443 n = Bits32(opcode, 19, 16); 7444 m = Bits32(opcode, 3, 0); 7445 7446 // index = TRUE; add = TRUE; wback = FALSE; 7447 index = true; 7448 add = true; 7449 wback = false; 7450 7451 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7452 shift_t = SRType_LSL; 7453 shift_n = Bits32(opcode, 5, 4); 7454 7455 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7456 if ((t == 13) || BadReg(m)) 7457 return false; 7458 break; 7459 7460 case eEncodingA1: 7461 // if P == '0' && W == '1' then SEE LDRHT; 7462 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7463 t = Bits32(opcode, 15, 12); 7464 n = Bits32(opcode, 19, 16); 7465 m = Bits32(opcode, 3, 0); 7466 7467 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7468 // (W == '1'); 7469 index = BitIsSet(opcode, 24); 7470 add = BitIsSet(opcode, 23); 7471 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7472 7473 // (shift_t, shift_n) = (SRType_LSL, 0); 7474 shift_t = SRType_LSL; 7475 shift_n = 0; 7476 7477 // if t == 15 || m == 15 then UNPREDICTABLE; 7478 if ((t == 15) || (m == 15)) 7479 return false; 7480 7481 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7482 if (wback && ((n == 15) || (n == t))) 7483 return false; 7484 7485 break; 7486 7487 default: 7488 return false; 7489 } 7490 7491 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7492 7493 uint64_t Rm = 7494 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7495 if (!success) 7496 return false; 7497 7498 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7499 if (!success) 7500 return false; 7501 7502 addr_t offset_addr; 7503 addr_t address; 7504 7505 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7506 uint64_t Rn = 7507 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7508 if (!success) 7509 return false; 7510 7511 if (add) 7512 offset_addr = Rn + offset; 7513 else 7514 offset_addr = Rn - offset; 7515 7516 // address = if index then offset_addr else R[n]; 7517 if (index) 7518 address = offset_addr; 7519 else 7520 address = Rn; 7521 7522 // data = MemU[address,2]; 7523 RegisterInfo base_reg; 7524 RegisterInfo offset_reg; 7525 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7526 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7527 7528 EmulateInstruction::Context context; 7529 context.type = eContextRegisterLoad; 7530 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7531 uint64_t data = MemURead(context, address, 2, 0, &success); 7532 if (!success) 7533 return false; 7534 7535 // if wback then R[n] = offset_addr; 7536 if (wback) { 7537 context.type = eContextAdjustBaseRegister; 7538 context.SetAddress(offset_addr); 7539 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7540 offset_addr)) 7541 return false; 7542 } 7543 7544 // if UnalignedSupport() || address<0> = '0' then 7545 if (UnalignedSupport() || BitIsClear(address, 0)) { 7546 // R[t] = ZeroExtend(data, 32); 7547 context.type = eContextRegisterLoad; 7548 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7549 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7550 data)) 7551 return false; 7552 } else // Can only apply before ARMv7 7553 { 7554 // R[t] = bits(32) UNKNOWN; 7555 WriteBits32Unknown(t); 7556 } 7557 } 7558 return true; 7559} 7560 7561// LDRSB (immediate) calculates an address from a base register value and an 7562// immediate offset, loads a byte from 7563// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7564// It can use offset, post-indexed, 7565// or pre-indexed addressing. 7566bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode, 7567 const ARMEncoding encoding) { 7568#if 0 7569 if ConditionPassed() then 7570 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7571 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7572 address = if index then offset_addr else R[n]; 7573 R[t] = SignExtend(MemU[address,1], 32); 7574 if wback then R[n] = offset_addr; 7575#endif 7576 7577 bool success = false; 7578 7579 if (ConditionPassed(opcode)) { 7580 uint32_t t; 7581 uint32_t n; 7582 uint32_t imm32; 7583 bool index; 7584 bool add; 7585 bool wback; 7586 7587 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7588 switch (encoding) { 7589 case eEncodingT1: 7590 // if Rt == '1111' then SEE PLI; 7591 // if Rn == '1111' then SEE LDRSB (literal); 7592 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7593 t = Bits32(opcode, 15, 12); 7594 n = Bits32(opcode, 19, 16); 7595 imm32 = Bits32(opcode, 11, 0); 7596 7597 // index = TRUE; add = TRUE; wback = FALSE; 7598 index = true; 7599 add = true; 7600 wback = false; 7601 7602 // if t == 13 then UNPREDICTABLE; 7603 if (t == 13) 7604 return false; 7605 7606 break; 7607 7608 case eEncodingT2: 7609 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7610 // if Rn == '1111' then SEE LDRSB (literal); 7611 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7612 // if P == '0' && W == '0' then UNDEFINED; 7613 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7614 return false; 7615 7616 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7617 t = Bits32(opcode, 15, 12); 7618 n = Bits32(opcode, 19, 16); 7619 imm32 = Bits32(opcode, 7, 0); 7620 7621 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7622 index = BitIsSet(opcode, 10); 7623 add = BitIsSet(opcode, 9); 7624 wback = BitIsSet(opcode, 8); 7625 7626 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7627 if (((t == 13) || 7628 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) || 7629 BitIsSet(opcode, 8)))) || 7630 (wback && (n == t))) 7631 return false; 7632 7633 break; 7634 7635 case eEncodingA1: { 7636 // if Rn == '1111' then SEE LDRSB (literal); 7637 // if P == '0' && W == '1' then SEE LDRSBT; 7638 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7639 t = Bits32(opcode, 15, 12); 7640 n = Bits32(opcode, 19, 16); 7641 7642 uint32_t imm4H = Bits32(opcode, 11, 8); 7643 uint32_t imm4L = Bits32(opcode, 3, 0); 7644 imm32 = (imm4H << 4) | imm4L; 7645 7646 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7647 // (W == '1'); 7648 index = BitIsSet(opcode, 24); 7649 add = BitIsSet(opcode, 23); 7650 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7651 7652 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7653 if ((t == 15) || (wback && (n == t))) 7654 return false; 7655 7656 break; 7657 } 7658 7659 default: 7660 return false; 7661 } 7662 7663 uint64_t Rn = ReadCoreReg(n, &success); 7664 if (!success) 7665 return false; 7666 7667 addr_t offset_addr; 7668 addr_t address; 7669 7670 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7671 if (add) 7672 offset_addr = Rn + imm32; 7673 else 7674 offset_addr = Rn - imm32; 7675 7676 // address = if index then offset_addr else R[n]; 7677 if (index) 7678 address = offset_addr; 7679 else 7680 address = Rn; 7681 7682 // R[t] = SignExtend(MemU[address,1], 32); 7683 RegisterInfo base_reg; 7684 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7685 7686 EmulateInstruction::Context context; 7687 context.type = eContextRegisterLoad; 7688 context.SetRegisterPlusOffset(base_reg, address - Rn); 7689 7690 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7691 if (!success) 7692 return false; 7693 7694 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7695 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7696 (uint64_t)signed_data)) 7697 return false; 7698 7699 // if wback then R[n] = offset_addr; 7700 if (wback) { 7701 context.type = eContextAdjustBaseRegister; 7702 context.SetAddress(offset_addr); 7703 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7704 offset_addr)) 7705 return false; 7706 } 7707 } 7708 7709 return true; 7710} 7711 7712// LDRSB (literal) calculates an address from the PC value and an immediate 7713// offset, loads a byte from memory, 7714// sign-extends it to form a 32-bit word, and writes tit to a register. 7715bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode, 7716 const ARMEncoding encoding) { 7717#if 0 7718 if ConditionPassed() then 7719 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7720 base = Align(PC,4); 7721 address = if add then (base + imm32) else (base - imm32); 7722 R[t] = SignExtend(MemU[address,1], 32); 7723#endif 7724 7725 bool success = false; 7726 7727 if (ConditionPassed(opcode)) { 7728 uint32_t t; 7729 uint32_t imm32; 7730 bool add; 7731 7732 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7733 switch (encoding) { 7734 case eEncodingT1: 7735 // if Rt == '1111' then SEE PLI; 7736 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7737 t = Bits32(opcode, 15, 12); 7738 imm32 = Bits32(opcode, 11, 0); 7739 add = BitIsSet(opcode, 23); 7740 7741 // if t == 13 then UNPREDICTABLE; 7742 if (t == 13) 7743 return false; 7744 7745 break; 7746 7747 case eEncodingA1: { 7748 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7749 t = Bits32(opcode, 15, 12); 7750 uint32_t imm4H = Bits32(opcode, 11, 8); 7751 uint32_t imm4L = Bits32(opcode, 3, 0); 7752 imm32 = (imm4H << 4) | imm4L; 7753 add = BitIsSet(opcode, 23); 7754 7755 // if t == 15 then UNPREDICTABLE; 7756 if (t == 15) 7757 return false; 7758 7759 break; 7760 } 7761 7762 default: 7763 return false; 7764 } 7765 7766 // base = Align(PC,4); 7767 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7768 if (!success) 7769 return false; 7770 uint64_t base = AlignPC(pc_value); 7771 7772 // address = if add then (base + imm32) else (base - imm32); 7773 addr_t address; 7774 if (add) 7775 address = base + imm32; 7776 else 7777 address = base - imm32; 7778 7779 // R[t] = SignExtend(MemU[address,1], 32); 7780 RegisterInfo base_reg; 7781 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7782 7783 EmulateInstruction::Context context; 7784 context.type = eContextRegisterLoad; 7785 context.SetRegisterPlusOffset(base_reg, address - base); 7786 7787 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7788 if (!success) 7789 return false; 7790 7791 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7792 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7793 (uint64_t)signed_data)) 7794 return false; 7795 } 7796 return true; 7797} 7798 7799// LDRSB (register) calculates an address from a base register value and an 7800// offset register value, loadsa byte from 7801// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7802// The offset register value can be 7803// shifted left by 0, 1, 2, or 3 bits. 7804bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode, 7805 const ARMEncoding encoding) { 7806#if 0 7807 if ConditionPassed() then 7808 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7809 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7810 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7811 address = if index then offset_addr else R[n]; 7812 R[t] = SignExtend(MemU[address,1], 32); 7813 if wback then R[n] = offset_addr; 7814#endif 7815 7816 bool success = false; 7817 7818 if (ConditionPassed(opcode)) { 7819 uint32_t t; 7820 uint32_t n; 7821 uint32_t m; 7822 bool index; 7823 bool add; 7824 bool wback; 7825 ARM_ShifterType shift_t; 7826 uint32_t shift_n; 7827 7828 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7829 switch (encoding) { 7830 case eEncodingT1: 7831 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7832 t = Bits32(opcode, 2, 0); 7833 n = Bits32(opcode, 5, 3); 7834 m = Bits32(opcode, 8, 6); 7835 7836 // index = TRUE; add = TRUE; wback = FALSE; 7837 index = true; 7838 add = true; 7839 wback = false; 7840 7841 // (shift_t, shift_n) = (SRType_LSL, 0); 7842 shift_t = SRType_LSL; 7843 shift_n = 0; 7844 7845 break; 7846 7847 case eEncodingT2: 7848 // if Rt == '1111' then SEE PLI; 7849 // if Rn == '1111' then SEE LDRSB (literal); 7850 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7851 t = Bits32(opcode, 15, 12); 7852 n = Bits32(opcode, 19, 16); 7853 m = Bits32(opcode, 3, 0); 7854 7855 // index = TRUE; add = TRUE; wback = FALSE; 7856 index = true; 7857 add = true; 7858 wback = false; 7859 7860 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7861 shift_t = SRType_LSL; 7862 shift_n = Bits32(opcode, 5, 4); 7863 7864 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7865 if ((t == 13) || BadReg(m)) 7866 return false; 7867 break; 7868 7869 case eEncodingA1: 7870 // if P == '0' && W == '1' then SEE LDRSBT; 7871 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7872 t = Bits32(opcode, 15, 12); 7873 n = Bits32(opcode, 19, 16); 7874 m = Bits32(opcode, 3, 0); 7875 7876 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7877 // (W == '1'); 7878 index = BitIsSet(opcode, 24); 7879 add = BitIsSet(opcode, 23); 7880 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7881 7882 // (shift_t, shift_n) = (SRType_LSL, 0); 7883 shift_t = SRType_LSL; 7884 shift_n = 0; 7885 7886 // if t == 15 || m == 15 then UNPREDICTABLE; 7887 if ((t == 15) || (m == 15)) 7888 return false; 7889 7890 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7891 if (wback && ((n == 15) || (n == t))) 7892 return false; 7893 break; 7894 7895 default: 7896 return false; 7897 } 7898 7899 uint64_t Rm = 7900 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7901 if (!success) 7902 return false; 7903 7904 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7905 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7906 if (!success) 7907 return false; 7908 7909 addr_t offset_addr; 7910 addr_t address; 7911 7912 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7913 uint64_t Rn = 7914 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7915 if (!success) 7916 return false; 7917 7918 if (add) 7919 offset_addr = Rn + offset; 7920 else 7921 offset_addr = Rn - offset; 7922 7923 // address = if index then offset_addr else R[n]; 7924 if (index) 7925 address = offset_addr; 7926 else 7927 address = Rn; 7928 7929 // R[t] = SignExtend(MemU[address,1], 32); 7930 RegisterInfo base_reg; 7931 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7932 RegisterInfo offset_reg; 7933 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7934 7935 EmulateInstruction::Context context; 7936 context.type = eContextRegisterLoad; 7937 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7938 7939 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7940 if (!success) 7941 return false; 7942 7943 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7944 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7945 (uint64_t)signed_data)) 7946 return false; 7947 7948 // if wback then R[n] = offset_addr; 7949 if (wback) { 7950 context.type = eContextAdjustBaseRegister; 7951 context.SetAddress(offset_addr); 7952 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7953 offset_addr)) 7954 return false; 7955 } 7956 } 7957 return true; 7958} 7959 7960// LDRSH (immediate) calculates an address from a base register value and an 7961// immediate offset, loads a halfword from 7962// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7963// It can use offset, post-indexed, or 7964// pre-indexed addressing. 7965bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode, 7966 const ARMEncoding encoding) { 7967#if 0 7968 if ConditionPassed() then 7969 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7970 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7971 address = if index then offset_addr else R[n]; 7972 data = MemU[address,2]; 7973 if wback then R[n] = offset_addr; 7974 if UnalignedSupport() || address<0> = '0' then 7975 R[t] = SignExtend(data, 32); 7976 else // Can only apply before ARMv7 7977 R[t] = bits(32) UNKNOWN; 7978#endif 7979 7980 bool success = false; 7981 7982 if (ConditionPassed(opcode)) { 7983 uint32_t t; 7984 uint32_t n; 7985 uint32_t imm32; 7986 bool index; 7987 bool add; 7988 bool wback; 7989 7990 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7991 switch (encoding) { 7992 case eEncodingT1: 7993 // if Rn == '1111' then SEE LDRSH (literal); 7994 // if Rt == '1111' then SEE "Unallocated memory hints"; 7995 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7996 t = Bits32(opcode, 15, 12); 7997 n = Bits32(opcode, 19, 16); 7998 imm32 = Bits32(opcode, 11, 0); 7999 8000 // index = TRUE; add = TRUE; wback = FALSE; 8001 index = true; 8002 add = true; 8003 wback = false; 8004 8005 // if t == 13 then UNPREDICTABLE; 8006 if (t == 13) 8007 return false; 8008 8009 break; 8010 8011 case eEncodingT2: 8012 // if Rn == '1111' then SEE LDRSH (literal); 8013 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 8014 // "Unallocated memory hints"; 8015 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 8016 // if P == '0' && W == '0' then UNDEFINED; 8017 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 8018 return false; 8019 8020 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 8021 t = Bits32(opcode, 15, 12); 8022 n = Bits32(opcode, 19, 16); 8023 imm32 = Bits32(opcode, 7, 0); 8024 8025 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 8026 index = BitIsSet(opcode, 10); 8027 add = BitIsSet(opcode, 9); 8028 wback = BitIsSet(opcode, 8); 8029 8030 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 8031 if (BadReg(t) || (wback && (n == t))) 8032 return false; 8033 8034 break; 8035 8036 case eEncodingA1: { 8037 // if Rn == '1111' then SEE LDRSH (literal); 8038 // if P == '0' && W == '1' then SEE LDRSHT; 8039 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 8040 t = Bits32(opcode, 15, 12); 8041 n = Bits32(opcode, 19, 16); 8042 uint32_t imm4H = Bits32(opcode, 11, 8); 8043 uint32_t imm4L = Bits32(opcode, 3, 0); 8044 imm32 = (imm4H << 4) | imm4L; 8045 8046 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8047 // (W == '1'); 8048 index = BitIsSet(opcode, 24); 8049 add = BitIsSet(opcode, 23); 8050 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8051 8052 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 8053 if ((t == 15) || (wback && (n == t))) 8054 return false; 8055 8056 break; 8057 } 8058 8059 default: 8060 return false; 8061 } 8062 8063 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 8064 uint64_t Rn = 8065 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8066 if (!success) 8067 return false; 8068 8069 addr_t offset_addr; 8070 if (add) 8071 offset_addr = Rn + imm32; 8072 else 8073 offset_addr = Rn - imm32; 8074 8075 // address = if index then offset_addr else R[n]; 8076 addr_t address; 8077 if (index) 8078 address = offset_addr; 8079 else 8080 address = Rn; 8081 8082 // data = MemU[address,2]; 8083 RegisterInfo base_reg; 8084 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8085 8086 EmulateInstruction::Context context; 8087 context.type = eContextRegisterLoad; 8088 context.SetRegisterPlusOffset(base_reg, address - Rn); 8089 8090 uint64_t data = MemURead(context, address, 2, 0, &success); 8091 if (!success) 8092 return false; 8093 8094 // if wback then R[n] = offset_addr; 8095 if (wback) { 8096 context.type = eContextAdjustBaseRegister; 8097 context.SetAddress(offset_addr); 8098 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8099 offset_addr)) 8100 return false; 8101 } 8102 8103 // if UnalignedSupport() || address<0> = '0' then 8104 if (UnalignedSupport() || BitIsClear(address, 0)) { 8105 // R[t] = SignExtend(data, 32); 8106 int64_t signed_data = llvm::SignExtend64<16>(data); 8107 context.type = eContextRegisterLoad; 8108 context.SetRegisterPlusOffset(base_reg, address - Rn); 8109 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8110 (uint64_t)signed_data)) 8111 return false; 8112 } else // Can only apply before ARMv7 8113 { 8114 // R[t] = bits(32) UNKNOWN; 8115 WriteBits32Unknown(t); 8116 } 8117 } 8118 return true; 8119} 8120 8121// LDRSH (literal) calculates an address from the PC value and an immediate 8122// offset, loads a halfword from memory, 8123// sign-extends it to from a 32-bit word, and writes it to a register. 8124bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode, 8125 const ARMEncoding encoding) { 8126#if 0 8127 if ConditionPassed() then 8128 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8129 base = Align(PC,4); 8130 address = if add then (base + imm32) else (base - imm32); 8131 data = MemU[address,2]; 8132 if UnalignedSupport() || address<0> = '0' then 8133 R[t] = SignExtend(data, 32); 8134 else // Can only apply before ARMv7 8135 R[t] = bits(32) UNKNOWN; 8136#endif 8137 8138 bool success = false; 8139 8140 if (ConditionPassed(opcode)) { 8141 uint32_t t; 8142 uint32_t imm32; 8143 bool add; 8144 8145 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8146 switch (encoding) { 8147 case eEncodingT1: 8148 // if Rt == '1111' then SEE "Unallocated memory hints"; 8149 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 8150 t = Bits32(opcode, 15, 12); 8151 imm32 = Bits32(opcode, 11, 0); 8152 add = BitIsSet(opcode, 23); 8153 8154 // if t == 13 then UNPREDICTABLE; 8155 if (t == 13) 8156 return false; 8157 8158 break; 8159 8160 case eEncodingA1: { 8161 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 8162 t = Bits32(opcode, 15, 12); 8163 uint32_t imm4H = Bits32(opcode, 11, 8); 8164 uint32_t imm4L = Bits32(opcode, 3, 0); 8165 imm32 = (imm4H << 4) | imm4L; 8166 add = BitIsSet(opcode, 23); 8167 8168 // if t == 15 then UNPREDICTABLE; 8169 if (t == 15) 8170 return false; 8171 8172 break; 8173 } 8174 default: 8175 return false; 8176 } 8177 8178 // base = Align(PC,4); 8179 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 8180 if (!success) 8181 return false; 8182 8183 uint64_t base = AlignPC(pc_value); 8184 8185 addr_t address; 8186 // address = if add then (base + imm32) else (base - imm32); 8187 if (add) 8188 address = base + imm32; 8189 else 8190 address = base - imm32; 8191 8192 // data = MemU[address,2]; 8193 RegisterInfo base_reg; 8194 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 8195 8196 EmulateInstruction::Context context; 8197 context.type = eContextRegisterLoad; 8198 context.SetRegisterPlusOffset(base_reg, imm32); 8199 8200 uint64_t data = MemURead(context, address, 2, 0, &success); 8201 if (!success) 8202 return false; 8203 8204 // if UnalignedSupport() || address<0> = '0' then 8205 if (UnalignedSupport() || BitIsClear(address, 0)) { 8206 // R[t] = SignExtend(data, 32); 8207 int64_t signed_data = llvm::SignExtend64<16>(data); 8208 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8209 (uint64_t)signed_data)) 8210 return false; 8211 } else // Can only apply before ARMv7 8212 { 8213 // R[t] = bits(32) UNKNOWN; 8214 WriteBits32Unknown(t); 8215 } 8216 } 8217 return true; 8218} 8219 8220// LDRSH (register) calculates an address from a base register value and an 8221// offset register value, loads a halfword 8222// from memory, sign-extends it to form a 32-bit word, and writes it to a 8223// register. The offset register value can be 8224// shifted left by 0, 1, 2, or 3 bits. 8225bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode, 8226 const ARMEncoding encoding) { 8227#if 0 8228 if ConditionPassed() then 8229 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8230 offset = Shift(R[m], shift_t, shift_n, APSR.C); 8231 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8232 address = if index then offset_addr else R[n]; 8233 data = MemU[address,2]; 8234 if wback then R[n] = offset_addr; 8235 if UnalignedSupport() || address<0> = '0' then 8236 R[t] = SignExtend(data, 32); 8237 else // Can only apply before ARMv7 8238 R[t] = bits(32) UNKNOWN; 8239#endif 8240 8241 bool success = false; 8242 8243 if (ConditionPassed(opcode)) { 8244 uint32_t t; 8245 uint32_t n; 8246 uint32_t m; 8247 bool index; 8248 bool add; 8249 bool wback; 8250 ARM_ShifterType shift_t; 8251 uint32_t shift_n; 8252 8253 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8254 switch (encoding) { 8255 case eEncodingT1: 8256 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 8257 // in ThumbEE"; 8258 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8259 t = Bits32(opcode, 2, 0); 8260 n = Bits32(opcode, 5, 3); 8261 m = Bits32(opcode, 8, 6); 8262 8263 // index = TRUE; add = TRUE; wback = FALSE; 8264 index = true; 8265 add = true; 8266 wback = false; 8267 8268 // (shift_t, shift_n) = (SRType_LSL, 0); 8269 shift_t = SRType_LSL; 8270 shift_n = 0; 8271 8272 break; 8273 8274 case eEncodingT2: 8275 // if Rn == '1111' then SEE LDRSH (literal); 8276 // if Rt == '1111' then SEE "Unallocated memory hints"; 8277 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8278 t = Bits32(opcode, 15, 12); 8279 n = Bits32(opcode, 19, 16); 8280 m = Bits32(opcode, 3, 0); 8281 8282 // index = TRUE; add = TRUE; wback = FALSE; 8283 index = true; 8284 add = true; 8285 wback = false; 8286 8287 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 8288 shift_t = SRType_LSL; 8289 shift_n = Bits32(opcode, 5, 4); 8290 8291 // if t == 13 || BadReg(m) then UNPREDICTABLE; 8292 if ((t == 13) || BadReg(m)) 8293 return false; 8294 8295 break; 8296 8297 case eEncodingA1: 8298 // if P == '0' && W == '1' then SEE LDRSHT; 8299 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8300 t = Bits32(opcode, 15, 12); 8301 n = Bits32(opcode, 19, 16); 8302 m = Bits32(opcode, 3, 0); 8303 8304 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8305 // (W == '1'); 8306 index = BitIsSet(opcode, 24); 8307 add = BitIsSet(opcode, 23); 8308 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8309 8310 // (shift_t, shift_n) = (SRType_LSL, 0); 8311 shift_t = SRType_LSL; 8312 shift_n = 0; 8313 8314 // if t == 15 || m == 15 then UNPREDICTABLE; 8315 if ((t == 15) || (m == 15)) 8316 return false; 8317 8318 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 8319 if (wback && ((n == 15) || (n == t))) 8320 return false; 8321 8322 break; 8323 8324 default: 8325 return false; 8326 } 8327 8328 uint64_t Rm = 8329 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8330 if (!success) 8331 return false; 8332 8333 uint64_t Rn = 8334 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8335 if (!success) 8336 return false; 8337 8338 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 8339 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 8340 if (!success) 8341 return false; 8342 8343 addr_t offset_addr; 8344 addr_t address; 8345 8346 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8347 if (add) 8348 offset_addr = Rn + offset; 8349 else 8350 offset_addr = Rn - offset; 8351 8352 // address = if index then offset_addr else R[n]; 8353 if (index) 8354 address = offset_addr; 8355 else 8356 address = Rn; 8357 8358 // data = MemU[address,2]; 8359 RegisterInfo base_reg; 8360 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8361 8362 RegisterInfo offset_reg; 8363 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 8364 8365 EmulateInstruction::Context context; 8366 context.type = eContextRegisterLoad; 8367 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8368 8369 uint64_t data = MemURead(context, address, 2, 0, &success); 8370 if (!success) 8371 return false; 8372 8373 // if wback then R[n] = offset_addr; 8374 if (wback) { 8375 context.type = eContextAdjustBaseRegister; 8376 context.SetAddress(offset_addr); 8377 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8378 offset_addr)) 8379 return false; 8380 } 8381 8382 // if UnalignedSupport() || address<0> = '0' then 8383 if (UnalignedSupport() || BitIsClear(address, 0)) { 8384 // R[t] = SignExtend(data, 32); 8385 context.type = eContextRegisterLoad; 8386 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8387 8388 int64_t signed_data = llvm::SignExtend64<16>(data); 8389 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8390 (uint64_t)signed_data)) 8391 return false; 8392 } else // Can only apply before ARMv7 8393 { 8394 // R[t] = bits(32) UNKNOWN; 8395 WriteBits32Unknown(t); 8396 } 8397 } 8398 return true; 8399} 8400 8401// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and 8402// writes the result to the destination 8403// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before 8404// extracting the 8-bit value. 8405bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode, 8406 const ARMEncoding encoding) { 8407#if 0 8408 if ConditionPassed() then 8409 EncodingSpecificOperations(); 8410 rotated = ROR(R[m], rotation); 8411 R[d] = SignExtend(rotated<7:0>, 32); 8412#endif 8413 8414 bool success = false; 8415 8416 if (ConditionPassed(opcode)) { 8417 uint32_t d; 8418 uint32_t m; 8419 uint32_t rotation; 8420 8421 // EncodingSpecificOperations(); 8422 switch (encoding) { 8423 case eEncodingT1: 8424 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8425 d = Bits32(opcode, 2, 0); 8426 m = Bits32(opcode, 5, 3); 8427 rotation = 0; 8428 8429 break; 8430 8431 case eEncodingT2: 8432 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8433 d = Bits32(opcode, 11, 8); 8434 m = Bits32(opcode, 3, 0); 8435 rotation = Bits32(opcode, 5, 4) << 3; 8436 8437 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8438 if (BadReg(d) || BadReg(m)) 8439 return false; 8440 8441 break; 8442 8443 case eEncodingA1: 8444 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8445 d = Bits32(opcode, 15, 12); 8446 m = Bits32(opcode, 3, 0); 8447 rotation = Bits32(opcode, 11, 10) << 3; 8448 8449 // if d == 15 || m == 15 then UNPREDICTABLE; 8450 if ((d == 15) || (m == 15)) 8451 return false; 8452 8453 break; 8454 8455 default: 8456 return false; 8457 } 8458 8459 uint64_t Rm = 8460 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8461 if (!success) 8462 return false; 8463 8464 // rotated = ROR(R[m], rotation); 8465 uint64_t rotated = ROR(Rm, rotation, &success); 8466 if (!success) 8467 return false; 8468 8469 // R[d] = SignExtend(rotated<7:0>, 32); 8470 int64_t data = llvm::SignExtend64<8>(rotated); 8471 8472 RegisterInfo source_reg; 8473 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8474 8475 EmulateInstruction::Context context; 8476 context.type = eContextRegisterLoad; 8477 context.SetRegister(source_reg); 8478 8479 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8480 (uint64_t)data)) 8481 return false; 8482 } 8483 return true; 8484} 8485 8486// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and 8487// writes the result to the destination 8488// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8489// extracting the 16-bit value. 8490bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode, 8491 const ARMEncoding encoding) { 8492#if 0 8493 if ConditionPassed() then 8494 EncodingSpecificOperations(); 8495 rotated = ROR(R[m], rotation); 8496 R[d] = SignExtend(rotated<15:0>, 32); 8497#endif 8498 8499 bool success = false; 8500 8501 if (ConditionPassed(opcode)) { 8502 uint32_t d; 8503 uint32_t m; 8504 uint32_t rotation; 8505 8506 // EncodingSpecificOperations(); 8507 switch (encoding) { 8508 case eEncodingT1: 8509 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8510 d = Bits32(opcode, 2, 0); 8511 m = Bits32(opcode, 5, 3); 8512 rotation = 0; 8513 8514 break; 8515 8516 case eEncodingT2: 8517 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8518 d = Bits32(opcode, 11, 8); 8519 m = Bits32(opcode, 3, 0); 8520 rotation = Bits32(opcode, 5, 4) << 3; 8521 8522 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8523 if (BadReg(d) || BadReg(m)) 8524 return false; 8525 8526 break; 8527 8528 case eEncodingA1: 8529 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8530 d = Bits32(opcode, 15, 12); 8531 m = Bits32(opcode, 3, 0); 8532 rotation = Bits32(opcode, 11, 10) << 3; 8533 8534 // if d == 15 || m == 15 then UNPREDICTABLE; 8535 if ((d == 15) || (m == 15)) 8536 return false; 8537 8538 break; 8539 8540 default: 8541 return false; 8542 } 8543 8544 uint64_t Rm = 8545 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8546 if (!success) 8547 return false; 8548 8549 // rotated = ROR(R[m], rotation); 8550 uint64_t rotated = ROR(Rm, rotation, &success); 8551 if (!success) 8552 return false; 8553 8554 // R[d] = SignExtend(rotated<15:0>, 32); 8555 RegisterInfo source_reg; 8556 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8557 8558 EmulateInstruction::Context context; 8559 context.type = eContextRegisterLoad; 8560 context.SetRegister(source_reg); 8561 8562 int64_t data = llvm::SignExtend64<16>(rotated); 8563 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8564 (uint64_t)data)) 8565 return false; 8566 } 8567 8568 return true; 8569} 8570 8571// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and 8572// writes the result to the destination 8573// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8574// extracting the 8-bit value. 8575bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode, 8576 const ARMEncoding encoding) { 8577#if 0 8578 if ConditionPassed() then 8579 EncodingSpecificOperations(); 8580 rotated = ROR(R[m], rotation); 8581 R[d] = ZeroExtend(rotated<7:0>, 32); 8582#endif 8583 8584 bool success = false; 8585 8586 if (ConditionPassed(opcode)) { 8587 uint32_t d; 8588 uint32_t m; 8589 uint32_t rotation; 8590 8591 // EncodingSpecificOperations(); 8592 switch (encoding) { 8593 case eEncodingT1: 8594 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8595 d = Bits32(opcode, 2, 0); 8596 m = Bits32(opcode, 5, 3); 8597 rotation = 0; 8598 8599 break; 8600 8601 case eEncodingT2: 8602 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8603 d = Bits32(opcode, 11, 8); 8604 m = Bits32(opcode, 3, 0); 8605 rotation = Bits32(opcode, 5, 4) << 3; 8606 8607 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8608 if (BadReg(d) || BadReg(m)) 8609 return false; 8610 8611 break; 8612 8613 case eEncodingA1: 8614 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8615 d = Bits32(opcode, 15, 12); 8616 m = Bits32(opcode, 3, 0); 8617 rotation = Bits32(opcode, 11, 10) << 3; 8618 8619 // if d == 15 || m == 15 then UNPREDICTABLE; 8620 if ((d == 15) || (m == 15)) 8621 return false; 8622 8623 break; 8624 8625 default: 8626 return false; 8627 } 8628 8629 uint64_t Rm = 8630 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8631 if (!success) 8632 return false; 8633 8634 // rotated = ROR(R[m], rotation); 8635 uint64_t rotated = ROR(Rm, rotation, &success); 8636 if (!success) 8637 return false; 8638 8639 // R[d] = ZeroExtend(rotated<7:0>, 32); 8640 RegisterInfo source_reg; 8641 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8642 8643 EmulateInstruction::Context context; 8644 context.type = eContextRegisterLoad; 8645 context.SetRegister(source_reg); 8646 8647 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8648 Bits32(rotated, 7, 0))) 8649 return false; 8650 } 8651 return true; 8652} 8653 8654// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and 8655// writes the result to the destination 8656// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8657// extracting the 16-bit value. 8658bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode, 8659 const ARMEncoding encoding) { 8660#if 0 8661 if ConditionPassed() then 8662 EncodingSpecificOperations(); 8663 rotated = ROR(R[m], rotation); 8664 R[d] = ZeroExtend(rotated<15:0>, 32); 8665#endif 8666 8667 bool success = false; 8668 8669 if (ConditionPassed(opcode)) { 8670 uint32_t d; 8671 uint32_t m; 8672 uint32_t rotation; 8673 8674 switch (encoding) { 8675 case eEncodingT1: 8676 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8677 d = Bits32(opcode, 2, 0); 8678 m = Bits32(opcode, 5, 3); 8679 rotation = 0; 8680 8681 break; 8682 8683 case eEncodingT2: 8684 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8685 d = Bits32(opcode, 11, 8); 8686 m = Bits32(opcode, 3, 0); 8687 rotation = Bits32(opcode, 5, 4) << 3; 8688 8689 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8690 if (BadReg(d) || BadReg(m)) 8691 return false; 8692 8693 break; 8694 8695 case eEncodingA1: 8696 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8697 d = Bits32(opcode, 15, 12); 8698 m = Bits32(opcode, 3, 0); 8699 rotation = Bits32(opcode, 11, 10) << 3; 8700 8701 // if d == 15 || m == 15 then UNPREDICTABLE; 8702 if ((d == 15) || (m == 15)) 8703 return false; 8704 8705 break; 8706 8707 default: 8708 return false; 8709 } 8710 8711 uint64_t Rm = 8712 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8713 if (!success) 8714 return false; 8715 8716 // rotated = ROR(R[m], rotation); 8717 uint64_t rotated = ROR(Rm, rotation, &success); 8718 if (!success) 8719 return false; 8720 8721 // R[d] = ZeroExtend(rotated<15:0>, 32); 8722 RegisterInfo source_reg; 8723 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8724 8725 EmulateInstruction::Context context; 8726 context.type = eContextRegisterLoad; 8727 context.SetRegister(source_reg); 8728 8729 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8730 Bits32(rotated, 15, 0))) 8731 return false; 8732 } 8733 return true; 8734} 8735 8736// RFE (Return From Exception) loads the PC and the CPSR from the word at the 8737// specified address and the following 8738// word respectively. 8739bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode, 8740 const ARMEncoding encoding) { 8741#if 0 8742 if ConditionPassed() then 8743 EncodingSpecificOperations(); 8744 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8745 UNPREDICTABLE; 8746 else 8747 address = if increment then R[n] else R[n]-8; 8748 if wordhigher then address = address+4; 8749 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8750 BranchWritePC(MemA[address,4]); 8751 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8752#endif 8753 8754 bool success = false; 8755 8756 if (ConditionPassed(opcode)) { 8757 uint32_t n; 8758 bool wback; 8759 bool increment; 8760 bool wordhigher; 8761 8762 // EncodingSpecificOperations(); 8763 switch (encoding) { 8764 case eEncodingT1: 8765 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = 8766 // FALSE; 8767 n = Bits32(opcode, 19, 16); 8768 wback = BitIsSet(opcode, 21); 8769 increment = false; 8770 wordhigher = false; 8771 8772 // if n == 15 then UNPREDICTABLE; 8773 if (n == 15) 8774 return false; 8775 8776 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8777 if (InITBlock() && !LastInITBlock()) 8778 return false; 8779 8780 break; 8781 8782 case eEncodingT2: 8783 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8784 n = Bits32(opcode, 19, 16); 8785 wback = BitIsSet(opcode, 21); 8786 increment = true; 8787 wordhigher = false; 8788 8789 // if n == 15 then UNPREDICTABLE; 8790 if (n == 15) 8791 return false; 8792 8793 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8794 if (InITBlock() && !LastInITBlock()) 8795 return false; 8796 8797 break; 8798 8799 case eEncodingA1: 8800 // n = UInt(Rn); 8801 n = Bits32(opcode, 19, 16); 8802 8803 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8804 wback = BitIsSet(opcode, 21); 8805 increment = BitIsSet(opcode, 23); 8806 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23)); 8807 8808 // if n == 15 then UNPREDICTABLE; 8809 if (n == 15) 8810 return false; 8811 8812 break; 8813 8814 default: 8815 return false; 8816 } 8817 8818 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE 8819 // then 8820 if (!CurrentModeIsPrivileged()) 8821 // UNPREDICTABLE; 8822 return false; 8823 else { 8824 uint64_t Rn = 8825 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8826 if (!success) 8827 return false; 8828 8829 addr_t address; 8830 // address = if increment then R[n] else R[n]-8; 8831 if (increment) 8832 address = Rn; 8833 else 8834 address = Rn - 8; 8835 8836 // if wordhigher then address = address+4; 8837 if (wordhigher) 8838 address = address + 4; 8839 8840 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8841 RegisterInfo base_reg; 8842 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8843 8844 EmulateInstruction::Context context; 8845 context.type = eContextReturnFromException; 8846 context.SetRegisterPlusOffset(base_reg, address - Rn); 8847 8848 uint64_t data = MemARead(context, address + 4, 4, 0, &success); 8849 if (!success) 8850 return false; 8851 8852 CPSRWriteByInstr(data, 15, true); 8853 8854 // BranchWritePC(MemA[address,4]); 8855 uint64_t data2 = MemARead(context, address, 4, 0, &success); 8856 if (!success) 8857 return false; 8858 8859 BranchWritePC(context, data2); 8860 8861 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8862 if (wback) { 8863 context.type = eContextAdjustBaseRegister; 8864 if (increment) { 8865 context.SetOffset(8); 8866 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8867 Rn + 8)) 8868 return false; 8869 } else { 8870 context.SetOffset(-8); 8871 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8872 Rn - 8)) 8873 return false; 8874 } 8875 } // if wback 8876 } 8877 } // if ConditionPassed() 8878 return true; 8879} 8880 8881// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a 8882// register value and an immediate value, 8883// and writes the result to the destination register. It can optionally update 8884// the condition flags based on 8885// the result. 8886bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode, 8887 const ARMEncoding encoding) { 8888#if 0 8889 // ARM pseudo code... 8890 if ConditionPassed() then 8891 EncodingSpecificOperations(); 8892 result = R[n] EOR imm32; 8893 if d == 15 then // Can only occur for ARM encoding 8894 ALUWritePC(result); // setflags is always FALSE here 8895 else 8896 R[d] = result; 8897 if setflags then 8898 APSR.N = result<31>; 8899 APSR.Z = IsZeroBit(result); 8900 APSR.C = carry; 8901 // APSR.V unchanged 8902#endif 8903 8904 bool success = false; 8905 8906 if (ConditionPassed(opcode)) { 8907 uint32_t Rd, Rn; 8908 uint32_t 8909 imm32; // the immediate value to be ORed to the value obtained from Rn 8910 bool setflags; 8911 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8912 switch (encoding) { 8913 case eEncodingT1: 8914 Rd = Bits32(opcode, 11, 8); 8915 Rn = Bits32(opcode, 19, 16); 8916 setflags = BitIsSet(opcode, 20); 8917 imm32 = ThumbExpandImm_C( 8918 opcode, APSR_C, 8919 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8920 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8921 if (Rd == 15 && setflags) 8922 return EmulateTEQImm(opcode, eEncodingT1); 8923 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8924 return false; 8925 break; 8926 case eEncodingA1: 8927 Rd = Bits32(opcode, 15, 12); 8928 Rn = Bits32(opcode, 19, 16); 8929 setflags = BitIsSet(opcode, 20); 8930 imm32 = 8931 ARMExpandImm_C(opcode, APSR_C, 8932 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8933 8934 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8935 // instructions; 8936 if (Rd == 15 && setflags) 8937 return EmulateSUBSPcLrEtc(opcode, encoding); 8938 break; 8939 default: 8940 return false; 8941 } 8942 8943 // Read the first operand. 8944 uint32_t val1 = ReadCoreReg(Rn, &success); 8945 if (!success) 8946 return false; 8947 8948 uint32_t result = val1 ^ imm32; 8949 8950 EmulateInstruction::Context context; 8951 context.type = EmulateInstruction::eContextImmediate; 8952 context.SetNoArgs(); 8953 8954 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8955 return false; 8956 } 8957 return true; 8958} 8959 8960// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register 8961// value and an 8962// optionally-shifted register value, and writes the result to the destination 8963// register. 8964// It can optionally update the condition flags based on the result. 8965bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode, 8966 const ARMEncoding encoding) { 8967#if 0 8968 // ARM pseudo code... 8969 if ConditionPassed() then 8970 EncodingSpecificOperations(); 8971 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8972 result = R[n] EOR shifted; 8973 if d == 15 then // Can only occur for ARM encoding 8974 ALUWritePC(result); // setflags is always FALSE here 8975 else 8976 R[d] = result; 8977 if setflags then 8978 APSR.N = result<31>; 8979 APSR.Z = IsZeroBit(result); 8980 APSR.C = carry; 8981 // APSR.V unchanged 8982#endif 8983 8984 bool success = false; 8985 8986 if (ConditionPassed(opcode)) { 8987 uint32_t Rd, Rn, Rm; 8988 ARM_ShifterType shift_t; 8989 uint32_t shift_n; // the shift applied to the value read from Rm 8990 bool setflags; 8991 uint32_t carry; 8992 switch (encoding) { 8993 case eEncodingT1: 8994 Rd = Rn = Bits32(opcode, 2, 0); 8995 Rm = Bits32(opcode, 5, 3); 8996 setflags = !InITBlock(); 8997 shift_t = SRType_LSL; 8998 shift_n = 0; 8999 break; 9000 case eEncodingT2: 9001 Rd = Bits32(opcode, 11, 8); 9002 Rn = Bits32(opcode, 19, 16); 9003 Rm = Bits32(opcode, 3, 0); 9004 setflags = BitIsSet(opcode, 20); 9005 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9006 // if Rd == '1111' && S == '1' then SEE TEQ (register); 9007 if (Rd == 15 && setflags) 9008 return EmulateTEQReg(opcode, eEncodingT1); 9009 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 9010 return false; 9011 break; 9012 case eEncodingA1: 9013 Rd = Bits32(opcode, 15, 12); 9014 Rn = Bits32(opcode, 19, 16); 9015 Rm = Bits32(opcode, 3, 0); 9016 setflags = BitIsSet(opcode, 20); 9017 shift_n = DecodeImmShiftARM(opcode, shift_t); 9018 9019 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9020 // instructions; 9021 if (Rd == 15 && setflags) 9022 return EmulateSUBSPcLrEtc(opcode, encoding); 9023 break; 9024 default: 9025 return false; 9026 } 9027 9028 // Read the first operand. 9029 uint32_t val1 = ReadCoreReg(Rn, &success); 9030 if (!success) 9031 return false; 9032 9033 // Read the second operand. 9034 uint32_t val2 = ReadCoreReg(Rm, &success); 9035 if (!success) 9036 return false; 9037 9038 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9039 if (!success) 9040 return false; 9041 uint32_t result = val1 ^ shifted; 9042 9043 EmulateInstruction::Context context; 9044 context.type = EmulateInstruction::eContextImmediate; 9045 context.SetNoArgs(); 9046 9047 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9048 return false; 9049 } 9050 return true; 9051} 9052 9053// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value 9054// and an immediate value, and 9055// writes the result to the destination register. It can optionally update the 9056// condition flags based 9057// on the result. 9058bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode, 9059 const ARMEncoding encoding) { 9060#if 0 9061 // ARM pseudo code... 9062 if ConditionPassed() then 9063 EncodingSpecificOperations(); 9064 result = R[n] OR imm32; 9065 if d == 15 then // Can only occur for ARM encoding 9066 ALUWritePC(result); // setflags is always FALSE here 9067 else 9068 R[d] = result; 9069 if setflags then 9070 APSR.N = result<31>; 9071 APSR.Z = IsZeroBit(result); 9072 APSR.C = carry; 9073 // APSR.V unchanged 9074#endif 9075 9076 bool success = false; 9077 9078 if (ConditionPassed(opcode)) { 9079 uint32_t Rd, Rn; 9080 uint32_t 9081 imm32; // the immediate value to be ORed to the value obtained from Rn 9082 bool setflags; 9083 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9084 switch (encoding) { 9085 case eEncodingT1: 9086 Rd = Bits32(opcode, 11, 8); 9087 Rn = Bits32(opcode, 19, 16); 9088 setflags = BitIsSet(opcode, 20); 9089 imm32 = ThumbExpandImm_C( 9090 opcode, APSR_C, 9091 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9092 // if Rn == '1111' then SEE MOV (immediate); 9093 if (Rn == 15) 9094 return EmulateMOVRdImm(opcode, eEncodingT2); 9095 if (BadReg(Rd) || Rn == 13) 9096 return false; 9097 break; 9098 case eEncodingA1: 9099 Rd = Bits32(opcode, 15, 12); 9100 Rn = Bits32(opcode, 19, 16); 9101 setflags = BitIsSet(opcode, 20); 9102 imm32 = 9103 ARMExpandImm_C(opcode, APSR_C, 9104 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9105 9106 if (Rd == 15 && setflags) 9107 return EmulateSUBSPcLrEtc(opcode, encoding); 9108 break; 9109 default: 9110 return false; 9111 } 9112 9113 // Read the first operand. 9114 uint32_t val1 = ReadCoreReg(Rn, &success); 9115 if (!success) 9116 return false; 9117 9118 uint32_t result = val1 | imm32; 9119 9120 EmulateInstruction::Context context; 9121 context.type = EmulateInstruction::eContextImmediate; 9122 context.SetNoArgs(); 9123 9124 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9125 return false; 9126 } 9127 return true; 9128} 9129 9130// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value 9131// and an optionally-shifted register 9132// value, and writes the result to the destination register. It can optionally 9133// update the condition flags based 9134// on the result. 9135bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode, 9136 const ARMEncoding encoding) { 9137#if 0 9138 // ARM pseudo code... 9139 if ConditionPassed() then 9140 EncodingSpecificOperations(); 9141 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9142 result = R[n] OR shifted; 9143 if d == 15 then // Can only occur for ARM encoding 9144 ALUWritePC(result); // setflags is always FALSE here 9145 else 9146 R[d] = result; 9147 if setflags then 9148 APSR.N = result<31>; 9149 APSR.Z = IsZeroBit(result); 9150 APSR.C = carry; 9151 // APSR.V unchanged 9152#endif 9153 9154 bool success = false; 9155 9156 if (ConditionPassed(opcode)) { 9157 uint32_t Rd, Rn, Rm; 9158 ARM_ShifterType shift_t; 9159 uint32_t shift_n; // the shift applied to the value read from Rm 9160 bool setflags; 9161 uint32_t carry; 9162 switch (encoding) { 9163 case eEncodingT1: 9164 Rd = Rn = Bits32(opcode, 2, 0); 9165 Rm = Bits32(opcode, 5, 3); 9166 setflags = !InITBlock(); 9167 shift_t = SRType_LSL; 9168 shift_n = 0; 9169 break; 9170 case eEncodingT2: 9171 Rd = Bits32(opcode, 11, 8); 9172 Rn = Bits32(opcode, 19, 16); 9173 Rm = Bits32(opcode, 3, 0); 9174 setflags = BitIsSet(opcode, 20); 9175 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9176 // if Rn == '1111' then SEE MOV (register); 9177 if (Rn == 15) 9178 return EmulateMOVRdRm(opcode, eEncodingT3); 9179 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 9180 return false; 9181 break; 9182 case eEncodingA1: 9183 Rd = Bits32(opcode, 15, 12); 9184 Rn = Bits32(opcode, 19, 16); 9185 Rm = Bits32(opcode, 3, 0); 9186 setflags = BitIsSet(opcode, 20); 9187 shift_n = DecodeImmShiftARM(opcode, shift_t); 9188 9189 if (Rd == 15 && setflags) 9190 return EmulateSUBSPcLrEtc(opcode, encoding); 9191 break; 9192 default: 9193 return false; 9194 } 9195 9196 // Read the first operand. 9197 uint32_t val1 = ReadCoreReg(Rn, &success); 9198 if (!success) 9199 return false; 9200 9201 // Read the second operand. 9202 uint32_t val2 = ReadCoreReg(Rm, &success); 9203 if (!success) 9204 return false; 9205 9206 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9207 if (!success) 9208 return false; 9209 uint32_t result = val1 | shifted; 9210 9211 EmulateInstruction::Context context; 9212 context.type = EmulateInstruction::eContextImmediate; 9213 context.SetNoArgs(); 9214 9215 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9216 return false; 9217 } 9218 return true; 9219} 9220 9221// Reverse Subtract (immediate) subtracts a register value from an immediate 9222// value, and writes the result to 9223// the destination register. It can optionally update the condition flags based 9224// on the result. 9225bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode, 9226 const ARMEncoding encoding) { 9227#if 0 9228 // ARM pseudo code... 9229 if ConditionPassed() then 9230 EncodingSpecificOperations(); 9231 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 9232 if d == 15 then // Can only occur for ARM encoding 9233 ALUWritePC(result); // setflags is always FALSE here 9234 else 9235 R[d] = result; 9236 if setflags then 9237 APSR.N = result<31>; 9238 APSR.Z = IsZeroBit(result); 9239 APSR.C = carry; 9240 APSR.V = overflow; 9241#endif 9242 9243 bool success = false; 9244 9245 uint32_t Rd; // the destination register 9246 uint32_t Rn; // the first operand 9247 bool setflags; 9248 uint32_t 9249 imm32; // the immediate value to be added to the value obtained from Rn 9250 switch (encoding) { 9251 case eEncodingT1: 9252 Rd = Bits32(opcode, 2, 0); 9253 Rn = Bits32(opcode, 5, 3); 9254 setflags = !InITBlock(); 9255 imm32 = 0; 9256 break; 9257 case eEncodingT2: 9258 Rd = Bits32(opcode, 11, 8); 9259 Rn = Bits32(opcode, 19, 16); 9260 setflags = BitIsSet(opcode, 20); 9261 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9262 if (BadReg(Rd) || BadReg(Rn)) 9263 return false; 9264 break; 9265 case eEncodingA1: 9266 Rd = Bits32(opcode, 15, 12); 9267 Rn = Bits32(opcode, 19, 16); 9268 setflags = BitIsSet(opcode, 20); 9269 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9270 9271 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9272 // instructions; 9273 if (Rd == 15 && setflags) 9274 return EmulateSUBSPcLrEtc(opcode, encoding); 9275 break; 9276 default: 9277 return false; 9278 } 9279 // Read the register value from the operand register Rn. 9280 uint32_t reg_val = ReadCoreReg(Rn, &success); 9281 if (!success) 9282 return false; 9283 9284 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 9285 9286 EmulateInstruction::Context context; 9287 context.type = EmulateInstruction::eContextImmediate; 9288 context.SetNoArgs(); 9289 9290 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9291 res.carry_out, res.overflow)) 9292 return false; 9293 9294 return true; 9295} 9296 9297// Reverse Subtract (register) subtracts a register value from an 9298// optionally-shifted register value, and writes the 9299// result to the destination register. It can optionally update the condition 9300// flags based on the result. 9301bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode, 9302 const ARMEncoding encoding) { 9303#if 0 9304 // ARM pseudo code... 9305 if ConditionPassed() then 9306 EncodingSpecificOperations(); 9307 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9308 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 9309 if d == 15 then // Can only occur for ARM encoding 9310 ALUWritePC(result); // setflags is always FALSE here 9311 else 9312 R[d] = result; 9313 if setflags then 9314 APSR.N = result<31>; 9315 APSR.Z = IsZeroBit(result); 9316 APSR.C = carry; 9317 APSR.V = overflow; 9318#endif 9319 9320 bool success = false; 9321 9322 uint32_t Rd; // the destination register 9323 uint32_t Rn; // the first operand 9324 uint32_t Rm; // the second operand 9325 bool setflags; 9326 ARM_ShifterType shift_t; 9327 uint32_t shift_n; // the shift applied to the value read from Rm 9328 switch (encoding) { 9329 case eEncodingT1: 9330 Rd = Bits32(opcode, 11, 8); 9331 Rn = Bits32(opcode, 19, 16); 9332 Rm = Bits32(opcode, 3, 0); 9333 setflags = BitIsSet(opcode, 20); 9334 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9335 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 9336 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9337 return false; 9338 break; 9339 case eEncodingA1: 9340 Rd = Bits32(opcode, 15, 12); 9341 Rn = Bits32(opcode, 19, 16); 9342 Rm = Bits32(opcode, 3, 0); 9343 setflags = BitIsSet(opcode, 20); 9344 shift_n = DecodeImmShiftARM(opcode, shift_t); 9345 9346 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9347 // instructions; 9348 if (Rd == 15 && setflags) 9349 return EmulateSUBSPcLrEtc(opcode, encoding); 9350 break; 9351 default: 9352 return false; 9353 } 9354 // Read the register value from register Rn. 9355 uint32_t val1 = ReadCoreReg(Rn, &success); 9356 if (!success) 9357 return false; 9358 9359 // Read the register value from register Rm. 9360 uint32_t val2 = ReadCoreReg(Rm, &success); 9361 if (!success) 9362 return false; 9363 9364 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9365 if (!success) 9366 return false; 9367 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 9368 9369 EmulateInstruction::Context context; 9370 context.type = EmulateInstruction::eContextImmediate; 9371 context.SetNoArgs(); 9372 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9373 res.carry_out, res.overflow)) 9374 return false; 9375 9376 return true; 9377} 9378 9379// Reverse Subtract with Carry (immediate) subtracts a register value and the 9380// value of NOT (Carry flag) from 9381// an immediate value, and writes the result to the destination register. It can 9382// optionally update the condition 9383// flags based on the result. 9384bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode, 9385 const ARMEncoding encoding) { 9386#if 0 9387 // ARM pseudo code... 9388 if ConditionPassed() then 9389 EncodingSpecificOperations(); 9390 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 9391 if d == 15 then 9392 ALUWritePC(result); // setflags is always FALSE here 9393 else 9394 R[d] = result; 9395 if setflags then 9396 APSR.N = result<31>; 9397 APSR.Z = IsZeroBit(result); 9398 APSR.C = carry; 9399 APSR.V = overflow; 9400#endif 9401 9402 bool success = false; 9403 9404 uint32_t Rd; // the destination register 9405 uint32_t Rn; // the first operand 9406 bool setflags; 9407 uint32_t 9408 imm32; // the immediate value to be added to the value obtained from Rn 9409 switch (encoding) { 9410 case eEncodingA1: 9411 Rd = Bits32(opcode, 15, 12); 9412 Rn = Bits32(opcode, 19, 16); 9413 setflags = BitIsSet(opcode, 20); 9414 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9415 9416 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9417 // instructions; 9418 if (Rd == 15 && setflags) 9419 return EmulateSUBSPcLrEtc(opcode, encoding); 9420 break; 9421 default: 9422 return false; 9423 } 9424 // Read the register value from the operand register Rn. 9425 uint32_t reg_val = ReadCoreReg(Rn, &success); 9426 if (!success) 9427 return false; 9428 9429 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 9430 9431 EmulateInstruction::Context context; 9432 context.type = EmulateInstruction::eContextImmediate; 9433 context.SetNoArgs(); 9434 9435 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9436 res.carry_out, res.overflow)) 9437 return false; 9438 9439 return true; 9440} 9441 9442// Reverse Subtract with Carry (register) subtracts a register value and the 9443// value of NOT (Carry flag) from an 9444// optionally-shifted register value, and writes the result to the destination 9445// register. It can optionally update the 9446// condition flags based on the result. 9447bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode, 9448 const ARMEncoding encoding) { 9449#if 0 9450 // ARM pseudo code... 9451 if ConditionPassed() then 9452 EncodingSpecificOperations(); 9453 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9454 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 9455 if d == 15 then 9456 ALUWritePC(result); // setflags is always FALSE here 9457 else 9458 R[d] = result; 9459 if setflags then 9460 APSR.N = result<31>; 9461 APSR.Z = IsZeroBit(result); 9462 APSR.C = carry; 9463 APSR.V = overflow; 9464#endif 9465 9466 bool success = false; 9467 9468 uint32_t Rd; // the destination register 9469 uint32_t Rn; // the first operand 9470 uint32_t Rm; // the second operand 9471 bool setflags; 9472 ARM_ShifterType shift_t; 9473 uint32_t shift_n; // the shift applied to the value read from Rm 9474 switch (encoding) { 9475 case eEncodingA1: 9476 Rd = Bits32(opcode, 15, 12); 9477 Rn = Bits32(opcode, 19, 16); 9478 Rm = Bits32(opcode, 3, 0); 9479 setflags = BitIsSet(opcode, 20); 9480 shift_n = DecodeImmShiftARM(opcode, shift_t); 9481 9482 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9483 // instructions; 9484 if (Rd == 15 && setflags) 9485 return EmulateSUBSPcLrEtc(opcode, encoding); 9486 break; 9487 default: 9488 return false; 9489 } 9490 // Read the register value from register Rn. 9491 uint32_t val1 = ReadCoreReg(Rn, &success); 9492 if (!success) 9493 return false; 9494 9495 // Read the register value from register Rm. 9496 uint32_t val2 = ReadCoreReg(Rm, &success); 9497 if (!success) 9498 return false; 9499 9500 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9501 if (!success) 9502 return false; 9503 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 9504 9505 EmulateInstruction::Context context; 9506 context.type = EmulateInstruction::eContextImmediate; 9507 context.SetNoArgs(); 9508 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9509 res.carry_out, res.overflow)) 9510 return false; 9511 9512 return true; 9513} 9514 9515// Subtract with Carry (immediate) subtracts an immediate value and the value of 9516// NOT (Carry flag) from a register value, and writes the result to the 9517// destination register. 9518// It can optionally update the condition flags based on the result. 9519bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode, 9520 const ARMEncoding encoding) { 9521#if 0 9522 // ARM pseudo code... 9523 if ConditionPassed() then 9524 EncodingSpecificOperations(); 9525 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 9526 if d == 15 then // Can only occur for ARM encoding 9527 ALUWritePC(result); // setflags is always FALSE here 9528 else 9529 R[d] = result; 9530 if setflags then 9531 APSR.N = result<31>; 9532 APSR.Z = IsZeroBit(result); 9533 APSR.C = carry; 9534 APSR.V = overflow; 9535#endif 9536 9537 bool success = false; 9538 9539 uint32_t Rd; // the destination register 9540 uint32_t Rn; // the first operand 9541 bool setflags; 9542 uint32_t 9543 imm32; // the immediate value to be added to the value obtained from Rn 9544 switch (encoding) { 9545 case eEncodingT1: 9546 Rd = Bits32(opcode, 11, 8); 9547 Rn = Bits32(opcode, 19, 16); 9548 setflags = BitIsSet(opcode, 20); 9549 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9550 if (BadReg(Rd) || BadReg(Rn)) 9551 return false; 9552 break; 9553 case eEncodingA1: 9554 Rd = Bits32(opcode, 15, 12); 9555 Rn = Bits32(opcode, 19, 16); 9556 setflags = BitIsSet(opcode, 20); 9557 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9558 9559 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9560 // instructions; 9561 if (Rd == 15 && setflags) 9562 return EmulateSUBSPcLrEtc(opcode, encoding); 9563 break; 9564 default: 9565 return false; 9566 } 9567 // Read the register value from the operand register Rn. 9568 uint32_t reg_val = ReadCoreReg(Rn, &success); 9569 if (!success) 9570 return false; 9571 9572 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9573 9574 EmulateInstruction::Context context; 9575 context.type = EmulateInstruction::eContextImmediate; 9576 context.SetNoArgs(); 9577 9578 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9579 res.carry_out, res.overflow)) 9580 return false; 9581 9582 return true; 9583} 9584 9585// Subtract with Carry (register) subtracts an optionally-shifted register value 9586// and the value of 9587// NOT (Carry flag) from a register value, and writes the result to the 9588// destination register. 9589// It can optionally update the condition flags based on the result. 9590bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode, 9591 const ARMEncoding encoding) { 9592#if 0 9593 // ARM pseudo code... 9594 if ConditionPassed() then 9595 EncodingSpecificOperations(); 9596 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9597 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9598 if d == 15 then // Can only occur for ARM encoding 9599 ALUWritePC(result); // setflags is always FALSE here 9600 else 9601 R[d] = result; 9602 if setflags then 9603 APSR.N = result<31>; 9604 APSR.Z = IsZeroBit(result); 9605 APSR.C = carry; 9606 APSR.V = overflow; 9607#endif 9608 9609 bool success = false; 9610 9611 uint32_t Rd; // the destination register 9612 uint32_t Rn; // the first operand 9613 uint32_t Rm; // the second operand 9614 bool setflags; 9615 ARM_ShifterType shift_t; 9616 uint32_t shift_n; // the shift applied to the value read from Rm 9617 switch (encoding) { 9618 case eEncodingT1: 9619 Rd = Rn = Bits32(opcode, 2, 0); 9620 Rm = Bits32(opcode, 5, 3); 9621 setflags = !InITBlock(); 9622 shift_t = SRType_LSL; 9623 shift_n = 0; 9624 break; 9625 case eEncodingT2: 9626 Rd = Bits32(opcode, 11, 8); 9627 Rn = Bits32(opcode, 19, 16); 9628 Rm = Bits32(opcode, 3, 0); 9629 setflags = BitIsSet(opcode, 20); 9630 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9631 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9632 return false; 9633 break; 9634 case eEncodingA1: 9635 Rd = Bits32(opcode, 15, 12); 9636 Rn = Bits32(opcode, 19, 16); 9637 Rm = Bits32(opcode, 3, 0); 9638 setflags = BitIsSet(opcode, 20); 9639 shift_n = DecodeImmShiftARM(opcode, shift_t); 9640 9641 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9642 // instructions; 9643 if (Rd == 15 && setflags) 9644 return EmulateSUBSPcLrEtc(opcode, encoding); 9645 break; 9646 default: 9647 return false; 9648 } 9649 // Read the register value from register Rn. 9650 uint32_t val1 = ReadCoreReg(Rn, &success); 9651 if (!success) 9652 return false; 9653 9654 // Read the register value from register Rm. 9655 uint32_t val2 = ReadCoreReg(Rm, &success); 9656 if (!success) 9657 return false; 9658 9659 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9660 if (!success) 9661 return false; 9662 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9663 9664 EmulateInstruction::Context context; 9665 context.type = EmulateInstruction::eContextImmediate; 9666 context.SetNoArgs(); 9667 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9668 res.carry_out, res.overflow)) 9669 return false; 9670 9671 return true; 9672} 9673 9674// This instruction subtracts an immediate value from a register value, and 9675// writes the result 9676// to the destination register. It can optionally update the condition flags 9677// based on the result. 9678bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode, 9679 const ARMEncoding encoding) { 9680#if 0 9681 // ARM pseudo code... 9682 if ConditionPassed() then 9683 EncodingSpecificOperations(); 9684 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9685 R[d] = result; 9686 if setflags then 9687 APSR.N = result<31>; 9688 APSR.Z = IsZeroBit(result); 9689 APSR.C = carry; 9690 APSR.V = overflow; 9691#endif 9692 9693 bool success = false; 9694 9695 uint32_t Rd; // the destination register 9696 uint32_t Rn; // the first operand 9697 bool setflags; 9698 uint32_t imm32; // the immediate value to be subtracted from the value 9699 // obtained from Rn 9700 switch (encoding) { 9701 case eEncodingT1: 9702 Rd = Bits32(opcode, 2, 0); 9703 Rn = Bits32(opcode, 5, 3); 9704 setflags = !InITBlock(); 9705 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9706 break; 9707 case eEncodingT2: 9708 Rd = Rn = Bits32(opcode, 10, 8); 9709 setflags = !InITBlock(); 9710 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9711 break; 9712 case eEncodingT3: 9713 Rd = Bits32(opcode, 11, 8); 9714 Rn = Bits32(opcode, 19, 16); 9715 setflags = BitIsSet(opcode, 20); 9716 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9717 9718 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9719 if (Rd == 15 && setflags) 9720 return EmulateCMPImm(opcode, eEncodingT2); 9721 9722 // if Rn == '1101' then SEE SUB (SP minus immediate); 9723 if (Rn == 13) 9724 return EmulateSUBSPImm(opcode, eEncodingT2); 9725 9726 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9727 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9728 return false; 9729 break; 9730 case eEncodingT4: 9731 Rd = Bits32(opcode, 11, 8); 9732 Rn = Bits32(opcode, 19, 16); 9733 setflags = BitIsSet(opcode, 20); 9734 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9735 9736 // if Rn == '1111' then SEE ADR; 9737 if (Rn == 15) 9738 return EmulateADR(opcode, eEncodingT2); 9739 9740 // if Rn == '1101' then SEE SUB (SP minus immediate); 9741 if (Rn == 13) 9742 return EmulateSUBSPImm(opcode, eEncodingT3); 9743 9744 if (BadReg(Rd)) 9745 return false; 9746 break; 9747 default: 9748 return false; 9749 } 9750 // Read the register value from the operand register Rn. 9751 uint32_t reg_val = ReadCoreReg(Rn, &success); 9752 if (!success) 9753 return false; 9754 9755 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9756 9757 EmulateInstruction::Context context; 9758 context.type = EmulateInstruction::eContextImmediate; 9759 context.SetNoArgs(); 9760 9761 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9762 res.carry_out, res.overflow)) 9763 return false; 9764 9765 return true; 9766} 9767 9768// This instruction subtracts an immediate value from a register value, and 9769// writes the result 9770// to the destination register. It can optionally update the condition flags 9771// based on the result. 9772bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode, 9773 const ARMEncoding encoding) { 9774#if 0 9775 // ARM pseudo code... 9776 if ConditionPassed() then 9777 EncodingSpecificOperations(); 9778 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9779 if d == 15 then 9780 ALUWritePC(result); // setflags is always FALSE here 9781 else 9782 R[d] = result; 9783 if setflags then 9784 APSR.N = result<31>; 9785 APSR.Z = IsZeroBit(result); 9786 APSR.C = carry; 9787 APSR.V = overflow; 9788#endif 9789 9790 bool success = false; 9791 9792 if (ConditionPassed(opcode)) { 9793 uint32_t Rd; // the destination register 9794 uint32_t Rn; // the first operand 9795 bool setflags; 9796 uint32_t imm32; // the immediate value to be subtracted from the value 9797 // obtained from Rn 9798 switch (encoding) { 9799 case eEncodingA1: 9800 Rd = Bits32(opcode, 15, 12); 9801 Rn = Bits32(opcode, 19, 16); 9802 setflags = BitIsSet(opcode, 20); 9803 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9804 9805 // if Rn == '1111' && S == '0' then SEE ADR; 9806 if (Rn == 15 && !setflags) 9807 return EmulateADR(opcode, eEncodingA2); 9808 9809 // if Rn == '1101' then SEE SUB (SP minus immediate); 9810 if (Rn == 13) 9811 return EmulateSUBSPImm(opcode, eEncodingA1); 9812 9813 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9814 // instructions; 9815 if (Rd == 15 && setflags) 9816 return EmulateSUBSPcLrEtc(opcode, encoding); 9817 break; 9818 default: 9819 return false; 9820 } 9821 // Read the register value from the operand register Rn. 9822 uint32_t reg_val = ReadCoreReg(Rn, &success); 9823 if (!success) 9824 return false; 9825 9826 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9827 9828 EmulateInstruction::Context context; 9829 if (Rd == 13) 9830 context.type = EmulateInstruction::eContextAdjustStackPointer; 9831 else 9832 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9833 9834 RegisterInfo dwarf_reg; 9835 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 9836 int64_t imm32_signed = imm32; 9837 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed); 9838 9839 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9840 res.carry_out, res.overflow)) 9841 return false; 9842 } 9843 return true; 9844} 9845 9846// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a 9847// register value and an 9848// immediate value. It updates the condition flags based on the result, and 9849// discards the result. 9850bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode, 9851 const ARMEncoding encoding) { 9852#if 0 9853 // ARM pseudo code... 9854 if ConditionPassed() then 9855 EncodingSpecificOperations(); 9856 result = R[n] EOR imm32; 9857 APSR.N = result<31>; 9858 APSR.Z = IsZeroBit(result); 9859 APSR.C = carry; 9860 // APSR.V unchanged 9861#endif 9862 9863 bool success = false; 9864 9865 if (ConditionPassed(opcode)) { 9866 uint32_t Rn; 9867 uint32_t 9868 imm32; // the immediate value to be ANDed to the value obtained from Rn 9869 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9870 switch (encoding) { 9871 case eEncodingT1: 9872 Rn = Bits32(opcode, 19, 16); 9873 imm32 = ThumbExpandImm_C( 9874 opcode, APSR_C, 9875 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9876 if (BadReg(Rn)) 9877 return false; 9878 break; 9879 case eEncodingA1: 9880 Rn = Bits32(opcode, 19, 16); 9881 imm32 = 9882 ARMExpandImm_C(opcode, APSR_C, 9883 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9884 break; 9885 default: 9886 return false; 9887 } 9888 9889 // Read the first operand. 9890 uint32_t val1 = ReadCoreReg(Rn, &success); 9891 if (!success) 9892 return false; 9893 9894 uint32_t result = val1 ^ imm32; 9895 9896 EmulateInstruction::Context context; 9897 context.type = EmulateInstruction::eContextImmediate; 9898 context.SetNoArgs(); 9899 9900 if (!WriteFlags(context, result, carry)) 9901 return false; 9902 } 9903 return true; 9904} 9905 9906// Test Equivalence (register) performs a bitwise exclusive OR operation on a 9907// register value and an 9908// optionally-shifted register value. It updates the condition flags based on 9909// the result, and discards 9910// the result. 9911bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode, 9912 const ARMEncoding encoding) { 9913#if 0 9914 // ARM pseudo code... 9915 if ConditionPassed() then 9916 EncodingSpecificOperations(); 9917 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9918 result = R[n] EOR shifted; 9919 APSR.N = result<31>; 9920 APSR.Z = IsZeroBit(result); 9921 APSR.C = carry; 9922 // APSR.V unchanged 9923#endif 9924 9925 bool success = false; 9926 9927 if (ConditionPassed(opcode)) { 9928 uint32_t Rn, Rm; 9929 ARM_ShifterType shift_t; 9930 uint32_t shift_n; // the shift applied to the value read from Rm 9931 uint32_t carry; 9932 switch (encoding) { 9933 case eEncodingT1: 9934 Rn = Bits32(opcode, 19, 16); 9935 Rm = Bits32(opcode, 3, 0); 9936 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9937 if (BadReg(Rn) || BadReg(Rm)) 9938 return false; 9939 break; 9940 case eEncodingA1: 9941 Rn = Bits32(opcode, 19, 16); 9942 Rm = Bits32(opcode, 3, 0); 9943 shift_n = DecodeImmShiftARM(opcode, shift_t); 9944 break; 9945 default: 9946 return false; 9947 } 9948 9949 // Read the first operand. 9950 uint32_t val1 = ReadCoreReg(Rn, &success); 9951 if (!success) 9952 return false; 9953 9954 // Read the second operand. 9955 uint32_t val2 = ReadCoreReg(Rm, &success); 9956 if (!success) 9957 return false; 9958 9959 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9960 if (!success) 9961 return false; 9962 uint32_t result = val1 ^ shifted; 9963 9964 EmulateInstruction::Context context; 9965 context.type = EmulateInstruction::eContextImmediate; 9966 context.SetNoArgs(); 9967 9968 if (!WriteFlags(context, result, carry)) 9969 return false; 9970 } 9971 return true; 9972} 9973 9974// Test (immediate) performs a bitwise AND operation on a register value and an 9975// immediate value. 9976// It updates the condition flags based on the result, and discards the result. 9977bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode, 9978 const ARMEncoding encoding) { 9979#if 0 9980 // ARM pseudo code... 9981 if ConditionPassed() then 9982 EncodingSpecificOperations(); 9983 result = R[n] AND imm32; 9984 APSR.N = result<31>; 9985 APSR.Z = IsZeroBit(result); 9986 APSR.C = carry; 9987 // APSR.V unchanged 9988#endif 9989 9990 bool success = false; 9991 9992 if (ConditionPassed(opcode)) { 9993 uint32_t Rn; 9994 uint32_t 9995 imm32; // the immediate value to be ANDed to the value obtained from Rn 9996 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9997 switch (encoding) { 9998 case eEncodingT1: 9999 Rn = Bits32(opcode, 19, 16); 10000 imm32 = ThumbExpandImm_C( 10001 opcode, APSR_C, 10002 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 10003 if (BadReg(Rn)) 10004 return false; 10005 break; 10006 case eEncodingA1: 10007 Rn = Bits32(opcode, 19, 16); 10008 imm32 = 10009 ARMExpandImm_C(opcode, APSR_C, 10010 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 10011 break; 10012 default: 10013 return false; 10014 } 10015 10016 // Read the first operand. 10017 uint32_t val1 = ReadCoreReg(Rn, &success); 10018 if (!success) 10019 return false; 10020 10021 uint32_t result = val1 & imm32; 10022 10023 EmulateInstruction::Context context; 10024 context.type = EmulateInstruction::eContextImmediate; 10025 context.SetNoArgs(); 10026 10027 if (!WriteFlags(context, result, carry)) 10028 return false; 10029 } 10030 return true; 10031} 10032 10033// Test (register) performs a bitwise AND operation on a register value and an 10034// optionally-shifted register value. 10035// It updates the condition flags based on the result, and discards the result. 10036bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode, 10037 const ARMEncoding encoding) { 10038#if 0 10039 // ARM pseudo code... 10040 if ConditionPassed() then 10041 EncodingSpecificOperations(); 10042 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 10043 result = R[n] AND shifted; 10044 APSR.N = result<31>; 10045 APSR.Z = IsZeroBit(result); 10046 APSR.C = carry; 10047 // APSR.V unchanged 10048#endif 10049 10050 bool success = false; 10051 10052 if (ConditionPassed(opcode)) { 10053 uint32_t Rn, Rm; 10054 ARM_ShifterType shift_t; 10055 uint32_t shift_n; // the shift applied to the value read from Rm 10056 uint32_t carry; 10057 switch (encoding) { 10058 case eEncodingT1: 10059 Rn = Bits32(opcode, 2, 0); 10060 Rm = Bits32(opcode, 5, 3); 10061 shift_t = SRType_LSL; 10062 shift_n = 0; 10063 break; 10064 case eEncodingT2: 10065 Rn = Bits32(opcode, 19, 16); 10066 Rm = Bits32(opcode, 3, 0); 10067 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10068 if (BadReg(Rn) || BadReg(Rm)) 10069 return false; 10070 break; 10071 case eEncodingA1: 10072 Rn = Bits32(opcode, 19, 16); 10073 Rm = Bits32(opcode, 3, 0); 10074 shift_n = DecodeImmShiftARM(opcode, shift_t); 10075 break; 10076 default: 10077 return false; 10078 } 10079 10080 // Read the first operand. 10081 uint32_t val1 = ReadCoreReg(Rn, &success); 10082 if (!success) 10083 return false; 10084 10085 // Read the second operand. 10086 uint32_t val2 = ReadCoreReg(Rm, &success); 10087 if (!success) 10088 return false; 10089 10090 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 10091 if (!success) 10092 return false; 10093 uint32_t result = val1 & shifted; 10094 10095 EmulateInstruction::Context context; 10096 context.type = EmulateInstruction::eContextImmediate; 10097 context.SetNoArgs(); 10098 10099 if (!WriteFlags(context, result, carry)) 10100 return false; 10101 } 10102 return true; 10103} 10104 10105// A8.6.216 SUB (SP minus register) 10106bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode, 10107 const ARMEncoding encoding) { 10108#if 0 10109 if ConditionPassed() then 10110 EncodingSpecificOperations(); 10111 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10112 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10113 if d == 15 then // Can only occur for ARM encoding 10114 ALUWritePC(result); // setflags is always FALSE here 10115 else 10116 R[d] = result; 10117 if setflags then 10118 APSR.N = result<31>; 10119 APSR.Z = IsZeroBit(result); 10120 APSR.C = carry; 10121 APSR.V = overflow; 10122#endif 10123 10124 bool success = false; 10125 10126 if (ConditionPassed(opcode)) { 10127 uint32_t d; 10128 uint32_t m; 10129 bool setflags; 10130 ARM_ShifterType shift_t; 10131 uint32_t shift_n; 10132 10133 switch (encoding) { 10134 case eEncodingT1: 10135 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10136 d = Bits32(opcode, 11, 8); 10137 m = Bits32(opcode, 3, 0); 10138 setflags = BitIsSet(opcode, 20); 10139 10140 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10141 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10142 10143 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then 10144 // UNPREDICTABLE; 10145 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 10146 return false; 10147 10148 // if d == 15 || BadReg(m) then UNPREDICTABLE; 10149 if ((d == 15) || BadReg(m)) 10150 return false; 10151 break; 10152 10153 case eEncodingA1: 10154 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10155 d = Bits32(opcode, 15, 12); 10156 m = Bits32(opcode, 3, 0); 10157 setflags = BitIsSet(opcode, 20); 10158 10159 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10160 // instructions; 10161 if (d == 15 && setflags) 10162 EmulateSUBSPcLrEtc(opcode, encoding); 10163 10164 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10165 shift_n = DecodeImmShiftARM(opcode, shift_t); 10166 break; 10167 10168 default: 10169 return false; 10170 } 10171 10172 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10173 uint32_t Rm = ReadCoreReg(m, &success); 10174 if (!success) 10175 return false; 10176 10177 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10178 if (!success) 10179 return false; 10180 10181 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10182 uint32_t sp_val = ReadCoreReg(SP_REG, &success); 10183 if (!success) 10184 return false; 10185 10186 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1); 10187 10188 EmulateInstruction::Context context; 10189 context.type = eContextArithmetic; 10190 RegisterInfo sp_reg; 10191 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 10192 RegisterInfo dwarf_reg; 10193 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 10194 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg); 10195 10196 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10197 res.carry_out, res.overflow)) 10198 return false; 10199 } 10200 return true; 10201} 10202 10203// A8.6.7 ADD (register-shifted register) 10204bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode, 10205 const ARMEncoding encoding) { 10206#if 0 10207 if ConditionPassed() then 10208 EncodingSpecificOperations(); 10209 shift_n = UInt(R[s]<7:0>); 10210 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10211 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10212 R[d] = result; 10213 if setflags then 10214 APSR.N = result<31>; 10215 APSR.Z = IsZeroBit(result); 10216 APSR.C = carry; 10217 APSR.V = overflow; 10218#endif 10219 10220 bool success = false; 10221 10222 if (ConditionPassed(opcode)) { 10223 uint32_t d; 10224 uint32_t n; 10225 uint32_t m; 10226 uint32_t s; 10227 bool setflags; 10228 ARM_ShifterType shift_t; 10229 10230 switch (encoding) { 10231 case eEncodingA1: 10232 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 10233 d = Bits32(opcode, 15, 12); 10234 n = Bits32(opcode, 19, 16); 10235 m = Bits32(opcode, 3, 0); 10236 s = Bits32(opcode, 11, 8); 10237 10238 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 10239 setflags = BitIsSet(opcode, 20); 10240 shift_t = DecodeRegShift(Bits32(opcode, 6, 5)); 10241 10242 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 10243 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 10244 return false; 10245 break; 10246 10247 default: 10248 return false; 10249 } 10250 10251 // shift_n = UInt(R[s]<7:0>); 10252 uint32_t Rs = ReadCoreReg(s, &success); 10253 if (!success) 10254 return false; 10255 10256 uint32_t shift_n = Bits32(Rs, 7, 0); 10257 10258 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10259 uint32_t Rm = ReadCoreReg(m, &success); 10260 if (!success) 10261 return false; 10262 10263 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10264 if (!success) 10265 return false; 10266 10267 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10268 uint32_t Rn = ReadCoreReg(n, &success); 10269 if (!success) 10270 return false; 10271 10272 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0); 10273 10274 // R[d] = result; 10275 EmulateInstruction::Context context; 10276 context.type = eContextArithmetic; 10277 RegisterInfo reg_n; 10278 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10279 RegisterInfo reg_m; 10280 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10281 10282 context.SetRegisterRegisterOperands(reg_n, reg_m); 10283 10284 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 10285 res.result)) 10286 return false; 10287 10288 // if setflags then 10289 // APSR.N = result<31>; 10290 // APSR.Z = IsZeroBit(result); 10291 // APSR.C = carry; 10292 // APSR.V = overflow; 10293 if (setflags) 10294 return WriteFlags(context, res.result, res.carry_out, res.overflow); 10295 } 10296 return true; 10297} 10298 10299// A8.6.213 SUB (register) 10300bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode, 10301 const ARMEncoding encoding) { 10302#if 0 10303 if ConditionPassed() then 10304 EncodingSpecificOperations(); 10305 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10306 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10307 if d == 15 then // Can only occur for ARM encoding 10308 ALUWritePC(result); // setflags is always FALSE here 10309 else 10310 R[d] = result; 10311 if setflags then 10312 APSR.N = result<31>; 10313 APSR.Z = IsZeroBit(result); 10314 APSR.C = carry; 10315 APSR.V = overflow; 10316#endif 10317 10318 bool success = false; 10319 10320 if (ConditionPassed(opcode)) { 10321 uint32_t d; 10322 uint32_t n; 10323 uint32_t m; 10324 bool setflags; 10325 ARM_ShifterType shift_t; 10326 uint32_t shift_n; 10327 10328 switch (encoding) { 10329 case eEncodingT1: 10330 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 10331 d = Bits32(opcode, 2, 0); 10332 n = Bits32(opcode, 5, 3); 10333 m = Bits32(opcode, 8, 6); 10334 setflags = !InITBlock(); 10335 10336 // (shift_t, shift_n) = (SRType_LSL, 0); 10337 shift_t = SRType_LSL; 10338 shift_n = 0; 10339 10340 break; 10341 10342 case eEncodingT2: 10343 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 10344 d = Bits32(opcode, 11, 8); 10345 n = Bits32(opcode, 19, 16); 10346 m = Bits32(opcode, 3, 0); 10347 setflags = BitIsSet(opcode, 20); 10348 10349 // if Rd == "1111" && S == "1" then SEE CMP (register); 10350 if (d == 15 && setflags == 1) 10351 return EmulateCMPImm(opcode, eEncodingT3); 10352 10353 // if Rn == "1101" then SEE SUB (SP minus register); 10354 if (n == 13) 10355 return EmulateSUBSPReg(opcode, eEncodingT1); 10356 10357 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10358 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10359 10360 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then 10361 // UNPREDICTABLE; 10362 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) || 10363 BadReg(m)) 10364 return false; 10365 10366 break; 10367 10368 case eEncodingA1: 10369 // if Rn == '1101' then SEE SUB (SP minus register); 10370 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 10371 d = Bits32(opcode, 15, 12); 10372 n = Bits32(opcode, 19, 16); 10373 m = Bits32(opcode, 3, 0); 10374 setflags = BitIsSet(opcode, 20); 10375 10376 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10377 // instructions; 10378 if ((d == 15) && setflags) 10379 EmulateSUBSPcLrEtc(opcode, encoding); 10380 10381 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10382 shift_n = DecodeImmShiftARM(opcode, shift_t); 10383 10384 break; 10385 10386 default: 10387 return false; 10388 } 10389 10390 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10391 uint32_t Rm = ReadCoreReg(m, &success); 10392 if (!success) 10393 return false; 10394 10395 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10396 if (!success) 10397 return false; 10398 10399 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10400 uint32_t Rn = ReadCoreReg(n, &success); 10401 if (!success) 10402 return false; 10403 10404 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1); 10405 10406 // if d == 15 then // Can only occur for ARM encoding 10407 // ALUWritePC(result); // setflags is always FALSE here 10408 // else 10409 // R[d] = result; 10410 // if setflags then 10411 // APSR.N = result<31>; 10412 // APSR.Z = IsZeroBit(result); 10413 // APSR.C = carry; 10414 // APSR.V = overflow; 10415 10416 EmulateInstruction::Context context; 10417 context.type = eContextArithmetic; 10418 RegisterInfo reg_n; 10419 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10420 RegisterInfo reg_m; 10421 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10422 context.SetRegisterRegisterOperands(reg_n, reg_m); 10423 10424 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10425 res.carry_out, res.overflow)) 10426 return false; 10427 } 10428 return true; 10429} 10430 10431// A8.6.202 STREX 10432// Store Register Exclusive calculates an address from a base register value and 10433// an immediate offset, and stores a 10434// word from a register to memory if the executing processor has exclusive 10435// access to the memory addressed. 10436bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode, 10437 const ARMEncoding encoding) { 10438#if 0 10439 if ConditionPassed() then 10440 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10441 address = R[n] + imm32; 10442 if ExclusiveMonitorsPass(address,4) then 10443 MemA[address,4] = R[t]; 10444 R[d] = 0; 10445 else 10446 R[d] = 1; 10447#endif 10448 10449 bool success = false; 10450 10451 if (ConditionPassed(opcode)) { 10452 uint32_t d; 10453 uint32_t t; 10454 uint32_t n; 10455 uint32_t imm32; 10456 const uint32_t addr_byte_size = GetAddressByteSize(); 10457 10458 switch (encoding) { 10459 case eEncodingT1: 10460 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 10461 // 32); 10462 d = Bits32(opcode, 11, 8); 10463 t = Bits32(opcode, 15, 12); 10464 n = Bits32(opcode, 19, 16); 10465 imm32 = Bits32(opcode, 7, 0) << 2; 10466 10467 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 10468 if (BadReg(d) || BadReg(t) || (n == 15)) 10469 return false; 10470 10471 // if d == n || d == t then UNPREDICTABLE; 10472 if ((d == n) || (d == t)) 10473 return false; 10474 10475 break; 10476 10477 case eEncodingA1: 10478 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero 10479 // offset 10480 d = Bits32(opcode, 15, 12); 10481 t = Bits32(opcode, 3, 0); 10482 n = Bits32(opcode, 19, 16); 10483 imm32 = 0; 10484 10485 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 10486 if ((d == 15) || (t == 15) || (n == 15)) 10487 return false; 10488 10489 // if d == n || d == t then UNPREDICTABLE; 10490 if ((d == n) || (d == t)) 10491 return false; 10492 10493 break; 10494 10495 default: 10496 return false; 10497 } 10498 10499 // address = R[n] + imm32; 10500 uint32_t Rn = ReadCoreReg(n, &success); 10501 if (!success) 10502 return false; 10503 10504 addr_t address = Rn + imm32; 10505 10506 RegisterInfo base_reg; 10507 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10508 RegisterInfo data_reg; 10509 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10510 EmulateInstruction::Context context; 10511 context.type = eContextRegisterStore; 10512 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32); 10513 10514 // if ExclusiveMonitorsPass(address,4) then 10515 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the 10516 // sake of emulation, we will say this 10517 // always return 10518 // true. 10519 if (true) { 10520 // MemA[address,4] = R[t]; 10521 uint32_t Rt = 10522 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 10523 if (!success) 10524 return false; 10525 10526 if (!MemAWrite(context, address, Rt, addr_byte_size)) 10527 return false; 10528 10529 // R[d] = 0; 10530 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 10531 return false; 10532 } 10533#if 0 // unreachable because if true 10534 else 10535 { 10536 // R[d] = 1; 10537 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 10538 return false; 10539 } 10540#endif // unreachable because if true 10541 } 10542 return true; 10543} 10544 10545// A8.6.197 STRB (immediate, ARM) 10546bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode, 10547 const ARMEncoding encoding) { 10548#if 0 10549 if ConditionPassed() then 10550 EncodingSpecificOperations(); 10551 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10552 address = if index then offset_addr else R[n]; 10553 MemU[address,1] = R[t]<7:0>; 10554 if wback then R[n] = offset_addr; 10555#endif 10556 10557 bool success = false; 10558 10559 if (ConditionPassed(opcode)) { 10560 uint32_t t; 10561 uint32_t n; 10562 uint32_t imm32; 10563 bool index; 10564 bool add; 10565 bool wback; 10566 10567 switch (encoding) { 10568 case eEncodingA1: 10569 // if P == '0' && W == '1' then SEE STRBT; 10570 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10571 t = Bits32(opcode, 15, 12); 10572 n = Bits32(opcode, 19, 16); 10573 imm32 = Bits32(opcode, 11, 0); 10574 10575 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10576 index = BitIsSet(opcode, 24); 10577 add = BitIsSet(opcode, 23); 10578 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10579 10580 // if t == 15 then UNPREDICTABLE; 10581 if (t == 15) 10582 return false; 10583 10584 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10585 if (wback && ((n == 15) || (n == t))) 10586 return false; 10587 10588 break; 10589 10590 default: 10591 return false; 10592 } 10593 10594 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10595 uint32_t Rn = ReadCoreReg(n, &success); 10596 if (!success) 10597 return false; 10598 10599 addr_t offset_addr; 10600 if (add) 10601 offset_addr = Rn + imm32; 10602 else 10603 offset_addr = Rn - imm32; 10604 10605 // address = if index then offset_addr else R[n]; 10606 addr_t address; 10607 if (index) 10608 address = offset_addr; 10609 else 10610 address = Rn; 10611 10612 // MemU[address,1] = R[t]<7:0>; 10613 uint32_t Rt = ReadCoreReg(t, &success); 10614 if (!success) 10615 return false; 10616 10617 RegisterInfo base_reg; 10618 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10619 RegisterInfo data_reg; 10620 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10621 EmulateInstruction::Context context; 10622 context.type = eContextRegisterStore; 10623 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10624 10625 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1)) 10626 return false; 10627 10628 // if wback then R[n] = offset_addr; 10629 if (wback) { 10630 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10631 offset_addr)) 10632 return false; 10633 } 10634 } 10635 return true; 10636} 10637 10638// A8.6.194 STR (immediate, ARM) 10639bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode, 10640 const ARMEncoding encoding) { 10641#if 0 10642 if ConditionPassed() then 10643 EncodingSpecificOperations(); 10644 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10645 address = if index then offset_addr else R[n]; 10646 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10647 if wback then R[n] = offset_addr; 10648#endif 10649 10650 bool success = false; 10651 10652 if (ConditionPassed(opcode)) { 10653 uint32_t t; 10654 uint32_t n; 10655 uint32_t imm32; 10656 bool index; 10657 bool add; 10658 bool wback; 10659 10660 const uint32_t addr_byte_size = GetAddressByteSize(); 10661 10662 switch (encoding) { 10663 case eEncodingA1: 10664 // if P == '0' && W == '1' then SEE STRT; 10665 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == 10666 // '000000000100' then SEE PUSH; 10667 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10668 t = Bits32(opcode, 15, 12); 10669 n = Bits32(opcode, 19, 16); 10670 imm32 = Bits32(opcode, 11, 0); 10671 10672 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10673 index = BitIsSet(opcode, 24); 10674 add = BitIsSet(opcode, 23); 10675 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10676 10677 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10678 if (wback && ((n == 15) || (n == t))) 10679 return false; 10680 10681 break; 10682 10683 default: 10684 return false; 10685 } 10686 10687 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10688 uint32_t Rn = ReadCoreReg(n, &success); 10689 if (!success) 10690 return false; 10691 10692 addr_t offset_addr; 10693 if (add) 10694 offset_addr = Rn + imm32; 10695 else 10696 offset_addr = Rn - imm32; 10697 10698 // address = if index then offset_addr else R[n]; 10699 addr_t address; 10700 if (index) 10701 address = offset_addr; 10702 else 10703 address = Rn; 10704 10705 RegisterInfo base_reg; 10706 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10707 RegisterInfo data_reg; 10708 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10709 EmulateInstruction::Context context; 10710 context.type = eContextRegisterStore; 10711 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10712 10713 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10714 uint32_t Rt = ReadCoreReg(t, &success); 10715 if (!success) 10716 return false; 10717 10718 if (t == 15) { 10719 uint32_t pc_value = ReadCoreReg(PC_REG, &success); 10720 if (!success) 10721 return false; 10722 10723 if (!MemUWrite(context, address, pc_value, addr_byte_size)) 10724 return false; 10725 } else { 10726 if (!MemUWrite(context, address, Rt, addr_byte_size)) 10727 return false; 10728 } 10729 10730 // if wback then R[n] = offset_addr; 10731 if (wback) { 10732 context.type = eContextAdjustBaseRegister; 10733 context.SetImmediate(offset_addr); 10734 10735 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10736 offset_addr)) 10737 return false; 10738 } 10739 } 10740 return true; 10741} 10742 10743// A8.6.66 LDRD (immediate) 10744// Load Register Dual (immediate) calculates an address from a base register 10745// value and an immediate offset, loads two 10746// words from memory, and writes them to two registers. It can use offset, 10747// post-indexed, or pre-indexed addressing. 10748bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode, 10749 const ARMEncoding encoding) { 10750#if 0 10751 if ConditionPassed() then 10752 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10753 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10754 address = if index then offset_addr else R[n]; 10755 R[t] = MemA[address,4]; 10756 R[t2] = MemA[address+4,4]; 10757 if wback then R[n] = offset_addr; 10758#endif 10759 10760 bool success = false; 10761 10762 if (ConditionPassed(opcode)) { 10763 uint32_t t; 10764 uint32_t t2; 10765 uint32_t n; 10766 uint32_t imm32; 10767 bool index; 10768 bool add; 10769 bool wback; 10770 10771 switch (encoding) { 10772 case eEncodingT1: 10773 // if P == '0' && W == '0' then SEE 'Related encodings'; 10774 // if Rn == '1111' then SEE LDRD (literal); 10775 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10776 // ZeroExtend(imm8:'00', 32); 10777 t = Bits32(opcode, 15, 12); 10778 t2 = Bits32(opcode, 11, 8); 10779 n = Bits32(opcode, 19, 16); 10780 imm32 = Bits32(opcode, 7, 0) << 2; 10781 10782 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10783 index = BitIsSet(opcode, 24); 10784 add = BitIsSet(opcode, 23); 10785 wback = BitIsSet(opcode, 21); 10786 10787 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10788 if (wback && ((n == t) || (n == t2))) 10789 return false; 10790 10791 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10792 if (BadReg(t) || BadReg(t2) || (t == t2)) 10793 return false; 10794 10795 break; 10796 10797 case eEncodingA1: 10798 // if Rn == '1111' then SEE LDRD (literal); 10799 // if Rt<0> == '1' then UNPREDICTABLE; 10800 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10801 // 32); 10802 t = Bits32(opcode, 15, 12); 10803 if (BitIsSet(t, 0)) 10804 return false; 10805 t2 = t + 1; 10806 n = Bits32(opcode, 19, 16); 10807 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10808 10809 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10810 index = BitIsSet(opcode, 24); 10811 add = BitIsSet(opcode, 23); 10812 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10813 10814 // if P == '0' && W == '1' then UNPREDICTABLE; 10815 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10816 return false; 10817 10818 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10819 if (wback && ((n == t) || (n == t2))) 10820 return false; 10821 10822 // if t2 == 15 then UNPREDICTABLE; 10823 if (t2 == 15) 10824 return false; 10825 10826 break; 10827 10828 default: 10829 return false; 10830 } 10831 10832 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10833 uint32_t Rn = ReadCoreReg(n, &success); 10834 if (!success) 10835 return false; 10836 10837 addr_t offset_addr; 10838 if (add) 10839 offset_addr = Rn + imm32; 10840 else 10841 offset_addr = Rn - imm32; 10842 10843 // address = if index then offset_addr else R[n]; 10844 addr_t address; 10845 if (index) 10846 address = offset_addr; 10847 else 10848 address = Rn; 10849 10850 // R[t] = MemA[address,4]; 10851 RegisterInfo base_reg; 10852 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10853 10854 EmulateInstruction::Context context; 10855 if (n == 13) 10856 context.type = eContextPopRegisterOffStack; 10857 else 10858 context.type = eContextRegisterLoad; 10859 context.SetAddress(address); 10860 10861 const uint32_t addr_byte_size = GetAddressByteSize(); 10862 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10863 if (!success) 10864 return false; 10865 10866 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10867 return false; 10868 10869 // R[t2] = MemA[address+4,4]; 10870 context.SetAddress(address + 4); 10871 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10872 if (!success) 10873 return false; 10874 10875 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10876 data)) 10877 return false; 10878 10879 // if wback then R[n] = offset_addr; 10880 if (wback) { 10881 context.type = eContextAdjustBaseRegister; 10882 context.SetAddress(offset_addr); 10883 10884 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10885 offset_addr)) 10886 return false; 10887 } 10888 } 10889 return true; 10890} 10891 10892// A8.6.68 LDRD (register) 10893// Load Register Dual (register) calculates an address from a base register 10894// value and a register offset, loads two 10895// words from memory, and writes them to two registers. It can use offset, 10896// post-indexed or pre-indexed addressing. 10897bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode, 10898 const ARMEncoding encoding) { 10899#if 0 10900 if ConditionPassed() then 10901 EncodingSpecificOperations(); 10902 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10903 address = if index then offset_addr else R[n]; 10904 R[t] = MemA[address,4]; 10905 R[t2] = MemA[address+4,4]; 10906 if wback then R[n] = offset_addr; 10907#endif 10908 10909 bool success = false; 10910 10911 if (ConditionPassed(opcode)) { 10912 uint32_t t; 10913 uint32_t t2; 10914 uint32_t n; 10915 uint32_t m; 10916 bool index; 10917 bool add; 10918 bool wback; 10919 10920 switch (encoding) { 10921 case eEncodingA1: 10922 // if Rt<0> == '1' then UNPREDICTABLE; 10923 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10924 t = Bits32(opcode, 15, 12); 10925 if (BitIsSet(t, 0)) 10926 return false; 10927 t2 = t + 1; 10928 n = Bits32(opcode, 19, 16); 10929 m = Bits32(opcode, 3, 0); 10930 10931 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10932 index = BitIsSet(opcode, 24); 10933 add = BitIsSet(opcode, 23); 10934 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10935 10936 // if P == '0' && W == '1' then UNPREDICTABLE; 10937 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10938 return false; 10939 10940 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10941 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10942 return false; 10943 10944 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10945 if (wback && ((n == 15) || (n == t) || (n == t2))) 10946 return false; 10947 10948 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10949 if ((ArchVersion() < 6) && wback && (m == n)) 10950 return false; 10951 break; 10952 10953 default: 10954 return false; 10955 } 10956 10957 uint32_t Rn = ReadCoreReg(n, &success); 10958 if (!success) 10959 return false; 10960 RegisterInfo base_reg; 10961 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10962 10963 uint32_t Rm = ReadCoreReg(m, &success); 10964 if (!success) 10965 return false; 10966 RegisterInfo offset_reg; 10967 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10968 10969 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10970 addr_t offset_addr; 10971 if (add) 10972 offset_addr = Rn + Rm; 10973 else 10974 offset_addr = Rn - Rm; 10975 10976 // address = if index then offset_addr else R[n]; 10977 addr_t address; 10978 if (index) 10979 address = offset_addr; 10980 else 10981 address = Rn; 10982 10983 EmulateInstruction::Context context; 10984 if (n == 13) 10985 context.type = eContextPopRegisterOffStack; 10986 else 10987 context.type = eContextRegisterLoad; 10988 context.SetAddress(address); 10989 10990 // R[t] = MemA[address,4]; 10991 const uint32_t addr_byte_size = GetAddressByteSize(); 10992 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10993 if (!success) 10994 return false; 10995 10996 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10997 return false; 10998 10999 // R[t2] = MemA[address+4,4]; 11000 11001 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 11002 if (!success) 11003 return false; 11004 11005 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 11006 data)) 11007 return false; 11008 11009 // if wback then R[n] = offset_addr; 11010 if (wback) { 11011 context.type = eContextAdjustBaseRegister; 11012 context.SetAddress(offset_addr); 11013 11014 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11015 offset_addr)) 11016 return false; 11017 } 11018 } 11019 return true; 11020} 11021 11022// A8.6.200 STRD (immediate) 11023// Store Register Dual (immediate) calculates an address from a base register 11024// value and an immediate offset, and 11025// stores two words from two registers to memory. It can use offset, 11026// post-indexed, or pre-indexed addressing. 11027bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode, 11028 const ARMEncoding encoding) { 11029#if 0 11030 if ConditionPassed() then 11031 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 11032 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11033 address = if index then offset_addr else R[n]; 11034 MemA[address,4] = R[t]; 11035 MemA[address+4,4] = R[t2]; 11036 if wback then R[n] = offset_addr; 11037#endif 11038 11039 bool success = false; 11040 11041 if (ConditionPassed(opcode)) { 11042 uint32_t t; 11043 uint32_t t2; 11044 uint32_t n; 11045 uint32_t imm32; 11046 bool index; 11047 bool add; 11048 bool wback; 11049 11050 switch (encoding) { 11051 case eEncodingT1: 11052 // if P == '0' && W == '0' then SEE 'Related encodings'; 11053 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 11054 // ZeroExtend(imm8:'00', 32); 11055 t = Bits32(opcode, 15, 12); 11056 t2 = Bits32(opcode, 11, 8); 11057 n = Bits32(opcode, 19, 16); 11058 imm32 = Bits32(opcode, 7, 0) << 2; 11059 11060 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 11061 index = BitIsSet(opcode, 24); 11062 add = BitIsSet(opcode, 23); 11063 wback = BitIsSet(opcode, 21); 11064 11065 // if wback && (n == t || n == t2) then UNPREDICTABLE; 11066 if (wback && ((n == t) || (n == t2))) 11067 return false; 11068 11069 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 11070 if ((n == 15) || BadReg(t) || BadReg(t2)) 11071 return false; 11072 11073 break; 11074 11075 case eEncodingA1: 11076 // if Rt<0> == '1' then UNPREDICTABLE; 11077 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 11078 // 32); 11079 t = Bits32(opcode, 15, 12); 11080 if (BitIsSet(t, 0)) 11081 return false; 11082 11083 t2 = t + 1; 11084 n = Bits32(opcode, 19, 16); 11085 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 11086 11087 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11088 index = BitIsSet(opcode, 24); 11089 add = BitIsSet(opcode, 23); 11090 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11091 11092 // if P == '0' && W == '1' then UNPREDICTABLE; 11093 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11094 return false; 11095 11096 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11097 if (wback && ((n == 15) || (n == t) || (n == t2))) 11098 return false; 11099 11100 // if t2 == 15 then UNPREDICTABLE; 11101 if (t2 == 15) 11102 return false; 11103 11104 break; 11105 11106 default: 11107 return false; 11108 } 11109 11110 RegisterInfo base_reg; 11111 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11112 11113 uint32_t Rn = ReadCoreReg(n, &success); 11114 if (!success) 11115 return false; 11116 11117 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11118 addr_t offset_addr; 11119 if (add) 11120 offset_addr = Rn + imm32; 11121 else 11122 offset_addr = Rn - imm32; 11123 11124 // address = if index then offset_addr else R[n]; 11125 addr_t address; 11126 if (index) 11127 address = offset_addr; 11128 else 11129 address = Rn; 11130 11131 // MemA[address,4] = R[t]; 11132 RegisterInfo data_reg; 11133 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11134 11135 uint32_t data = ReadCoreReg(t, &success); 11136 if (!success) 11137 return false; 11138 11139 EmulateInstruction::Context context; 11140 if (n == 13) 11141 context.type = eContextPushRegisterOnStack; 11142 else 11143 context.type = eContextRegisterStore; 11144 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11145 11146 const uint32_t addr_byte_size = GetAddressByteSize(); 11147 11148 if (!MemAWrite(context, address, data, addr_byte_size)) 11149 return false; 11150 11151 // MemA[address+4,4] = R[t2]; 11152 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11153 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11154 (address + 4) - Rn); 11155 11156 data = ReadCoreReg(t2, &success); 11157 if (!success) 11158 return false; 11159 11160 if (!MemAWrite(context, address + 4, data, addr_byte_size)) 11161 return false; 11162 11163 // if wback then R[n] = offset_addr; 11164 if (wback) { 11165 if (n == 13) 11166 context.type = eContextAdjustStackPointer; 11167 else 11168 context.type = eContextAdjustBaseRegister; 11169 context.SetAddress(offset_addr); 11170 11171 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11172 offset_addr)) 11173 return false; 11174 } 11175 } 11176 return true; 11177} 11178 11179// A8.6.201 STRD (register) 11180bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode, 11181 const ARMEncoding encoding) { 11182#if 0 11183 if ConditionPassed() then 11184 EncodingSpecificOperations(); 11185 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11186 address = if index then offset_addr else R[n]; 11187 MemA[address,4] = R[t]; 11188 MemA[address+4,4] = R[t2]; 11189 if wback then R[n] = offset_addr; 11190#endif 11191 11192 bool success = false; 11193 11194 if (ConditionPassed(opcode)) { 11195 uint32_t t; 11196 uint32_t t2; 11197 uint32_t n; 11198 uint32_t m; 11199 bool index; 11200 bool add; 11201 bool wback; 11202 11203 switch (encoding) { 11204 case eEncodingA1: 11205 // if Rt<0> == '1' then UNPREDICTABLE; 11206 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 11207 t = Bits32(opcode, 15, 12); 11208 if (BitIsSet(t, 0)) 11209 return false; 11210 11211 t2 = t + 1; 11212 n = Bits32(opcode, 19, 16); 11213 m = Bits32(opcode, 3, 0); 11214 11215 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11216 index = BitIsSet(opcode, 24); 11217 add = BitIsSet(opcode, 23); 11218 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11219 11220 // if P == '0' && W == '1' then UNPREDICTABLE; 11221 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11222 return false; 11223 11224 // if t2 == 15 || m == 15 then UNPREDICTABLE; 11225 if ((t2 == 15) || (m == 15)) 11226 return false; 11227 11228 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11229 if (wback && ((n == 15) || (n == t) || (n == t2))) 11230 return false; 11231 11232 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 11233 if ((ArchVersion() < 6) && wback && (m == n)) 11234 return false; 11235 11236 break; 11237 11238 default: 11239 return false; 11240 } 11241 11242 RegisterInfo base_reg; 11243 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11244 RegisterInfo offset_reg; 11245 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 11246 RegisterInfo data_reg; 11247 11248 uint32_t Rn = ReadCoreReg(n, &success); 11249 if (!success) 11250 return false; 11251 11252 uint32_t Rm = ReadCoreReg(m, &success); 11253 if (!success) 11254 return false; 11255 11256 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11257 addr_t offset_addr; 11258 if (add) 11259 offset_addr = Rn + Rm; 11260 else 11261 offset_addr = Rn - Rm; 11262 11263 // address = if index then offset_addr else R[n]; 11264 addr_t address; 11265 if (index) 11266 address = offset_addr; 11267 else 11268 address = Rn; 11269 // MemA[address,4] = R[t]; 11270 uint32_t Rt = ReadCoreReg(t, &success); 11271 if (!success) 11272 return false; 11273 11274 EmulateInstruction::Context context; 11275 if (t == 13) 11276 context.type = eContextPushRegisterOnStack; 11277 else 11278 context.type = eContextRegisterStore; 11279 11280 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11281 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11282 data_reg); 11283 11284 const uint32_t addr_byte_size = GetAddressByteSize(); 11285 11286 if (!MemAWrite(context, address, Rt, addr_byte_size)) 11287 return false; 11288 11289 // MemA[address+4,4] = R[t2]; 11290 uint32_t Rt2 = ReadCoreReg(t2, &success); 11291 if (!success) 11292 return false; 11293 11294 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11295 11296 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11297 data_reg); 11298 11299 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size)) 11300 return false; 11301 11302 // if wback then R[n] = offset_addr; 11303 if (wback) { 11304 context.type = eContextAdjustBaseRegister; 11305 context.SetAddress(offset_addr); 11306 11307 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11308 offset_addr)) 11309 return false; 11310 } 11311 } 11312 return true; 11313} 11314 11315// A8.6.319 VLDM 11316// Vector Load Multiple loads multiple extension registers from consecutive 11317// memory locations using an address from 11318// an ARM core register. 11319bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode, 11320 const ARMEncoding encoding) { 11321#if 0 11322 if ConditionPassed() then 11323 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11324 address = if add then R[n] else R[n]-imm32; 11325 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11326 for r = 0 to regs-1 11327 if single_regs then 11328 S[d+r] = MemA[address,4]; address = address+4; 11329 else 11330 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 11331 // Combine the word-aligned words in the correct order for current endianness. 11332 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11333#endif 11334 11335 bool success = false; 11336 11337 if (ConditionPassed(opcode)) { 11338 bool single_regs; 11339 bool add; 11340 bool wback; 11341 uint32_t d; 11342 uint32_t n; 11343 uint32_t imm32; 11344 uint32_t regs; 11345 11346 switch (encoding) { 11347 case eEncodingT1: 11348 case eEncodingA1: 11349 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11350 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11351 // if P == '1' && W == '0' then SEE VLDR; 11352 // if P == U && W == '1' then UNDEFINED; 11353 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11354 return false; 11355 11356 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11357 // !), 101 (DB with !) 11358 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11359 single_regs = false; 11360 add = BitIsSet(opcode, 23); 11361 wback = BitIsSet(opcode, 21); 11362 11363 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11364 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11365 n = Bits32(opcode, 19, 16); 11366 imm32 = Bits32(opcode, 7, 0) << 2; 11367 11368 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 11369 regs = Bits32(opcode, 7, 0) / 2; 11370 11371 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11372 // UNPREDICTABLE; 11373 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 11374 return false; 11375 11376 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11377 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11378 return false; 11379 11380 break; 11381 11382 case eEncodingT2: 11383 case eEncodingA2: 11384 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11385 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11386 // if P == '1' && W == '0' then SEE VLDR; 11387 // if P == U && W == '1' then UNDEFINED; 11388 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11389 return false; 11390 11391 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11392 // !), 101 (DB with !) 11393 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = 11394 // UInt(Vd:D); n = UInt(Rn); 11395 single_regs = true; 11396 add = BitIsSet(opcode, 23); 11397 wback = BitIsSet(opcode, 21); 11398 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11399 n = Bits32(opcode, 19, 16); 11400 11401 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11402 imm32 = Bits32(opcode, 7, 0) << 2; 11403 regs = Bits32(opcode, 7, 0); 11404 11405 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11406 // UNPREDICTABLE; 11407 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11408 return false; 11409 11410 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11411 if ((regs == 0) || ((d + regs) > 32)) 11412 return false; 11413 break; 11414 11415 default: 11416 return false; 11417 } 11418 11419 RegisterInfo base_reg; 11420 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11421 11422 uint32_t Rn = ReadCoreReg(n, &success); 11423 if (!success) 11424 return false; 11425 11426 // address = if add then R[n] else R[n]-imm32; 11427 addr_t address; 11428 if (add) 11429 address = Rn; 11430 else 11431 address = Rn - imm32; 11432 11433 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11434 EmulateInstruction::Context context; 11435 11436 if (wback) { 11437 uint32_t value; 11438 if (add) 11439 value = Rn + imm32; 11440 else 11441 value = Rn - imm32; 11442 11443 context.type = eContextAdjustBaseRegister; 11444 context.SetImmediateSigned(value - Rn); 11445 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11446 value)) 11447 return false; 11448 } 11449 11450 const uint32_t addr_byte_size = GetAddressByteSize(); 11451 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11452 11453 context.type = eContextRegisterLoad; 11454 11455 // for r = 0 to regs-1 11456 for (uint32_t r = 0; r < regs; ++r) { 11457 if (single_regs) { 11458 // S[d+r] = MemA[address,4]; address = address+4; 11459 context.SetRegisterPlusOffset(base_reg, address - Rn); 11460 11461 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11462 if (!success) 11463 return false; 11464 11465 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11466 start_reg + d + r, data)) 11467 return false; 11468 11469 address = address + 4; 11470 } else { 11471 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = 11472 // address+8; 11473 context.SetRegisterPlusOffset(base_reg, address - Rn); 11474 uint32_t word1 = 11475 MemARead(context, address, addr_byte_size, 0, &success); 11476 if (!success) 11477 return false; 11478 11479 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn); 11480 uint32_t word2 = 11481 MemARead(context, address + 4, addr_byte_size, 0, &success); 11482 if (!success) 11483 return false; 11484 11485 address = address + 8; 11486 // // Combine the word-aligned words in the correct order for current 11487 // endianness. 11488 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11489 uint64_t data; 11490 if (GetByteOrder() == eByteOrderBig) { 11491 data = word1; 11492 data = (data << 32) | word2; 11493 } else { 11494 data = word2; 11495 data = (data << 32) | word1; 11496 } 11497 11498 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11499 start_reg + d + r, data)) 11500 return false; 11501 } 11502 } 11503 } 11504 return true; 11505} 11506 11507// A8.6.399 VSTM 11508// Vector Store Multiple stores multiple extension registers to consecutive 11509// memory locations using an address from an 11510// ARM core register. 11511bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode, 11512 const ARMEncoding encoding) { 11513#if 0 11514 if ConditionPassed() then 11515 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11516 address = if add then R[n] else R[n]-imm32; 11517 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11518 for r = 0 to regs-1 11519 if single_regs then 11520 MemA[address,4] = S[d+r]; address = address+4; 11521 else 11522 // Store as two word-aligned words in the correct order for current endianness. 11523 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11524 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11525 address = address+8; 11526#endif 11527 11528 bool success = false; 11529 11530 if (ConditionPassed(opcode)) { 11531 bool single_regs; 11532 bool add; 11533 bool wback; 11534 uint32_t d; 11535 uint32_t n; 11536 uint32_t imm32; 11537 uint32_t regs; 11538 11539 switch (encoding) { 11540 case eEncodingT1: 11541 case eEncodingA1: 11542 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11543 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11544 // if P == '1' && W == '0' then SEE VSTR; 11545 // if P == U && W == '1' then UNDEFINED; 11546 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11547 return false; 11548 11549 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11550 // !), 101 (DB with !) 11551 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11552 single_regs = false; 11553 add = BitIsSet(opcode, 23); 11554 wback = BitIsSet(opcode, 21); 11555 11556 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11557 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11558 n = Bits32(opcode, 19, 16); 11559 imm32 = Bits32(opcode, 7, 0) << 2; 11560 11561 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11562 regs = Bits32(opcode, 7, 0) / 2; 11563 11564 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11565 // UNPREDICTABLE; 11566 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11567 return false; 11568 11569 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11570 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11571 return false; 11572 11573 break; 11574 11575 case eEncodingT2: 11576 case eEncodingA2: 11577 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11578 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11579 // if P == '1' && W == '0' then SEE VSTR; 11580 // if P == U && W == '1' then UNDEFINED; 11581 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11582 return false; 11583 11584 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11585 // !), 101 (DB with !) 11586 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = 11587 // UInt(Vd:D); n = UInt(Rn); 11588 single_regs = true; 11589 add = BitIsSet(opcode, 23); 11590 wback = BitIsSet(opcode, 21); 11591 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11592 n = Bits32(opcode, 19, 16); 11593 11594 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11595 imm32 = Bits32(opcode, 7, 0) << 2; 11596 regs = Bits32(opcode, 7, 0); 11597 11598 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11599 // UNPREDICTABLE; 11600 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11601 return false; 11602 11603 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11604 if ((regs == 0) || ((d + regs) > 32)) 11605 return false; 11606 11607 break; 11608 11609 default: 11610 return false; 11611 } 11612 11613 RegisterInfo base_reg; 11614 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11615 11616 uint32_t Rn = ReadCoreReg(n, &success); 11617 if (!success) 11618 return false; 11619 11620 // address = if add then R[n] else R[n]-imm32; 11621 addr_t address; 11622 if (add) 11623 address = Rn; 11624 else 11625 address = Rn - imm32; 11626 11627 EmulateInstruction::Context context; 11628 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11629 if (wback) { 11630 uint32_t value; 11631 if (add) 11632 value = Rn + imm32; 11633 else 11634 value = Rn - imm32; 11635 11636 context.type = eContextAdjustBaseRegister; 11637 context.SetRegisterPlusOffset(base_reg, value - Rn); 11638 11639 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11640 value)) 11641 return false; 11642 } 11643 11644 const uint32_t addr_byte_size = GetAddressByteSize(); 11645 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11646 11647 context.type = eContextRegisterStore; 11648 // for r = 0 to regs-1 11649 for (uint32_t r = 0; r < regs; ++r) { 11650 11651 if (single_regs) { 11652 // MemA[address,4] = S[d+r]; address = address+4; 11653 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11654 start_reg + d + r, 0, &success); 11655 if (!success) 11656 return false; 11657 11658 RegisterInfo data_reg; 11659 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11660 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11661 address - Rn); 11662 if (!MemAWrite(context, address, data, addr_byte_size)) 11663 return false; 11664 11665 address = address + 4; 11666 } else { 11667 // // Store as two word-aligned words in the correct order for current 11668 // endianness. 11669 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else 11670 // D[d+r]<31:0>; 11671 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else 11672 // D[d+r]<63:32>; 11673 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11674 start_reg + d + r, 0, &success); 11675 if (!success) 11676 return false; 11677 11678 RegisterInfo data_reg; 11679 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11680 11681 if (GetByteOrder() == eByteOrderBig) { 11682 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11683 address - Rn); 11684 if (!MemAWrite(context, address, Bits64(data, 63, 32), 11685 addr_byte_size)) 11686 return false; 11687 11688 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11689 (address + 4) - Rn); 11690 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11691 addr_byte_size)) 11692 return false; 11693 } else { 11694 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11695 address - Rn); 11696 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11697 return false; 11698 11699 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11700 (address + 4) - Rn); 11701 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11702 addr_byte_size)) 11703 return false; 11704 } 11705 // address = address+8; 11706 address = address + 8; 11707 } 11708 } 11709 } 11710 return true; 11711} 11712 11713// A8.6.320 11714// This instruction loads a single extension register from memory, using an 11715// address from an ARM core register, with 11716// an optional offset. 11717bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode, 11718 ARMEncoding encoding) { 11719#if 0 11720 if ConditionPassed() then 11721 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11722 base = if n == 15 then Align(PC,4) else R[n]; 11723 address = if add then (base + imm32) else (base - imm32); 11724 if single_reg then 11725 S[d] = MemA[address,4]; 11726 else 11727 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11728 // Combine the word-aligned words in the correct order for current endianness. 11729 D[d] = if BigEndian() then word1:word2 else word2:word1; 11730#endif 11731 11732 bool success = false; 11733 11734 if (ConditionPassed(opcode)) { 11735 bool single_reg; 11736 bool add; 11737 uint32_t imm32; 11738 uint32_t d; 11739 uint32_t n; 11740 11741 switch (encoding) { 11742 case eEncodingT1: 11743 case eEncodingA1: 11744 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11745 // 32); 11746 single_reg = false; 11747 add = BitIsSet(opcode, 23); 11748 imm32 = Bits32(opcode, 7, 0) << 2; 11749 11750 // d = UInt(D:Vd); n = UInt(Rn); 11751 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11752 n = Bits32(opcode, 19, 16); 11753 11754 break; 11755 11756 case eEncodingT2: 11757 case eEncodingA2: 11758 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11759 single_reg = true; 11760 add = BitIsSet(opcode, 23); 11761 imm32 = Bits32(opcode, 7, 0) << 2; 11762 11763 // d = UInt(Vd:D); n = UInt(Rn); 11764 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11765 n = Bits32(opcode, 19, 16); 11766 11767 break; 11768 11769 default: 11770 return false; 11771 } 11772 RegisterInfo base_reg; 11773 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11774 11775 uint32_t Rn = ReadCoreReg(n, &success); 11776 if (!success) 11777 return false; 11778 11779 // base = if n == 15 then Align(PC,4) else R[n]; 11780 uint32_t base; 11781 if (n == 15) 11782 base = AlignPC(Rn); 11783 else 11784 base = Rn; 11785 11786 // address = if add then (base + imm32) else (base - imm32); 11787 addr_t address; 11788 if (add) 11789 address = base + imm32; 11790 else 11791 address = base - imm32; 11792 11793 const uint32_t addr_byte_size = GetAddressByteSize(); 11794 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11795 11796 EmulateInstruction::Context context; 11797 context.type = eContextRegisterLoad; 11798 context.SetRegisterPlusOffset(base_reg, address - base); 11799 11800 if (single_reg) { 11801 // S[d] = MemA[address,4]; 11802 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11803 if (!success) 11804 return false; 11805 11806 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11807 data)) 11808 return false; 11809 } else { 11810 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11811 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success); 11812 if (!success) 11813 return false; 11814 11815 context.SetRegisterPlusOffset(base_reg, (address + 4) - base); 11816 uint32_t word2 = 11817 MemARead(context, address + 4, addr_byte_size, 0, &success); 11818 if (!success) 11819 return false; 11820 // // Combine the word-aligned words in the correct order for current 11821 // endianness. 11822 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11823 uint64_t data64; 11824 if (GetByteOrder() == eByteOrderBig) { 11825 data64 = word1; 11826 data64 = (data64 << 32) | word2; 11827 } else { 11828 data64 = word2; 11829 data64 = (data64 << 32) | word1; 11830 } 11831 11832 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11833 data64)) 11834 return false; 11835 } 11836 } 11837 return true; 11838} 11839 11840// A8.6.400 VSTR 11841// This instruction stores a signle extension register to memory, using an 11842// address from an ARM core register, with an 11843// optional offset. 11844bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode, 11845 ARMEncoding encoding) { 11846#if 0 11847 if ConditionPassed() then 11848 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11849 address = if add then (R[n] + imm32) else (R[n] - imm32); 11850 if single_reg then 11851 MemA[address,4] = S[d]; 11852 else 11853 // Store as two word-aligned words in the correct order for current endianness. 11854 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11855 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11856#endif 11857 11858 bool success = false; 11859 11860 if (ConditionPassed(opcode)) { 11861 bool single_reg; 11862 bool add; 11863 uint32_t imm32; 11864 uint32_t d; 11865 uint32_t n; 11866 11867 switch (encoding) { 11868 case eEncodingT1: 11869 case eEncodingA1: 11870 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11871 // 32); 11872 single_reg = false; 11873 add = BitIsSet(opcode, 23); 11874 imm32 = Bits32(opcode, 7, 0) << 2; 11875 11876 // d = UInt(D:Vd); n = UInt(Rn); 11877 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11878 n = Bits32(opcode, 19, 16); 11879 11880 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11881 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11882 return false; 11883 11884 break; 11885 11886 case eEncodingT2: 11887 case eEncodingA2: 11888 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11889 single_reg = true; 11890 add = BitIsSet(opcode, 23); 11891 imm32 = Bits32(opcode, 7, 0) << 2; 11892 11893 // d = UInt(Vd:D); n = UInt(Rn); 11894 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11895 n = Bits32(opcode, 19, 16); 11896 11897 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11898 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11899 return false; 11900 11901 break; 11902 11903 default: 11904 return false; 11905 } 11906 11907 RegisterInfo base_reg; 11908 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11909 11910 uint32_t Rn = ReadCoreReg(n, &success); 11911 if (!success) 11912 return false; 11913 11914 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11915 addr_t address; 11916 if (add) 11917 address = Rn + imm32; 11918 else 11919 address = Rn - imm32; 11920 11921 const uint32_t addr_byte_size = GetAddressByteSize(); 11922 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11923 11924 RegisterInfo data_reg; 11925 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg); 11926 EmulateInstruction::Context context; 11927 context.type = eContextRegisterStore; 11928 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11929 11930 if (single_reg) { 11931 // MemA[address,4] = S[d]; 11932 uint32_t data = 11933 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11934 if (!success) 11935 return false; 11936 11937 if (!MemAWrite(context, address, data, addr_byte_size)) 11938 return false; 11939 } else { 11940 // // Store as two word-aligned words in the correct order for current 11941 // endianness. 11942 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11943 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11944 uint64_t data = 11945 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11946 if (!success) 11947 return false; 11948 11949 if (GetByteOrder() == eByteOrderBig) { 11950 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size)) 11951 return false; 11952 11953 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11954 (address + 4) - Rn); 11955 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11956 addr_byte_size)) 11957 return false; 11958 } else { 11959 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11960 return false; 11961 11962 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11963 (address + 4) - Rn); 11964 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11965 addr_byte_size)) 11966 return false; 11967 } 11968 } 11969 } 11970 return true; 11971} 11972 11973// A8.6.307 VLDI1 (multiple single elements) 11974// This instruction loads elements from memory into one, two, three or four 11975// registers, without de-interleaving. Every 11976// element of each register is loaded. 11977bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode, 11978 ARMEncoding encoding) { 11979#if 0 11980 if ConditionPassed() then 11981 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11982 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11983 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11984 for r = 0 to regs-1 11985 for e = 0 to elements-1 11986 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11987 address = address + ebytes; 11988#endif 11989 11990 bool success = false; 11991 11992 if (ConditionPassed(opcode)) { 11993 uint32_t regs; 11994 uint32_t alignment; 11995 uint32_t ebytes; 11996 uint32_t esize; 11997 uint32_t elements; 11998 uint32_t d; 11999 uint32_t n; 12000 uint32_t m; 12001 bool wback; 12002 bool register_index; 12003 12004 switch (encoding) { 12005 case eEncodingT1: 12006 case eEncodingA1: { 12007 // case type of 12008 // when '0111' 12009 // regs = 1; if align<1> == '1' then UNDEFINED; 12010 // when '1010' 12011 // regs = 2; if align == '11' then UNDEFINED; 12012 // when '0110' 12013 // regs = 3; if align<1> == '1' then UNDEFINED; 12014 // when '0010' 12015 // regs = 4; 12016 // otherwise 12017 // SEE 'Related encodings'; 12018 uint32_t type = Bits32(opcode, 11, 8); 12019 uint32_t align = Bits32(opcode, 5, 4); 12020 if (type == 7) // '0111' 12021 { 12022 regs = 1; 12023 if (BitIsSet(align, 1)) 12024 return false; 12025 } else if (type == 10) // '1010' 12026 { 12027 regs = 2; 12028 if (align == 3) 12029 return false; 12030 12031 } else if (type == 6) // '0110' 12032 { 12033 regs = 3; 12034 if (BitIsSet(align, 1)) 12035 return false; 12036 } else if (type == 2) // '0010' 12037 { 12038 regs = 4; 12039 } else 12040 return false; 12041 12042 // alignment = if align == '00' then 1 else 4 << UInt(align); 12043 if (align == 0) 12044 alignment = 1; 12045 else 12046 alignment = 4 << align; 12047 12048 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 12049 ebytes = 1 << Bits32(opcode, 7, 6); 12050 esize = 8 * ebytes; 12051 elements = 8 / ebytes; 12052 12053 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12054 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12055 n = Bits32(opcode, 19, 15); 12056 m = Bits32(opcode, 3, 0); 12057 12058 // wback = (m != 15); register_index = (m != 15 && m != 13); 12059 wback = (m != 15); 12060 register_index = ((m != 15) && (m != 13)); 12061 12062 // if d+regs > 32 then UNPREDICTABLE; 12063 if ((d + regs) > 32) 12064 return false; 12065 } break; 12066 12067 default: 12068 return false; 12069 } 12070 12071 RegisterInfo base_reg; 12072 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12073 12074 uint32_t Rn = ReadCoreReg(n, &success); 12075 if (!success) 12076 return false; 12077 12078 // address = R[n]; if (address MOD alignment) != 0 then 12079 // GenerateAlignmentException(); 12080 addr_t address = Rn; 12081 if ((address % alignment) != 0) 12082 return false; 12083 12084 EmulateInstruction::Context context; 12085 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12086 if (wback) { 12087 uint32_t Rm = ReadCoreReg(m, &success); 12088 if (!success) 12089 return false; 12090 12091 uint32_t offset; 12092 if (register_index) 12093 offset = Rm; 12094 else 12095 offset = 8 * regs; 12096 12097 uint32_t value = Rn + offset; 12098 context.type = eContextAdjustBaseRegister; 12099 context.SetRegisterPlusOffset(base_reg, offset); 12100 12101 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12102 value)) 12103 return false; 12104 } 12105 12106 // for r = 0 to regs-1 12107 for (uint32_t r = 0; r < regs; ++r) { 12108 // for e = 0 to elements-1 12109 uint64_t assembled_data = 0; 12110 for (uint32_t e = 0; e < elements; ++e) { 12111 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 12112 context.type = eContextRegisterLoad; 12113 context.SetRegisterPlusOffset(base_reg, address - Rn); 12114 uint64_t data = MemURead(context, address, ebytes, 0, &success); 12115 if (!success) 12116 return false; 12117 12118 assembled_data = 12119 (data << (e * esize)) | 12120 assembled_data; // New data goes to the left of existing data 12121 12122 // address = address + ebytes; 12123 address = address + ebytes; 12124 } 12125 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12126 assembled_data)) 12127 return false; 12128 } 12129 } 12130 return true; 12131} 12132 12133// A8.6.308 VLD1 (single element to one lane) 12134// 12135bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode, 12136 const ARMEncoding encoding) { 12137#if 0 12138 if ConditionPassed() then 12139 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12140 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12141 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12142 Elem[D[d],index,esize] = MemU[address,ebytes]; 12143#endif 12144 12145 bool success = false; 12146 12147 if (ConditionPassed(opcode)) { 12148 uint32_t ebytes; 12149 uint32_t esize; 12150 uint32_t index; 12151 uint32_t alignment; 12152 uint32_t d; 12153 uint32_t n; 12154 uint32_t m; 12155 bool wback; 12156 bool register_index; 12157 12158 switch (encoding) { 12159 case eEncodingT1: 12160 case eEncodingA1: { 12161 uint32_t size = Bits32(opcode, 11, 10); 12162 uint32_t index_align = Bits32(opcode, 7, 4); 12163 // if size == '11' then SEE VLD1 (single element to all lanes); 12164 if (size == 3) 12165 return EmulateVLD1SingleAll(opcode, encoding); 12166 // case size of 12167 if (size == 0) // when '00' 12168 { 12169 // if index_align<0> != '0' then UNDEFINED; 12170 if (BitIsClear(index_align, 0)) 12171 return false; 12172 12173 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12174 ebytes = 1; 12175 esize = 8; 12176 index = Bits32(index_align, 3, 1); 12177 alignment = 1; 12178 } else if (size == 1) // when '01' 12179 { 12180 // if index_align<1> != '0' then UNDEFINED; 12181 if (BitIsClear(index_align, 1)) 12182 return false; 12183 12184 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12185 ebytes = 2; 12186 esize = 16; 12187 index = Bits32(index_align, 3, 2); 12188 12189 // alignment = if index_align<0> == '0' then 1 else 2; 12190 if (BitIsClear(index_align, 0)) 12191 alignment = 1; 12192 else 12193 alignment = 2; 12194 } else if (size == 2) // when '10' 12195 { 12196 // if index_align<2> != '0' then UNDEFINED; 12197 if (BitIsClear(index_align, 2)) 12198 return false; 12199 12200 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12201 // UNDEFINED; 12202 if ((Bits32(index_align, 1, 0) != 0) && 12203 (Bits32(index_align, 1, 0) != 3)) 12204 return false; 12205 12206 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12207 ebytes = 4; 12208 esize = 32; 12209 index = Bit32(index_align, 3); 12210 12211 // alignment = if index_align<1:0> == '00' then 1 else 4; 12212 if (Bits32(index_align, 1, 0) == 0) 12213 alignment = 1; 12214 else 12215 alignment = 4; 12216 } else { 12217 return false; 12218 } 12219 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12220 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12221 n = Bits32(opcode, 19, 16); 12222 m = Bits32(opcode, 3, 0); 12223 12224 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12225 // then UNPREDICTABLE; 12226 wback = (m != 15); 12227 register_index = ((m != 15) && (m != 13)); 12228 12229 if (n == 15) 12230 return false; 12231 12232 } break; 12233 12234 default: 12235 return false; 12236 } 12237 12238 RegisterInfo base_reg; 12239 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12240 12241 uint32_t Rn = ReadCoreReg(n, &success); 12242 if (!success) 12243 return false; 12244 12245 // address = R[n]; if (address MOD alignment) != 0 then 12246 // GenerateAlignmentException(); 12247 addr_t address = Rn; 12248 if ((address % alignment) != 0) 12249 return false; 12250 12251 EmulateInstruction::Context context; 12252 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12253 if (wback) { 12254 uint32_t Rm = ReadCoreReg(m, &success); 12255 if (!success) 12256 return false; 12257 12258 uint32_t offset; 12259 if (register_index) 12260 offset = Rm; 12261 else 12262 offset = ebytes; 12263 12264 uint32_t value = Rn + offset; 12265 12266 context.type = eContextAdjustBaseRegister; 12267 context.SetRegisterPlusOffset(base_reg, offset); 12268 12269 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12270 value)) 12271 return false; 12272 } 12273 12274 // Elem[D[d],index,esize] = MemU[address,ebytes]; 12275 uint32_t element = MemURead(context, address, esize, 0, &success); 12276 if (!success) 12277 return false; 12278 12279 element = element << (index * esize); 12280 12281 uint64_t reg_data = 12282 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12283 if (!success) 12284 return false; 12285 12286 uint64_t all_ones = -1; 12287 uint64_t mask = all_ones 12288 << ((index + 1) * esize); // mask is all 1's to left of 12289 // where 'element' goes, & all 0's 12290 // at element & to the right of element. 12291 if (index > 0) 12292 mask = mask | Bits64(all_ones, (index * esize) - 1, 12293 0); // add 1's to the right of where 'element' goes. 12294 // now mask should be 0's where element goes & 1's 12295 // everywhere else. 12296 12297 uint64_t masked_reg = 12298 reg_data & mask; // Take original reg value & zero out 'element' bits 12299 reg_data = 12300 masked_reg & element; // Put 'element' into those bits in reg_data. 12301 12302 context.type = eContextRegisterLoad; 12303 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 12304 reg_data)) 12305 return false; 12306 } 12307 return true; 12308} 12309 12310// A8.6.391 VST1 (multiple single elements) 12311// Vector Store (multiple single elements) stores elements to memory from one, 12312// two, three, or four registers, without 12313// interleaving. Every element of each register is stored. 12314bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode, 12315 ARMEncoding encoding) { 12316#if 0 12317 if ConditionPassed() then 12318 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12319 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12320 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12321 for r = 0 to regs-1 12322 for e = 0 to elements-1 12323 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12324 address = address + ebytes; 12325#endif 12326 12327 bool success = false; 12328 12329 if (ConditionPassed(opcode)) { 12330 uint32_t regs; 12331 uint32_t alignment; 12332 uint32_t ebytes; 12333 uint32_t esize; 12334 uint32_t elements; 12335 uint32_t d; 12336 uint32_t n; 12337 uint32_t m; 12338 bool wback; 12339 bool register_index; 12340 12341 switch (encoding) { 12342 case eEncodingT1: 12343 case eEncodingA1: { 12344 uint32_t type = Bits32(opcode, 11, 8); 12345 uint32_t align = Bits32(opcode, 5, 4); 12346 12347 // case type of 12348 if (type == 7) // when '0111' 12349 { 12350 // regs = 1; if align<1> == '1' then UNDEFINED; 12351 regs = 1; 12352 if (BitIsSet(align, 1)) 12353 return false; 12354 } else if (type == 10) // when '1010' 12355 { 12356 // regs = 2; if align == '11' then UNDEFINED; 12357 regs = 2; 12358 if (align == 3) 12359 return false; 12360 } else if (type == 6) // when '0110' 12361 { 12362 // regs = 3; if align<1> == '1' then UNDEFINED; 12363 regs = 3; 12364 if (BitIsSet(align, 1)) 12365 return false; 12366 } else if (type == 2) // when '0010' 12367 // regs = 4; 12368 regs = 4; 12369 else // otherwise 12370 // SEE 'Related encodings'; 12371 return false; 12372 12373 // alignment = if align == '00' then 1 else 4 << UInt(align); 12374 if (align == 0) 12375 alignment = 1; 12376 else 12377 alignment = 4 << align; 12378 12379 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 12380 ebytes = 1 << Bits32(opcode, 7, 6); 12381 esize = 8 * ebytes; 12382 elements = 8 / ebytes; 12383 12384 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12385 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12386 n = Bits32(opcode, 19, 16); 12387 m = Bits32(opcode, 3, 0); 12388 12389 // wback = (m != 15); register_index = (m != 15 && m != 13); 12390 wback = (m != 15); 12391 register_index = ((m != 15) && (m != 13)); 12392 12393 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12394 if ((d + regs) > 32) 12395 return false; 12396 12397 if (n == 15) 12398 return false; 12399 12400 } break; 12401 12402 default: 12403 return false; 12404 } 12405 12406 RegisterInfo base_reg; 12407 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12408 12409 uint32_t Rn = ReadCoreReg(n, &success); 12410 if (!success) 12411 return false; 12412 12413 // address = R[n]; if (address MOD alignment) != 0 then 12414 // GenerateAlignmentException(); 12415 addr_t address = Rn; 12416 if ((address % alignment) != 0) 12417 return false; 12418 12419 EmulateInstruction::Context context; 12420 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12421 if (wback) { 12422 uint32_t Rm = ReadCoreReg(m, &success); 12423 if (!success) 12424 return false; 12425 12426 uint32_t offset; 12427 if (register_index) 12428 offset = Rm; 12429 else 12430 offset = 8 * regs; 12431 12432 context.type = eContextAdjustBaseRegister; 12433 context.SetRegisterPlusOffset(base_reg, offset); 12434 12435 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12436 Rn + offset)) 12437 return false; 12438 } 12439 12440 RegisterInfo data_reg; 12441 context.type = eContextRegisterStore; 12442 // for r = 0 to regs-1 12443 for (uint32_t r = 0; r < regs; ++r) { 12444 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 12445 uint64_t register_data = ReadRegisterUnsigned( 12446 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 12447 if (!success) 12448 return false; 12449 12450 // for e = 0 to elements-1 12451 for (uint32_t e = 0; e < elements; ++e) { 12452 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12453 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize); 12454 12455 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12456 address - Rn); 12457 if (!MemUWrite(context, address, word, ebytes)) 12458 return false; 12459 12460 // address = address + ebytes; 12461 address = address + ebytes; 12462 } 12463 } 12464 } 12465 return true; 12466} 12467 12468// A8.6.392 VST1 (single element from one lane) 12469// This instruction stores one element to memory from one element of a register. 12470bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode, 12471 ARMEncoding encoding) { 12472#if 0 12473 if ConditionPassed() then 12474 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12475 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12476 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12477 MemU[address,ebytes] = Elem[D[d],index,esize]; 12478#endif 12479 12480 bool success = false; 12481 12482 if (ConditionPassed(opcode)) { 12483 uint32_t ebytes; 12484 uint32_t esize; 12485 uint32_t index; 12486 uint32_t alignment; 12487 uint32_t d; 12488 uint32_t n; 12489 uint32_t m; 12490 bool wback; 12491 bool register_index; 12492 12493 switch (encoding) { 12494 case eEncodingT1: 12495 case eEncodingA1: { 12496 uint32_t size = Bits32(opcode, 11, 10); 12497 uint32_t index_align = Bits32(opcode, 7, 4); 12498 12499 // if size == '11' then UNDEFINED; 12500 if (size == 3) 12501 return false; 12502 12503 // case size of 12504 if (size == 0) // when '00' 12505 { 12506 // if index_align<0> != '0' then UNDEFINED; 12507 if (BitIsClear(index_align, 0)) 12508 return false; 12509 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12510 ebytes = 1; 12511 esize = 8; 12512 index = Bits32(index_align, 3, 1); 12513 alignment = 1; 12514 } else if (size == 1) // when '01' 12515 { 12516 // if index_align<1> != '0' then UNDEFINED; 12517 if (BitIsClear(index_align, 1)) 12518 return false; 12519 12520 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12521 ebytes = 2; 12522 esize = 16; 12523 index = Bits32(index_align, 3, 2); 12524 12525 // alignment = if index_align<0> == '0' then 1 else 2; 12526 if (BitIsClear(index_align, 0)) 12527 alignment = 1; 12528 else 12529 alignment = 2; 12530 } else if (size == 2) // when '10' 12531 { 12532 // if index_align<2> != '0' then UNDEFINED; 12533 if (BitIsClear(index_align, 2)) 12534 return false; 12535 12536 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12537 // UNDEFINED; 12538 if ((Bits32(index_align, 1, 0) != 0) && 12539 (Bits32(index_align, 1, 0) != 3)) 12540 return false; 12541 12542 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12543 ebytes = 4; 12544 esize = 32; 12545 index = Bit32(index_align, 3); 12546 12547 // alignment = if index_align<1:0> == '00' then 1 else 4; 12548 if (Bits32(index_align, 1, 0) == 0) 12549 alignment = 1; 12550 else 12551 alignment = 4; 12552 } else { 12553 return false; 12554 } 12555 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12556 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12557 n = Bits32(opcode, 19, 16); 12558 m = Bits32(opcode, 3, 0); 12559 12560 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12561 // then UNPREDICTABLE; 12562 wback = (m != 15); 12563 register_index = ((m != 15) && (m != 13)); 12564 12565 if (n == 15) 12566 return false; 12567 } break; 12568 12569 default: 12570 return false; 12571 } 12572 12573 RegisterInfo base_reg; 12574 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12575 12576 uint32_t Rn = ReadCoreReg(n, &success); 12577 if (!success) 12578 return false; 12579 12580 // address = R[n]; if (address MOD alignment) != 0 then 12581 // GenerateAlignmentException(); 12582 addr_t address = Rn; 12583 if ((address % alignment) != 0) 12584 return false; 12585 12586 EmulateInstruction::Context context; 12587 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12588 if (wback) { 12589 uint32_t Rm = ReadCoreReg(m, &success); 12590 if (!success) 12591 return false; 12592 12593 uint32_t offset; 12594 if (register_index) 12595 offset = Rm; 12596 else 12597 offset = ebytes; 12598 12599 context.type = eContextAdjustBaseRegister; 12600 context.SetRegisterPlusOffset(base_reg, offset); 12601 12602 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12603 Rn + offset)) 12604 return false; 12605 } 12606 12607 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12608 uint64_t register_data = 12609 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12610 if (!success) 12611 return false; 12612 12613 uint64_t word = 12614 Bits64(register_data, ((index + 1) * esize) - 1, index * esize); 12615 12616 RegisterInfo data_reg; 12617 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12618 context.type = eContextRegisterStore; 12619 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 12620 12621 if (!MemUWrite(context, address, word, ebytes)) 12622 return false; 12623 } 12624 return true; 12625} 12626 12627// A8.6.309 VLD1 (single element to all lanes) 12628// This instruction loads one element from memory into every element of one or 12629// two vectors. 12630bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode, 12631 const ARMEncoding encoding) { 12632#if 0 12633 if ConditionPassed() then 12634 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12635 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12636 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12637 replicated_element = Replicate(MemU[address,ebytes], elements); 12638 for r = 0 to regs-1 12639 D[d+r] = replicated_element; 12640#endif 12641 12642 bool success = false; 12643 12644 if (ConditionPassed(opcode)) { 12645 uint32_t ebytes; 12646 uint32_t elements; 12647 uint32_t regs; 12648 uint32_t alignment; 12649 uint32_t d; 12650 uint32_t n; 12651 uint32_t m; 12652 bool wback; 12653 bool register_index; 12654 12655 switch (encoding) { 12656 case eEncodingT1: 12657 case eEncodingA1: { 12658 // if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12659 uint32_t size = Bits32(opcode, 7, 6); 12660 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4))) 12661 return false; 12662 12663 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' 12664 // then 1 else 2; 12665 ebytes = 1 << size; 12666 elements = 8 / ebytes; 12667 if (BitIsClear(opcode, 5)) 12668 regs = 1; 12669 else 12670 regs = 2; 12671 12672 // alignment = if a == '0' then 1 else ebytes; 12673 if (BitIsClear(opcode, 4)) 12674 alignment = 1; 12675 else 12676 alignment = ebytes; 12677 12678 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12679 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12680 n = Bits32(opcode, 19, 16); 12681 m = Bits32(opcode, 3, 0); 12682 12683 // wback = (m != 15); register_index = (m != 15 && m != 13); 12684 wback = (m != 15); 12685 register_index = ((m != 15) && (m != 13)); 12686 12687 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12688 if ((d + regs) > 32) 12689 return false; 12690 12691 if (n == 15) 12692 return false; 12693 } break; 12694 12695 default: 12696 return false; 12697 } 12698 12699 RegisterInfo base_reg; 12700 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12701 12702 uint32_t Rn = ReadCoreReg(n, &success); 12703 if (!success) 12704 return false; 12705 12706 // address = R[n]; if (address MOD alignment) != 0 then 12707 // GenerateAlignmentException(); 12708 addr_t address = Rn; 12709 if ((address % alignment) != 0) 12710 return false; 12711 12712 EmulateInstruction::Context context; 12713 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12714 if (wback) { 12715 uint32_t Rm = ReadCoreReg(m, &success); 12716 if (!success) 12717 return false; 12718 12719 uint32_t offset; 12720 if (register_index) 12721 offset = Rm; 12722 else 12723 offset = ebytes; 12724 12725 context.type = eContextAdjustBaseRegister; 12726 context.SetRegisterPlusOffset(base_reg, offset); 12727 12728 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12729 Rn + offset)) 12730 return false; 12731 } 12732 12733 // replicated_element = Replicate(MemU[address,ebytes], elements); 12734 12735 context.type = eContextRegisterLoad; 12736 uint64_t word = MemURead(context, address, ebytes, 0, &success); 12737 if (!success) 12738 return false; 12739 12740 uint64_t replicated_element = 0; 12741 uint32_t esize = ebytes * 8; 12742 for (uint32_t e = 0; e < elements; ++e) 12743 replicated_element = 12744 (replicated_element << esize) | Bits64(word, esize - 1, 0); 12745 12746 // for r = 0 to regs-1 12747 for (uint32_t r = 0; r < regs; ++r) { 12748 // D[d+r] = replicated_element; 12749 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12750 replicated_element)) 12751 return false; 12752 } 12753 } 12754 return true; 12755} 12756 12757// B6.2.13 SUBS PC, LR and related instructions 12758// The SUBS PC, LR, #<const? instruction provides an exception return without 12759// the use of the stack. It subtracts the 12760// immediate constant from the LR, branches to the resulting address, and also 12761// copies the SPSR to the CPSR. 12762bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode, 12763 const ARMEncoding encoding) { 12764#if 0 12765 if ConditionPassed() then 12766 EncodingSpecificOperations(); 12767 if CurrentInstrSet() == InstrSet_ThumbEE then 12768 UNPREDICTABLE; 12769 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12770 case opcode of 12771 when '0000' result = R[n] AND operand2; // AND 12772 when '0001' result = R[n] EOR operand2; // EOR 12773 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12774 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12775 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12776 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12777 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12778 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12779 when '1100' result = R[n] OR operand2; // ORR 12780 when '1101' result = operand2; // MOV 12781 when '1110' result = R[n] AND NOT(operand2); // BIC 12782 when '1111' result = NOT(operand2); // MVN 12783 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12784 BranchWritePC(result); 12785#endif 12786 12787 bool success = false; 12788 12789 if (ConditionPassed(opcode)) { 12790 uint32_t n; 12791 uint32_t m; 12792 uint32_t imm32; 12793 bool register_form; 12794 ARM_ShifterType shift_t; 12795 uint32_t shift_n; 12796 uint32_t code; 12797 12798 switch (encoding) { 12799 case eEncodingT1: 12800 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12801 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = 12802 // '0010'; // = SUB 12803 n = 14; 12804 imm32 = Bits32(opcode, 7, 0); 12805 register_form = false; 12806 code = 2; 12807 12808 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12809 if (InITBlock() && !LastInITBlock()) 12810 return false; 12811 12812 break; 12813 12814 case eEncodingA1: 12815 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12816 n = Bits32(opcode, 19, 16); 12817 imm32 = ARMExpandImm(opcode); 12818 register_form = false; 12819 code = Bits32(opcode, 24, 21); 12820 12821 break; 12822 12823 case eEncodingA2: 12824 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12825 n = Bits32(opcode, 19, 16); 12826 m = Bits32(opcode, 3, 0); 12827 register_form = true; 12828 12829 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12830 shift_n = DecodeImmShiftARM(opcode, shift_t); 12831 12832 break; 12833 12834 default: 12835 return false; 12836 } 12837 12838 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) 12839 // else imm32; 12840 uint32_t operand2; 12841 if (register_form) { 12842 uint32_t Rm = ReadCoreReg(m, &success); 12843 if (!success) 12844 return false; 12845 12846 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success); 12847 if (!success) 12848 return false; 12849 } else { 12850 operand2 = imm32; 12851 } 12852 12853 uint32_t Rn = ReadCoreReg(n, &success); 12854 if (!success) 12855 return false; 12856 12857 AddWithCarryResult result; 12858 12859 // case opcode of 12860 switch (code) { 12861 case 0: // when '0000' 12862 // result = R[n] AND operand2; // AND 12863 result.result = Rn & operand2; 12864 break; 12865 12866 case 1: // when '0001' 12867 // result = R[n] EOR operand2; // EOR 12868 result.result = Rn ^ operand2; 12869 break; 12870 12871 case 2: // when '0010' 12872 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12873 result = AddWithCarry(Rn, ~(operand2), 1); 12874 break; 12875 12876 case 3: // when '0011' 12877 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12878 result = AddWithCarry(~(Rn), operand2, 1); 12879 break; 12880 12881 case 4: // when '0100' 12882 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12883 result = AddWithCarry(Rn, operand2, 0); 12884 break; 12885 12886 case 5: // when '0101' 12887 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12888 result = AddWithCarry(Rn, operand2, APSR_C); 12889 break; 12890 12891 case 6: // when '0110' 12892 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12893 result = AddWithCarry(Rn, ~(operand2), APSR_C); 12894 break; 12895 12896 case 7: // when '0111' 12897 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12898 result = AddWithCarry(~(Rn), operand2, APSR_C); 12899 break; 12900 12901 case 10: // when '1100' 12902 // result = R[n] OR operand2; // ORR 12903 result.result = Rn | operand2; 12904 break; 12905 12906 case 11: // when '1101' 12907 // result = operand2; // MOV 12908 result.result = operand2; 12909 break; 12910 12911 case 12: // when '1110' 12912 // result = R[n] AND NOT(operand2); // BIC 12913 result.result = Rn & ~(operand2); 12914 break; 12915 12916 case 15: // when '1111' 12917 // result = NOT(operand2); // MVN 12918 result.result = ~(operand2); 12919 break; 12920 12921 default: 12922 return false; 12923 } 12924 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12925 12926 // For now, in emulation mode, we don't have access to the SPSR, so we will 12927 // use the CPSR instead, and hope for 12928 // the best. 12929 uint32_t spsr = 12930 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12931 if (!success) 12932 return false; 12933 12934 CPSRWriteByInstr(spsr, 15, true); 12935 12936 // BranchWritePC(result); 12937 EmulateInstruction::Context context; 12938 context.type = eContextAdjustPC; 12939 context.SetImmediate(result.result); 12940 12941 BranchWritePC(context, result.result); 12942 } 12943 return true; 12944} 12945 12946EmulateInstructionARM::ARMOpcode * 12947EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode, 12948 uint32_t arm_isa) { 12949 static ARMOpcode g_arm_opcodes[] = { 12950 //---------------------------------------------------------------------- 12951 // Prologue instructions 12952 //---------------------------------------------------------------------- 12953 12954 // push register(s) 12955 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12956 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 12957 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12958 &EmulateInstructionARM::EmulatePUSH, "push <register>"}, 12959 12960 // set r7 to point to a stack offset 12961 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12962 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"}, 12963 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12964 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12965 // copy the stack pointer to ip 12966 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, 12967 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"}, 12968 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12969 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"}, 12970 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12971 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12972 12973 // adjust the stack pointer 12974 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12975 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12976 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12977 &EmulateInstructionARM::EmulateSUBSPReg, 12978 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 12979 12980 // push one register 12981 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12982 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12983 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"}, 12984 12985 // vector push consecutive extension register(s) 12986 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12987 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12988 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12989 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12990 12991 //---------------------------------------------------------------------- 12992 // Epilogue instructions 12993 //---------------------------------------------------------------------- 12994 12995 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12996 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12997 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12998 &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12999 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 13000 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 13001 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 13002 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 13003 13004 //---------------------------------------------------------------------- 13005 // Supervisor Call (previously Software Interrupt) 13006 //---------------------------------------------------------------------- 13007 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13008 &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 13009 13010 //---------------------------------------------------------------------- 13011 // Branch instructions 13012 //---------------------------------------------------------------------- 13013 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and 13014 // "bl <label>". 13015 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, 13016 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 13017 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13018 &EmulateInstructionARM::EmulateB, "b #imm24"}, 13019 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13020 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 13021 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, 13022 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 13023 // for example, "bx lr" 13024 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, 13025 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 13026 // bxj 13027 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, 13028 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 13029 13030 //---------------------------------------------------------------------- 13031 // Data-processing instructions 13032 //---------------------------------------------------------------------- 13033 // adc (immediate) 13034 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13035 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 13036 // adc (register) 13037 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13038 &EmulateInstructionARM::EmulateADCReg, 13039 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13040 // add (immediate) 13041 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13042 &EmulateInstructionARM::EmulateADDImmARM, 13043 "add{s}<c> <Rd>, <Rn>, #const"}, 13044 // add (register) 13045 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13046 &EmulateInstructionARM::EmulateADDReg, 13047 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13048 // add (register-shifted register) 13049 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, 13050 &EmulateInstructionARM::EmulateADDRegShift, 13051 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 13052 // adr 13053 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13054 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13055 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, 13056 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 13057 // and (immediate) 13058 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13059 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 13060 // and (register) 13061 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13062 &EmulateInstructionARM::EmulateANDReg, 13063 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13064 // bic (immediate) 13065 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13066 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 13067 // bic (register) 13068 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13069 &EmulateInstructionARM::EmulateBICReg, 13070 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13071 // eor (immediate) 13072 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13073 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 13074 // eor (register) 13075 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13076 &EmulateInstructionARM::EmulateEORReg, 13077 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13078 // orr (immediate) 13079 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13080 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 13081 // orr (register) 13082 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13083 &EmulateInstructionARM::EmulateORRReg, 13084 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13085 // rsb (immediate) 13086 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13087 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 13088 // rsb (register) 13089 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13090 &EmulateInstructionARM::EmulateRSBReg, 13091 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13092 // rsc (immediate) 13093 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13094 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 13095 // rsc (register) 13096 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13097 &EmulateInstructionARM::EmulateRSCReg, 13098 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13099 // sbc (immediate) 13100 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13101 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13102 // sbc (register) 13103 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13104 &EmulateInstructionARM::EmulateSBCReg, 13105 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13106 // sub (immediate, ARM) 13107 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13108 &EmulateInstructionARM::EmulateSUBImmARM, 13109 "sub{s}<c> <Rd>, <Rn>, #<const>"}, 13110 // sub (sp minus immediate) 13111 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13112 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 13113 // sub (register) 13114 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13115 &EmulateInstructionARM::EmulateSUBReg, 13116 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 13117 // teq (immediate) 13118 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13119 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 13120 // teq (register) 13121 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13122 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13123 // tst (immediate) 13124 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13125 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 13126 // tst (register) 13127 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13128 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 13129 13130 // mov (immediate) 13131 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13132 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 13133 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 13134 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"}, 13135 // mov (register) 13136 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13137 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 13138 // mvn (immediate) 13139 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13140 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 13141 // mvn (register) 13142 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13143 &EmulateInstructionARM::EmulateMVNReg, 13144 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 13145 // cmn (immediate) 13146 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13147 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13148 // cmn (register) 13149 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13150 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13151 // cmp (immediate) 13152 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13153 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 13154 // cmp (register) 13155 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13156 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 13157 // asr (immediate) 13158 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, 13159 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 13160 // asr (register) 13161 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13162 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 13163 // lsl (immediate) 13164 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13165 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 13166 // lsl (register) 13167 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, 13168 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 13169 // lsr (immediate) 13170 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, 13171 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 13172 // lsr (register) 13173 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13174 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 13175 // rrx is a special case encoding of ror (immediate) 13176 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13177 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 13178 // ror (immediate) 13179 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13180 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 13181 // ror (register) 13182 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, 13183 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 13184 // mul 13185 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, 13186 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"}, 13187 13188 // subs pc, lr and related instructions 13189 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13190 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13191 "<opc>S<c> PC,#<const> | <Rn>,#<const>"}, 13192 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, 13193 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13194 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"}, 13195 13196 //---------------------------------------------------------------------- 13197 // Load instructions 13198 //---------------------------------------------------------------------- 13199 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13200 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13201 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13202 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"}, 13203 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13204 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13205 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13206 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"}, 13207 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13208 &EmulateInstructionARM::EmulateLDRImmediateARM, 13209 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"}, 13210 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13211 &EmulateInstructionARM::EmulateLDRRegister, 13212 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"}, 13213 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13214 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 13215 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13216 &EmulateInstructionARM::EmulateLDRBRegister, 13217 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"}, 13218 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13219 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13220 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13221 &EmulateInstructionARM::EmulateLDRHRegister, 13222 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13223 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13224 &EmulateInstructionARM::EmulateLDRSBImmediate, 13225 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"}, 13226 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13227 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"}, 13228 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13229 &EmulateInstructionARM::EmulateLDRSBRegister, 13230 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13231 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13232 &EmulateInstructionARM::EmulateLDRSHImmediate, 13233 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 13234 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13235 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13236 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13237 &EmulateInstructionARM::EmulateLDRSHRegister, 13238 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13239 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13240 &EmulateInstructionARM::EmulateLDRDImmediate, 13241 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 13242 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13243 &EmulateInstructionARM::EmulateLDRDRegister, 13244 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13245 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13246 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13247 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13248 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13249 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13250 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13251 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13252 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13253 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13254 &EmulateInstructionARM::EmulateVLD1Multiple, 13255 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13256 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13257 &EmulateInstructionARM::EmulateVLD1Single, 13258 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13259 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13260 &EmulateInstructionARM::EmulateVLD1SingleAll, 13261 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13262 13263 //---------------------------------------------------------------------- 13264 // Store instructions 13265 //---------------------------------------------------------------------- 13266 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13267 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13268 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13269 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"}, 13270 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13271 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13272 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13273 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"}, 13274 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13275 &EmulateInstructionARM::EmulateSTRRegister, 13276 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"}, 13277 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13278 &EmulateInstructionARM::EmulateSTRHRegister, 13279 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"}, 13280 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13281 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 13282 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13283 &EmulateInstructionARM::EmulateSTRBImmARM, 13284 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13285 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13286 &EmulateInstructionARM::EmulateSTRImmARM, 13287 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13288 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13289 &EmulateInstructionARM::EmulateSTRDImm, 13290 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 13291 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13292 &EmulateInstructionARM::EmulateSTRDReg, 13293 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13294 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13295 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13296 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13297 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13298 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13299 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 13300 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13301 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 13302 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13303 &EmulateInstructionARM::EmulateVST1Multiple, 13304 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13305 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13306 &EmulateInstructionARM::EmulateVST1Single, 13307 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13308 13309 //---------------------------------------------------------------------- 13310 // Other instructions 13311 //---------------------------------------------------------------------- 13312 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13313 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13314 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13315 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"}, 13316 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13317 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13318 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13319 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"}, 13320 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13321 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"} 13322 13323 }; 13324 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 13325 13326 for (size_t i = 0; i < k_num_arm_opcodes; ++i) { 13327 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 13328 (g_arm_opcodes[i].variants & arm_isa) != 0) 13329 return &g_arm_opcodes[i]; 13330 } 13331 return NULL; 13332} 13333 13334EmulateInstructionARM::ARMOpcode * 13335EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode, 13336 uint32_t arm_isa) { 13337 13338 static ARMOpcode g_thumb_opcodes[] = { 13339 //---------------------------------------------------------------------- 13340 // Prologue instructions 13341 //---------------------------------------------------------------------- 13342 13343 // push register(s) 13344 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, 13345 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 13346 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13347 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"}, 13348 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13349 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"}, 13350 13351 // set r7 to point to a stack offset 13352 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13353 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"}, 13354 // copy the stack pointer to r7 13355 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, 13356 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"}, 13357 // move from high register to low register (comes after "mov r7, sp" to 13358 // resolve ambiguity) 13359 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, 13360 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"}, 13361 13362 // PC-relative load into register (see also EmulateADDSPRm) 13363 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13364 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 13365 13366 // adjust the stack pointer 13367 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, 13368 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 13369 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13370 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 13371 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13372 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 13373 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13374 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 13375 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13376 &EmulateInstructionARM::EmulateSUBSPReg, 13377 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 13378 13379 // vector push consecutive extension register(s) 13380 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13381 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 13382 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13383 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 13384 13385 //---------------------------------------------------------------------- 13386 // Epilogue instructions 13387 //---------------------------------------------------------------------- 13388 13389 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13390 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 13391 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13392 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 13393 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13394 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 13395 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13396 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"}, 13397 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13398 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"}, 13399 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13400 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 13401 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13402 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 13403 13404 //---------------------------------------------------------------------- 13405 // Supervisor Call (previously Software Interrupt) 13406 //---------------------------------------------------------------------- 13407 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13408 &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 13409 13410 //---------------------------------------------------------------------- 13411 // If Then makes up to four following instructions conditional. 13412 //---------------------------------------------------------------------- 13413 // The next 5 opcode _must_ come before the if then instruction 13414 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13415 &EmulateInstructionARM::EmulateNop, "nop"}, 13416 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13417 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 13418 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13419 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 13420 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13421 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 13422 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13423 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 13424 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13425 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 13426 13427 //---------------------------------------------------------------------- 13428 // Branch instructions 13429 //---------------------------------------------------------------------- 13430 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 13431 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13432 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 13433 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13434 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 13435 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13436 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 13437 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13438 &EmulateInstructionARM::EmulateB, 13439 "b<c>.w #imm8 (outside or last in IT)"}, 13440 // J1 == J2 == 1 13441 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, 13442 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 13443 // J1 == J2 == 1 13444 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, 13445 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 13446 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, 13447 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 13448 // for example, "bx lr" 13449 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, 13450 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 13451 // bxj 13452 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, 13453 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 13454 // compare and branch 13455 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13456 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 13457 // table branch byte 13458 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13459 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 13460 // table branch halfword 13461 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13462 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 13463 13464 //---------------------------------------------------------------------- 13465 // Data-processing instructions 13466 //---------------------------------------------------------------------- 13467 // adc (immediate) 13468 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13469 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 13470 // adc (register) 13471 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, 13472 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 13473 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13474 &EmulateInstructionARM::EmulateADCReg, 13475 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13476 // add (register) 13477 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13478 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 13479 // Make sure "add sp, <Rm>" comes before this instruction, so there's no 13480 // ambiguity decoding the two. 13481 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, 13482 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 13483 // adr 13484 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13485 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13486 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13487 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 13488 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13489 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13490 // and (immediate) 13491 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13492 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 13493 // and (register) 13494 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13495 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 13496 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13497 &EmulateInstructionARM::EmulateANDReg, 13498 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13499 // bic (immediate) 13500 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13501 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 13502 // bic (register) 13503 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, 13504 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 13505 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13506 &EmulateInstructionARM::EmulateBICReg, 13507 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13508 // eor (immediate) 13509 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13510 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 13511 // eor (register) 13512 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, 13513 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 13514 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13515 &EmulateInstructionARM::EmulateEORReg, 13516 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13517 // orr (immediate) 13518 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13519 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 13520 // orr (register) 13521 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, 13522 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 13523 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13524 &EmulateInstructionARM::EmulateORRReg, 13525 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13526 // rsb (immediate) 13527 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, 13528 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 13529 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13530 &EmulateInstructionARM::EmulateRSBImm, 13531 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 13532 // rsb (register) 13533 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13534 &EmulateInstructionARM::EmulateRSBReg, 13535 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13536 // sbc (immediate) 13537 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13538 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13539 // sbc (register) 13540 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, 13541 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 13542 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13543 &EmulateInstructionARM::EmulateSBCReg, 13544 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13545 // add (immediate, Thumb) 13546 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13547 &EmulateInstructionARM::EmulateADDImmThumb, 13548 "adds|add<c> <Rd>,<Rn>,#<imm3>"}, 13549 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13550 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"}, 13551 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13552 &EmulateInstructionARM::EmulateADDImmThumb, 13553 "add{s}<c>.w <Rd>,<Rn>,#<const>"}, 13554 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13555 &EmulateInstructionARM::EmulateADDImmThumb, 13556 "addw<c> <Rd>,<Rn>,#<imm12>"}, 13557 // sub (immediate, Thumb) 13558 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13559 &EmulateInstructionARM::EmulateSUBImmThumb, 13560 "subs|sub<c> <Rd>, <Rn> #imm3"}, 13561 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, 13562 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 13563 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13564 &EmulateInstructionARM::EmulateSUBImmThumb, 13565 "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 13566 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13567 &EmulateInstructionARM::EmulateSUBImmThumb, 13568 "subw<c> <Rd>, <Rn>, #imm12"}, 13569 // sub (sp minus immediate) 13570 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13571 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 13572 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13573 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 13574 // sub (register) 13575 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13576 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 13577 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13578 &EmulateInstructionARM::EmulateSUBReg, 13579 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 13580 // teq (immediate) 13581 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13582 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 13583 // teq (register) 13584 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13585 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13586 // tst (immediate) 13587 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13588 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 13589 // tst (register) 13590 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, 13591 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 13592 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13593 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 13594 13595 // move from high register to high register 13596 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, 13597 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 13598 // move from low register to low register 13599 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13600 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 13601 // mov{s}<c>.w <Rd>, <Rm> 13602 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13603 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 13604 // move immediate 13605 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13606 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 13607 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13608 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 13609 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13610 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 13611 // mvn (immediate) 13612 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13613 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 13614 // mvn (register) 13615 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13616 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 13617 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13618 &EmulateInstructionARM::EmulateMVNReg, 13619 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 13620 // cmn (immediate) 13621 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13622 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13623 // cmn (register) 13624 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13625 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 13626 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13627 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13628 // cmp (immediate) 13629 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13630 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 13631 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13632 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 13633 // cmp (register) (Rn and Rm both from r0-r7) 13634 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, 13635 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13636 // cmp (register) (Rn and Rm not both from r0-r7) 13637 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, 13638 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13639 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, 13640 &EmulateInstructionARM::EmulateCMPReg, 13641 "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 13642 // asr (immediate) 13643 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13644 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 13645 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13646 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 13647 // asr (register) 13648 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, 13649 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 13650 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13651 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13652 // lsl (immediate) 13653 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13654 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 13655 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13656 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 13657 // lsl (register) 13658 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13659 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 13660 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13661 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13662 // lsr (immediate) 13663 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13664 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 13665 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13666 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 13667 // lsr (register) 13668 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13669 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 13670 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13671 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13672 // rrx is a special case encoding of ror (immediate) 13673 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13674 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 13675 // ror (immediate) 13676 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13677 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 13678 // ror (register) 13679 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13680 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 13681 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13682 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13683 // mul 13684 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13685 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"}, 13686 // mul 13687 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13688 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"}, 13689 13690 // subs pc, lr and related instructions 13691 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13692 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"}, 13693 13694 //---------------------------------------------------------------------- 13695 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE 13696 // LDM.. Instructions in this table; 13697 // otherwise the wrong instructions will be selected. 13698 //---------------------------------------------------------------------- 13699 13700 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13701 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"}, 13702 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13703 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"}, 13704 13705 //---------------------------------------------------------------------- 13706 // Load instructions 13707 //---------------------------------------------------------------------- 13708 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13709 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13710 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13711 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"}, 13712 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13713 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13714 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13715 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 13716 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13717 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 13718 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13719 &EmulateInstructionARM::EmulateLDRRtRnImm, 13720 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 13721 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13722 &EmulateInstructionARM::EmulateLDRRtRnImm, 13723 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 13724 // Thumb2 PC-relative load into register 13725 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13726 &EmulateInstructionARM::EmulateLDRRtPCRelative, 13727 "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 13728 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13729 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"}, 13730 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13731 &EmulateInstructionARM::EmulateLDRRegister, 13732 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"}, 13733 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13734 &EmulateInstructionARM::EmulateLDRBImmediate, 13735 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"}, 13736 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13737 &EmulateInstructionARM::EmulateLDRBImmediate, 13738 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13739 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13740 &EmulateInstructionARM::EmulateLDRBImmediate, 13741 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"}, 13742 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13743 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"}, 13744 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13745 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"}, 13746 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13747 &EmulateInstructionARM::EmulateLDRBRegister, 13748 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13749 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13750 &EmulateInstructionARM::EmulateLDRHImmediate, 13751 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"}, 13752 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13753 &EmulateInstructionARM::EmulateLDRHImmediate, 13754 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13755 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13756 &EmulateInstructionARM::EmulateLDRHImmediate, 13757 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"}, 13758 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13759 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13760 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13761 &EmulateInstructionARM::EmulateLDRHRegister, 13762 "ldrh<c> <Rt>, [<Rn>,<Rm>]"}, 13763 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13764 &EmulateInstructionARM::EmulateLDRHRegister, 13765 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13766 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13767 &EmulateInstructionARM::EmulateLDRSBImmediate, 13768 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"}, 13769 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13770 &EmulateInstructionARM::EmulateLDRSBImmediate, 13771 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13772 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13773 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"}, 13774 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13775 &EmulateInstructionARM::EmulateLDRSBRegister, 13776 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"}, 13777 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13778 &EmulateInstructionARM::EmulateLDRSBRegister, 13779 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13780 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13781 &EmulateInstructionARM::EmulateLDRSHImmediate, 13782 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"}, 13783 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13784 &EmulateInstructionARM::EmulateLDRSHImmediate, 13785 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13786 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13787 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13788 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13789 &EmulateInstructionARM::EmulateLDRSHRegister, 13790 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"}, 13791 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13792 &EmulateInstructionARM::EmulateLDRSHRegister, 13793 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13794 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13795 &EmulateInstructionARM::EmulateLDRDImmediate, 13796 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 13797 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13798 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13799 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13800 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13801 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13802 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13803 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13804 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 13805 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13806 &EmulateInstructionARM::EmulateVLD1Multiple, 13807 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13808 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13809 &EmulateInstructionARM::EmulateVLD1Single, 13810 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13811 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13812 &EmulateInstructionARM::EmulateVLD1SingleAll, 13813 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13814 13815 //---------------------------------------------------------------------- 13816 // Store instructions 13817 //---------------------------------------------------------------------- 13818 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13819 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13820 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13821 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"}, 13822 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13823 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13824 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13825 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"}, 13826 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13827 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"}, 13828 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13829 &EmulateInstructionARM::EmulateSTRThumb, 13830 "str<c>.w <Rt>, [<Rn>,#<imm12>]"}, 13831 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13832 &EmulateInstructionARM::EmulateSTRThumb, 13833 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"}, 13834 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13835 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"}, 13836 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13837 &EmulateInstructionARM::EmulateSTRRegister, 13838 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"}, 13839 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13840 &EmulateInstructionARM::EmulateSTRBThumb, 13841 "strb<c> <Rt>, [<Rn>, #<imm5>]"}, 13842 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13843 &EmulateInstructionARM::EmulateSTRBThumb, 13844 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"}, 13845 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13846 &EmulateInstructionARM::EmulateSTRBThumb, 13847 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"}, 13848 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13849 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"}, 13850 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13851 &EmulateInstructionARM::EmulateSTRHRegister, 13852 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13853 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13854 &EmulateInstructionARM::EmulateSTREX, 13855 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"}, 13856 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13857 &EmulateInstructionARM::EmulateSTRDImm, 13858 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 13859 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13860 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13861 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13862 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13863 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13864 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13865 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13866 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13867 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13868 &EmulateInstructionARM::EmulateVST1Multiple, 13869 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13870 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13871 &EmulateInstructionARM::EmulateVST1Single, 13872 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13873 13874 //---------------------------------------------------------------------- 13875 // Other instructions 13876 //---------------------------------------------------------------------- 13877 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13878 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"}, 13879 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, 13880 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13881 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13882 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"}, 13883 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13884 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13885 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13886 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"}, 13887 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13888 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13889 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13890 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"}, 13891 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13892 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13893 }; 13894 13895 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 13896 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) { 13897 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 13898 (g_thumb_opcodes[i].variants & arm_isa) != 0) 13899 return &g_thumb_opcodes[i]; 13900 } 13901 return NULL; 13902} 13903 13904bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) { 13905 m_arch = arch; 13906 m_arm_isa = 0; 13907 const char *arch_cstr = arch.GetArchitectureName(); 13908 if (arch_cstr) { 13909 if (0 == ::strcasecmp(arch_cstr, "armv4t")) 13910 m_arm_isa = ARMv4T; 13911 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) 13912 m_arm_isa = ARMv5TEJ; 13913 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) 13914 m_arm_isa = ARMv5TE; 13915 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) 13916 m_arm_isa = ARMv5T; 13917 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) 13918 m_arm_isa = ARMv6K; 13919 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) 13920 m_arm_isa = ARMv6T2; 13921 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) 13922 m_arm_isa = ARMv7S; 13923 else if (0 == ::strcasecmp(arch_cstr, "arm")) 13924 m_arm_isa = ARMvAll; 13925 else if (0 == ::strcasecmp(arch_cstr, "thumb")) 13926 m_arm_isa = ARMvAll; 13927 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5)) 13928 m_arm_isa = ARMv4; 13929 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5)) 13930 m_arm_isa = ARMv6; 13931 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5)) 13932 m_arm_isa = ARMv7; 13933 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5)) 13934 m_arm_isa = ARMv8; 13935 } 13936 return m_arm_isa != 0; 13937} 13938 13939bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode, 13940 const Address &inst_addr, 13941 Target *target) { 13942 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { 13943 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || 13944 m_arch.IsAlwaysThumbInstructions()) 13945 m_opcode_mode = eModeThumb; 13946 else { 13947 AddressClass addr_class = inst_addr.GetAddressClass(); 13948 13949 if ((addr_class == eAddressClassCode) || 13950 (addr_class == eAddressClassUnknown)) 13951 m_opcode_mode = eModeARM; 13952 else if (addr_class == eAddressClassCodeAlternateISA) 13953 m_opcode_mode = eModeThumb; 13954 else 13955 return false; 13956 } 13957 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions()) 13958 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13959 else 13960 m_opcode_cpsr = CPSR_MODE_USR; 13961 return true; 13962 } 13963 return false; 13964} 13965 13966bool EmulateInstructionARM::ReadInstruction() { 13967 bool success = false; 13968 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric, 13969 LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13970 if (success) { 13971 addr_t pc = 13972 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 13973 LLDB_INVALID_ADDRESS, &success); 13974 if (success) { 13975 Context read_inst_context; 13976 read_inst_context.type = eContextReadOpcode; 13977 read_inst_context.SetNoArgs(); 13978 13979 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) { 13980 m_opcode_mode = eModeThumb; 13981 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13982 13983 if (success) { 13984 if ((thumb_opcode & 0xe000) != 0xe000 || 13985 ((thumb_opcode & 0x1800u) == 0)) { 13986 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder()); 13987 } else { 13988 m_opcode.SetOpcode32( 13989 (thumb_opcode << 16) | 13990 MemARead(read_inst_context, pc + 2, 2, 0, &success), 13991 GetByteOrder()); 13992 } 13993 } 13994 } else { 13995 m_opcode_mode = eModeARM; 13996 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success), 13997 GetByteOrder()); 13998 } 13999 14000 if (!m_ignore_conditions) { 14001 // If we are not ignoreing the conditions then init the it session from 14002 // the current 14003 // value of cpsr. 14004 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | 14005 Bits32(m_opcode_cpsr, 26, 25); 14006 if (it != 0) 14007 m_it_session.InitIT(it); 14008 } 14009 } 14010 } 14011 if (!success) { 14012 m_opcode_mode = eModeInvalid; 14013 m_addr = LLDB_INVALID_ADDRESS; 14014 } 14015 return success; 14016} 14017 14018uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; } 14019 14020bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) { 14021 // If we are ignoring conditions, then always return true. 14022 // this allows us to iterate over disassembly code and still 14023 // emulate an instruction even if we don't have all the right 14024 // bits set in the CPSR register... 14025 if (m_ignore_conditions) 14026 return true; 14027 14028 const uint32_t cond = CurrentCond(opcode); 14029 if (cond == UINT32_MAX) 14030 return false; 14031 14032 bool result = false; 14033 switch (UnsignedBits(cond, 3, 1)) { 14034 case 0: 14035 if (m_opcode_cpsr == 0) 14036 result = true; 14037 else 14038 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 14039 break; 14040 case 1: 14041 if (m_opcode_cpsr == 0) 14042 result = true; 14043 else 14044 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 14045 break; 14046 case 2: 14047 if (m_opcode_cpsr == 0) 14048 result = true; 14049 else 14050 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 14051 break; 14052 case 3: 14053 if (m_opcode_cpsr == 0) 14054 result = true; 14055 else 14056 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 14057 break; 14058 case 4: 14059 if (m_opcode_cpsr == 0) 14060 result = true; 14061 else 14062 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && 14063 ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 14064 break; 14065 case 5: 14066 if (m_opcode_cpsr == 0) 14067 result = true; 14068 else { 14069 bool n = (m_opcode_cpsr & MASK_CPSR_N); 14070 bool v = (m_opcode_cpsr & MASK_CPSR_V); 14071 result = n == v; 14072 } 14073 break; 14074 case 6: 14075 if (m_opcode_cpsr == 0) 14076 result = true; 14077 else { 14078 bool n = (m_opcode_cpsr & MASK_CPSR_N); 14079 bool v = (m_opcode_cpsr & MASK_CPSR_V); 14080 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 14081 } 14082 break; 14083 case 7: 14084 // Always execute (cond == 0b1110, or the special 0b1111 which gives 14085 // opcodes different meanings, but always means execution happens. 14086 return true; 14087 } 14088 14089 if (cond & 1) 14090 result = !result; 14091 return result; 14092} 14093 14094uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) { 14095 switch (m_opcode_mode) { 14096 case eModeInvalid: 14097 break; 14098 14099 case eModeARM: 14100 return UnsignedBits(opcode, 31, 28); 14101 14102 case eModeThumb: 14103 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 14104 // 'cond' field of the encoding. 14105 { 14106 const uint32_t byte_size = m_opcode.GetByteSize(); 14107 if (byte_size == 2) { 14108 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 14109 return Bits32(opcode, 11, 8); 14110 } else if (byte_size == 4) { 14111 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 && 14112 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) { 14113 return Bits32(opcode, 25, 22); 14114 } 14115 } else 14116 // We have an invalid thumb instruction, let's bail out. 14117 break; 14118 14119 return m_it_session.GetCond(); 14120 } 14121 } 14122 return UINT32_MAX; // Return invalid value 14123} 14124 14125bool EmulateInstructionARM::InITBlock() { 14126 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 14127} 14128 14129bool EmulateInstructionARM::LastInITBlock() { 14130 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 14131} 14132 14133bool EmulateInstructionARM::BadMode(uint32_t mode) { 14134 14135 switch (mode) { 14136 case 16: 14137 return false; // '10000' 14138 case 17: 14139 return false; // '10001' 14140 case 18: 14141 return false; // '10010' 14142 case 19: 14143 return false; // '10011' 14144 case 22: 14145 return false; // '10110' 14146 case 23: 14147 return false; // '10111' 14148 case 27: 14149 return false; // '11011' 14150 case 31: 14151 return false; // '11111' 14152 default: 14153 return true; 14154 } 14155 return true; 14156} 14157 14158bool EmulateInstructionARM::CurrentModeIsPrivileged() { 14159 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0); 14160 14161 if (BadMode(mode)) 14162 return false; 14163 14164 if (mode == 16) 14165 return false; 14166 14167 return true; 14168} 14169 14170void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask, 14171 bool affect_execstate) { 14172 bool privileged = CurrentModeIsPrivileged(); 14173 14174 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20; 14175 14176 if (BitIsSet(bytemask, 3)) { 14177 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27); 14178 if (affect_execstate) 14179 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24); 14180 } 14181 14182 if (BitIsSet(bytemask, 2)) { 14183 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16); 14184 } 14185 14186 if (BitIsSet(bytemask, 1)) { 14187 if (affect_execstate) 14188 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10); 14189 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9); 14190 if (privileged) 14191 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8); 14192 } 14193 14194 if (BitIsSet(bytemask, 0)) { 14195 if (privileged) 14196 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6); 14197 if (affect_execstate) 14198 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5); 14199 if (privileged) 14200 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0); 14201 } 14202 14203 m_opcode_cpsr = tmp_cpsr; 14204} 14205 14206bool EmulateInstructionARM::BranchWritePC(const Context &context, 14207 uint32_t addr) { 14208 addr_t target; 14209 14210 // Check the current instruction set. 14211 if (CurrentInstrSet() == eModeARM) 14212 target = addr & 0xfffffffc; 14213 else 14214 target = addr & 0xfffffffe; 14215 14216 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14217 LLDB_REGNUM_GENERIC_PC, target)) 14218 return false; 14219 14220 return true; 14221} 14222 14223// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by 14224// inspecting addr. 14225bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) { 14226 addr_t target; 14227 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 14228 // we want to record it and issue a WriteRegister callback so the clients 14229 // can track the mode changes accordingly. 14230 bool cpsr_changed = false; 14231 14232 if (BitIsSet(addr, 0)) { 14233 if (CurrentInstrSet() != eModeThumb) { 14234 SelectInstrSet(eModeThumb); 14235 cpsr_changed = true; 14236 } 14237 target = addr & 0xfffffffe; 14238 context.SetISA(eModeThumb); 14239 } else if (BitIsClear(addr, 1)) { 14240 if (CurrentInstrSet() != eModeARM) { 14241 SelectInstrSet(eModeARM); 14242 cpsr_changed = true; 14243 } 14244 target = addr & 0xfffffffc; 14245 context.SetISA(eModeARM); 14246 } else 14247 return false; // address<1:0> == '10' => UNPREDICTABLE 14248 14249 if (cpsr_changed) { 14250 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14251 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14252 return false; 14253 } 14254 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14255 LLDB_REGNUM_GENERIC_PC, target)) 14256 return false; 14257 14258 return true; 14259} 14260 14261// Dispatches to either BXWritePC or BranchWritePC based on architecture 14262// versions. 14263bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) { 14264 if (ArchVersion() >= ARMv5T) 14265 return BXWritePC(context, addr); 14266 else 14267 return BranchWritePC((const Context)context, addr); 14268} 14269 14270// Dispatches to either BXWritePC or BranchWritePC based on architecture 14271// versions and current instruction set. 14272bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) { 14273 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 14274 return BXWritePC(context, addr); 14275 else 14276 return BranchWritePC((const Context)context, addr); 14277} 14278 14279EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() { 14280 return m_opcode_mode; 14281} 14282 14283// Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 14284// ReadInstruction() is performed. This function has a side effect of updating 14285// the m_new_inst_cpsr member variable if necessary. 14286bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) { 14287 m_new_inst_cpsr = m_opcode_cpsr; 14288 switch (arm_or_thumb) { 14289 default: 14290 return false; 14291 case eModeARM: 14292 // Clear the T bit. 14293 m_new_inst_cpsr &= ~MASK_CPSR_T; 14294 break; 14295 case eModeThumb: 14296 // Set the T bit. 14297 m_new_inst_cpsr |= MASK_CPSR_T; 14298 break; 14299 } 14300 return true; 14301} 14302 14303// This function returns TRUE if the processor currently provides support for 14304// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 14305// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 14306bool EmulateInstructionARM::UnalignedSupport() { 14307 return (ArchVersion() >= ARMv7); 14308} 14309 14310// The main addition and subtraction instructions can produce status information 14311// about both unsigned carry and signed overflow conditions. This status 14312// information can be used to synthesize multi-word additions and subtractions. 14313EmulateInstructionARM::AddWithCarryResult 14314EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) { 14315 uint32_t result; 14316 uint8_t carry_out; 14317 uint8_t overflow; 14318 14319 uint64_t unsigned_sum = x + y + carry_in; 14320 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 14321 14322 result = UnsignedBits(unsigned_sum, 31, 0); 14323 // carry_out = (result == unsigned_sum ? 0 : 1); 14324 overflow = ((int32_t)result == signed_sum ? 0 : 1); 14325 14326 if (carry_in) 14327 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0; 14328 else 14329 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0; 14330 14331 AddWithCarryResult res = {result, carry_out, overflow}; 14332 return res; 14333} 14334 14335uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) { 14336 lldb::RegisterKind reg_kind; 14337 uint32_t reg_num; 14338 switch (num) { 14339 case SP_REG: 14340 reg_kind = eRegisterKindGeneric; 14341 reg_num = LLDB_REGNUM_GENERIC_SP; 14342 break; 14343 case LR_REG: 14344 reg_kind = eRegisterKindGeneric; 14345 reg_num = LLDB_REGNUM_GENERIC_RA; 14346 break; 14347 case PC_REG: 14348 reg_kind = eRegisterKindGeneric; 14349 reg_num = LLDB_REGNUM_GENERIC_PC; 14350 break; 14351 default: 14352 if (num < SP_REG) { 14353 reg_kind = eRegisterKindDWARF; 14354 reg_num = dwarf_r0 + num; 14355 } else { 14356 // assert(0 && "Invalid register number"); 14357 *success = false; 14358 return UINT32_MAX; 14359 } 14360 break; 14361 } 14362 14363 // Read our register. 14364 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success); 14365 14366 // When executing an ARM instruction , PC reads as the address of the current 14367 // instruction plus 8. 14368 // When executing a Thumb instruction , PC reads as the address of the current 14369 // instruction plus 4. 14370 if (num == 15) { 14371 if (CurrentInstrSet() == eModeARM) 14372 val += 8; 14373 else 14374 val += 4; 14375 } 14376 14377 return val; 14378} 14379 14380// Write the result to the ARM core register Rd, and optionally update the 14381// condition flags based on the result. 14382// 14383// This helper method tries to encapsulate the following pseudocode from the 14384// ARM Architecture Reference Manual: 14385// 14386// if d == 15 then // Can only occur for encoding A1 14387// ALUWritePC(result); // setflags is always FALSE here 14388// else 14389// R[d] = result; 14390// if setflags then 14391// APSR.N = result<31>; 14392// APSR.Z = IsZeroBit(result); 14393// APSR.C = carry; 14394// // APSR.V unchanged 14395// 14396// In the above case, the API client does not pass in the overflow arg, which 14397// defaults to ~0u. 14398bool EmulateInstructionARM::WriteCoreRegOptionalFlags( 14399 Context &context, const uint32_t result, const uint32_t Rd, bool setflags, 14400 const uint32_t carry, const uint32_t overflow) { 14401 if (Rd == 15) { 14402 if (!ALUWritePC(context, result)) 14403 return false; 14404 } else { 14405 lldb::RegisterKind reg_kind; 14406 uint32_t reg_num; 14407 switch (Rd) { 14408 case SP_REG: 14409 reg_kind = eRegisterKindGeneric; 14410 reg_num = LLDB_REGNUM_GENERIC_SP; 14411 break; 14412 case LR_REG: 14413 reg_kind = eRegisterKindGeneric; 14414 reg_num = LLDB_REGNUM_GENERIC_RA; 14415 break; 14416 default: 14417 reg_kind = eRegisterKindDWARF; 14418 reg_num = dwarf_r0 + Rd; 14419 } 14420 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result)) 14421 return false; 14422 if (setflags) 14423 return WriteFlags(context, result, carry, overflow); 14424 } 14425 return true; 14426} 14427 14428// This helper method tries to encapsulate the following pseudocode from the 14429// ARM Architecture Reference Manual: 14430// 14431// APSR.N = result<31>; 14432// APSR.Z = IsZeroBit(result); 14433// APSR.C = carry; 14434// APSR.V = overflow 14435// 14436// Default arguments can be specified for carry and overflow parameters, which 14437// means 14438// not to update the respective flags. 14439bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result, 14440 const uint32_t carry, 14441 const uint32_t overflow) { 14442 m_new_inst_cpsr = m_opcode_cpsr; 14443 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 14444 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 14445 if (carry != ~0u) 14446 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 14447 if (overflow != ~0u) 14448 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 14449 if (m_new_inst_cpsr != m_opcode_cpsr) { 14450 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14451 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14452 return false; 14453 } 14454 return true; 14455} 14456 14457bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) { 14458 ARMOpcode *opcode_data = NULL; 14459 14460 if (m_opcode_mode == eModeThumb) 14461 opcode_data = 14462 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14463 else if (m_opcode_mode == eModeARM) 14464 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14465 14466 const bool auto_advance_pc = 14467 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 14468 m_ignore_conditions = 14469 evaluate_options & eEmulateInstructionOptionIgnoreConditions; 14470 14471 bool success = false; 14472 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) { 14473 m_opcode_cpsr = 14474 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 14475 } 14476 14477 // Only return false if we are unable to read the CPSR if we care about 14478 // conditions 14479 if (success == false && m_ignore_conditions == false) 14480 return false; 14481 14482 uint32_t orig_pc_value = 0; 14483 if (auto_advance_pc) { 14484 orig_pc_value = 14485 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14486 if (!success) 14487 return false; 14488 } 14489 14490 // Call the Emulate... function if we managed to decode the opcode. 14491 if (opcode_data) { 14492 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(), 14493 opcode_data->encoding); 14494 if (!success) 14495 return false; 14496 } 14497 14498 // Advance the ITSTATE bits to their values for the next instruction if we 14499 // haven't just executed 14500 // an IT instruction what initialized it. 14501 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() && 14502 (opcode_data == nullptr || 14503 opcode_data->callback != &EmulateInstructionARM::EmulateIT)) 14504 m_it_session.ITAdvance(); 14505 14506 if (auto_advance_pc) { 14507 uint32_t after_pc_value = 14508 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14509 if (!success) 14510 return false; 14511 14512 if (auto_advance_pc && (after_pc_value == orig_pc_value)) { 14513 after_pc_value += m_opcode.GetByteSize(); 14514 14515 EmulateInstruction::Context context; 14516 context.type = eContextAdvancePC; 14517 context.SetNoArgs(); 14518 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc, 14519 after_pc_value)) 14520 return false; 14521 } 14522 } 14523 return true; 14524} 14525 14526EmulateInstruction::InstructionCondition 14527EmulateInstructionARM::GetInstructionCondition() { 14528 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32()); 14529 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX) 14530 return EmulateInstruction::UnconditionalCondition; 14531 return cond; 14532} 14533 14534bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, 14535 OptionValueDictionary *test_data) { 14536 if (!test_data) { 14537 out_stream->Printf("TestEmulation: Missing test data.\n"); 14538 return false; 14539 } 14540 14541 static ConstString opcode_key("opcode"); 14542 static ConstString before_key("before_state"); 14543 static ConstString after_key("after_state"); 14544 14545 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key); 14546 14547 uint32_t test_opcode; 14548 if ((value_sp.get() == NULL) || 14549 (value_sp->GetType() != OptionValue::eTypeUInt64)) { 14550 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n"); 14551 return false; 14552 } 14553 test_opcode = value_sp->GetUInt64Value(); 14554 14555 if (arch.GetTriple().getArch() == llvm::Triple::thumb || 14556 arch.IsAlwaysThumbInstructions()) { 14557 m_opcode_mode = eModeThumb; 14558 if (test_opcode < 0x10000) 14559 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder()); 14560 else 14561 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14562 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) { 14563 m_opcode_mode = eModeARM; 14564 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14565 } else { 14566 out_stream->Printf("TestEmulation: Invalid arch.\n"); 14567 return false; 14568 } 14569 14570 EmulationStateARM before_state; 14571 EmulationStateARM after_state; 14572 14573 value_sp = test_data->GetValueForKey(before_key); 14574 if ((value_sp.get() == NULL) || 14575 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14576 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n"); 14577 return false; 14578 } 14579 14580 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary(); 14581 if (!before_state.LoadStateFromDictionary(state_dictionary)) { 14582 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n"); 14583 return false; 14584 } 14585 14586 value_sp = test_data->GetValueForKey(after_key); 14587 if ((value_sp.get() == NULL) || 14588 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14589 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n"); 14590 return false; 14591 } 14592 14593 state_dictionary = value_sp->GetAsDictionary(); 14594 if (!after_state.LoadStateFromDictionary(state_dictionary)) { 14595 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n"); 14596 return false; 14597 } 14598 14599 SetBaton((void *)&before_state); 14600 SetCallbacks(&EmulationStateARM::ReadPseudoMemory, 14601 &EmulationStateARM::WritePseudoMemory, 14602 &EmulationStateARM::ReadPseudoRegister, 14603 &EmulationStateARM::WritePseudoRegister); 14604 14605 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 14606 if (!success) { 14607 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n"); 14608 return false; 14609 } 14610 14611 success = before_state.CompareState(after_state); 14612 if (!success) 14613 out_stream->Printf( 14614 "TestEmulation: 'before' and 'after' states do not match.\n"); 14615 14616 return success; 14617} 14618// 14619// 14620// const char * 14621// EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 14622//{ 14623// if (reg_kind == eRegisterKindGeneric) 14624// { 14625// switch (reg_num) 14626// { 14627// case LLDB_REGNUM_GENERIC_PC: return "pc"; 14628// case LLDB_REGNUM_GENERIC_SP: return "sp"; 14629// case LLDB_REGNUM_GENERIC_FP: return "fp"; 14630// case LLDB_REGNUM_GENERIC_RA: return "lr"; 14631// case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 14632// default: return NULL; 14633// } 14634// } 14635// else if (reg_kind == eRegisterKindDWARF) 14636// { 14637// return GetARMDWARFRegisterName (reg_num); 14638// } 14639// return NULL; 14640//} 14641// 14642bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { 14643 unwind_plan.Clear(); 14644 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 14645 14646 UnwindPlan::RowSP row(new UnwindPlan::Row); 14647 14648 // Our previous Call Frame Address is the stack pointer 14649 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0); 14650 14651 unwind_plan.AppendRow(row); 14652 unwind_plan.SetSourceName("EmulateInstructionARM"); 14653 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 14654 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 14655 unwind_plan.SetReturnAddressRegister(dwarf_lr); 14656 return true; 14657} 14658