EmulateInstructionARM.cpp revision 341825
1//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include <stdlib.h> 11 12#include "EmulateInstructionARM.h" 13#include "EmulationStateARM.h" 14#include "lldb/Core/Address.h" 15#include "lldb/Core/PluginManager.h" 16#include "lldb/Host/PosixApi.h" 17#include "lldb/Interpreter/OptionValueArray.h" 18#include "lldb/Interpreter/OptionValueDictionary.h" 19#include "lldb/Symbol/UnwindPlan.h" 20#include "lldb/Utility/ArchSpec.h" 21#include "lldb/Utility/ConstString.h" 22#include "lldb/Utility/Stream.h" 23 24#include "Plugins/Process/Utility/ARMDefines.h" 25#include "Plugins/Process/Utility/ARMUtils.h" 26#include "Utility/ARM_DWARF_Registers.h" 27 28#include "llvm/ADT/STLExtras.h" 29#include "llvm/Support/MathExtras.h" // for SignExtend32 template function 30 // and countTrailingZeros function 31 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 XScale accumulator 262 // register 0 - 7 (they do overlap with wCGR0 - wCGR7) 263 case dwarf_wCGR0: 264 reg_info.name = "wCGR0/ACC0"; 265 break; 266 case dwarf_wCGR1: 267 reg_info.name = "wCGR1/ACC1"; 268 break; 269 case dwarf_wCGR2: 270 reg_info.name = "wCGR2/ACC2"; 271 break; 272 case dwarf_wCGR3: 273 reg_info.name = "wCGR3/ACC3"; 274 break; 275 case dwarf_wCGR4: 276 reg_info.name = "wCGR4/ACC4"; 277 break; 278 case dwarf_wCGR5: 279 reg_info.name = "wCGR5/ACC5"; 280 break; 281 case dwarf_wCGR6: 282 reg_info.name = "wCGR6/ACC6"; 283 break; 284 case dwarf_wCGR7: 285 reg_info.name = "wCGR7/ACC7"; 286 break; 287 288 // Intel wireless MMX data registers 0 - 15 289 case dwarf_wR0: 290 reg_info.name = "wR0"; 291 break; 292 case dwarf_wR1: 293 reg_info.name = "wR1"; 294 break; 295 case dwarf_wR2: 296 reg_info.name = "wR2"; 297 break; 298 case dwarf_wR3: 299 reg_info.name = "wR3"; 300 break; 301 case dwarf_wR4: 302 reg_info.name = "wR4"; 303 break; 304 case dwarf_wR5: 305 reg_info.name = "wR5"; 306 break; 307 case dwarf_wR6: 308 reg_info.name = "wR6"; 309 break; 310 case dwarf_wR7: 311 reg_info.name = "wR7"; 312 break; 313 case dwarf_wR8: 314 reg_info.name = "wR8"; 315 break; 316 case dwarf_wR9: 317 reg_info.name = "wR9"; 318 break; 319 case dwarf_wR10: 320 reg_info.name = "wR10"; 321 break; 322 case dwarf_wR11: 323 reg_info.name = "wR11"; 324 break; 325 case dwarf_wR12: 326 reg_info.name = "wR12"; 327 break; 328 case dwarf_wR13: 329 reg_info.name = "wR13"; 330 break; 331 case dwarf_wR14: 332 reg_info.name = "wR14"; 333 break; 334 case dwarf_wR15: 335 reg_info.name = "wR15"; 336 break; 337 338 case dwarf_spsr: 339 reg_info.name = "spsr"; 340 break; 341 case dwarf_spsr_fiq: 342 reg_info.name = "spsr_fiq"; 343 break; 344 case dwarf_spsr_irq: 345 reg_info.name = "spsr_irq"; 346 break; 347 case dwarf_spsr_abt: 348 reg_info.name = "spsr_abt"; 349 break; 350 case dwarf_spsr_und: 351 reg_info.name = "spsr_und"; 352 break; 353 case dwarf_spsr_svc: 354 reg_info.name = "spsr_svc"; 355 break; 356 357 case dwarf_r8_usr: 358 reg_info.name = "r8_usr"; 359 break; 360 case dwarf_r9_usr: 361 reg_info.name = "r9_usr"; 362 break; 363 case dwarf_r10_usr: 364 reg_info.name = "r10_usr"; 365 break; 366 case dwarf_r11_usr: 367 reg_info.name = "r11_usr"; 368 break; 369 case dwarf_r12_usr: 370 reg_info.name = "r12_usr"; 371 break; 372 case dwarf_r13_usr: 373 reg_info.name = "r13_usr"; 374 break; 375 case dwarf_r14_usr: 376 reg_info.name = "r14_usr"; 377 break; 378 case dwarf_r8_fiq: 379 reg_info.name = "r8_fiq"; 380 break; 381 case dwarf_r9_fiq: 382 reg_info.name = "r9_fiq"; 383 break; 384 case dwarf_r10_fiq: 385 reg_info.name = "r10_fiq"; 386 break; 387 case dwarf_r11_fiq: 388 reg_info.name = "r11_fiq"; 389 break; 390 case dwarf_r12_fiq: 391 reg_info.name = "r12_fiq"; 392 break; 393 case dwarf_r13_fiq: 394 reg_info.name = "r13_fiq"; 395 break; 396 case dwarf_r14_fiq: 397 reg_info.name = "r14_fiq"; 398 break; 399 case dwarf_r13_irq: 400 reg_info.name = "r13_irq"; 401 break; 402 case dwarf_r14_irq: 403 reg_info.name = "r14_irq"; 404 break; 405 case dwarf_r13_abt: 406 reg_info.name = "r13_abt"; 407 break; 408 case dwarf_r14_abt: 409 reg_info.name = "r14_abt"; 410 break; 411 case dwarf_r13_und: 412 reg_info.name = "r13_und"; 413 break; 414 case dwarf_r14_und: 415 reg_info.name = "r14_und"; 416 break; 417 case dwarf_r13_svc: 418 reg_info.name = "r13_svc"; 419 break; 420 case dwarf_r14_svc: 421 reg_info.name = "r14_svc"; 422 break; 423 424 // Intel wireless MMX control register in co-processor 0 - 7 425 case dwarf_wC0: 426 reg_info.name = "wC0"; 427 break; 428 case dwarf_wC1: 429 reg_info.name = "wC1"; 430 break; 431 case dwarf_wC2: 432 reg_info.name = "wC2"; 433 break; 434 case dwarf_wC3: 435 reg_info.name = "wC3"; 436 break; 437 case dwarf_wC4: 438 reg_info.name = "wC4"; 439 break; 440 case dwarf_wC5: 441 reg_info.name = "wC5"; 442 break; 443 case dwarf_wC6: 444 reg_info.name = "wC6"; 445 break; 446 case dwarf_wC7: 447 reg_info.name = "wC7"; 448 break; 449 450 // VFP-v3/Neon 451 case dwarf_d0: 452 reg_info.name = "d0"; 453 break; 454 case dwarf_d1: 455 reg_info.name = "d1"; 456 break; 457 case dwarf_d2: 458 reg_info.name = "d2"; 459 break; 460 case dwarf_d3: 461 reg_info.name = "d3"; 462 break; 463 case dwarf_d4: 464 reg_info.name = "d4"; 465 break; 466 case dwarf_d5: 467 reg_info.name = "d5"; 468 break; 469 case dwarf_d6: 470 reg_info.name = "d6"; 471 break; 472 case dwarf_d7: 473 reg_info.name = "d7"; 474 break; 475 case dwarf_d8: 476 reg_info.name = "d8"; 477 break; 478 case dwarf_d9: 479 reg_info.name = "d9"; 480 break; 481 case dwarf_d10: 482 reg_info.name = "d10"; 483 break; 484 case dwarf_d11: 485 reg_info.name = "d11"; 486 break; 487 case dwarf_d12: 488 reg_info.name = "d12"; 489 break; 490 case dwarf_d13: 491 reg_info.name = "d13"; 492 break; 493 case dwarf_d14: 494 reg_info.name = "d14"; 495 break; 496 case dwarf_d15: 497 reg_info.name = "d15"; 498 break; 499 case dwarf_d16: 500 reg_info.name = "d16"; 501 break; 502 case dwarf_d17: 503 reg_info.name = "d17"; 504 break; 505 case dwarf_d18: 506 reg_info.name = "d18"; 507 break; 508 case dwarf_d19: 509 reg_info.name = "d19"; 510 break; 511 case dwarf_d20: 512 reg_info.name = "d20"; 513 break; 514 case dwarf_d21: 515 reg_info.name = "d21"; 516 break; 517 case dwarf_d22: 518 reg_info.name = "d22"; 519 break; 520 case dwarf_d23: 521 reg_info.name = "d23"; 522 break; 523 case dwarf_d24: 524 reg_info.name = "d24"; 525 break; 526 case dwarf_d25: 527 reg_info.name = "d25"; 528 break; 529 case dwarf_d26: 530 reg_info.name = "d26"; 531 break; 532 case dwarf_d27: 533 reg_info.name = "d27"; 534 break; 535 case dwarf_d28: 536 reg_info.name = "d28"; 537 break; 538 case dwarf_d29: 539 reg_info.name = "d29"; 540 break; 541 case dwarf_d30: 542 reg_info.name = "d30"; 543 break; 544 case dwarf_d31: 545 reg_info.name = "d31"; 546 break; 547 548 // NEON 128-bit vector registers (overlays the d registers) 549 case dwarf_q0: 550 reg_info.name = "q0"; 551 break; 552 case dwarf_q1: 553 reg_info.name = "q1"; 554 break; 555 case dwarf_q2: 556 reg_info.name = "q2"; 557 break; 558 case dwarf_q3: 559 reg_info.name = "q3"; 560 break; 561 case dwarf_q4: 562 reg_info.name = "q4"; 563 break; 564 case dwarf_q5: 565 reg_info.name = "q5"; 566 break; 567 case dwarf_q6: 568 reg_info.name = "q6"; 569 break; 570 case dwarf_q7: 571 reg_info.name = "q7"; 572 break; 573 case dwarf_q8: 574 reg_info.name = "q8"; 575 break; 576 case dwarf_q9: 577 reg_info.name = "q9"; 578 break; 579 case dwarf_q10: 580 reg_info.name = "q10"; 581 break; 582 case dwarf_q11: 583 reg_info.name = "q11"; 584 break; 585 case dwarf_q12: 586 reg_info.name = "q12"; 587 break; 588 case dwarf_q13: 589 reg_info.name = "q13"; 590 break; 591 case dwarf_q14: 592 reg_info.name = "q14"; 593 break; 594 case dwarf_q15: 595 reg_info.name = "q15"; 596 break; 597 598 default: 599 return false; 600 } 601 return true; 602} 603 604// A8.6.50 605// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 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 905// updates 906// SP to point to the start of the stored data. 907bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode, 908 const ARMEncoding encoding) { 909#if 0 910 // ARM pseudo code... 911 if (ConditionPassed()) 912 { 913 EncodingSpecificOperations(); 914 NullCheckIfThumbEE(13); 915 address = SP - 4*BitCount(registers); 916 917 for (i = 0 to 14) 918 { 919 if (registers<i> == '1') 920 { 921 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 922 MemA[address,4] = bits(32) UNKNOWN; 923 else 924 MemA[address,4] = R[i]; 925 address = address + 4; 926 } 927 } 928 929 if (registers<15> == '1') // Only possible for encoding A1 or A2 930 MemA[address,4] = PCStoreValue(); 931 932 SP = SP - 4*BitCount(registers); 933 } 934#endif 935 936 bool success = false; 937 if (ConditionPassed(opcode)) { 938 const uint32_t addr_byte_size = GetAddressByteSize(); 939 const addr_t sp = ReadCoreReg(SP_REG, &success); 940 if (!success) 941 return false; 942 uint32_t registers = 0; 943 uint32_t Rt; // the source register 944 switch (encoding) { 945 case eEncodingT1: 946 registers = Bits32(opcode, 7, 0); 947 // The M bit represents LR. 948 if (Bit32(opcode, 8)) 949 registers |= (1u << 14); 950 // if BitCount(registers) < 1 then UNPREDICTABLE; 951 if (BitCount(registers) < 1) 952 return false; 953 break; 954 case eEncodingT2: 955 // Ignore bits 15 & 13. 956 registers = Bits32(opcode, 15, 0) & ~0xa000; 957 // if BitCount(registers) < 2 then UNPREDICTABLE; 958 if (BitCount(registers) < 2) 959 return false; 960 break; 961 case eEncodingT3: 962 Rt = Bits32(opcode, 15, 12); 963 // if BadReg(t) then UNPREDICTABLE; 964 if (BadReg(Rt)) 965 return false; 966 registers = (1u << Rt); 967 break; 968 case eEncodingA1: 969 registers = Bits32(opcode, 15, 0); 970 // Instead of return false, let's handle the following case as well, 971 // which amounts to pushing one reg onto the full descending stacks. 972 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 973 break; 974 case eEncodingA2: 975 Rt = Bits32(opcode, 15, 12); 976 // if t == 13 then UNPREDICTABLE; 977 if (Rt == dwarf_sp) 978 return false; 979 registers = (1u << Rt); 980 break; 981 default: 982 return false; 983 } 984 addr_t sp_offset = addr_byte_size * BitCount(registers); 985 addr_t addr = sp - sp_offset; 986 uint32_t i; 987 988 EmulateInstruction::Context context; 989 context.type = EmulateInstruction::eContextPushRegisterOnStack; 990 RegisterInfo reg_info; 991 RegisterInfo sp_reg; 992 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 993 for (i = 0; i < 15; ++i) { 994 if (BitIsSet(registers, i)) { 995 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info); 996 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 997 uint32_t reg_value = ReadCoreReg(i, &success); 998 if (!success) 999 return false; 1000 if (!MemAWrite(context, addr, reg_value, addr_byte_size)) 1001 return false; 1002 addr += addr_byte_size; 1003 } 1004 } 1005 1006 if (BitIsSet(registers, 15)) { 1007 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info); 1008 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 1009 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1010 if (!success) 1011 return false; 1012 if (!MemAWrite(context, addr, pc, addr_byte_size)) 1013 return false; 1014 } 1015 1016 context.type = EmulateInstruction::eContextAdjustStackPointer; 1017 context.SetImmediateSigned(-sp_offset); 1018 1019 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1020 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1021 return false; 1022 } 1023 return true; 1024} 1025 1026// Pop Multiple Registers loads multiple registers from the stack, loading from 1027// consecutive memory locations staring at the address in SP, and updates 1028// SP to point just above the loaded data. 1029bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode, 1030 const ARMEncoding encoding) { 1031#if 0 1032 // ARM pseudo code... 1033 if (ConditionPassed()) 1034 { 1035 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 1036 address = SP; 1037 for i = 0 to 14 1038 if registers<i> == '1' then 1039 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 1040 if registers<15> == '1' then 1041 if UnalignedAllowed then 1042 LoadWritePC(MemU[address,4]); 1043 else 1044 LoadWritePC(MemA[address,4]); 1045 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 1046 if registers<13> == '1' then SP = bits(32) UNKNOWN; 1047 } 1048#endif 1049 1050 bool success = false; 1051 1052 if (ConditionPassed(opcode)) { 1053 const uint32_t addr_byte_size = GetAddressByteSize(); 1054 const addr_t sp = ReadCoreReg(SP_REG, &success); 1055 if (!success) 1056 return false; 1057 uint32_t registers = 0; 1058 uint32_t Rt; // the destination register 1059 switch (encoding) { 1060 case eEncodingT1: 1061 registers = Bits32(opcode, 7, 0); 1062 // The P bit represents PC. 1063 if (Bit32(opcode, 8)) 1064 registers |= (1u << 15); 1065 // if BitCount(registers) < 1 then UNPREDICTABLE; 1066 if (BitCount(registers) < 1) 1067 return false; 1068 break; 1069 case eEncodingT2: 1070 // Ignore bit 13. 1071 registers = Bits32(opcode, 15, 0) & ~0x2000; 1072 // if BitCount(registers) < 2 || (P == '1' && M == '1') then 1073 // UNPREDICTABLE; 1074 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 1075 return false; 1076 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 1077 // UNPREDICTABLE; 1078 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 1079 return false; 1080 break; 1081 case eEncodingT3: 1082 Rt = Bits32(opcode, 15, 12); 1083 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then 1084 // UNPREDICTABLE; 1085 if (Rt == 13) 1086 return false; 1087 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1088 return false; 1089 registers = (1u << Rt); 1090 break; 1091 case eEncodingA1: 1092 registers = Bits32(opcode, 15, 0); 1093 // Instead of return false, let's handle the following case as well, 1094 // which amounts to popping one reg from the full descending stacks. 1095 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 1096 1097 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 1098 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 1099 return false; 1100 break; 1101 case eEncodingA2: 1102 Rt = Bits32(opcode, 15, 12); 1103 // if t == 13 then UNPREDICTABLE; 1104 if (Rt == dwarf_sp) 1105 return false; 1106 registers = (1u << Rt); 1107 break; 1108 default: 1109 return false; 1110 } 1111 addr_t sp_offset = addr_byte_size * BitCount(registers); 1112 addr_t addr = sp; 1113 uint32_t i, data; 1114 1115 EmulateInstruction::Context context; 1116 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1117 1118 RegisterInfo sp_reg; 1119 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1120 1121 for (i = 0; i < 15; ++i) { 1122 if (BitIsSet(registers, i)) { 1123 context.SetAddress(addr); 1124 data = MemARead(context, addr, 4, 0, &success); 1125 if (!success) 1126 return false; 1127 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 1128 data)) 1129 return false; 1130 addr += addr_byte_size; 1131 } 1132 } 1133 1134 if (BitIsSet(registers, 15)) { 1135 context.SetRegisterPlusOffset(sp_reg, addr - sp); 1136 data = MemARead(context, addr, 4, 0, &success); 1137 if (!success) 1138 return false; 1139 // In ARMv5T and above, this is an interworking branch. 1140 if (!LoadWritePC(context, data)) 1141 return false; 1142 // addr += addr_byte_size; 1143 } 1144 1145 context.type = EmulateInstruction::eContextAdjustStackPointer; 1146 context.SetImmediateSigned(sp_offset); 1147 1148 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1149 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1150 return false; 1151 } 1152 return true; 1153} 1154 1155// Set r7 or ip to point to saved value residing within the stack. 1156// ADD (SP plus immediate) 1157bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode, 1158 const ARMEncoding encoding) { 1159#if 0 1160 // ARM pseudo code... 1161 if (ConditionPassed()) 1162 { 1163 EncodingSpecificOperations(); 1164 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1165 if d == 15 then 1166 ALUWritePC(result); // setflags is always FALSE here 1167 else 1168 R[d] = result; 1169 if setflags then 1170 APSR.N = result<31>; 1171 APSR.Z = IsZeroBit(result); 1172 APSR.C = carry; 1173 APSR.V = overflow; 1174 } 1175#endif 1176 1177 bool success = false; 1178 1179 if (ConditionPassed(opcode)) { 1180 const addr_t sp = ReadCoreReg(SP_REG, &success); 1181 if (!success) 1182 return false; 1183 uint32_t Rd; // the destination register 1184 uint32_t imm32; 1185 switch (encoding) { 1186 case eEncodingT1: 1187 Rd = 7; 1188 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 1189 break; 1190 case eEncodingA1: 1191 Rd = Bits32(opcode, 15, 12); 1192 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1193 break; 1194 default: 1195 return false; 1196 } 1197 addr_t sp_offset = imm32; 1198 addr_t addr = sp + sp_offset; // a pointer to the stack area 1199 1200 EmulateInstruction::Context context; 1201 if (Rd == GetFramePointerRegisterNumber()) 1202 context.type = eContextSetFramePointer; 1203 else 1204 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1205 RegisterInfo sp_reg; 1206 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1207 context.SetRegisterPlusOffset(sp_reg, sp_offset); 1208 1209 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, 1210 addr)) 1211 return false; 1212 } 1213 return true; 1214} 1215 1216// Set r7 or ip to the current stack pointer. 1217// MOV (register) 1218bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode, 1219 const ARMEncoding encoding) { 1220#if 0 1221 // ARM pseudo code... 1222 if (ConditionPassed()) 1223 { 1224 EncodingSpecificOperations(); 1225 result = R[m]; 1226 if d == 15 then 1227 ALUWritePC(result); // setflags is always FALSE here 1228 else 1229 R[d] = result; 1230 if setflags then 1231 APSR.N = result<31>; 1232 APSR.Z = IsZeroBit(result); 1233 // APSR.C unchanged 1234 // APSR.V unchanged 1235 } 1236#endif 1237 1238 bool success = false; 1239 1240 if (ConditionPassed(opcode)) { 1241 const addr_t sp = ReadCoreReg(SP_REG, &success); 1242 if (!success) 1243 return false; 1244 uint32_t Rd; // the destination register 1245 switch (encoding) { 1246 case eEncodingT1: 1247 Rd = 7; 1248 break; 1249 case eEncodingA1: 1250 Rd = 12; 1251 break; 1252 default: 1253 return false; 1254 } 1255 1256 EmulateInstruction::Context context; 1257 if (Rd == GetFramePointerRegisterNumber()) 1258 context.type = EmulateInstruction::eContextSetFramePointer; 1259 else 1260 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1261 RegisterInfo sp_reg; 1262 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1263 context.SetRegisterPlusOffset(sp_reg, 0); 1264 1265 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 1266 return false; 1267 } 1268 return true; 1269} 1270 1271// Move from high register (r8-r15) to low register (r0-r7). 1272// MOV (register) 1273bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode, 1274 const ARMEncoding encoding) { 1275 return EmulateMOVRdRm(opcode, encoding); 1276} 1277 1278// Move from register to register. 1279// MOV (register) 1280bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode, 1281 const ARMEncoding encoding) { 1282#if 0 1283 // ARM pseudo code... 1284 if (ConditionPassed()) 1285 { 1286 EncodingSpecificOperations(); 1287 result = R[m]; 1288 if d == 15 then 1289 ALUWritePC(result); // setflags is always FALSE here 1290 else 1291 R[d] = result; 1292 if setflags then 1293 APSR.N = result<31>; 1294 APSR.Z = IsZeroBit(result); 1295 // APSR.C unchanged 1296 // APSR.V unchanged 1297 } 1298#endif 1299 1300 bool success = false; 1301 1302 if (ConditionPassed(opcode)) { 1303 uint32_t Rm; // the source register 1304 uint32_t Rd; // the destination register 1305 bool setflags; 1306 switch (encoding) { 1307 case eEncodingT1: 1308 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1309 Rm = Bits32(opcode, 6, 3); 1310 setflags = false; 1311 if (Rd == 15 && InITBlock() && !LastInITBlock()) 1312 return false; 1313 break; 1314 case eEncodingT2: 1315 Rd = Bits32(opcode, 2, 0); 1316 Rm = Bits32(opcode, 5, 3); 1317 setflags = true; 1318 if (InITBlock()) 1319 return false; 1320 break; 1321 case eEncodingT3: 1322 Rd = Bits32(opcode, 11, 8); 1323 Rm = Bits32(opcode, 3, 0); 1324 setflags = BitIsSet(opcode, 20); 1325 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1326 if (setflags && (BadReg(Rd) || BadReg(Rm))) 1327 return false; 1328 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then 1329 // UNPREDICTABLE; 1330 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 1331 return false; 1332 break; 1333 case eEncodingA1: 1334 Rd = Bits32(opcode, 15, 12); 1335 Rm = Bits32(opcode, 3, 0); 1336 setflags = BitIsSet(opcode, 20); 1337 1338 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1339 // instructions; 1340 if (Rd == 15 && setflags) 1341 return EmulateSUBSPcLrEtc(opcode, encoding); 1342 break; 1343 default: 1344 return false; 1345 } 1346 uint32_t result = ReadCoreReg(Rm, &success); 1347 if (!success) 1348 return false; 1349 1350 // The context specifies that Rm is to be moved into Rd. 1351 EmulateInstruction::Context context; 1352 if (Rd == 13) 1353 context.type = EmulateInstruction::eContextAdjustStackPointer; 1354 else 1355 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1356 RegisterInfo dwarf_reg; 1357 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1358 context.SetRegisterPlusOffset(dwarf_reg, 0); 1359 1360 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 1361 return false; 1362 } 1363 return true; 1364} 1365 1366// Move (immediate) writes an immediate value to the destination register. It 1367// can optionally update the condition flags based on the value. 1368// MOV (immediate) 1369bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode, 1370 const ARMEncoding encoding) { 1371#if 0 1372 // ARM pseudo code... 1373 if (ConditionPassed()) 1374 { 1375 EncodingSpecificOperations(); 1376 result = imm32; 1377 if d == 15 then // Can only occur for ARM encoding 1378 ALUWritePC(result); // setflags is always FALSE here 1379 else 1380 R[d] = result; 1381 if setflags then 1382 APSR.N = result<31>; 1383 APSR.Z = IsZeroBit(result); 1384 APSR.C = carry; 1385 // APSR.V unchanged 1386 } 1387#endif 1388 1389 if (ConditionPassed(opcode)) { 1390 uint32_t Rd; // the destination register 1391 uint32_t imm32; // the immediate value to be written to Rd 1392 uint32_t carry = 1393 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 1394 // for setflags == false, this value is a don't care initialized to 1395 // 0 to silence the static analyzer 1396 bool setflags; 1397 switch (encoding) { 1398 case eEncodingT1: 1399 Rd = Bits32(opcode, 10, 8); 1400 setflags = !InITBlock(); 1401 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 1402 carry = APSR_C; 1403 1404 break; 1405 1406 case eEncodingT2: 1407 Rd = Bits32(opcode, 11, 8); 1408 setflags = BitIsSet(opcode, 20); 1409 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1410 if (BadReg(Rd)) 1411 return false; 1412 1413 break; 1414 1415 case eEncodingT3: { 1416 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 1417 // 32); 1418 Rd = Bits32(opcode, 11, 8); 1419 setflags = false; 1420 uint32_t imm4 = Bits32(opcode, 19, 16); 1421 uint32_t imm3 = Bits32(opcode, 14, 12); 1422 uint32_t i = Bit32(opcode, 26); 1423 uint32_t imm8 = Bits32(opcode, 7, 0); 1424 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 1425 1426 // if BadReg(d) then UNPREDICTABLE; 1427 if (BadReg(Rd)) 1428 return false; 1429 } break; 1430 1431 case eEncodingA1: 1432 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = 1433 // ARMExpandImm_C(imm12, APSR.C); 1434 Rd = Bits32(opcode, 15, 12); 1435 setflags = BitIsSet(opcode, 20); 1436 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1437 1438 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1439 // instructions; 1440 if ((Rd == 15) && setflags) 1441 return EmulateSUBSPcLrEtc(opcode, encoding); 1442 1443 break; 1444 1445 case eEncodingA2: { 1446 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 1447 Rd = Bits32(opcode, 15, 12); 1448 setflags = false; 1449 uint32_t imm4 = Bits32(opcode, 19, 16); 1450 uint32_t imm12 = Bits32(opcode, 11, 0); 1451 imm32 = (imm4 << 12) | imm12; 1452 1453 // if d == 15 then UNPREDICTABLE; 1454 if (Rd == 15) 1455 return false; 1456 } break; 1457 1458 default: 1459 return false; 1460 } 1461 uint32_t result = imm32; 1462 1463 // The context specifies that an immediate is to be moved into Rd. 1464 EmulateInstruction::Context context; 1465 context.type = EmulateInstruction::eContextImmediate; 1466 context.SetNoArgs(); 1467 1468 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1469 return false; 1470 } 1471 return true; 1472} 1473 1474// MUL multiplies two register values. The least significant 32 bits of the 1475// result are written to the destination 1476// register. These 32 bits do not depend on whether the source register values 1477// are considered to be signed values or unsigned values. 1478// 1479// Optionally, it can update the condition flags based on the result. In the 1480// Thumb instruction set, this option is limited to only a few forms of the 1481// 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. It can optionally update the condition flags based 1610// 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. It can optionally update the condition flags based on 1670// 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 2009// subroutine at a PC-relative address, and changes instruction set from ARM to 2010// Thumb, or 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 2114// and 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 address and instruction set specified by a 2224// register as though it were a BX instruction. 2225// 2226// TODO: Emulate Jazelle architecture? 2227// We currently assume that switching to Jazelle state fails, thus 2228// treating BXJ as a BX operation. 2229bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode, 2230 const ARMEncoding encoding) { 2231#if 0 2232 // ARM pseudo code... 2233 if (ConditionPassed()) 2234 { 2235 EncodingSpecificOperations(); 2236 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 2237 BXWritePC(R[m]); 2238 else 2239 if JazelleAcceptsExecution() then 2240 SwitchToJazelleExecution(); 2241 else 2242 SUBARCHITECTURE_DEFINED handler call; 2243 } 2244#endif 2245 2246 if (ConditionPassed(opcode)) { 2247 EmulateInstruction::Context context; 2248 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2249 uint32_t Rm; // the register with the target address 2250 switch (encoding) { 2251 case eEncodingT1: 2252 Rm = Bits32(opcode, 19, 16); 2253 if (BadReg(Rm)) 2254 return false; 2255 if (InITBlock() && !LastInITBlock()) 2256 return false; 2257 break; 2258 case eEncodingA1: 2259 Rm = Bits32(opcode, 3, 0); 2260 if (Rm == 15) 2261 return false; 2262 break; 2263 default: 2264 return false; 2265 } 2266 bool success = false; 2267 addr_t target = ReadCoreReg(Rm, &success); 2268 if (!success) 2269 return false; 2270 2271 RegisterInfo dwarf_reg; 2272 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2273 context.SetRegister(dwarf_reg); 2274 if (!BXWritePC(context, target)) 2275 return false; 2276 } 2277 return true; 2278} 2279 2280// Set r7 to point to some ip offset. 2281// SUB (immediate) 2282bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode, 2283 const ARMEncoding encoding) { 2284#if 0 2285 // ARM pseudo code... 2286 if (ConditionPassed()) 2287 { 2288 EncodingSpecificOperations(); 2289 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2290 if d == 15 then // Can only occur for ARM encoding 2291 ALUWritePC(result); // setflags is always FALSE here 2292 else 2293 R[d] = result; 2294 if setflags then 2295 APSR.N = result<31>; 2296 APSR.Z = IsZeroBit(result); 2297 APSR.C = carry; 2298 APSR.V = overflow; 2299 } 2300#endif 2301 2302 if (ConditionPassed(opcode)) { 2303 bool success = false; 2304 const addr_t ip = ReadCoreReg(12, &success); 2305 if (!success) 2306 return false; 2307 uint32_t imm32; 2308 switch (encoding) { 2309 case eEncodingA1: 2310 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2311 break; 2312 default: 2313 return false; 2314 } 2315 addr_t ip_offset = imm32; 2316 addr_t addr = ip - ip_offset; // the adjusted ip value 2317 2318 EmulateInstruction::Context context; 2319 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2320 RegisterInfo dwarf_reg; 2321 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg); 2322 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset); 2323 2324 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr)) 2325 return false; 2326 } 2327 return true; 2328} 2329 2330// Set ip to point to some stack offset. 2331// SUB (SP minus immediate) 2332bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode, 2333 const ARMEncoding encoding) { 2334#if 0 2335 // ARM pseudo code... 2336 if (ConditionPassed()) 2337 { 2338 EncodingSpecificOperations(); 2339 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2340 if d == 15 then // Can only occur for ARM encoding 2341 ALUWritePC(result); // setflags is always FALSE here 2342 else 2343 R[d] = result; 2344 if setflags then 2345 APSR.N = result<31>; 2346 APSR.Z = IsZeroBit(result); 2347 APSR.C = carry; 2348 APSR.V = overflow; 2349 } 2350#endif 2351 2352 if (ConditionPassed(opcode)) { 2353 bool success = false; 2354 const addr_t sp = ReadCoreReg(SP_REG, &success); 2355 if (!success) 2356 return false; 2357 uint32_t imm32; 2358 switch (encoding) { 2359 case eEncodingA1: 2360 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2361 break; 2362 default: 2363 return false; 2364 } 2365 addr_t sp_offset = imm32; 2366 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 2367 2368 EmulateInstruction::Context context; 2369 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2370 RegisterInfo dwarf_reg; 2371 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 2372 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset); 2373 2374 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr)) 2375 return false; 2376 } 2377 return true; 2378} 2379 2380// This instruction subtracts an immediate value from the SP value, and writes 2381// the result to the destination register. 2382// 2383// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local 2384// storage. 2385bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode, 2386 const ARMEncoding encoding) { 2387#if 0 2388 // ARM pseudo code... 2389 if (ConditionPassed()) 2390 { 2391 EncodingSpecificOperations(); 2392 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2393 if d == 15 then // Can only occur for ARM encoding 2394 ALUWritePC(result); // setflags is always FALSE here 2395 else 2396 R[d] = result; 2397 if setflags then 2398 APSR.N = result<31>; 2399 APSR.Z = IsZeroBit(result); 2400 APSR.C = carry; 2401 APSR.V = overflow; 2402 } 2403#endif 2404 2405 bool success = false; 2406 if (ConditionPassed(opcode)) { 2407 const addr_t sp = ReadCoreReg(SP_REG, &success); 2408 if (!success) 2409 return false; 2410 2411 uint32_t Rd; 2412 bool setflags; 2413 uint32_t imm32; 2414 switch (encoding) { 2415 case eEncodingT1: 2416 Rd = 13; 2417 setflags = false; 2418 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 2419 break; 2420 case eEncodingT2: 2421 Rd = Bits32(opcode, 11, 8); 2422 setflags = BitIsSet(opcode, 20); 2423 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2424 if (Rd == 15 && setflags) 2425 return EmulateCMPImm(opcode, eEncodingT2); 2426 if (Rd == 15 && !setflags) 2427 return false; 2428 break; 2429 case eEncodingT3: 2430 Rd = Bits32(opcode, 11, 8); 2431 setflags = false; 2432 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 2433 if (Rd == 15) 2434 return false; 2435 break; 2436 case eEncodingA1: 2437 Rd = Bits32(opcode, 15, 12); 2438 setflags = BitIsSet(opcode, 20); 2439 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2440 2441 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 2442 // instructions; 2443 if (Rd == 15 && setflags) 2444 return EmulateSUBSPcLrEtc(opcode, encoding); 2445 break; 2446 default: 2447 return false; 2448 } 2449 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 2450 2451 EmulateInstruction::Context context; 2452 if (Rd == 13) { 2453 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting 2454 // to negate it, or the wrong 2455 // value gets passed down to context.SetImmediateSigned. 2456 context.type = EmulateInstruction::eContextAdjustStackPointer; 2457 context.SetImmediateSigned(-imm64); // the stack pointer offset 2458 } else { 2459 context.type = EmulateInstruction::eContextImmediate; 2460 context.SetNoArgs(); 2461 } 2462 2463 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 2464 res.carry_out, res.overflow)) 2465 return false; 2466 } 2467 return true; 2468} 2469 2470// A store operation to the stack that also updates the SP. 2471bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode, 2472 const ARMEncoding encoding) { 2473#if 0 2474 // ARM pseudo code... 2475 if (ConditionPassed()) 2476 { 2477 EncodingSpecificOperations(); 2478 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2479 address = if index then offset_addr else R[n]; 2480 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 2481 if wback then R[n] = offset_addr; 2482 } 2483#endif 2484 2485 bool success = false; 2486 if (ConditionPassed(opcode)) { 2487 const uint32_t addr_byte_size = GetAddressByteSize(); 2488 const addr_t sp = ReadCoreReg(SP_REG, &success); 2489 if (!success) 2490 return false; 2491 uint32_t Rt; // the source register 2492 uint32_t imm12; 2493 uint32_t 2494 Rn; // This function assumes Rn is the SP, but we should verify that. 2495 2496 bool index; 2497 bool add; 2498 bool wback; 2499 switch (encoding) { 2500 case eEncodingA1: 2501 Rt = Bits32(opcode, 15, 12); 2502 imm12 = Bits32(opcode, 11, 0); 2503 Rn = Bits32(opcode, 19, 16); 2504 2505 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 2506 return false; 2507 2508 index = BitIsSet(opcode, 24); 2509 add = BitIsSet(opcode, 23); 2510 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 2511 2512 if (wback && ((Rn == 15) || (Rn == Rt))) 2513 return false; 2514 break; 2515 default: 2516 return false; 2517 } 2518 addr_t offset_addr; 2519 if (add) 2520 offset_addr = sp + imm12; 2521 else 2522 offset_addr = sp - imm12; 2523 2524 addr_t addr; 2525 if (index) 2526 addr = offset_addr; 2527 else 2528 addr = sp; 2529 2530 EmulateInstruction::Context context; 2531 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2532 RegisterInfo sp_reg; 2533 RegisterInfo dwarf_reg; 2534 2535 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2536 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2537 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2538 if (Rt != 15) { 2539 uint32_t reg_value = ReadCoreReg(Rt, &success); 2540 if (!success) 2541 return false; 2542 if (!MemUWrite(context, addr, reg_value, addr_byte_size)) 2543 return false; 2544 } else { 2545 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2546 if (!success) 2547 return false; 2548 if (!MemUWrite(context, addr, pc, addr_byte_size)) 2549 return false; 2550 } 2551 2552 if (wback) { 2553 context.type = EmulateInstruction::eContextAdjustStackPointer; 2554 context.SetImmediateSigned(addr - sp); 2555 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2556 LLDB_REGNUM_GENERIC_SP, offset_addr)) 2557 return false; 2558 } 2559 } 2560 return true; 2561} 2562 2563// Vector Push stores multiple extension registers to the stack. It also 2564// updates SP to point to the start of the stored data. 2565bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode, 2566 const ARMEncoding encoding) { 2567#if 0 2568 // ARM pseudo code... 2569 if (ConditionPassed()) 2570 { 2571 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2572 address = SP - imm32; 2573 SP = SP - imm32; 2574 if single_regs then 2575 for r = 0 to regs-1 2576 MemA[address,4] = S[d+r]; address = address+4; 2577 else 2578 for r = 0 to regs-1 2579 // Store as two word-aligned words in the correct order for 2580 // 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. It also 2657// 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 2674 // current endianness. 2675 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2676 } 2677#endif 2678 2679 bool success = false; 2680 if (ConditionPassed(opcode)) { 2681 const uint32_t addr_byte_size = GetAddressByteSize(); 2682 const addr_t sp = ReadCoreReg(SP_REG, &success); 2683 if (!success) 2684 return false; 2685 bool single_regs; 2686 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2687 uint32_t imm32; // stack offset 2688 uint32_t regs; // number of registers 2689 switch (encoding) { 2690 case eEncodingT1: 2691 case eEncodingA1: 2692 single_regs = false; 2693 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2694 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2695 // If UInt(imm8) is odd, see "FLDMX". 2696 regs = Bits32(opcode, 7, 0) / 2; 2697 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2698 if (regs == 0 || regs > 16 || (d + regs) > 32) 2699 return false; 2700 break; 2701 case eEncodingT2: 2702 case eEncodingA2: 2703 single_regs = true; 2704 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2705 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2706 regs = Bits32(opcode, 7, 0); 2707 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2708 if (regs == 0 || regs > 16 || (d + regs) > 32) 2709 return false; 2710 break; 2711 default: 2712 return false; 2713 } 2714 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2715 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2716 addr_t sp_offset = imm32; 2717 addr_t addr = sp; 2718 uint32_t i; 2719 uint64_t data; // uint64_t to accommodate 64-bit registers. 2720 2721 EmulateInstruction::Context context; 2722 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2723 2724 RegisterInfo dwarf_reg; 2725 RegisterInfo sp_reg; 2726 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2727 for (i = 0; i < regs; ++i) { 2728 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2729 context.SetAddress(addr); 2730 data = MemARead(context, addr, reg_byte_size, 0, &success); 2731 if (!success) 2732 return false; 2733 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2734 return false; 2735 addr += reg_byte_size; 2736 } 2737 2738 context.type = EmulateInstruction::eContextAdjustStackPointer; 2739 context.SetImmediateSigned(sp_offset); 2740 2741 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2742 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2743 return false; 2744 } 2745 return true; 2746} 2747 2748// SVC (previously SWI) 2749bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode, 2750 const ARMEncoding encoding) { 2751#if 0 2752 // ARM pseudo code... 2753 if (ConditionPassed()) 2754 { 2755 EncodingSpecificOperations(); 2756 CallSupervisor(); 2757 } 2758#endif 2759 2760 bool success = false; 2761 2762 if (ConditionPassed(opcode)) { 2763 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2764 addr_t lr; // next instruction address 2765 if (!success) 2766 return false; 2767 uint32_t imm32; // the immediate constant 2768 uint32_t mode; // ARM or Thumb mode 2769 switch (encoding) { 2770 case eEncodingT1: 2771 lr = (pc + 2) | 1u; // return address 2772 imm32 = Bits32(opcode, 7, 0); 2773 mode = eModeThumb; 2774 break; 2775 case eEncodingA1: 2776 lr = pc + 4; // return address 2777 imm32 = Bits32(opcode, 23, 0); 2778 mode = eModeARM; 2779 break; 2780 default: 2781 return false; 2782 } 2783 2784 EmulateInstruction::Context context; 2785 context.type = EmulateInstruction::eContextSupervisorCall; 2786 context.SetISAAndImmediate(mode, imm32); 2787 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2788 LLDB_REGNUM_GENERIC_RA, lr)) 2789 return false; 2790 } 2791 return true; 2792} 2793 2794// If Then makes up to four following instructions (the IT block) conditional. 2795bool EmulateInstructionARM::EmulateIT(const uint32_t opcode, 2796 const ARMEncoding encoding) { 2797#if 0 2798 // ARM pseudo code... 2799 EncodingSpecificOperations(); 2800 ITSTATE.IT<7:0> = firstcond:mask; 2801#endif 2802 2803 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2804 return true; 2805} 2806 2807bool EmulateInstructionARM::EmulateNop(const uint32_t opcode, 2808 const ARMEncoding encoding) { 2809 // NOP, nothing to do... 2810 return true; 2811} 2812 2813// Branch causes a branch to a target address. 2814bool EmulateInstructionARM::EmulateB(const uint32_t opcode, 2815 const ARMEncoding encoding) { 2816#if 0 2817 // ARM pseudo code... 2818 if (ConditionPassed()) 2819 { 2820 EncodingSpecificOperations(); 2821 BranchWritePC(PC + imm32); 2822 } 2823#endif 2824 2825 bool success = false; 2826 2827 if (ConditionPassed(opcode)) { 2828 EmulateInstruction::Context context; 2829 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2830 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2831 if (!success) 2832 return false; 2833 addr_t target; // target address 2834 int32_t imm32; // PC-relative offset 2835 switch (encoding) { 2836 case eEncodingT1: 2837 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2838 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2839 target = pc + imm32; 2840 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2841 break; 2842 case eEncodingT2: 2843 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2844 target = pc + imm32; 2845 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2846 break; 2847 case eEncodingT3: 2848 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2849 { 2850 if (Bits32(opcode, 25, 23) == 7) 2851 return false; // See Branches and miscellaneous control on page 2852 // A6-235. 2853 2854 uint32_t S = Bit32(opcode, 26); 2855 uint32_t imm6 = Bits32(opcode, 21, 16); 2856 uint32_t J1 = Bit32(opcode, 13); 2857 uint32_t J2 = Bit32(opcode, 11); 2858 uint32_t imm11 = Bits32(opcode, 10, 0); 2859 uint32_t imm21 = 2860 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2861 imm32 = llvm::SignExtend32<21>(imm21); 2862 target = pc + imm32; 2863 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2864 break; 2865 } 2866 case eEncodingT4: { 2867 uint32_t S = Bit32(opcode, 26); 2868 uint32_t imm10 = Bits32(opcode, 25, 16); 2869 uint32_t J1 = Bit32(opcode, 13); 2870 uint32_t J2 = Bit32(opcode, 11); 2871 uint32_t imm11 = Bits32(opcode, 10, 0); 2872 uint32_t I1 = !(J1 ^ S); 2873 uint32_t I2 = !(J2 ^ S); 2874 uint32_t imm25 = 2875 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2876 imm32 = llvm::SignExtend32<25>(imm25); 2877 target = pc + imm32; 2878 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2879 break; 2880 } 2881 case eEncodingA1: 2882 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2883 target = pc + imm32; 2884 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2885 break; 2886 default: 2887 return false; 2888 } 2889 if (!BranchWritePC(context, target)) 2890 return false; 2891 } 2892 return true; 2893} 2894 2895// Compare and Branch on Nonzero and Compare and Branch on Zero compare the 2896// value in a register with zero and conditionally branch forward a constant 2897// value. They do not affect the condition flags. CBNZ, CBZ 2898bool EmulateInstructionARM::EmulateCB(const uint32_t opcode, 2899 const ARMEncoding encoding) { 2900#if 0 2901 // ARM pseudo code... 2902 EncodingSpecificOperations(); 2903 if nonzero ^ IsZero(R[n]) then 2904 BranchWritePC(PC + imm32); 2905#endif 2906 2907 bool success = false; 2908 2909 // Read the register value from the operand register Rn. 2910 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2911 if (!success) 2912 return false; 2913 2914 EmulateInstruction::Context context; 2915 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2916 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2917 if (!success) 2918 return false; 2919 2920 addr_t target; // target address 2921 uint32_t imm32; // PC-relative offset to branch forward 2922 bool nonzero; 2923 switch (encoding) { 2924 case eEncodingT1: 2925 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2926 nonzero = BitIsSet(opcode, 11); 2927 target = pc + imm32; 2928 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2929 break; 2930 default: 2931 return false; 2932 } 2933 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2934 if (!BranchWritePC(context, target)) 2935 return false; 2936 2937 return true; 2938} 2939 2940// Table Branch Byte causes a PC-relative forward branch using a table of 2941// single byte offsets. 2942// A base register provides a pointer to the table, and a second register 2943// supplies an index into the table. 2944// The branch length is twice the value of the byte returned from the table. 2945// 2946// Table Branch Halfword causes a PC-relative forward branch using a table of 2947// single halfword offsets. 2948// A base register provides a pointer to the table, and a second register 2949// supplies an index into the table. 2950// The branch length is twice the value of the halfword returned from the 2951// table. TBB, TBH 2952bool EmulateInstructionARM::EmulateTB(const uint32_t opcode, 2953 const ARMEncoding encoding) { 2954#if 0 2955 // ARM pseudo code... 2956 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2957 if is_tbh then 2958 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2959 else 2960 halfwords = UInt(MemU[R[n]+R[m], 1]); 2961 BranchWritePC(PC + 2*halfwords); 2962#endif 2963 2964 bool success = false; 2965 2966 if (ConditionPassed(opcode)) { 2967 uint32_t Rn; // the base register which contains the address of the table of 2968 // branch lengths 2969 uint32_t Rm; // the index register which contains an integer pointing to a 2970 // byte/halfword in the table 2971 bool is_tbh; // true if table branch halfword 2972 switch (encoding) { 2973 case eEncodingT1: 2974 Rn = Bits32(opcode, 19, 16); 2975 Rm = Bits32(opcode, 3, 0); 2976 is_tbh = BitIsSet(opcode, 4); 2977 if (Rn == 13 || BadReg(Rm)) 2978 return false; 2979 if (InITBlock() && !LastInITBlock()) 2980 return false; 2981 break; 2982 default: 2983 return false; 2984 } 2985 2986 // Read the address of the table from the operand register Rn. The PC can 2987 // be used, in which case the table immediately follows this instruction. 2988 uint32_t base = ReadCoreReg(Rn, &success); 2989 if (!success) 2990 return false; 2991 2992 // the table index 2993 uint32_t index = ReadCoreReg(Rm, &success); 2994 if (!success) 2995 return false; 2996 2997 // the offsetted table address 2998 addr_t addr = base + (is_tbh ? index * 2 : index); 2999 3000 // PC-relative offset to branch forward 3001 EmulateInstruction::Context context; 3002 context.type = EmulateInstruction::eContextTableBranchReadMemory; 3003 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 3004 if (!success) 3005 return false; 3006 3007 const uint32_t pc = ReadCoreReg(PC_REG, &success); 3008 if (!success) 3009 return false; 3010 3011 // target address 3012 addr_t target = pc + offset; 3013 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 3014 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset); 3015 3016 if (!BranchWritePC(context, target)) 3017 return false; 3018 } 3019 3020 return true; 3021} 3022 3023// This instruction adds an immediate value to a register value, and writes the 3024// result to the destination register. It can optionally update the condition 3025// flags based on the result. 3026bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode, 3027 const ARMEncoding encoding) { 3028#if 0 3029 if ConditionPassed() then 3030 EncodingSpecificOperations(); 3031 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3032 R[d] = result; 3033 if setflags then 3034 APSR.N = result<31>; 3035 APSR.Z = IsZeroBit(result); 3036 APSR.C = carry; 3037 APSR.V = overflow; 3038#endif 3039 3040 bool success = false; 3041 3042 if (ConditionPassed(opcode)) { 3043 uint32_t d; 3044 uint32_t n; 3045 bool setflags; 3046 uint32_t imm32; 3047 uint32_t carry_out; 3048 3049 // EncodingSpecificOperations(); 3050 switch (encoding) { 3051 case eEncodingT1: 3052 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = 3053 // ZeroExtend(imm3, 32); 3054 d = Bits32(opcode, 2, 0); 3055 n = Bits32(opcode, 5, 3); 3056 setflags = !InITBlock(); 3057 imm32 = Bits32(opcode, 8, 6); 3058 3059 break; 3060 3061 case eEncodingT2: 3062 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = 3063 // ZeroExtend(imm8, 32); 3064 d = Bits32(opcode, 10, 8); 3065 n = Bits32(opcode, 10, 8); 3066 setflags = !InITBlock(); 3067 imm32 = Bits32(opcode, 7, 0); 3068 3069 break; 3070 3071 case eEncodingT3: 3072 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 3073 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = 3074 // ThumbExpandImm(i:imm3:imm8); 3075 d = Bits32(opcode, 11, 8); 3076 n = Bits32(opcode, 19, 16); 3077 setflags = BitIsSet(opcode, 20); 3078 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out); 3079 3080 // if Rn == '1101' then SEE ADD (SP plus immediate); 3081 if (n == 13) 3082 return EmulateADDSPImm(opcode, eEncodingT3); 3083 3084 // if BadReg(d) || n == 15 then UNPREDICTABLE; 3085 if (BadReg(d) || (n == 15)) 3086 return false; 3087 3088 break; 3089 3090 case eEncodingT4: { 3091 // if Rn == '1111' then SEE ADR; 3092 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = 3093 // ZeroExtend(i:imm3:imm8, 32); 3094 d = Bits32(opcode, 11, 8); 3095 n = Bits32(opcode, 19, 16); 3096 setflags = false; 3097 uint32_t i = Bit32(opcode, 26); 3098 uint32_t imm3 = Bits32(opcode, 14, 12); 3099 uint32_t imm8 = Bits32(opcode, 7, 0); 3100 imm32 = (i << 11) | (imm3 << 8) | imm8; 3101 3102 // if Rn == '1101' then SEE ADD (SP plus immediate); 3103 if (n == 13) 3104 return EmulateADDSPImm(opcode, eEncodingT4); 3105 3106 // if BadReg(d) then UNPREDICTABLE; 3107 if (BadReg(d)) 3108 return false; 3109 3110 break; 3111 } 3112 3113 default: 3114 return false; 3115 } 3116 3117 uint64_t Rn = 3118 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3119 if (!success) 3120 return false; 3121 3122 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3123 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0); 3124 3125 RegisterInfo reg_n; 3126 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 3127 3128 EmulateInstruction::Context context; 3129 context.type = eContextArithmetic; 3130 context.SetRegisterPlusOffset(reg_n, imm32); 3131 3132 // R[d] = result; 3133 // if setflags then 3134 // APSR.N = result<31>; 3135 // APSR.Z = IsZeroBit(result); 3136 // APSR.C = carry; 3137 // APSR.V = overflow; 3138 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 3139 res.carry_out, res.overflow)) 3140 return false; 3141 } 3142 return true; 3143} 3144 3145// This instruction adds an immediate value to a register value, and writes the 3146// result to the destination register. It can optionally update the condition 3147// flags based on the result. 3148bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode, 3149 const ARMEncoding encoding) { 3150#if 0 3151 // ARM pseudo code... 3152 if ConditionPassed() then 3153 EncodingSpecificOperations(); 3154 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3155 if d == 15 then 3156 ALUWritePC(result); // setflags is always FALSE here 3157 else 3158 R[d] = result; 3159 if setflags then 3160 APSR.N = result<31>; 3161 APSR.Z = IsZeroBit(result); 3162 APSR.C = carry; 3163 APSR.V = overflow; 3164#endif 3165 3166 bool success = false; 3167 3168 if (ConditionPassed(opcode)) { 3169 uint32_t Rd, Rn; 3170 uint32_t 3171 imm32; // the immediate value to be added to the value obtained from Rn 3172 bool setflags; 3173 switch (encoding) { 3174 case eEncodingA1: 3175 Rd = Bits32(opcode, 15, 12); 3176 Rn = Bits32(opcode, 19, 16); 3177 setflags = BitIsSet(opcode, 20); 3178 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3179 break; 3180 default: 3181 return false; 3182 } 3183 3184 // Read the first operand. 3185 uint32_t val1 = ReadCoreReg(Rn, &success); 3186 if (!success) 3187 return false; 3188 3189 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 3190 3191 EmulateInstruction::Context context; 3192 if (Rd == 13) 3193 context.type = EmulateInstruction::eContextAdjustStackPointer; 3194 else if (Rd == GetFramePointerRegisterNumber()) 3195 context.type = EmulateInstruction::eContextSetFramePointer; 3196 else 3197 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3198 3199 RegisterInfo dwarf_reg; 3200 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 3201 context.SetRegisterPlusOffset(dwarf_reg, imm32); 3202 3203 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3204 res.carry_out, res.overflow)) 3205 return false; 3206 } 3207 return true; 3208} 3209 3210// This instruction adds a register value and an optionally-shifted register 3211// value, and writes the result to the destination register. It can optionally 3212// update the condition flags based on the result. 3213bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode, 3214 const ARMEncoding encoding) { 3215#if 0 3216 // ARM pseudo code... 3217 if ConditionPassed() then 3218 EncodingSpecificOperations(); 3219 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3220 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3221 if d == 15 then 3222 ALUWritePC(result); // setflags is always FALSE here 3223 else 3224 R[d] = result; 3225 if setflags then 3226 APSR.N = result<31>; 3227 APSR.Z = IsZeroBit(result); 3228 APSR.C = carry; 3229 APSR.V = overflow; 3230#endif 3231 3232 bool success = false; 3233 3234 if (ConditionPassed(opcode)) { 3235 uint32_t Rd, Rn, Rm; 3236 ARM_ShifterType shift_t; 3237 uint32_t shift_n; // the shift applied to the value read from Rm 3238 bool setflags; 3239 switch (encoding) { 3240 case eEncodingT1: 3241 Rd = Bits32(opcode, 2, 0); 3242 Rn = Bits32(opcode, 5, 3); 3243 Rm = Bits32(opcode, 8, 6); 3244 setflags = !InITBlock(); 3245 shift_t = SRType_LSL; 3246 shift_n = 0; 3247 break; 3248 case eEncodingT2: 3249 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3250 Rm = Bits32(opcode, 6, 3); 3251 setflags = false; 3252 shift_t = SRType_LSL; 3253 shift_n = 0; 3254 if (Rn == 15 && Rm == 15) 3255 return false; 3256 if (Rd == 15 && InITBlock() && !LastInITBlock()) 3257 return false; 3258 break; 3259 case eEncodingA1: 3260 Rd = Bits32(opcode, 15, 12); 3261 Rn = Bits32(opcode, 19, 16); 3262 Rm = Bits32(opcode, 3, 0); 3263 setflags = BitIsSet(opcode, 20); 3264 shift_n = DecodeImmShiftARM(opcode, shift_t); 3265 break; 3266 default: 3267 return false; 3268 } 3269 3270 // Read the first operand. 3271 uint32_t val1 = ReadCoreReg(Rn, &success); 3272 if (!success) 3273 return false; 3274 3275 // Read the second operand. 3276 uint32_t val2 = ReadCoreReg(Rm, &success); 3277 if (!success) 3278 return false; 3279 3280 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3281 if (!success) 3282 return false; 3283 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3284 3285 EmulateInstruction::Context context; 3286 context.type = eContextArithmetic; 3287 RegisterInfo op1_reg; 3288 RegisterInfo op2_reg; 3289 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 3290 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 3291 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 3292 3293 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3294 res.carry_out, res.overflow)) 3295 return false; 3296 } 3297 return true; 3298} 3299 3300// Compare Negative (immediate) adds a register value and an immediate value. 3301// It updates the condition flags based on the result, and discards the result. 3302bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode, 3303 const ARMEncoding encoding) { 3304#if 0 3305 // ARM pseudo code... 3306 if ConditionPassed() then 3307 EncodingSpecificOperations(); 3308 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3309 APSR.N = result<31>; 3310 APSR.Z = IsZeroBit(result); 3311 APSR.C = carry; 3312 APSR.V = overflow; 3313#endif 3314 3315 bool success = false; 3316 3317 uint32_t Rn; // the first operand 3318 uint32_t imm32; // the immediate value to be compared with 3319 switch (encoding) { 3320 case eEncodingT1: 3321 Rn = Bits32(opcode, 19, 16); 3322 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3323 if (Rn == 15) 3324 return false; 3325 break; 3326 case eEncodingA1: 3327 Rn = Bits32(opcode, 19, 16); 3328 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3329 break; 3330 default: 3331 return false; 3332 } 3333 // Read the register value from the operand register Rn. 3334 uint32_t reg_val = ReadCoreReg(Rn, &success); 3335 if (!success) 3336 return false; 3337 3338 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 3339 3340 EmulateInstruction::Context context; 3341 context.type = EmulateInstruction::eContextImmediate; 3342 context.SetNoArgs(); 3343 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3344 return false; 3345 3346 return true; 3347} 3348 3349// Compare Negative (register) adds a register value and an optionally-shifted 3350// register value. It updates the condition flags based on the result, and 3351// discards the result. 3352bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode, 3353 const ARMEncoding encoding) { 3354#if 0 3355 // ARM pseudo code... 3356 if ConditionPassed() then 3357 EncodingSpecificOperations(); 3358 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3359 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3360 APSR.N = result<31>; 3361 APSR.Z = IsZeroBit(result); 3362 APSR.C = carry; 3363 APSR.V = overflow; 3364#endif 3365 3366 bool success = false; 3367 3368 uint32_t Rn; // the first operand 3369 uint32_t Rm; // the second operand 3370 ARM_ShifterType shift_t; 3371 uint32_t shift_n; // the shift applied to the value read from Rm 3372 switch (encoding) { 3373 case eEncodingT1: 3374 Rn = Bits32(opcode, 2, 0); 3375 Rm = Bits32(opcode, 5, 3); 3376 shift_t = SRType_LSL; 3377 shift_n = 0; 3378 break; 3379 case eEncodingT2: 3380 Rn = Bits32(opcode, 19, 16); 3381 Rm = Bits32(opcode, 3, 0); 3382 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3383 // if n == 15 || BadReg(m) then UNPREDICTABLE; 3384 if (Rn == 15 || BadReg(Rm)) 3385 return false; 3386 break; 3387 case eEncodingA1: 3388 Rn = Bits32(opcode, 19, 16); 3389 Rm = Bits32(opcode, 3, 0); 3390 shift_n = DecodeImmShiftARM(opcode, shift_t); 3391 break; 3392 default: 3393 return false; 3394 } 3395 // Read the register value from register Rn. 3396 uint32_t val1 = ReadCoreReg(Rn, &success); 3397 if (!success) 3398 return false; 3399 3400 // Read the register value from register Rm. 3401 uint32_t val2 = ReadCoreReg(Rm, &success); 3402 if (!success) 3403 return false; 3404 3405 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3406 if (!success) 3407 return false; 3408 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3409 3410 EmulateInstruction::Context context; 3411 context.type = EmulateInstruction::eContextImmediate; 3412 context.SetNoArgs(); 3413 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3414 return false; 3415 3416 return true; 3417} 3418 3419// Compare (immediate) subtracts an immediate value from a register value. It 3420// updates the condition flags based on the result, and discards the result. 3421bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode, 3422 const ARMEncoding encoding) { 3423#if 0 3424 // ARM pseudo code... 3425 if ConditionPassed() then 3426 EncodingSpecificOperations(); 3427 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 3428 APSR.N = result<31>; 3429 APSR.Z = IsZeroBit(result); 3430 APSR.C = carry; 3431 APSR.V = overflow; 3432#endif 3433 3434 bool success = false; 3435 3436 uint32_t Rn; // the first operand 3437 uint32_t imm32; // the immediate value to be compared with 3438 switch (encoding) { 3439 case eEncodingT1: 3440 Rn = Bits32(opcode, 10, 8); 3441 imm32 = Bits32(opcode, 7, 0); 3442 break; 3443 case eEncodingT2: 3444 Rn = Bits32(opcode, 19, 16); 3445 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3446 if (Rn == 15) 3447 return false; 3448 break; 3449 case eEncodingA1: 3450 Rn = Bits32(opcode, 19, 16); 3451 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3452 break; 3453 default: 3454 return false; 3455 } 3456 // Read the register value from the operand register Rn. 3457 uint32_t reg_val = ReadCoreReg(Rn, &success); 3458 if (!success) 3459 return false; 3460 3461 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 3462 3463 EmulateInstruction::Context context; 3464 context.type = EmulateInstruction::eContextImmediate; 3465 context.SetNoArgs(); 3466 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3467 return false; 3468 3469 return true; 3470} 3471 3472// Compare (register) subtracts an optionally-shifted register value from a 3473// register value. It updates the condition flags based on the result, and 3474// discards the result. 3475bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode, 3476 const ARMEncoding encoding) { 3477#if 0 3478 // ARM pseudo code... 3479 if ConditionPassed() then 3480 EncodingSpecificOperations(); 3481 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3482 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 3483 APSR.N = result<31>; 3484 APSR.Z = IsZeroBit(result); 3485 APSR.C = carry; 3486 APSR.V = overflow; 3487#endif 3488 3489 bool success = false; 3490 3491 uint32_t Rn; // the first operand 3492 uint32_t Rm; // the second operand 3493 ARM_ShifterType shift_t; 3494 uint32_t shift_n; // the shift applied to the value read from Rm 3495 switch (encoding) { 3496 case eEncodingT1: 3497 Rn = Bits32(opcode, 2, 0); 3498 Rm = Bits32(opcode, 5, 3); 3499 shift_t = SRType_LSL; 3500 shift_n = 0; 3501 break; 3502 case eEncodingT2: 3503 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3504 Rm = Bits32(opcode, 6, 3); 3505 shift_t = SRType_LSL; 3506 shift_n = 0; 3507 if (Rn < 8 && Rm < 8) 3508 return false; 3509 if (Rn == 15 || Rm == 15) 3510 return false; 3511 break; 3512 case eEncodingT3: 3513 Rn = Bits32(opcode, 19, 16); 3514 Rm = Bits32(opcode, 3, 0); 3515 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3516 if (Rn == 15 || BadReg(Rm)) 3517 return false; 3518 break; 3519 case eEncodingA1: 3520 Rn = Bits32(opcode, 19, 16); 3521 Rm = Bits32(opcode, 3, 0); 3522 shift_n = DecodeImmShiftARM(opcode, shift_t); 3523 break; 3524 default: 3525 return false; 3526 } 3527 // Read the register value from register Rn. 3528 uint32_t val1 = ReadCoreReg(Rn, &success); 3529 if (!success) 3530 return false; 3531 3532 // Read the register value from register Rm. 3533 uint32_t val2 = ReadCoreReg(Rm, &success); 3534 if (!success) 3535 return false; 3536 3537 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3538 if (!success) 3539 return false; 3540 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3541 3542 EmulateInstruction::Context context; 3543 context.type = EmulateInstruction::eContextImmediate; 3544 context.SetNoArgs(); 3545 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3546 return false; 3547 3548 return true; 3549} 3550 3551// Arithmetic Shift Right (immediate) shifts a register value right by an 3552// immediate number of bits, shifting in copies of its sign bit, and writes the 3553// result to the destination register. It can optionally update the condition 3554// flags based on the result. 3555bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode, 3556 const ARMEncoding encoding) { 3557#if 0 3558 // ARM pseudo code... 3559 if ConditionPassed() then 3560 EncodingSpecificOperations(); 3561 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3562 if d == 15 then // Can only occur for ARM encoding 3563 ALUWritePC(result); // setflags is always FALSE here 3564 else 3565 R[d] = result; 3566 if setflags then 3567 APSR.N = result<31>; 3568 APSR.Z = IsZeroBit(result); 3569 APSR.C = carry; 3570 // APSR.V unchanged 3571#endif 3572 3573 return EmulateShiftImm(opcode, encoding, SRType_ASR); 3574} 3575 3576// Arithmetic Shift Right (register) shifts a register value right by a 3577// variable number of bits, shifting in copies of its sign bit, and writes the 3578// result to the destination register. The variable number of bits is read from 3579// the bottom byte of a register. It can optionally update the condition flags 3580// based on the result. 3581bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode, 3582 const ARMEncoding encoding) { 3583#if 0 3584 // ARM pseudo code... 3585 if ConditionPassed() then 3586 EncodingSpecificOperations(); 3587 shift_n = UInt(R[m]<7:0>); 3588 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3589 R[d] = result; 3590 if setflags then 3591 APSR.N = result<31>; 3592 APSR.Z = IsZeroBit(result); 3593 APSR.C = carry; 3594 // APSR.V unchanged 3595#endif 3596 3597 return EmulateShiftReg(opcode, encoding, SRType_ASR); 3598} 3599 3600// Logical Shift Left (immediate) shifts a register value left by an immediate 3601// number of bits, shifting in zeros, and writes the result to the destination 3602// register. It can optionally update the condition flags based on the result. 3603bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode, 3604 const ARMEncoding encoding) { 3605#if 0 3606 // ARM pseudo code... 3607 if ConditionPassed() then 3608 EncodingSpecificOperations(); 3609 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3610 if d == 15 then // Can only occur for ARM encoding 3611 ALUWritePC(result); // setflags is always FALSE here 3612 else 3613 R[d] = result; 3614 if setflags then 3615 APSR.N = result<31>; 3616 APSR.Z = IsZeroBit(result); 3617 APSR.C = carry; 3618 // APSR.V unchanged 3619#endif 3620 3621 return EmulateShiftImm(opcode, encoding, SRType_LSL); 3622} 3623 3624// Logical Shift Left (register) shifts a register value left by a variable 3625// number of bits, shifting in zeros, and writes the result to the destination 3626// register. The variable number of bits is read from the bottom byte of a 3627// register. It can optionally update the condition flags based on the result. 3628bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode, 3629 const ARMEncoding encoding) { 3630#if 0 3631 // ARM pseudo code... 3632 if ConditionPassed() then 3633 EncodingSpecificOperations(); 3634 shift_n = UInt(R[m]<7:0>); 3635 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3636 R[d] = result; 3637 if setflags then 3638 APSR.N = result<31>; 3639 APSR.Z = IsZeroBit(result); 3640 APSR.C = carry; 3641 // APSR.V unchanged 3642#endif 3643 3644 return EmulateShiftReg(opcode, encoding, SRType_LSL); 3645} 3646 3647// Logical Shift Right (immediate) shifts a register value right by an 3648// immediate number of bits, shifting in zeros, and writes the result to the 3649// destination register. It can optionally update the condition flags based on 3650// the result. 3651bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode, 3652 const ARMEncoding encoding) { 3653#if 0 3654 // ARM pseudo code... 3655 if ConditionPassed() then 3656 EncodingSpecificOperations(); 3657 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3658 if d == 15 then // Can only occur for ARM encoding 3659 ALUWritePC(result); // setflags is always FALSE here 3660 else 3661 R[d] = result; 3662 if setflags then 3663 APSR.N = result<31>; 3664 APSR.Z = IsZeroBit(result); 3665 APSR.C = carry; 3666 // APSR.V unchanged 3667#endif 3668 3669 return EmulateShiftImm(opcode, encoding, SRType_LSR); 3670} 3671 3672// Logical Shift Right (register) shifts a register value right by a variable 3673// number of bits, shifting in zeros, and writes the result to the destination 3674// register. The variable number of bits is read from the bottom byte of a 3675// register. It can optionally update the condition flags based on the result. 3676bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode, 3677 const ARMEncoding encoding) { 3678#if 0 3679 // ARM pseudo code... 3680 if ConditionPassed() then 3681 EncodingSpecificOperations(); 3682 shift_n = UInt(R[m]<7:0>); 3683 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3684 R[d] = result; 3685 if setflags then 3686 APSR.N = result<31>; 3687 APSR.Z = IsZeroBit(result); 3688 APSR.C = carry; 3689 // APSR.V unchanged 3690#endif 3691 3692 return EmulateShiftReg(opcode, encoding, SRType_LSR); 3693} 3694 3695// Rotate Right (immediate) provides the value of the contents of a register 3696// rotated by a constant value. The bits that are rotated off the right end are 3697// inserted into the vacated bit positions on the left. It can optionally 3698// update the condition flags based on the result. 3699bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode, 3700 const ARMEncoding encoding) { 3701#if 0 3702 // ARM pseudo code... 3703 if ConditionPassed() then 3704 EncodingSpecificOperations(); 3705 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3706 if d == 15 then // Can only occur for ARM encoding 3707 ALUWritePC(result); // setflags is always FALSE here 3708 else 3709 R[d] = result; 3710 if setflags then 3711 APSR.N = result<31>; 3712 APSR.Z = IsZeroBit(result); 3713 APSR.C = carry; 3714 // APSR.V unchanged 3715#endif 3716 3717 return EmulateShiftImm(opcode, encoding, SRType_ROR); 3718} 3719 3720// Rotate Right (register) provides the value of the contents of a register 3721// rotated by a variable number of bits. The bits that are rotated off the 3722// right end are inserted into the vacated bit positions on the left. The 3723// variable number of bits is read from the bottom byte of a register. It can 3724// optionally update the condition flags based on the result. 3725bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode, 3726 const ARMEncoding encoding) { 3727#if 0 3728 // ARM pseudo code... 3729 if ConditionPassed() then 3730 EncodingSpecificOperations(); 3731 shift_n = UInt(R[m]<7:0>); 3732 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3733 R[d] = result; 3734 if setflags then 3735 APSR.N = result<31>; 3736 APSR.Z = IsZeroBit(result); 3737 APSR.C = carry; 3738 // APSR.V unchanged 3739#endif 3740 3741 return EmulateShiftReg(opcode, encoding, SRType_ROR); 3742} 3743 3744// Rotate Right with Extend provides the value of the contents of a register 3745// shifted right by one place, with the carry flag shifted into bit [31]. 3746// 3747// RRX can optionally update the condition flags based on the result. 3748// In that case, bit [0] is shifted into the carry flag. 3749bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode, 3750 const ARMEncoding encoding) { 3751#if 0 3752 // ARM pseudo code... 3753 if ConditionPassed() then 3754 EncodingSpecificOperations(); 3755 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3756 if d == 15 then // Can only occur for ARM encoding 3757 ALUWritePC(result); // setflags is always FALSE here 3758 else 3759 R[d] = result; 3760 if setflags then 3761 APSR.N = result<31>; 3762 APSR.Z = IsZeroBit(result); 3763 APSR.C = carry; 3764 // APSR.V unchanged 3765#endif 3766 3767 return EmulateShiftImm(opcode, encoding, SRType_RRX); 3768} 3769 3770bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode, 3771 const ARMEncoding encoding, 3772 ARM_ShifterType shift_type) { 3773 // assert(shift_type == SRType_ASR 3774 // || shift_type == SRType_LSL 3775 // || shift_type == SRType_LSR 3776 // || shift_type == SRType_ROR 3777 // || shift_type == SRType_RRX); 3778 3779 bool success = false; 3780 3781 if (ConditionPassed(opcode)) { 3782 uint32_t Rd; // the destination register 3783 uint32_t Rm; // the first operand register 3784 uint32_t imm5; // encoding for the shift amount 3785 uint32_t carry; // the carry bit after the shift operation 3786 bool setflags; 3787 3788 // Special case handling! 3789 // A8.6.139 ROR (immediate) -- Encoding T1 3790 ARMEncoding use_encoding = encoding; 3791 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) { 3792 // Morph the T1 encoding from the ARM Architecture Manual into T2 3793 // encoding to have the same decoding of bit fields as the other Thumb2 3794 // shift operations. 3795 use_encoding = eEncodingT2; 3796 } 3797 3798 switch (use_encoding) { 3799 case eEncodingT1: 3800 // Due to the above special case handling! 3801 if (shift_type == SRType_ROR) 3802 return false; 3803 3804 Rd = Bits32(opcode, 2, 0); 3805 Rm = Bits32(opcode, 5, 3); 3806 setflags = !InITBlock(); 3807 imm5 = Bits32(opcode, 10, 6); 3808 break; 3809 case eEncodingT2: 3810 // A8.6.141 RRX 3811 // There's no imm form of RRX instructions. 3812 if (shift_type == SRType_RRX) 3813 return false; 3814 3815 Rd = Bits32(opcode, 11, 8); 3816 Rm = Bits32(opcode, 3, 0); 3817 setflags = BitIsSet(opcode, 20); 3818 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3819 if (BadReg(Rd) || BadReg(Rm)) 3820 return false; 3821 break; 3822 case eEncodingA1: 3823 Rd = Bits32(opcode, 15, 12); 3824 Rm = Bits32(opcode, 3, 0); 3825 setflags = BitIsSet(opcode, 20); 3826 imm5 = Bits32(opcode, 11, 7); 3827 break; 3828 default: 3829 return false; 3830 } 3831 3832 // A8.6.139 ROR (immediate) 3833 if (shift_type == SRType_ROR && imm5 == 0) 3834 shift_type = SRType_RRX; 3835 3836 // Get the first operand. 3837 uint32_t value = ReadCoreReg(Rm, &success); 3838 if (!success) 3839 return false; 3840 3841 // Decode the shift amount if not RRX. 3842 uint32_t amt = 3843 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3844 3845 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3846 if (!success) 3847 return false; 3848 3849 // The context specifies that an immediate is to be moved into Rd. 3850 EmulateInstruction::Context context; 3851 context.type = EmulateInstruction::eContextImmediate; 3852 context.SetNoArgs(); 3853 3854 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3855 return false; 3856 } 3857 return true; 3858} 3859 3860bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode, 3861 const ARMEncoding encoding, 3862 ARM_ShifterType shift_type) { 3863 // assert(shift_type == SRType_ASR 3864 // || shift_type == SRType_LSL 3865 // || shift_type == SRType_LSR 3866 // || shift_type == SRType_ROR); 3867 3868 bool success = false; 3869 3870 if (ConditionPassed(opcode)) { 3871 uint32_t Rd; // the destination register 3872 uint32_t Rn; // the first operand register 3873 uint32_t 3874 Rm; // the register whose bottom byte contains the amount to shift by 3875 uint32_t carry; // the carry bit after the shift operation 3876 bool setflags; 3877 switch (encoding) { 3878 case eEncodingT1: 3879 Rd = Bits32(opcode, 2, 0); 3880 Rn = Rd; 3881 Rm = Bits32(opcode, 5, 3); 3882 setflags = !InITBlock(); 3883 break; 3884 case eEncodingT2: 3885 Rd = Bits32(opcode, 11, 8); 3886 Rn = Bits32(opcode, 19, 16); 3887 Rm = Bits32(opcode, 3, 0); 3888 setflags = BitIsSet(opcode, 20); 3889 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3890 return false; 3891 break; 3892 case eEncodingA1: 3893 Rd = Bits32(opcode, 15, 12); 3894 Rn = Bits32(opcode, 3, 0); 3895 Rm = Bits32(opcode, 11, 8); 3896 setflags = BitIsSet(opcode, 20); 3897 if (Rd == 15 || Rn == 15 || Rm == 15) 3898 return false; 3899 break; 3900 default: 3901 return false; 3902 } 3903 3904 // Get the first operand. 3905 uint32_t value = ReadCoreReg(Rn, &success); 3906 if (!success) 3907 return false; 3908 // Get the Rm register content. 3909 uint32_t val = ReadCoreReg(Rm, &success); 3910 if (!success) 3911 return false; 3912 3913 // Get the shift amount. 3914 uint32_t amt = Bits32(val, 7, 0); 3915 3916 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3917 if (!success) 3918 return false; 3919 3920 // The context specifies that an immediate is to be moved into Rd. 3921 EmulateInstruction::Context context; 3922 context.type = EmulateInstruction::eContextImmediate; 3923 context.SetNoArgs(); 3924 3925 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3926 return false; 3927 } 3928 return true; 3929} 3930 3931// LDM loads multiple registers from consecutive memory locations, using an 3932// address from a base register. Optionally the address just above the highest 3933// of those locations can be written back to the base register. 3934bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode, 3935 const ARMEncoding encoding) { 3936#if 0 3937 // ARM pseudo code... 3938 if ConditionPassed() 3939 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3940 address = R[n]; 3941 3942 for i = 0 to 14 3943 if registers<i> == '1' then 3944 R[i] = MemA[address, 4]; address = address + 4; 3945 if registers<15> == '1' then 3946 LoadWritePC (MemA[address, 4]); 3947 3948 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3949 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3950 3951#endif 3952 3953 bool success = false; 3954 if (ConditionPassed(opcode)) { 3955 uint32_t n; 3956 uint32_t registers = 0; 3957 bool wback; 3958 const uint32_t addr_byte_size = GetAddressByteSize(); 3959 switch (encoding) { 3960 case eEncodingT1: 3961 // n = UInt(Rn); registers = '00000000':register_list; wback = 3962 // (registers<n> == '0'); 3963 n = Bits32(opcode, 10, 8); 3964 registers = Bits32(opcode, 7, 0); 3965 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3966 wback = BitIsClear(registers, n); 3967 // if BitCount(registers) < 1 then UNPREDICTABLE; 3968 if (BitCount(registers) < 1) 3969 return false; 3970 break; 3971 case eEncodingT2: 3972 // if W == '1' && Rn == '1101' then SEE POP; 3973 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3974 n = Bits32(opcode, 19, 16); 3975 registers = Bits32(opcode, 15, 0); 3976 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3977 wback = BitIsSet(opcode, 21); 3978 3979 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 3980 // UNPREDICTABLE; 3981 if ((n == 15) || (BitCount(registers) < 2) || 3982 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 3983 return false; 3984 3985 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 3986 // UNPREDICTABLE; 3987 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 3988 return false; 3989 3990 // if wback && registers<n> == '1' then UNPREDICTABLE; 3991 if (wback && BitIsSet(registers, n)) 3992 return false; 3993 break; 3994 3995 case eEncodingA1: 3996 n = Bits32(opcode, 19, 16); 3997 registers = Bits32(opcode, 15, 0); 3998 wback = BitIsSet(opcode, 21); 3999 if ((n == 15) || (BitCount(registers) < 1)) 4000 return false; 4001 break; 4002 default: 4003 return false; 4004 } 4005 4006 int32_t offset = 0; 4007 const addr_t base_address = 4008 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4009 if (!success) 4010 return false; 4011 4012 EmulateInstruction::Context context; 4013 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4014 RegisterInfo dwarf_reg; 4015 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4016 context.SetRegisterPlusOffset(dwarf_reg, offset); 4017 4018 for (int i = 0; i < 14; ++i) { 4019 if (BitIsSet(registers, i)) { 4020 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4021 context.SetRegisterPlusOffset(dwarf_reg, offset); 4022 if (wback && (n == 13)) // Pop Instruction 4023 { 4024 context.type = EmulateInstruction::eContextPopRegisterOffStack; 4025 context.SetAddress(base_address + offset); 4026 } 4027 4028 // R[i] = MemA [address, 4]; address = address + 4; 4029 uint32_t data = MemARead(context, base_address + offset, addr_byte_size, 4030 0, &success); 4031 if (!success) 4032 return false; 4033 4034 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4035 data)) 4036 return false; 4037 4038 offset += addr_byte_size; 4039 } 4040 } 4041 4042 if (BitIsSet(registers, 15)) { 4043 // LoadWritePC (MemA [address, 4]); 4044 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4045 context.SetRegisterPlusOffset(dwarf_reg, offset); 4046 uint32_t data = 4047 MemARead(context, base_address + offset, addr_byte_size, 0, &success); 4048 if (!success) 4049 return false; 4050 // In ARMv5T and above, this is an interworking branch. 4051 if (!LoadWritePC(context, data)) 4052 return false; 4053 } 4054 4055 if (wback && BitIsClear(registers, n)) { 4056 // R[n] = R[n] + 4 * BitCount (registers) 4057 int32_t offset = addr_byte_size * BitCount(registers); 4058 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4059 context.SetRegisterPlusOffset(dwarf_reg, offset); 4060 4061 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4062 base_address + offset)) 4063 return false; 4064 } 4065 if (wback && BitIsSet(registers, n)) 4066 // R[n] bits(32) UNKNOWN; 4067 return WriteBits32Unknown(n); 4068 } 4069 return true; 4070} 4071 4072// LDMDA loads multiple registers from consecutive memory locations using an 4073// address from a base register. 4074// The consecutive memory locations end at this address and the address just 4075// below the lowest of those locations can optionally be written back to the 4076// base register. 4077bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode, 4078 const ARMEncoding encoding) { 4079#if 0 4080 // ARM pseudo code... 4081 if ConditionPassed() then 4082 EncodingSpecificOperations(); 4083 address = R[n] - 4*BitCount(registers) + 4; 4084 4085 for i = 0 to 14 4086 if registers<i> == '1' then 4087 R[i] = MemA[address,4]; address = address + 4; 4088 4089 if registers<15> == '1' then 4090 LoadWritePC(MemA[address,4]); 4091 4092 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4093 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4094#endif 4095 4096 bool success = false; 4097 4098 if (ConditionPassed(opcode)) { 4099 uint32_t n; 4100 uint32_t registers = 0; 4101 bool wback; 4102 const uint32_t addr_byte_size = GetAddressByteSize(); 4103 4104 // EncodingSpecificOperations(); 4105 switch (encoding) { 4106 case eEncodingA1: 4107 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4108 n = Bits32(opcode, 19, 16); 4109 registers = Bits32(opcode, 15, 0); 4110 wback = BitIsSet(opcode, 21); 4111 4112 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4113 if ((n == 15) || (BitCount(registers) < 1)) 4114 return false; 4115 4116 break; 4117 4118 default: 4119 return false; 4120 } 4121 // address = R[n] - 4*BitCount(registers) + 4; 4122 4123 int32_t offset = 0; 4124 addr_t Rn = ReadCoreReg(n, &success); 4125 4126 if (!success) 4127 return false; 4128 4129 addr_t address = 4130 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size; 4131 4132 EmulateInstruction::Context context; 4133 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4134 RegisterInfo dwarf_reg; 4135 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4136 context.SetRegisterPlusOffset(dwarf_reg, offset); 4137 4138 // for i = 0 to 14 4139 for (int i = 0; i < 14; ++i) { 4140 // if registers<i> == '1' then 4141 if (BitIsSet(registers, i)) { 4142 // R[i] = MemA[address,4]; address = address + 4; 4143 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4144 uint32_t data = 4145 MemARead(context, address + offset, addr_byte_size, 0, &success); 4146 if (!success) 4147 return false; 4148 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4149 data)) 4150 return false; 4151 offset += addr_byte_size; 4152 } 4153 } 4154 4155 // if registers<15> == '1' then 4156 // LoadWritePC(MemA[address,4]); 4157 if (BitIsSet(registers, 15)) { 4158 context.SetRegisterPlusOffset(dwarf_reg, offset); 4159 uint32_t data = 4160 MemARead(context, address + offset, addr_byte_size, 0, &success); 4161 if (!success) 4162 return false; 4163 // In ARMv5T and above, this is an interworking branch. 4164 if (!LoadWritePC(context, data)) 4165 return false; 4166 } 4167 4168 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4169 if (wback && BitIsClear(registers, n)) { 4170 if (!success) 4171 return false; 4172 4173 offset = (addr_byte_size * BitCount(registers)) * -1; 4174 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4175 context.SetImmediateSigned(offset); 4176 addr_t addr = Rn + offset; 4177 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4178 addr)) 4179 return false; 4180 } 4181 4182 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4183 if (wback && BitIsSet(registers, n)) 4184 return WriteBits32Unknown(n); 4185 } 4186 return true; 4187} 4188 4189// LDMDB loads multiple registers from consecutive memory locations using an 4190// address from a base register. The 4191// consecutive memory locations end just below this address, and the address of 4192// the lowest of those locations can be optionally written back to the base 4193// register. 4194bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode, 4195 const ARMEncoding encoding) { 4196#if 0 4197 // ARM pseudo code... 4198 if ConditionPassed() then 4199 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4200 address = R[n] - 4*BitCount(registers); 4201 4202 for i = 0 to 14 4203 if registers<i> == '1' then 4204 R[i] = MemA[address,4]; address = address + 4; 4205 if registers<15> == '1' then 4206 LoadWritePC(MemA[address,4]); 4207 4208 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4209 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 4210#endif 4211 4212 bool success = false; 4213 4214 if (ConditionPassed(opcode)) { 4215 uint32_t n; 4216 uint32_t registers = 0; 4217 bool wback; 4218 const uint32_t addr_byte_size = GetAddressByteSize(); 4219 switch (encoding) { 4220 case eEncodingT1: 4221 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 4222 n = Bits32(opcode, 19, 16); 4223 registers = Bits32(opcode, 15, 0); 4224 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 4225 wback = BitIsSet(opcode, 21); 4226 4227 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 4228 // UNPREDICTABLE; 4229 if ((n == 15) || (BitCount(registers) < 2) || 4230 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 4231 return false; 4232 4233 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 4234 // UNPREDICTABLE; 4235 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 4236 return false; 4237 4238 // if wback && registers<n> == '1' then UNPREDICTABLE; 4239 if (wback && BitIsSet(registers, n)) 4240 return false; 4241 4242 break; 4243 4244 case eEncodingA1: 4245 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4246 n = Bits32(opcode, 19, 16); 4247 registers = Bits32(opcode, 15, 0); 4248 wback = BitIsSet(opcode, 21); 4249 4250 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4251 if ((n == 15) || (BitCount(registers) < 1)) 4252 return false; 4253 4254 break; 4255 4256 default: 4257 return false; 4258 } 4259 4260 // address = R[n] - 4*BitCount(registers); 4261 4262 int32_t offset = 0; 4263 addr_t Rn = 4264 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4265 4266 if (!success) 4267 return false; 4268 4269 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4270 EmulateInstruction::Context context; 4271 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4272 RegisterInfo dwarf_reg; 4273 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4274 context.SetRegisterPlusOffset(dwarf_reg, Rn - address); 4275 4276 for (int i = 0; i < 14; ++i) { 4277 if (BitIsSet(registers, i)) { 4278 // R[i] = MemA[address,4]; address = address + 4; 4279 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4280 uint32_t data = 4281 MemARead(context, address + offset, addr_byte_size, 0, &success); 4282 if (!success) 4283 return false; 4284 4285 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4286 data)) 4287 return false; 4288 4289 offset += addr_byte_size; 4290 } 4291 } 4292 4293 // if registers<15> == '1' then 4294 // LoadWritePC(MemA[address,4]); 4295 if (BitIsSet(registers, 15)) { 4296 context.SetRegisterPlusOffset(dwarf_reg, offset); 4297 uint32_t data = 4298 MemARead(context, address + offset, addr_byte_size, 0, &success); 4299 if (!success) 4300 return false; 4301 // In ARMv5T and above, this is an interworking branch. 4302 if (!LoadWritePC(context, data)) 4303 return false; 4304 } 4305 4306 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4307 if (wback && BitIsClear(registers, n)) { 4308 if (!success) 4309 return false; 4310 4311 offset = (addr_byte_size * BitCount(registers)) * -1; 4312 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4313 context.SetImmediateSigned(offset); 4314 addr_t addr = Rn + offset; 4315 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4316 addr)) 4317 return false; 4318 } 4319 4320 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4321 // possible for encoding A1 4322 if (wback && BitIsSet(registers, n)) 4323 return WriteBits32Unknown(n); 4324 } 4325 return true; 4326} 4327 4328// LDMIB loads multiple registers from consecutive memory locations using an 4329// address from a base register. The 4330// consecutive memory locations start just above this address, and thea ddress 4331// of the last of those locations can optinoally be written back to the base 4332// register. 4333bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode, 4334 const ARMEncoding encoding) { 4335#if 0 4336 if ConditionPassed() then 4337 EncodingSpecificOperations(); 4338 address = R[n] + 4; 4339 4340 for i = 0 to 14 4341 if registers<i> == '1' then 4342 R[i] = MemA[address,4]; address = address + 4; 4343 if registers<15> == '1' then 4344 LoadWritePC(MemA[address,4]); 4345 4346 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4347 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4348#endif 4349 4350 bool success = false; 4351 4352 if (ConditionPassed(opcode)) { 4353 uint32_t n; 4354 uint32_t registers = 0; 4355 bool wback; 4356 const uint32_t addr_byte_size = GetAddressByteSize(); 4357 switch (encoding) { 4358 case eEncodingA1: 4359 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4360 n = Bits32(opcode, 19, 16); 4361 registers = Bits32(opcode, 15, 0); 4362 wback = BitIsSet(opcode, 21); 4363 4364 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4365 if ((n == 15) || (BitCount(registers) < 1)) 4366 return false; 4367 4368 break; 4369 default: 4370 return false; 4371 } 4372 // address = R[n] + 4; 4373 4374 int32_t offset = 0; 4375 addr_t Rn = 4376 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4377 4378 if (!success) 4379 return false; 4380 4381 addr_t address = Rn + addr_byte_size; 4382 4383 EmulateInstruction::Context context; 4384 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4385 RegisterInfo dwarf_reg; 4386 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4387 context.SetRegisterPlusOffset(dwarf_reg, offset); 4388 4389 for (int i = 0; i < 14; ++i) { 4390 if (BitIsSet(registers, i)) { 4391 // R[i] = MemA[address,4]; address = address + 4; 4392 4393 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size); 4394 uint32_t data = 4395 MemARead(context, address + offset, addr_byte_size, 0, &success); 4396 if (!success) 4397 return false; 4398 4399 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4400 data)) 4401 return false; 4402 4403 offset += addr_byte_size; 4404 } 4405 } 4406 4407 // if registers<15> == '1' then 4408 // LoadWritePC(MemA[address,4]); 4409 if (BitIsSet(registers, 15)) { 4410 context.SetRegisterPlusOffset(dwarf_reg, offset); 4411 uint32_t data = 4412 MemARead(context, address + offset, addr_byte_size, 0, &success); 4413 if (!success) 4414 return false; 4415 // In ARMv5T and above, this is an interworking branch. 4416 if (!LoadWritePC(context, data)) 4417 return false; 4418 } 4419 4420 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4421 if (wback && BitIsClear(registers, n)) { 4422 if (!success) 4423 return false; 4424 4425 offset = addr_byte_size * BitCount(registers); 4426 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4427 context.SetImmediateSigned(offset); 4428 addr_t addr = Rn + offset; 4429 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4430 addr)) 4431 return false; 4432 } 4433 4434 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4435 // possible for encoding A1 4436 if (wback && BitIsSet(registers, n)) 4437 return WriteBits32Unknown(n); 4438 } 4439 return true; 4440} 4441 4442// Load Register (immediate) calculates an address from a base register value 4443// and an immediate offset, loads a word from memory, and writes to a register. 4444// LDR (immediate, Thumb) 4445bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode, 4446 const ARMEncoding encoding) { 4447#if 0 4448 // ARM pseudo code... 4449 if (ConditionPassed()) 4450 { 4451 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 4452 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4453 address = if index then offset_addr else R[n]; 4454 data = MemU[address,4]; 4455 if wback then R[n] = offset_addr; 4456 if t == 15 then 4457 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 4458 elsif UnalignedSupport() || address<1:0> = '00' then 4459 R[t] = data; 4460 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 4461 } 4462#endif 4463 4464 bool success = false; 4465 4466 if (ConditionPassed(opcode)) { 4467 uint32_t Rt; // the destination register 4468 uint32_t Rn; // the base register 4469 uint32_t imm32; // the immediate offset used to form the address 4470 addr_t offset_addr; // the offset address 4471 addr_t address; // the calculated address 4472 uint32_t data; // the literal data value from memory load 4473 bool add, index, wback; 4474 switch (encoding) { 4475 case eEncodingT1: 4476 Rt = Bits32(opcode, 2, 0); 4477 Rn = Bits32(opcode, 5, 3); 4478 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 4479 // index = TRUE; add = TRUE; wback = FALSE 4480 add = true; 4481 index = true; 4482 wback = false; 4483 4484 break; 4485 4486 case eEncodingT2: 4487 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4488 Rt = Bits32(opcode, 10, 8); 4489 Rn = 13; 4490 imm32 = Bits32(opcode, 7, 0) << 2; 4491 4492 // index = TRUE; add = TRUE; wback = FALSE; 4493 index = true; 4494 add = true; 4495 wback = false; 4496 4497 break; 4498 4499 case eEncodingT3: 4500 // if Rn == '1111' then SEE LDR (literal); 4501 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4502 Rt = Bits32(opcode, 15, 12); 4503 Rn = Bits32(opcode, 19, 16); 4504 imm32 = Bits32(opcode, 11, 0); 4505 4506 // index = TRUE; add = TRUE; wback = FALSE; 4507 index = true; 4508 add = true; 4509 wback = false; 4510 4511 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4512 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4513 return false; 4514 4515 break; 4516 4517 case eEncodingT4: 4518 // if Rn == '1111' then SEE LDR (literal); 4519 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4520 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == 4521 // '00000100' then SEE POP; 4522 // if P == '0' && W == '0' then UNDEFINED; 4523 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 4524 return false; 4525 4526 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4527 Rt = Bits32(opcode, 15, 12); 4528 Rn = Bits32(opcode, 19, 16); 4529 imm32 = Bits32(opcode, 7, 0); 4530 4531 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4532 index = BitIsSet(opcode, 10); 4533 add = BitIsSet(opcode, 9); 4534 wback = BitIsSet(opcode, 8); 4535 4536 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) 4537 // then UNPREDICTABLE; 4538 if ((wback && (Rn == Rt)) || 4539 ((Rt == 15) && InITBlock() && !LastInITBlock())) 4540 return false; 4541 4542 break; 4543 4544 default: 4545 return false; 4546 } 4547 uint32_t base = ReadCoreReg(Rn, &success); 4548 if (!success) 4549 return false; 4550 if (add) 4551 offset_addr = base + imm32; 4552 else 4553 offset_addr = base - imm32; 4554 4555 address = (index ? offset_addr : base); 4556 4557 RegisterInfo base_reg; 4558 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4559 if (wback) { 4560 EmulateInstruction::Context ctx; 4561 if (Rn == 13) { 4562 ctx.type = eContextAdjustStackPointer; 4563 ctx.SetImmediateSigned((int32_t)(offset_addr - base)); 4564 } else if (Rn == GetFramePointerRegisterNumber()) { 4565 ctx.type = eContextSetFramePointer; 4566 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4567 } else { 4568 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4569 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4570 } 4571 4572 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn, 4573 offset_addr)) 4574 return false; 4575 } 4576 4577 // Prepare to write to the Rt register. 4578 EmulateInstruction::Context context; 4579 context.type = EmulateInstruction::eContextRegisterLoad; 4580 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4581 4582 // Read memory from the address. 4583 data = MemURead(context, address, 4, 0, &success); 4584 if (!success) 4585 return false; 4586 4587 if (Rt == 15) { 4588 if (Bits32(address, 1, 0) == 0) { 4589 if (!LoadWritePC(context, data)) 4590 return false; 4591 } else 4592 return false; 4593 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 4594 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 4595 data)) 4596 return false; 4597 } else 4598 WriteBits32Unknown(Rt); 4599 } 4600 return true; 4601} 4602 4603// STM (Store Multiple Increment After) stores multiple registers to consecutive 4604// memory locations using an address 4605// from a base register. The consecutive memory locations start at this 4606// address, and the address just above the last of those locations can 4607// optionally be written back to the base register. 4608bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode, 4609 const ARMEncoding encoding) { 4610#if 0 4611 if ConditionPassed() then 4612 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4613 address = R[n]; 4614 4615 for i = 0 to 14 4616 if registers<i> == '1' then 4617 if i == n && wback && i != LowestSetBit(registers) then 4618 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4619 else 4620 MemA[address,4] = R[i]; 4621 address = address + 4; 4622 4623 if registers<15> == '1' then // Only possible for encoding A1 4624 MemA[address,4] = PCStoreValue(); 4625 if wback then R[n] = R[n] + 4*BitCount(registers); 4626#endif 4627 4628 bool success = false; 4629 4630 if (ConditionPassed(opcode)) { 4631 uint32_t n; 4632 uint32_t registers = 0; 4633 bool wback; 4634 const uint32_t addr_byte_size = GetAddressByteSize(); 4635 4636 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4637 switch (encoding) { 4638 case eEncodingT1: 4639 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4640 n = Bits32(opcode, 10, 8); 4641 registers = Bits32(opcode, 7, 0); 4642 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4643 wback = true; 4644 4645 // if BitCount(registers) < 1 then UNPREDICTABLE; 4646 if (BitCount(registers) < 1) 4647 return false; 4648 4649 break; 4650 4651 case eEncodingT2: 4652 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4653 n = Bits32(opcode, 19, 16); 4654 registers = Bits32(opcode, 15, 0); 4655 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4656 wback = BitIsSet(opcode, 21); 4657 4658 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4659 if ((n == 15) || (BitCount(registers) < 2)) 4660 return false; 4661 4662 // if wback && registers<n> == '1' then UNPREDICTABLE; 4663 if (wback && BitIsSet(registers, n)) 4664 return false; 4665 4666 break; 4667 4668 case eEncodingA1: 4669 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4670 n = Bits32(opcode, 19, 16); 4671 registers = Bits32(opcode, 15, 0); 4672 wback = BitIsSet(opcode, 21); 4673 4674 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4675 if ((n == 15) || (BitCount(registers) < 1)) 4676 return false; 4677 4678 break; 4679 4680 default: 4681 return false; 4682 } 4683 4684 // address = R[n]; 4685 int32_t offset = 0; 4686 const addr_t address = 4687 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4688 if (!success) 4689 return false; 4690 4691 EmulateInstruction::Context context; 4692 context.type = EmulateInstruction::eContextRegisterStore; 4693 RegisterInfo base_reg; 4694 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4695 4696 // for i = 0 to 14 4697 uint32_t lowest_set_bit = 14; 4698 for (uint32_t i = 0; i < 14; ++i) { 4699 // if registers<i> == '1' then 4700 if (BitIsSet(registers, i)) { 4701 if (i < lowest_set_bit) 4702 lowest_set_bit = i; 4703 // if i == n && wback && i != LowestSetBit(registers) then 4704 if ((i == n) && wback && (i != lowest_set_bit)) 4705 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings 4706 // T1 and A1 4707 WriteBits32UnknownToMemory(address + offset); 4708 else { 4709 // MemA[address,4] = R[i]; 4710 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4711 0, &success); 4712 if (!success) 4713 return false; 4714 4715 RegisterInfo data_reg; 4716 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4717 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 4718 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4719 return false; 4720 } 4721 4722 // address = address + 4; 4723 offset += addr_byte_size; 4724 } 4725 } 4726 4727 // if registers<15> == '1' then // Only possible for encoding A1 4728 // MemA[address,4] = PCStoreValue(); 4729 if (BitIsSet(registers, 15)) { 4730 RegisterInfo pc_reg; 4731 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4732 context.SetRegisterPlusOffset(pc_reg, 8); 4733 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4734 if (!success) 4735 return false; 4736 4737 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4738 return false; 4739 } 4740 4741 // if wback then R[n] = R[n] + 4*BitCount(registers); 4742 if (wback) { 4743 offset = addr_byte_size * BitCount(registers); 4744 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4745 context.SetImmediateSigned(offset); 4746 addr_t data = address + offset; 4747 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4748 data)) 4749 return false; 4750 } 4751 } 4752 return true; 4753} 4754 4755// STMDA (Store Multiple Decrement After) stores multiple registers to 4756// consecutive memory locations using an address from a base register. The 4757// consecutive memory locations end at this address, and the address just below 4758// the lowest of those locations can optionally be written back to the base 4759// register. 4760bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode, 4761 const ARMEncoding encoding) { 4762#if 0 4763 if ConditionPassed() then 4764 EncodingSpecificOperations(); 4765 address = R[n] - 4*BitCount(registers) + 4; 4766 4767 for i = 0 to 14 4768 if registers<i> == '1' then 4769 if i == n && wback && i != LowestSetBit(registers) then 4770 MemA[address,4] = bits(32) UNKNOWN; 4771 else 4772 MemA[address,4] = R[i]; 4773 address = address + 4; 4774 4775 if registers<15> == '1' then 4776 MemA[address,4] = PCStoreValue(); 4777 4778 if wback then R[n] = R[n] - 4*BitCount(registers); 4779#endif 4780 4781 bool success = false; 4782 4783 if (ConditionPassed(opcode)) { 4784 uint32_t n; 4785 uint32_t registers = 0; 4786 bool wback; 4787 const uint32_t addr_byte_size = GetAddressByteSize(); 4788 4789 // EncodingSpecificOperations(); 4790 switch (encoding) { 4791 case eEncodingA1: 4792 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4793 n = Bits32(opcode, 19, 16); 4794 registers = Bits32(opcode, 15, 0); 4795 wback = BitIsSet(opcode, 21); 4796 4797 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4798 if ((n == 15) || (BitCount(registers) < 1)) 4799 return false; 4800 break; 4801 default: 4802 return false; 4803 } 4804 4805 // address = R[n] - 4*BitCount(registers) + 4; 4806 int32_t offset = 0; 4807 addr_t Rn = ReadCoreReg(n, &success); 4808 if (!success) 4809 return false; 4810 4811 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4; 4812 4813 EmulateInstruction::Context context; 4814 context.type = EmulateInstruction::eContextRegisterStore; 4815 RegisterInfo base_reg; 4816 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4817 4818 // for i = 0 to 14 4819 uint32_t lowest_bit_set = 14; 4820 for (uint32_t i = 0; i < 14; ++i) { 4821 // if registers<i> == '1' then 4822 if (BitIsSet(registers, i)) { 4823 if (i < lowest_bit_set) 4824 lowest_bit_set = i; 4825 // if i == n && wback && i != LowestSetBit(registers) then 4826 if ((i == n) && wback && (i != lowest_bit_set)) 4827 // MemA[address,4] = bits(32) UNKNOWN; 4828 WriteBits32UnknownToMemory(address + offset); 4829 else { 4830 // MemA[address,4] = R[i]; 4831 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4832 0, &success); 4833 if (!success) 4834 return false; 4835 4836 RegisterInfo data_reg; 4837 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4838 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4839 Rn - (address + offset)); 4840 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4841 return false; 4842 } 4843 4844 // address = address + 4; 4845 offset += addr_byte_size; 4846 } 4847 } 4848 4849 // if registers<15> == '1' then 4850 // MemA[address,4] = PCStoreValue(); 4851 if (BitIsSet(registers, 15)) { 4852 RegisterInfo pc_reg; 4853 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4854 context.SetRegisterPlusOffset(pc_reg, 8); 4855 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4856 if (!success) 4857 return false; 4858 4859 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4860 return false; 4861 } 4862 4863 // if wback then R[n] = R[n] - 4*BitCount(registers); 4864 if (wback) { 4865 offset = (addr_byte_size * BitCount(registers)) * -1; 4866 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4867 context.SetImmediateSigned(offset); 4868 addr_t data = Rn + offset; 4869 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4870 data)) 4871 return false; 4872 } 4873 } 4874 return true; 4875} 4876 4877// STMDB (Store Multiple Decrement Before) stores multiple registers to 4878// consecutive memory locations using an address from a base register. The 4879// consecutive memory locations end just below this address, and the address of 4880// the first of those locations can optionally be written back to the base 4881// register. 4882bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode, 4883 const ARMEncoding encoding) { 4884#if 0 4885 if ConditionPassed() then 4886 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4887 address = R[n] - 4*BitCount(registers); 4888 4889 for i = 0 to 14 4890 if registers<i> == '1' then 4891 if i == n && wback && i != LowestSetBit(registers) then 4892 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4893 else 4894 MemA[address,4] = R[i]; 4895 address = address + 4; 4896 4897 if registers<15> == '1' then // Only possible for encoding A1 4898 MemA[address,4] = PCStoreValue(); 4899 4900 if wback then R[n] = R[n] - 4*BitCount(registers); 4901#endif 4902 4903 bool success = false; 4904 4905 if (ConditionPassed(opcode)) { 4906 uint32_t n; 4907 uint32_t registers = 0; 4908 bool wback; 4909 const uint32_t addr_byte_size = GetAddressByteSize(); 4910 4911 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4912 switch (encoding) { 4913 case eEncodingT1: 4914 // if W == '1' && Rn == '1101' then SEE PUSH; 4915 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) { 4916 // See PUSH 4917 } 4918 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4919 n = Bits32(opcode, 19, 16); 4920 registers = Bits32(opcode, 15, 0); 4921 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4922 wback = BitIsSet(opcode, 21); 4923 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4924 if ((n == 15) || BitCount(registers) < 2) 4925 return false; 4926 // if wback && registers<n> == '1' then UNPREDICTABLE; 4927 if (wback && BitIsSet(registers, n)) 4928 return false; 4929 break; 4930 4931 case eEncodingA1: 4932 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE 4933 // PUSH; 4934 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) && 4935 BitCount(Bits32(opcode, 15, 0)) >= 2) { 4936 // See Push 4937 } 4938 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4939 n = Bits32(opcode, 19, 16); 4940 registers = Bits32(opcode, 15, 0); 4941 wback = BitIsSet(opcode, 21); 4942 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4943 if ((n == 15) || BitCount(registers) < 1) 4944 return false; 4945 break; 4946 4947 default: 4948 return false; 4949 } 4950 4951 // address = R[n] - 4*BitCount(registers); 4952 4953 int32_t offset = 0; 4954 addr_t Rn = 4955 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4956 if (!success) 4957 return false; 4958 4959 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4960 4961 EmulateInstruction::Context context; 4962 context.type = EmulateInstruction::eContextRegisterStore; 4963 RegisterInfo base_reg; 4964 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4965 4966 // for i = 0 to 14 4967 uint32_t lowest_set_bit = 14; 4968 for (uint32_t i = 0; i < 14; ++i) { 4969 // if registers<i> == '1' then 4970 if (BitIsSet(registers, i)) { 4971 if (i < lowest_set_bit) 4972 lowest_set_bit = i; 4973 // if i == n && wback && i != LowestSetBit(registers) then 4974 if ((i == n) && wback && (i != lowest_set_bit)) 4975 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding 4976 // A1 4977 WriteBits32UnknownToMemory(address + offset); 4978 else { 4979 // MemA[address,4] = R[i]; 4980 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4981 0, &success); 4982 if (!success) 4983 return false; 4984 4985 RegisterInfo data_reg; 4986 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4987 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4988 Rn - (address + offset)); 4989 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4990 return false; 4991 } 4992 4993 // address = address + 4; 4994 offset += addr_byte_size; 4995 } 4996 } 4997 4998 // if registers<15> == '1' then // Only possible for encoding A1 4999 // MemA[address,4] = PCStoreValue(); 5000 if (BitIsSet(registers, 15)) { 5001 RegisterInfo pc_reg; 5002 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5003 context.SetRegisterPlusOffset(pc_reg, 8); 5004 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5005 if (!success) 5006 return false; 5007 5008 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5009 return false; 5010 } 5011 5012 // if wback then R[n] = R[n] - 4*BitCount(registers); 5013 if (wback) { 5014 offset = (addr_byte_size * BitCount(registers)) * -1; 5015 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5016 context.SetImmediateSigned(offset); 5017 addr_t data = Rn + offset; 5018 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5019 data)) 5020 return false; 5021 } 5022 } 5023 return true; 5024} 5025 5026// STMIB (Store Multiple Increment Before) stores multiple registers to 5027// consecutive memory locations using an address from a base register. The 5028// consecutive memory locations start just above this address, and the address 5029// of the last of those locations can optionally be written back to the base 5030// register. 5031bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode, 5032 const ARMEncoding encoding) { 5033#if 0 5034 if ConditionPassed() then 5035 EncodingSpecificOperations(); 5036 address = R[n] + 4; 5037 5038 for i = 0 to 14 5039 if registers<i> == '1' then 5040 if i == n && wback && i != LowestSetBit(registers) then 5041 MemA[address,4] = bits(32) UNKNOWN; 5042 else 5043 MemA[address,4] = R[i]; 5044 address = address + 4; 5045 5046 if registers<15> == '1' then 5047 MemA[address,4] = PCStoreValue(); 5048 5049 if wback then R[n] = R[n] + 4*BitCount(registers); 5050#endif 5051 5052 bool success = false; 5053 5054 if (ConditionPassed(opcode)) { 5055 uint32_t n; 5056 uint32_t registers = 0; 5057 bool wback; 5058 const uint32_t addr_byte_size = GetAddressByteSize(); 5059 5060 // EncodingSpecificOperations(); 5061 switch (encoding) { 5062 case eEncodingA1: 5063 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 5064 n = Bits32(opcode, 19, 16); 5065 registers = Bits32(opcode, 15, 0); 5066 wback = BitIsSet(opcode, 21); 5067 5068 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 5069 if ((n == 15) && (BitCount(registers) < 1)) 5070 return false; 5071 break; 5072 default: 5073 return false; 5074 } 5075 // address = R[n] + 4; 5076 5077 int32_t offset = 0; 5078 addr_t Rn = ReadCoreReg(n, &success); 5079 if (!success) 5080 return false; 5081 5082 addr_t address = Rn + addr_byte_size; 5083 5084 EmulateInstruction::Context context; 5085 context.type = EmulateInstruction::eContextRegisterStore; 5086 RegisterInfo base_reg; 5087 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5088 5089 uint32_t lowest_set_bit = 14; 5090 // for i = 0 to 14 5091 for (uint32_t i = 0; i < 14; ++i) { 5092 // if registers<i> == '1' then 5093 if (BitIsSet(registers, i)) { 5094 if (i < lowest_set_bit) 5095 lowest_set_bit = i; 5096 // if i == n && wback && i != LowestSetBit(registers) then 5097 if ((i == n) && wback && (i != lowest_set_bit)) 5098 // MemA[address,4] = bits(32) UNKNOWN; 5099 WriteBits32UnknownToMemory(address + offset); 5100 // else 5101 else { 5102 // MemA[address,4] = R[i]; 5103 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5104 0, &success); 5105 if (!success) 5106 return false; 5107 5108 RegisterInfo data_reg; 5109 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5110 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5111 offset + addr_byte_size); 5112 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5113 return false; 5114 } 5115 5116 // address = address + 4; 5117 offset += addr_byte_size; 5118 } 5119 } 5120 5121 // if registers<15> == '1' then 5122 // MemA[address,4] = PCStoreValue(); 5123 if (BitIsSet(registers, 15)) { 5124 RegisterInfo pc_reg; 5125 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5126 context.SetRegisterPlusOffset(pc_reg, 8); 5127 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5128 if (!success) 5129 return false; 5130 5131 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5132 return false; 5133 } 5134 5135 // if wback then R[n] = R[n] + 4*BitCount(registers); 5136 if (wback) { 5137 offset = addr_byte_size * BitCount(registers); 5138 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5139 context.SetImmediateSigned(offset); 5140 addr_t data = Rn + offset; 5141 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5142 data)) 5143 return false; 5144 } 5145 } 5146 return true; 5147} 5148 5149// STR (store immediate) calculates an address from a base register value and an 5150// immediate offset, and stores a word 5151// from a register to memory. It can use offset, post-indexed, or pre-indexed 5152// addressing. 5153bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode, 5154 const ARMEncoding encoding) { 5155#if 0 5156 if ConditionPassed() then 5157 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5158 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5159 address = if index then offset_addr else R[n]; 5160 if UnalignedSupport() || address<1:0> == '00' then 5161 MemU[address,4] = R[t]; 5162 else // Can only occur before ARMv7 5163 MemU[address,4] = bits(32) UNKNOWN; 5164 if wback then R[n] = offset_addr; 5165#endif 5166 5167 bool success = false; 5168 5169 if (ConditionPassed(opcode)) { 5170 const uint32_t addr_byte_size = GetAddressByteSize(); 5171 5172 uint32_t t; 5173 uint32_t n; 5174 uint32_t imm32; 5175 bool index; 5176 bool add; 5177 bool wback; 5178 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5179 switch (encoding) { 5180 case eEncodingT1: 5181 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 5182 t = Bits32(opcode, 2, 0); 5183 n = Bits32(opcode, 5, 3); 5184 imm32 = Bits32(opcode, 10, 6) << 2; 5185 5186 // index = TRUE; add = TRUE; wback = FALSE; 5187 index = true; 5188 add = false; 5189 wback = false; 5190 break; 5191 5192 case eEncodingT2: 5193 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 5194 t = Bits32(opcode, 10, 8); 5195 n = 13; 5196 imm32 = Bits32(opcode, 7, 0) << 2; 5197 5198 // index = TRUE; add = TRUE; wback = FALSE; 5199 index = true; 5200 add = true; 5201 wback = false; 5202 break; 5203 5204 case eEncodingT3: 5205 // if Rn == '1111' then UNDEFINED; 5206 if (Bits32(opcode, 19, 16) == 15) 5207 return false; 5208 5209 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5210 t = Bits32(opcode, 15, 12); 5211 n = Bits32(opcode, 19, 16); 5212 imm32 = Bits32(opcode, 11, 0); 5213 5214 // index = TRUE; add = TRUE; wback = FALSE; 5215 index = true; 5216 add = true; 5217 wback = false; 5218 5219 // if t == 15 then UNPREDICTABLE; 5220 if (t == 15) 5221 return false; 5222 break; 5223 5224 case eEncodingT4: 5225 // if P == '1' && U == '1' && W == '0' then SEE STRT; 5226 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == 5227 // '00000100' then SEE PUSH; 5228 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5229 if ((Bits32(opcode, 19, 16) == 15) || 5230 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))) 5231 return false; 5232 5233 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5234 t = Bits32(opcode, 15, 12); 5235 n = Bits32(opcode, 19, 16); 5236 imm32 = Bits32(opcode, 7, 0); 5237 5238 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5239 index = BitIsSet(opcode, 10); 5240 add = BitIsSet(opcode, 9); 5241 wback = BitIsSet(opcode, 8); 5242 5243 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 5244 if ((t == 15) || (wback && (n == t))) 5245 return false; 5246 break; 5247 5248 default: 5249 return false; 5250 } 5251 5252 addr_t offset_addr; 5253 addr_t address; 5254 5255 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5256 uint32_t base_address = ReadCoreReg(n, &success); 5257 if (!success) 5258 return false; 5259 5260 if (add) 5261 offset_addr = base_address + imm32; 5262 else 5263 offset_addr = base_address - imm32; 5264 5265 // address = if index then offset_addr else R[n]; 5266 if (index) 5267 address = offset_addr; 5268 else 5269 address = base_address; 5270 5271 EmulateInstruction::Context context; 5272 if (n == 13) 5273 context.type = eContextPushRegisterOnStack; 5274 else 5275 context.type = eContextRegisterStore; 5276 5277 RegisterInfo base_reg; 5278 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5279 5280 // if UnalignedSupport() || address<1:0> == '00' then 5281 if (UnalignedSupport() || 5282 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 5283 // MemU[address,4] = R[t]; 5284 uint32_t data = 5285 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5286 if (!success) 5287 return false; 5288 5289 RegisterInfo data_reg; 5290 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5291 int32_t offset = address - base_address; 5292 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 5293 if (!MemUWrite(context, address, data, addr_byte_size)) 5294 return false; 5295 } else { 5296 // MemU[address,4] = bits(32) UNKNOWN; 5297 WriteBits32UnknownToMemory(address); 5298 } 5299 5300 // if wback then R[n] = offset_addr; 5301 if (wback) { 5302 if (n == 13) 5303 context.type = eContextAdjustStackPointer; 5304 else 5305 context.type = eContextAdjustBaseRegister; 5306 context.SetAddress(offset_addr); 5307 5308 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5309 offset_addr)) 5310 return false; 5311 } 5312 } 5313 return true; 5314} 5315 5316// STR (Store Register) calculates an address from a base register value and an 5317// offset register value, stores a 5318// word from a register to memory. The offset register value can optionally 5319// be shifted. 5320bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode, 5321 const ARMEncoding encoding) { 5322#if 0 5323 if ConditionPassed() then 5324 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5325 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5326 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5327 address = if index then offset_addr else R[n]; 5328 if t == 15 then // Only possible for encoding A1 5329 data = PCStoreValue(); 5330 else 5331 data = R[t]; 5332 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 5333 MemU[address,4] = data; 5334 else // Can only occur before ARMv7 5335 MemU[address,4] = bits(32) UNKNOWN; 5336 if wback then R[n] = offset_addr; 5337#endif 5338 5339 bool success = false; 5340 5341 if (ConditionPassed(opcode)) { 5342 const uint32_t addr_byte_size = GetAddressByteSize(); 5343 5344 uint32_t t; 5345 uint32_t n; 5346 uint32_t m; 5347 ARM_ShifterType shift_t; 5348 uint32_t shift_n; 5349 bool index; 5350 bool add; 5351 bool wback; 5352 5353 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5354 switch (encoding) { 5355 case eEncodingT1: 5356 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5357 // in ThumbEE"; 5358 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5359 t = Bits32(opcode, 2, 0); 5360 n = Bits32(opcode, 5, 3); 5361 m = Bits32(opcode, 8, 6); 5362 5363 // index = TRUE; add = TRUE; wback = FALSE; 5364 index = true; 5365 add = true; 5366 wback = false; 5367 5368 // (shift_t, shift_n) = (SRType_LSL, 0); 5369 shift_t = SRType_LSL; 5370 shift_n = 0; 5371 break; 5372 5373 case eEncodingT2: 5374 // if Rn == '1111' then UNDEFINED; 5375 if (Bits32(opcode, 19, 16) == 15) 5376 return false; 5377 5378 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5379 t = Bits32(opcode, 15, 12); 5380 n = Bits32(opcode, 19, 16); 5381 m = Bits32(opcode, 3, 0); 5382 5383 // index = TRUE; add = TRUE; wback = FALSE; 5384 index = true; 5385 add = true; 5386 wback = false; 5387 5388 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5389 shift_t = SRType_LSL; 5390 shift_n = Bits32(opcode, 5, 4); 5391 5392 // if t == 15 || BadReg(m) then UNPREDICTABLE; 5393 if ((t == 15) || (BadReg(m))) 5394 return false; 5395 break; 5396 5397 case eEncodingA1: { 5398 // if P == '0' && W == '1' then SEE STRT; 5399 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5400 t = Bits32(opcode, 15, 12); 5401 n = Bits32(opcode, 19, 16); 5402 m = Bits32(opcode, 3, 0); 5403 5404 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5405 // (W == '1'); 5406 index = BitIsSet(opcode, 24); 5407 add = BitIsSet(opcode, 23); 5408 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5409 5410 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5411 uint32_t typ = Bits32(opcode, 6, 5); 5412 uint32_t imm5 = Bits32(opcode, 11, 7); 5413 shift_n = DecodeImmShift(typ, imm5, shift_t); 5414 5415 // if m == 15 then UNPREDICTABLE; 5416 if (m == 15) 5417 return false; 5418 5419 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5420 if (wback && ((n == 15) || (n == t))) 5421 return false; 5422 5423 break; 5424 } 5425 default: 5426 return false; 5427 } 5428 5429 addr_t offset_addr; 5430 addr_t address; 5431 int32_t offset = 0; 5432 5433 addr_t base_address = 5434 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5435 if (!success) 5436 return false; 5437 5438 uint32_t Rm_data = 5439 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5440 if (!success) 5441 return false; 5442 5443 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5444 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success); 5445 if (!success) 5446 return false; 5447 5448 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5449 if (add) 5450 offset_addr = base_address + offset; 5451 else 5452 offset_addr = base_address - offset; 5453 5454 // address = if index then offset_addr else R[n]; 5455 if (index) 5456 address = offset_addr; 5457 else 5458 address = base_address; 5459 5460 uint32_t data; 5461 // if t == 15 then // Only possible for encoding A1 5462 if (t == 15) 5463 // data = PCStoreValue(); 5464 data = ReadCoreReg(PC_REG, &success); 5465 else 5466 // data = R[t]; 5467 data = 5468 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5469 5470 if (!success) 5471 return false; 5472 5473 EmulateInstruction::Context context; 5474 context.type = eContextRegisterStore; 5475 5476 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == 5477 // InstrSet_ARM then 5478 if (UnalignedSupport() || 5479 (BitIsClear(address, 1) && BitIsClear(address, 0)) || 5480 CurrentInstrSet() == eModeARM) { 5481 // MemU[address,4] = data; 5482 5483 RegisterInfo base_reg; 5484 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5485 5486 RegisterInfo data_reg; 5487 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5488 5489 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5490 address - base_address); 5491 if (!MemUWrite(context, address, data, addr_byte_size)) 5492 return false; 5493 5494 } else 5495 // MemU[address,4] = bits(32) UNKNOWN; 5496 WriteBits32UnknownToMemory(address); 5497 5498 // if wback then R[n] = offset_addr; 5499 if (wback) { 5500 context.type = eContextRegisterLoad; 5501 context.SetAddress(offset_addr); 5502 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5503 offset_addr)) 5504 return false; 5505 } 5506 } 5507 return true; 5508} 5509 5510bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode, 5511 const ARMEncoding encoding) { 5512#if 0 5513 if ConditionPassed() then 5514 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5515 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5516 address = if index then offset_addr else R[n]; 5517 MemU[address,1] = R[t]<7:0>; 5518 if wback then R[n] = offset_addr; 5519#endif 5520 5521 bool success = false; 5522 5523 if (ConditionPassed(opcode)) { 5524 uint32_t t; 5525 uint32_t n; 5526 uint32_t imm32; 5527 bool index; 5528 bool add; 5529 bool wback; 5530 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5531 switch (encoding) { 5532 case eEncodingT1: 5533 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5534 t = Bits32(opcode, 2, 0); 5535 n = Bits32(opcode, 5, 3); 5536 imm32 = Bits32(opcode, 10, 6); 5537 5538 // index = TRUE; add = TRUE; wback = FALSE; 5539 index = true; 5540 add = true; 5541 wback = false; 5542 break; 5543 5544 case eEncodingT2: 5545 // if Rn == '1111' then UNDEFINED; 5546 if (Bits32(opcode, 19, 16) == 15) 5547 return false; 5548 5549 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5550 t = Bits32(opcode, 15, 12); 5551 n = Bits32(opcode, 19, 16); 5552 imm32 = Bits32(opcode, 11, 0); 5553 5554 // index = TRUE; add = TRUE; wback = FALSE; 5555 index = true; 5556 add = true; 5557 wback = false; 5558 5559 // if BadReg(t) then UNPREDICTABLE; 5560 if (BadReg(t)) 5561 return false; 5562 break; 5563 5564 case eEncodingT3: 5565 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5566 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5567 if (Bits32(opcode, 19, 16) == 15) 5568 return false; 5569 5570 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5571 t = Bits32(opcode, 15, 12); 5572 n = Bits32(opcode, 19, 16); 5573 imm32 = Bits32(opcode, 7, 0); 5574 5575 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5576 index = BitIsSet(opcode, 10); 5577 add = BitIsSet(opcode, 9); 5578 wback = BitIsSet(opcode, 8); 5579 5580 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5581 if ((BadReg(t)) || (wback && (n == t))) 5582 return false; 5583 break; 5584 5585 default: 5586 return false; 5587 } 5588 5589 addr_t offset_addr; 5590 addr_t address; 5591 addr_t base_address = 5592 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5593 if (!success) 5594 return false; 5595 5596 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5597 if (add) 5598 offset_addr = base_address + imm32; 5599 else 5600 offset_addr = base_address - imm32; 5601 5602 // address = if index then offset_addr else R[n]; 5603 if (index) 5604 address = offset_addr; 5605 else 5606 address = base_address; 5607 5608 // MemU[address,1] = R[t]<7:0> 5609 RegisterInfo base_reg; 5610 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5611 5612 RegisterInfo data_reg; 5613 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5614 5615 EmulateInstruction::Context context; 5616 context.type = eContextRegisterStore; 5617 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5618 address - base_address); 5619 5620 uint32_t data = 5621 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5622 if (!success) 5623 return false; 5624 5625 data = Bits32(data, 7, 0); 5626 5627 if (!MemUWrite(context, address, data, 1)) 5628 return false; 5629 5630 // if wback then R[n] = offset_addr; 5631 if (wback) { 5632 context.type = eContextRegisterLoad; 5633 context.SetAddress(offset_addr); 5634 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5635 offset_addr)) 5636 return false; 5637 } 5638 } 5639 5640 return true; 5641} 5642 5643// STRH (register) calculates an address from a base register value and an 5644// offset register value, and stores a 5645// halfword from a register to memory. The offset register value can be 5646// shifted left by 0, 1, 2, or 3 bits. 5647bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode, 5648 const ARMEncoding encoding) { 5649#if 0 5650 if ConditionPassed() then 5651 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5652 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5653 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5654 address = if index then offset_addr else R[n]; 5655 if UnalignedSupport() || address<0> == '0' then 5656 MemU[address,2] = R[t]<15:0>; 5657 else // Can only occur before ARMv7 5658 MemU[address,2] = bits(16) UNKNOWN; 5659 if wback then R[n] = offset_addr; 5660#endif 5661 5662 bool success = false; 5663 5664 if (ConditionPassed(opcode)) { 5665 uint32_t t; 5666 uint32_t n; 5667 uint32_t m; 5668 bool index; 5669 bool add; 5670 bool wback; 5671 ARM_ShifterType shift_t; 5672 uint32_t shift_n; 5673 5674 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5675 switch (encoding) { 5676 case eEncodingT1: 5677 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5678 // in ThumbEE"; 5679 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5680 t = Bits32(opcode, 2, 0); 5681 n = Bits32(opcode, 5, 3); 5682 m = Bits32(opcode, 8, 6); 5683 5684 // index = TRUE; add = TRUE; wback = FALSE; 5685 index = true; 5686 add = true; 5687 wback = false; 5688 5689 // (shift_t, shift_n) = (SRType_LSL, 0); 5690 shift_t = SRType_LSL; 5691 shift_n = 0; 5692 5693 break; 5694 5695 case eEncodingT2: 5696 // if Rn == '1111' then UNDEFINED; 5697 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5698 t = Bits32(opcode, 15, 12); 5699 n = Bits32(opcode, 19, 16); 5700 m = Bits32(opcode, 3, 0); 5701 if (n == 15) 5702 return false; 5703 5704 // index = TRUE; add = TRUE; wback = FALSE; 5705 index = true; 5706 add = true; 5707 wback = false; 5708 5709 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5710 shift_t = SRType_LSL; 5711 shift_n = Bits32(opcode, 5, 4); 5712 5713 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5714 if (BadReg(t) || BadReg(m)) 5715 return false; 5716 5717 break; 5718 5719 case eEncodingA1: 5720 // if P == '0' && W == '1' then SEE STRHT; 5721 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5722 t = Bits32(opcode, 15, 12); 5723 n = Bits32(opcode, 19, 16); 5724 m = Bits32(opcode, 3, 0); 5725 5726 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5727 // (W == '1'); 5728 index = BitIsSet(opcode, 24); 5729 add = BitIsSet(opcode, 23); 5730 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5731 5732 // (shift_t, shift_n) = (SRType_LSL, 0); 5733 shift_t = SRType_LSL; 5734 shift_n = 0; 5735 5736 // if t == 15 || m == 15 then UNPREDICTABLE; 5737 if ((t == 15) || (m == 15)) 5738 return false; 5739 5740 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5741 if (wback && ((n == 15) || (n == t))) 5742 return false; 5743 5744 break; 5745 5746 default: 5747 return false; 5748 } 5749 5750 uint32_t Rm = ReadCoreReg(m, &success); 5751 if (!success) 5752 return false; 5753 5754 uint32_t Rn = ReadCoreReg(n, &success); 5755 if (!success) 5756 return false; 5757 5758 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5759 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 5760 if (!success) 5761 return false; 5762 5763 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5764 addr_t offset_addr; 5765 if (add) 5766 offset_addr = Rn + offset; 5767 else 5768 offset_addr = Rn - offset; 5769 5770 // address = if index then offset_addr else R[n]; 5771 addr_t address; 5772 if (index) 5773 address = offset_addr; 5774 else 5775 address = Rn; 5776 5777 EmulateInstruction::Context context; 5778 context.type = eContextRegisterStore; 5779 RegisterInfo base_reg; 5780 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5781 RegisterInfo offset_reg; 5782 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5783 5784 // if UnalignedSupport() || address<0> == '0' then 5785 if (UnalignedSupport() || BitIsClear(address, 0)) { 5786 // MemU[address,2] = R[t]<15:0>; 5787 uint32_t Rt = ReadCoreReg(t, &success); 5788 if (!success) 5789 return false; 5790 5791 EmulateInstruction::Context context; 5792 context.type = eContextRegisterStore; 5793 RegisterInfo base_reg; 5794 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5795 RegisterInfo offset_reg; 5796 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5797 RegisterInfo data_reg; 5798 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5799 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 5800 data_reg); 5801 5802 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2)) 5803 return false; 5804 } else // Can only occur before ARMv7 5805 { 5806 // MemU[address,2] = bits(16) UNKNOWN; 5807 } 5808 5809 // if wback then R[n] = offset_addr; 5810 if (wback) { 5811 context.type = eContextAdjustBaseRegister; 5812 context.SetAddress(offset_addr); 5813 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5814 offset_addr)) 5815 return false; 5816 } 5817 } 5818 5819 return true; 5820} 5821 5822// Add with Carry (immediate) adds an immediate value and the carry flag value 5823// to a register value, and writes the result to the destination register. It 5824// can optionally update the condition flags based on the result. 5825bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode, 5826 const ARMEncoding encoding) { 5827#if 0 5828 // ARM pseudo code... 5829 if ConditionPassed() then 5830 EncodingSpecificOperations(); 5831 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5832 if d == 15 then // Can only occur for ARM encoding 5833 ALUWritePC(result); // setflags is always FALSE here 5834 else 5835 R[d] = result; 5836 if setflags then 5837 APSR.N = result<31>; 5838 APSR.Z = IsZeroBit(result); 5839 APSR.C = carry; 5840 APSR.V = overflow; 5841#endif 5842 5843 bool success = false; 5844 5845 if (ConditionPassed(opcode)) { 5846 uint32_t Rd, Rn; 5847 uint32_t 5848 imm32; // the immediate value to be added to the value obtained from Rn 5849 bool setflags; 5850 switch (encoding) { 5851 case eEncodingT1: 5852 Rd = Bits32(opcode, 11, 8); 5853 Rn = Bits32(opcode, 19, 16); 5854 setflags = BitIsSet(opcode, 20); 5855 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5856 if (BadReg(Rd) || BadReg(Rn)) 5857 return false; 5858 break; 5859 case eEncodingA1: 5860 Rd = Bits32(opcode, 15, 12); 5861 Rn = Bits32(opcode, 19, 16); 5862 setflags = BitIsSet(opcode, 20); 5863 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5864 5865 if (Rd == 15 && setflags) 5866 return EmulateSUBSPcLrEtc(opcode, encoding); 5867 break; 5868 default: 5869 return false; 5870 } 5871 5872 // Read the first operand. 5873 int32_t val1 = ReadCoreReg(Rn, &success); 5874 if (!success) 5875 return false; 5876 5877 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5878 5879 EmulateInstruction::Context context; 5880 context.type = EmulateInstruction::eContextImmediate; 5881 context.SetNoArgs(); 5882 5883 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5884 res.carry_out, res.overflow)) 5885 return false; 5886 } 5887 return true; 5888} 5889 5890// Add with Carry (register) adds a register value, the carry flag value, and 5891// an optionally-shifted register value, and writes the result to the 5892// destination register. It can optionally update the condition flags based on 5893// the result. 5894bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode, 5895 const ARMEncoding encoding) { 5896#if 0 5897 // ARM pseudo code... 5898 if ConditionPassed() then 5899 EncodingSpecificOperations(); 5900 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5901 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5902 if d == 15 then // Can only occur for ARM encoding 5903 ALUWritePC(result); // setflags is always FALSE here 5904 else 5905 R[d] = result; 5906 if setflags then 5907 APSR.N = result<31>; 5908 APSR.Z = IsZeroBit(result); 5909 APSR.C = carry; 5910 APSR.V = overflow; 5911#endif 5912 5913 bool success = false; 5914 5915 if (ConditionPassed(opcode)) { 5916 uint32_t Rd, Rn, Rm; 5917 ARM_ShifterType shift_t; 5918 uint32_t shift_n; // the shift applied to the value read from Rm 5919 bool setflags; 5920 switch (encoding) { 5921 case eEncodingT1: 5922 Rd = Rn = Bits32(opcode, 2, 0); 5923 Rm = Bits32(opcode, 5, 3); 5924 setflags = !InITBlock(); 5925 shift_t = SRType_LSL; 5926 shift_n = 0; 5927 break; 5928 case eEncodingT2: 5929 Rd = Bits32(opcode, 11, 8); 5930 Rn = Bits32(opcode, 19, 16); 5931 Rm = Bits32(opcode, 3, 0); 5932 setflags = BitIsSet(opcode, 20); 5933 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5934 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5935 return false; 5936 break; 5937 case eEncodingA1: 5938 Rd = Bits32(opcode, 15, 12); 5939 Rn = Bits32(opcode, 19, 16); 5940 Rm = Bits32(opcode, 3, 0); 5941 setflags = BitIsSet(opcode, 20); 5942 shift_n = DecodeImmShiftARM(opcode, shift_t); 5943 5944 if (Rd == 15 && setflags) 5945 return EmulateSUBSPcLrEtc(opcode, encoding); 5946 break; 5947 default: 5948 return false; 5949 } 5950 5951 // Read the first operand. 5952 int32_t val1 = ReadCoreReg(Rn, &success); 5953 if (!success) 5954 return false; 5955 5956 // Read the second operand. 5957 int32_t val2 = ReadCoreReg(Rm, &success); 5958 if (!success) 5959 return false; 5960 5961 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5962 if (!success) 5963 return false; 5964 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5965 5966 EmulateInstruction::Context context; 5967 context.type = EmulateInstruction::eContextImmediate; 5968 context.SetNoArgs(); 5969 5970 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5971 res.carry_out, res.overflow)) 5972 return false; 5973 } 5974 return true; 5975} 5976 5977// This instruction adds an immediate value to the PC value to form a PC- 5978// relative address, and writes the result to the destination register. 5979bool EmulateInstructionARM::EmulateADR(const uint32_t opcode, 5980 const ARMEncoding encoding) { 5981#if 0 5982 // ARM pseudo code... 5983 if ConditionPassed() then 5984 EncodingSpecificOperations(); 5985 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5986 if d == 15 then // Can only occur for ARM encodings 5987 ALUWritePC(result); 5988 else 5989 R[d] = result; 5990#endif 5991 5992 bool success = false; 5993 5994 if (ConditionPassed(opcode)) { 5995 uint32_t Rd; 5996 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5997 bool add; 5998 switch (encoding) { 5999 case eEncodingT1: 6000 Rd = Bits32(opcode, 10, 8); 6001 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 6002 add = true; 6003 break; 6004 case eEncodingT2: 6005 case eEncodingT3: 6006 Rd = Bits32(opcode, 11, 8); 6007 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 6008 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 6009 if (BadReg(Rd)) 6010 return false; 6011 break; 6012 case eEncodingA1: 6013 case eEncodingA2: 6014 Rd = Bits32(opcode, 15, 12); 6015 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 6016 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 6017 break; 6018 default: 6019 return false; 6020 } 6021 6022 // Read the PC value. 6023 uint32_t pc = ReadCoreReg(PC_REG, &success); 6024 if (!success) 6025 return false; 6026 6027 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 6028 6029 EmulateInstruction::Context context; 6030 context.type = EmulateInstruction::eContextImmediate; 6031 context.SetNoArgs(); 6032 6033 if (!WriteCoreReg(context, result, Rd)) 6034 return false; 6035 } 6036 return true; 6037} 6038 6039// This instruction performs a bitwise AND of a register value and an immediate 6040// value, and writes the result to the destination register. It can optionally 6041// update the condition flags based on the result. 6042bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode, 6043 const ARMEncoding encoding) { 6044#if 0 6045 // ARM pseudo code... 6046 if ConditionPassed() then 6047 EncodingSpecificOperations(); 6048 result = R[n] AND imm32; 6049 if d == 15 then // Can only occur for ARM encoding 6050 ALUWritePC(result); // setflags is always FALSE here 6051 else 6052 R[d] = result; 6053 if setflags then 6054 APSR.N = result<31>; 6055 APSR.Z = IsZeroBit(result); 6056 APSR.C = carry; 6057 // APSR.V unchanged 6058#endif 6059 6060 bool success = false; 6061 6062 if (ConditionPassed(opcode)) { 6063 uint32_t Rd, Rn; 6064 uint32_t 6065 imm32; // the immediate value to be ANDed to the value obtained from Rn 6066 bool setflags; 6067 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6068 switch (encoding) { 6069 case eEncodingT1: 6070 Rd = Bits32(opcode, 11, 8); 6071 Rn = Bits32(opcode, 19, 16); 6072 setflags = BitIsSet(opcode, 20); 6073 imm32 = ThumbExpandImm_C( 6074 opcode, APSR_C, 6075 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6076 // if Rd == '1111' && S == '1' then SEE TST (immediate); 6077 if (Rd == 15 && setflags) 6078 return EmulateTSTImm(opcode, eEncodingT1); 6079 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 6080 return false; 6081 break; 6082 case eEncodingA1: 6083 Rd = Bits32(opcode, 15, 12); 6084 Rn = Bits32(opcode, 19, 16); 6085 setflags = BitIsSet(opcode, 20); 6086 imm32 = 6087 ARMExpandImm_C(opcode, APSR_C, 6088 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6089 6090 if (Rd == 15 && setflags) 6091 return EmulateSUBSPcLrEtc(opcode, encoding); 6092 break; 6093 default: 6094 return false; 6095 } 6096 6097 // Read the first operand. 6098 uint32_t val1 = ReadCoreReg(Rn, &success); 6099 if (!success) 6100 return false; 6101 6102 uint32_t result = val1 & imm32; 6103 6104 EmulateInstruction::Context context; 6105 context.type = EmulateInstruction::eContextImmediate; 6106 context.SetNoArgs(); 6107 6108 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6109 return false; 6110 } 6111 return true; 6112} 6113 6114// This instruction performs a bitwise AND of a register value and an 6115// optionally-shifted register value, and writes the result to the destination 6116// register. It can optionally update the condition flags based on the result. 6117bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode, 6118 const ARMEncoding encoding) { 6119#if 0 6120 // ARM pseudo code... 6121 if ConditionPassed() then 6122 EncodingSpecificOperations(); 6123 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6124 result = R[n] AND shifted; 6125 if d == 15 then // Can only occur for ARM encoding 6126 ALUWritePC(result); // setflags is always FALSE here 6127 else 6128 R[d] = result; 6129 if setflags then 6130 APSR.N = result<31>; 6131 APSR.Z = IsZeroBit(result); 6132 APSR.C = carry; 6133 // APSR.V unchanged 6134#endif 6135 6136 bool success = false; 6137 6138 if (ConditionPassed(opcode)) { 6139 uint32_t Rd, Rn, Rm; 6140 ARM_ShifterType shift_t; 6141 uint32_t shift_n; // the shift applied to the value read from Rm 6142 bool setflags; 6143 uint32_t carry; 6144 switch (encoding) { 6145 case eEncodingT1: 6146 Rd = Rn = Bits32(opcode, 2, 0); 6147 Rm = Bits32(opcode, 5, 3); 6148 setflags = !InITBlock(); 6149 shift_t = SRType_LSL; 6150 shift_n = 0; 6151 break; 6152 case eEncodingT2: 6153 Rd = Bits32(opcode, 11, 8); 6154 Rn = Bits32(opcode, 19, 16); 6155 Rm = Bits32(opcode, 3, 0); 6156 setflags = BitIsSet(opcode, 20); 6157 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6158 // if Rd == '1111' && S == '1' then SEE TST (register); 6159 if (Rd == 15 && setflags) 6160 return EmulateTSTReg(opcode, eEncodingT2); 6161 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 6162 return false; 6163 break; 6164 case eEncodingA1: 6165 Rd = Bits32(opcode, 15, 12); 6166 Rn = Bits32(opcode, 19, 16); 6167 Rm = Bits32(opcode, 3, 0); 6168 setflags = BitIsSet(opcode, 20); 6169 shift_n = DecodeImmShiftARM(opcode, shift_t); 6170 6171 if (Rd == 15 && setflags) 6172 return EmulateSUBSPcLrEtc(opcode, encoding); 6173 break; 6174 default: 6175 return false; 6176 } 6177 6178 // Read the first operand. 6179 uint32_t val1 = ReadCoreReg(Rn, &success); 6180 if (!success) 6181 return false; 6182 6183 // Read the second operand. 6184 uint32_t val2 = ReadCoreReg(Rm, &success); 6185 if (!success) 6186 return false; 6187 6188 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6189 if (!success) 6190 return false; 6191 uint32_t result = val1 & shifted; 6192 6193 EmulateInstruction::Context context; 6194 context.type = EmulateInstruction::eContextImmediate; 6195 context.SetNoArgs(); 6196 6197 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6198 return false; 6199 } 6200 return true; 6201} 6202 6203// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and 6204// the complement of an immediate value, and writes the result to the 6205// destination register. It can optionally update the condition flags based on 6206// the result. 6207bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode, 6208 const ARMEncoding encoding) { 6209#if 0 6210 // ARM pseudo code... 6211 if ConditionPassed() then 6212 EncodingSpecificOperations(); 6213 result = R[n] AND NOT(imm32); 6214 if d == 15 then // Can only occur for ARM encoding 6215 ALUWritePC(result); // setflags is always FALSE here 6216 else 6217 R[d] = result; 6218 if setflags then 6219 APSR.N = result<31>; 6220 APSR.Z = IsZeroBit(result); 6221 APSR.C = carry; 6222 // APSR.V unchanged 6223#endif 6224 6225 bool success = false; 6226 6227 if (ConditionPassed(opcode)) { 6228 uint32_t Rd, Rn; 6229 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to 6230 // the value obtained from Rn 6231 bool setflags; 6232 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6233 switch (encoding) { 6234 case eEncodingT1: 6235 Rd = Bits32(opcode, 11, 8); 6236 Rn = Bits32(opcode, 19, 16); 6237 setflags = BitIsSet(opcode, 20); 6238 imm32 = ThumbExpandImm_C( 6239 opcode, APSR_C, 6240 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6241 if (BadReg(Rd) || BadReg(Rn)) 6242 return false; 6243 break; 6244 case eEncodingA1: 6245 Rd = Bits32(opcode, 15, 12); 6246 Rn = Bits32(opcode, 19, 16); 6247 setflags = BitIsSet(opcode, 20); 6248 imm32 = 6249 ARMExpandImm_C(opcode, APSR_C, 6250 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6251 6252 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6253 // instructions; 6254 if (Rd == 15 && setflags) 6255 return EmulateSUBSPcLrEtc(opcode, encoding); 6256 break; 6257 default: 6258 return false; 6259 } 6260 6261 // Read the first operand. 6262 uint32_t val1 = ReadCoreReg(Rn, &success); 6263 if (!success) 6264 return false; 6265 6266 uint32_t result = val1 & ~imm32; 6267 6268 EmulateInstruction::Context context; 6269 context.type = EmulateInstruction::eContextImmediate; 6270 context.SetNoArgs(); 6271 6272 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6273 return false; 6274 } 6275 return true; 6276} 6277 6278// Bitwise Bit Clear (register) performs a bitwise AND of a register value and 6279// the complement of an optionally-shifted register value, and writes the 6280// result to the destination register. It can optionally update the condition 6281// flags based on the result. 6282bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode, 6283 const ARMEncoding encoding) { 6284#if 0 6285 // ARM pseudo code... 6286 if ConditionPassed() then 6287 EncodingSpecificOperations(); 6288 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6289 result = R[n] AND NOT(shifted); 6290 if d == 15 then // Can only occur for ARM encoding 6291 ALUWritePC(result); // setflags is always FALSE here 6292 else 6293 R[d] = result; 6294 if setflags then 6295 APSR.N = result<31>; 6296 APSR.Z = IsZeroBit(result); 6297 APSR.C = carry; 6298 // APSR.V unchanged 6299#endif 6300 6301 bool success = false; 6302 6303 if (ConditionPassed(opcode)) { 6304 uint32_t Rd, Rn, Rm; 6305 ARM_ShifterType shift_t; 6306 uint32_t shift_n; // the shift applied to the value read from Rm 6307 bool setflags; 6308 uint32_t carry; 6309 switch (encoding) { 6310 case eEncodingT1: 6311 Rd = Rn = Bits32(opcode, 2, 0); 6312 Rm = Bits32(opcode, 5, 3); 6313 setflags = !InITBlock(); 6314 shift_t = SRType_LSL; 6315 shift_n = 0; 6316 break; 6317 case eEncodingT2: 6318 Rd = Bits32(opcode, 11, 8); 6319 Rn = Bits32(opcode, 19, 16); 6320 Rm = Bits32(opcode, 3, 0); 6321 setflags = BitIsSet(opcode, 20); 6322 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6323 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 6324 return false; 6325 break; 6326 case eEncodingA1: 6327 Rd = Bits32(opcode, 15, 12); 6328 Rn = Bits32(opcode, 19, 16); 6329 Rm = Bits32(opcode, 3, 0); 6330 setflags = BitIsSet(opcode, 20); 6331 shift_n = DecodeImmShiftARM(opcode, shift_t); 6332 6333 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6334 // instructions; 6335 if (Rd == 15 && setflags) 6336 return EmulateSUBSPcLrEtc(opcode, encoding); 6337 break; 6338 default: 6339 return false; 6340 } 6341 6342 // Read the first operand. 6343 uint32_t val1 = ReadCoreReg(Rn, &success); 6344 if (!success) 6345 return false; 6346 6347 // Read the second operand. 6348 uint32_t val2 = ReadCoreReg(Rm, &success); 6349 if (!success) 6350 return false; 6351 6352 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6353 if (!success) 6354 return false; 6355 uint32_t result = val1 & ~shifted; 6356 6357 EmulateInstruction::Context context; 6358 context.type = EmulateInstruction::eContextImmediate; 6359 context.SetNoArgs(); 6360 6361 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6362 return false; 6363 } 6364 return true; 6365} 6366 6367// LDR (immediate, ARM) calculates an address from a base register value and an 6368// immediate offset, loads a word 6369// from memory, and writes it to a register. It can use offset, post-indexed, 6370// or pre-indexed addressing. 6371bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode, 6372 const ARMEncoding encoding) { 6373#if 0 6374 if ConditionPassed() then 6375 EncodingSpecificOperations(); 6376 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6377 address = if index then offset_addr else R[n]; 6378 data = MemU[address,4]; 6379 if wback then R[n] = offset_addr; 6380 if t == 15 then 6381 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6382 elsif UnalignedSupport() || address<1:0> = '00' then 6383 R[t] = data; 6384 else // Can only apply before ARMv7 6385 R[t] = ROR(data, 8*UInt(address<1:0>)); 6386#endif 6387 6388 bool success = false; 6389 6390 if (ConditionPassed(opcode)) { 6391 const uint32_t addr_byte_size = GetAddressByteSize(); 6392 6393 uint32_t t; 6394 uint32_t n; 6395 uint32_t imm32; 6396 bool index; 6397 bool add; 6398 bool wback; 6399 6400 switch (encoding) { 6401 case eEncodingA1: 6402 // if Rn == '1111' then SEE LDR (literal); 6403 // if P == '0' && W == '1' then SEE LDRT; 6404 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == 6405 // '000000000100' then SEE POP; 6406 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6407 t = Bits32(opcode, 15, 12); 6408 n = Bits32(opcode, 19, 16); 6409 imm32 = Bits32(opcode, 11, 0); 6410 6411 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6412 // (W == '1'); 6413 index = BitIsSet(opcode, 24); 6414 add = BitIsSet(opcode, 23); 6415 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6416 6417 // if wback && n == t then UNPREDICTABLE; 6418 if (wback && (n == t)) 6419 return false; 6420 6421 break; 6422 6423 default: 6424 return false; 6425 } 6426 6427 addr_t address; 6428 addr_t offset_addr; 6429 addr_t base_address = ReadCoreReg(n, &success); 6430 if (!success) 6431 return false; 6432 6433 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6434 if (add) 6435 offset_addr = base_address + imm32; 6436 else 6437 offset_addr = base_address - imm32; 6438 6439 // address = if index then offset_addr else R[n]; 6440 if (index) 6441 address = offset_addr; 6442 else 6443 address = base_address; 6444 6445 // data = MemU[address,4]; 6446 6447 RegisterInfo base_reg; 6448 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6449 6450 EmulateInstruction::Context context; 6451 context.type = eContextRegisterLoad; 6452 context.SetRegisterPlusOffset(base_reg, address - base_address); 6453 6454 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6455 if (!success) 6456 return false; 6457 6458 // if wback then R[n] = offset_addr; 6459 if (wback) { 6460 context.type = eContextAdjustBaseRegister; 6461 context.SetAddress(offset_addr); 6462 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6463 offset_addr)) 6464 return false; 6465 } 6466 6467 // if t == 15 then 6468 if (t == 15) { 6469 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6470 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6471 // LoadWritePC (data); 6472 context.type = eContextRegisterLoad; 6473 context.SetRegisterPlusOffset(base_reg, address - base_address); 6474 LoadWritePC(context, data); 6475 } else 6476 return false; 6477 } 6478 // elsif UnalignedSupport() || address<1:0> = '00' then 6479 else if (UnalignedSupport() || 6480 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6481 // R[t] = data; 6482 context.type = eContextRegisterLoad; 6483 context.SetRegisterPlusOffset(base_reg, address - base_address); 6484 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6485 data)) 6486 return false; 6487 } 6488 // else // Can only apply before ARMv7 6489 else { 6490 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6491 data = ROR(data, Bits32(address, 1, 0), &success); 6492 if (!success) 6493 return false; 6494 context.type = eContextRegisterLoad; 6495 context.SetImmediate(data); 6496 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6497 data)) 6498 return false; 6499 } 6500 } 6501 return true; 6502} 6503 6504// LDR (register) calculates an address from a base register value and an offset 6505// register value, loads a word 6506// from memory, and writes it to a register. The offset register value can 6507// optionally be shifted. 6508bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode, 6509 const ARMEncoding encoding) { 6510#if 0 6511 if ConditionPassed() then 6512 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6513 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6514 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6515 address = if index then offset_addr else R[n]; 6516 data = MemU[address,4]; 6517 if wback then R[n] = offset_addr; 6518 if t == 15 then 6519 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6520 elsif UnalignedSupport() || address<1:0> = '00' then 6521 R[t] = data; 6522 else // Can only apply before ARMv7 6523 if CurrentInstrSet() == InstrSet_ARM then 6524 R[t] = ROR(data, 8*UInt(address<1:0>)); 6525 else 6526 R[t] = bits(32) UNKNOWN; 6527#endif 6528 6529 bool success = false; 6530 6531 if (ConditionPassed(opcode)) { 6532 const uint32_t addr_byte_size = GetAddressByteSize(); 6533 6534 uint32_t t; 6535 uint32_t n; 6536 uint32_t m; 6537 bool index; 6538 bool add; 6539 bool wback; 6540 ARM_ShifterType shift_t; 6541 uint32_t shift_n; 6542 6543 switch (encoding) { 6544 case eEncodingT1: 6545 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 6546 // in ThumbEE"; 6547 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6548 t = Bits32(opcode, 2, 0); 6549 n = Bits32(opcode, 5, 3); 6550 m = Bits32(opcode, 8, 6); 6551 6552 // index = TRUE; add = TRUE; wback = FALSE; 6553 index = true; 6554 add = true; 6555 wback = false; 6556 6557 // (shift_t, shift_n) = (SRType_LSL, 0); 6558 shift_t = SRType_LSL; 6559 shift_n = 0; 6560 6561 break; 6562 6563 case eEncodingT2: 6564 // if Rn == '1111' then SEE LDR (literal); 6565 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6566 t = Bits32(opcode, 15, 12); 6567 n = Bits32(opcode, 19, 16); 6568 m = Bits32(opcode, 3, 0); 6569 6570 // index = TRUE; add = TRUE; wback = FALSE; 6571 index = true; 6572 add = true; 6573 wback = false; 6574 6575 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6576 shift_t = SRType_LSL; 6577 shift_n = Bits32(opcode, 5, 4); 6578 6579 // if BadReg(m) then UNPREDICTABLE; 6580 if (BadReg(m)) 6581 return false; 6582 6583 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6584 if ((t == 15) && InITBlock() && !LastInITBlock()) 6585 return false; 6586 6587 break; 6588 6589 case eEncodingA1: { 6590 // if P == '0' && W == '1' then SEE LDRT; 6591 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6592 t = Bits32(opcode, 15, 12); 6593 n = Bits32(opcode, 19, 16); 6594 m = Bits32(opcode, 3, 0); 6595 6596 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6597 // (W == '1'); 6598 index = BitIsSet(opcode, 24); 6599 add = BitIsSet(opcode, 23); 6600 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6601 6602 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6603 uint32_t type = Bits32(opcode, 6, 5); 6604 uint32_t imm5 = Bits32(opcode, 11, 7); 6605 shift_n = DecodeImmShift(type, imm5, shift_t); 6606 6607 // if m == 15 then UNPREDICTABLE; 6608 if (m == 15) 6609 return false; 6610 6611 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6612 if (wback && ((n == 15) || (n == t))) 6613 return false; 6614 } break; 6615 6616 default: 6617 return false; 6618 } 6619 6620 uint32_t Rm = 6621 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6622 if (!success) 6623 return false; 6624 6625 uint32_t Rn = 6626 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6627 if (!success) 6628 return false; 6629 6630 addr_t offset_addr; 6631 addr_t address; 6632 6633 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is 6634 // an application level alias for the CPSR". 6635 addr_t offset = 6636 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success); 6637 if (!success) 6638 return false; 6639 6640 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6641 if (add) 6642 offset_addr = Rn + offset; 6643 else 6644 offset_addr = Rn - offset; 6645 6646 // address = if index then offset_addr else R[n]; 6647 if (index) 6648 address = offset_addr; 6649 else 6650 address = Rn; 6651 6652 // data = MemU[address,4]; 6653 RegisterInfo base_reg; 6654 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6655 6656 EmulateInstruction::Context context; 6657 context.type = eContextRegisterLoad; 6658 context.SetRegisterPlusOffset(base_reg, address - Rn); 6659 6660 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6661 if (!success) 6662 return false; 6663 6664 // if wback then R[n] = offset_addr; 6665 if (wback) { 6666 context.type = eContextAdjustBaseRegister; 6667 context.SetAddress(offset_addr); 6668 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6669 offset_addr)) 6670 return false; 6671 } 6672 6673 // if t == 15 then 6674 if (t == 15) { 6675 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6676 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6677 context.type = eContextRegisterLoad; 6678 context.SetRegisterPlusOffset(base_reg, address - Rn); 6679 LoadWritePC(context, data); 6680 } else 6681 return false; 6682 } 6683 // elsif UnalignedSupport() || address<1:0> = '00' then 6684 else if (UnalignedSupport() || 6685 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6686 // R[t] = data; 6687 context.type = eContextRegisterLoad; 6688 context.SetRegisterPlusOffset(base_reg, address - Rn); 6689 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6690 data)) 6691 return false; 6692 } else // Can only apply before ARMv7 6693 { 6694 // if CurrentInstrSet() == InstrSet_ARM then 6695 if (CurrentInstrSet() == eModeARM) { 6696 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6697 data = ROR(data, Bits32(address, 1, 0), &success); 6698 if (!success) 6699 return false; 6700 context.type = eContextRegisterLoad; 6701 context.SetImmediate(data); 6702 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6703 data)) 6704 return false; 6705 } else { 6706 // R[t] = bits(32) UNKNOWN; 6707 WriteBits32Unknown(t); 6708 } 6709 } 6710 } 6711 return true; 6712} 6713 6714// LDRB (immediate, Thumb) 6715bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode, 6716 const ARMEncoding encoding) { 6717#if 0 6718 if ConditionPassed() then 6719 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6720 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6721 address = if index then offset_addr else R[n]; 6722 R[t] = ZeroExtend(MemU[address,1], 32); 6723 if wback then R[n] = offset_addr; 6724#endif 6725 6726 bool success = false; 6727 6728 if (ConditionPassed(opcode)) { 6729 uint32_t t; 6730 uint32_t n; 6731 uint32_t imm32; 6732 bool index; 6733 bool add; 6734 bool wback; 6735 6736 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6737 switch (encoding) { 6738 case eEncodingT1: 6739 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6740 t = Bits32(opcode, 2, 0); 6741 n = Bits32(opcode, 5, 3); 6742 imm32 = Bits32(opcode, 10, 6); 6743 6744 // index = TRUE; add = TRUE; wback = FALSE; 6745 index = true; 6746 add = true; 6747 wback = false; 6748 6749 break; 6750 6751 case eEncodingT2: 6752 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6753 t = Bits32(opcode, 15, 12); 6754 n = Bits32(opcode, 19, 16); 6755 imm32 = Bits32(opcode, 11, 0); 6756 6757 // index = TRUE; add = TRUE; wback = FALSE; 6758 index = true; 6759 add = true; 6760 wback = false; 6761 6762 // if Rt == '1111' then SEE PLD; 6763 if (t == 15) 6764 return false; // PLD is not implemented yet 6765 6766 // if Rn == '1111' then SEE LDRB (literal); 6767 if (n == 15) 6768 return EmulateLDRBLiteral(opcode, eEncodingT1); 6769 6770 // if t == 13 then UNPREDICTABLE; 6771 if (t == 13) 6772 return false; 6773 6774 break; 6775 6776 case eEncodingT3: 6777 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6778 // if P == '0' && W == '0' then UNDEFINED; 6779 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 6780 return false; 6781 6782 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6783 t = Bits32(opcode, 15, 12); 6784 n = Bits32(opcode, 19, 16); 6785 imm32 = Bits32(opcode, 7, 0); 6786 6787 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6788 index = BitIsSet(opcode, 10); 6789 add = BitIsSet(opcode, 9); 6790 wback = BitIsSet(opcode, 8); 6791 6792 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6793 if (t == 15) 6794 return false; // PLD is not implemented yet 6795 6796 // if Rn == '1111' then SEE LDRB (literal); 6797 if (n == 15) 6798 return EmulateLDRBLiteral(opcode, eEncodingT1); 6799 6800 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6801 if (BadReg(t) || (wback && (n == t))) 6802 return false; 6803 6804 break; 6805 6806 default: 6807 return false; 6808 } 6809 6810 uint32_t Rn = 6811 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6812 if (!success) 6813 return false; 6814 6815 addr_t address; 6816 addr_t offset_addr; 6817 6818 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6819 if (add) 6820 offset_addr = Rn + imm32; 6821 else 6822 offset_addr = Rn - imm32; 6823 6824 // address = if index then offset_addr else R[n]; 6825 if (index) 6826 address = offset_addr; 6827 else 6828 address = Rn; 6829 6830 // R[t] = ZeroExtend(MemU[address,1], 32); 6831 RegisterInfo base_reg; 6832 RegisterInfo data_reg; 6833 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6834 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6835 6836 EmulateInstruction::Context context; 6837 context.type = eContextRegisterLoad; 6838 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 6839 6840 uint64_t data = MemURead(context, address, 1, 0, &success); 6841 if (!success) 6842 return false; 6843 6844 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6845 return false; 6846 6847 // if wback then R[n] = offset_addr; 6848 if (wback) { 6849 context.type = eContextAdjustBaseRegister; 6850 context.SetAddress(offset_addr); 6851 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6852 offset_addr)) 6853 return false; 6854 } 6855 } 6856 return true; 6857} 6858 6859// LDRB (literal) calculates an address from the PC value and an immediate 6860// offset, loads a byte from memory, 6861// zero-extends it to form a 32-bit word and writes it to a register. 6862bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode, 6863 const ARMEncoding encoding) { 6864#if 0 6865 if ConditionPassed() then 6866 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6867 base = Align(PC,4); 6868 address = if add then (base + imm32) else (base - imm32); 6869 R[t] = ZeroExtend(MemU[address,1], 32); 6870#endif 6871 6872 bool success = false; 6873 6874 if (ConditionPassed(opcode)) { 6875 uint32_t t; 6876 uint32_t imm32; 6877 bool add; 6878 switch (encoding) { 6879 case eEncodingT1: 6880 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6881 t = Bits32(opcode, 15, 12); 6882 imm32 = Bits32(opcode, 11, 0); 6883 add = BitIsSet(opcode, 23); 6884 6885 // if Rt == '1111' then SEE PLD; 6886 if (t == 15) 6887 return false; // PLD is not implemented yet 6888 6889 // if t == 13 then UNPREDICTABLE; 6890 if (t == 13) 6891 return false; 6892 6893 break; 6894 6895 case eEncodingA1: 6896 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6897 t = Bits32(opcode, 15, 12); 6898 imm32 = Bits32(opcode, 11, 0); 6899 add = BitIsSet(opcode, 23); 6900 6901 // if t == 15 then UNPREDICTABLE; 6902 if (t == 15) 6903 return false; 6904 break; 6905 6906 default: 6907 return false; 6908 } 6909 6910 // base = Align(PC,4); 6911 uint32_t pc_val = ReadCoreReg(PC_REG, &success); 6912 if (!success) 6913 return false; 6914 6915 uint32_t base = AlignPC(pc_val); 6916 6917 addr_t address; 6918 // address = if add then (base + imm32) else (base - imm32); 6919 if (add) 6920 address = base + imm32; 6921 else 6922 address = base - imm32; 6923 6924 // R[t] = ZeroExtend(MemU[address,1], 32); 6925 EmulateInstruction::Context context; 6926 context.type = eContextRelativeBranchImmediate; 6927 context.SetImmediate(address - base); 6928 6929 uint64_t data = MemURead(context, address, 1, 0, &success); 6930 if (!success) 6931 return false; 6932 6933 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6934 return false; 6935 } 6936 return true; 6937} 6938 6939// LDRB (register) calculates an address from a base register value and an 6940// offset rigister value, loads a byte from memory, zero-extends it to form a 6941// 32-bit word, and writes it to a register. The offset register value can 6942// optionally be shifted. 6943bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode, 6944 const ARMEncoding encoding) { 6945#if 0 6946 if ConditionPassed() then 6947 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6948 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6949 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6950 address = if index then offset_addr else R[n]; 6951 R[t] = ZeroExtend(MemU[address,1],32); 6952 if wback then R[n] = offset_addr; 6953#endif 6954 6955 bool success = false; 6956 6957 if (ConditionPassed(opcode)) { 6958 uint32_t t; 6959 uint32_t n; 6960 uint32_t m; 6961 bool index; 6962 bool add; 6963 bool wback; 6964 ARM_ShifterType shift_t; 6965 uint32_t shift_n; 6966 6967 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6968 switch (encoding) { 6969 case eEncodingT1: 6970 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6971 t = Bits32(opcode, 2, 0); 6972 n = Bits32(opcode, 5, 3); 6973 m = Bits32(opcode, 8, 6); 6974 6975 // index = TRUE; add = TRUE; wback = FALSE; 6976 index = true; 6977 add = true; 6978 wback = false; 6979 6980 // (shift_t, shift_n) = (SRType_LSL, 0); 6981 shift_t = SRType_LSL; 6982 shift_n = 0; 6983 break; 6984 6985 case eEncodingT2: 6986 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6987 t = Bits32(opcode, 15, 12); 6988 n = Bits32(opcode, 19, 16); 6989 m = Bits32(opcode, 3, 0); 6990 6991 // index = TRUE; add = TRUE; wback = FALSE; 6992 index = true; 6993 add = true; 6994 wback = false; 6995 6996 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6997 shift_t = SRType_LSL; 6998 shift_n = Bits32(opcode, 5, 4); 6999 7000 // if Rt == '1111' then SEE PLD; 7001 if (t == 15) 7002 return false; // PLD is not implemented yet 7003 7004 // if Rn == '1111' then SEE LDRB (literal); 7005 if (n == 15) 7006 return EmulateLDRBLiteral(opcode, eEncodingT1); 7007 7008 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7009 if ((t == 13) || BadReg(m)) 7010 return false; 7011 break; 7012 7013 case eEncodingA1: { 7014 // if P == '0' && W == '1' then SEE LDRBT; 7015 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7016 t = Bits32(opcode, 15, 12); 7017 n = Bits32(opcode, 19, 16); 7018 m = Bits32(opcode, 3, 0); 7019 7020 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7021 // (W == '1'); 7022 index = BitIsSet(opcode, 24); 7023 add = BitIsSet(opcode, 23); 7024 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7025 7026 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 7027 uint32_t type = Bits32(opcode, 6, 5); 7028 uint32_t imm5 = Bits32(opcode, 11, 7); 7029 shift_n = DecodeImmShift(type, imm5, shift_t); 7030 7031 // if t == 15 || m == 15 then UNPREDICTABLE; 7032 if ((t == 15) || (m == 15)) 7033 return false; 7034 7035 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7036 if (wback && ((n == 15) || (n == t))) 7037 return false; 7038 } break; 7039 7040 default: 7041 return false; 7042 } 7043 7044 addr_t offset_addr; 7045 addr_t address; 7046 7047 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7048 uint32_t Rm = 7049 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7050 if (!success) 7051 return false; 7052 7053 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7054 if (!success) 7055 return false; 7056 7057 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7058 uint32_t Rn = 7059 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7060 if (!success) 7061 return false; 7062 7063 if (add) 7064 offset_addr = Rn + offset; 7065 else 7066 offset_addr = Rn - offset; 7067 7068 // address = if index then offset_addr else R[n]; 7069 if (index) 7070 address = offset_addr; 7071 else 7072 address = Rn; 7073 7074 // R[t] = ZeroExtend(MemU[address,1],32); 7075 RegisterInfo base_reg; 7076 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7077 7078 EmulateInstruction::Context context; 7079 context.type = eContextRegisterLoad; 7080 context.SetRegisterPlusOffset(base_reg, address - Rn); 7081 7082 uint64_t data = MemURead(context, address, 1, 0, &success); 7083 if (!success) 7084 return false; 7085 7086 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7087 return false; 7088 7089 // if wback then R[n] = offset_addr; 7090 if (wback) { 7091 context.type = eContextAdjustBaseRegister; 7092 context.SetAddress(offset_addr); 7093 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7094 offset_addr)) 7095 return false; 7096 } 7097 } 7098 return true; 7099} 7100 7101// LDRH (immediate, Thumb) calculates an address from a base register value and 7102// an immediate offset, loads a 7103// halfword from memory, zero-extends it to form a 32-bit word, and writes it 7104// to a register. It can use offset, post-indexed, or pre-indexed addressing. 7105bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode, 7106 const ARMEncoding encoding) { 7107#if 0 7108 if ConditionPassed() then 7109 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7110 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7111 address = if index then offset_addr else R[n]; 7112 data = MemU[address,2]; 7113 if wback then R[n] = offset_addr; 7114 if UnalignedSupport() || address<0> = '0' then 7115 R[t] = ZeroExtend(data, 32); 7116 else // Can only apply before ARMv7 7117 R[t] = bits(32) UNKNOWN; 7118#endif 7119 7120 bool success = false; 7121 7122 if (ConditionPassed(opcode)) { 7123 uint32_t t; 7124 uint32_t n; 7125 uint32_t imm32; 7126 bool index; 7127 bool add; 7128 bool wback; 7129 7130 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7131 switch (encoding) { 7132 case eEncodingT1: 7133 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 7134 t = Bits32(opcode, 2, 0); 7135 n = Bits32(opcode, 5, 3); 7136 imm32 = Bits32(opcode, 10, 6) << 1; 7137 7138 // index = TRUE; add = TRUE; wback = FALSE; 7139 index = true; 7140 add = true; 7141 wback = false; 7142 7143 break; 7144 7145 case eEncodingT2: 7146 // if Rt == '1111' then SEE "Unallocated memory hints"; 7147 // if Rn == '1111' then SEE LDRH (literal); 7148 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7149 t = Bits32(opcode, 15, 12); 7150 n = Bits32(opcode, 19, 16); 7151 imm32 = Bits32(opcode, 11, 0); 7152 7153 // index = TRUE; add = TRUE; wback = FALSE; 7154 index = true; 7155 add = true; 7156 wback = false; 7157 7158 // if t == 13 then UNPREDICTABLE; 7159 if (t == 13) 7160 return false; 7161 break; 7162 7163 case eEncodingT3: 7164 // if Rn == '1111' then SEE LDRH (literal); 7165 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7166 // "Unallocated memory hints"; 7167 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 7168 // if P == '0' && W == '0' then UNDEFINED; 7169 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7170 return false; 7171 7172 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7173 t = Bits32(opcode, 15, 12); 7174 n = Bits32(opcode, 19, 16); 7175 imm32 = Bits32(opcode, 7, 0); 7176 7177 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7178 index = BitIsSet(opcode, 10); 7179 add = BitIsSet(opcode, 9); 7180 wback = BitIsSet(opcode, 8); 7181 7182 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7183 if (BadReg(t) || (wback && (n == t))) 7184 return false; 7185 break; 7186 7187 default: 7188 return false; 7189 } 7190 7191 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7192 uint32_t Rn = 7193 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7194 if (!success) 7195 return false; 7196 7197 addr_t offset_addr; 7198 addr_t address; 7199 7200 if (add) 7201 offset_addr = Rn + imm32; 7202 else 7203 offset_addr = Rn - imm32; 7204 7205 // address = if index then offset_addr else R[n]; 7206 if (index) 7207 address = offset_addr; 7208 else 7209 address = Rn; 7210 7211 // data = MemU[address,2]; 7212 RegisterInfo base_reg; 7213 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7214 7215 EmulateInstruction::Context context; 7216 context.type = eContextRegisterLoad; 7217 context.SetRegisterPlusOffset(base_reg, address - Rn); 7218 7219 uint64_t data = MemURead(context, address, 2, 0, &success); 7220 if (!success) 7221 return false; 7222 7223 // if wback then R[n] = offset_addr; 7224 if (wback) { 7225 context.type = eContextAdjustBaseRegister; 7226 context.SetAddress(offset_addr); 7227 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7228 offset_addr)) 7229 return false; 7230 } 7231 7232 // if UnalignedSupport() || address<0> = '0' then 7233 if (UnalignedSupport() || BitIsClear(address, 0)) { 7234 // R[t] = ZeroExtend(data, 32); 7235 context.type = eContextRegisterLoad; 7236 context.SetRegisterPlusOffset(base_reg, address - Rn); 7237 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7238 data)) 7239 return false; 7240 } else // Can only apply before ARMv7 7241 { 7242 // R[t] = bits(32) UNKNOWN; 7243 WriteBits32Unknown(t); 7244 } 7245 } 7246 return true; 7247} 7248 7249// LDRH (literal) caculates an address from the PC value and an immediate 7250// offset, loads a halfword from memory, 7251// zero-extends it to form a 32-bit word, and writes it to a register. 7252bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode, 7253 const ARMEncoding encoding) { 7254#if 0 7255 if ConditionPassed() then 7256 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7257 base = Align(PC,4); 7258 address = if add then (base + imm32) else (base - imm32); 7259 data = MemU[address,2]; 7260 if UnalignedSupport() || address<0> = '0' then 7261 R[t] = ZeroExtend(data, 32); 7262 else // Can only apply before ARMv7 7263 R[t] = bits(32) UNKNOWN; 7264#endif 7265 7266 bool success = false; 7267 7268 if (ConditionPassed(opcode)) { 7269 uint32_t t; 7270 uint32_t imm32; 7271 bool add; 7272 7273 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7274 switch (encoding) { 7275 case eEncodingT1: 7276 // if Rt == '1111' then SEE "Unallocated memory hints"; 7277 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7278 t = Bits32(opcode, 15, 12); 7279 imm32 = Bits32(opcode, 11, 0); 7280 add = BitIsSet(opcode, 23); 7281 7282 // if t == 13 then UNPREDICTABLE; 7283 if (t == 13) 7284 return false; 7285 7286 break; 7287 7288 case eEncodingA1: { 7289 uint32_t imm4H = Bits32(opcode, 11, 8); 7290 uint32_t imm4L = Bits32(opcode, 3, 0); 7291 7292 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7293 t = Bits32(opcode, 15, 12); 7294 imm32 = (imm4H << 4) | imm4L; 7295 add = BitIsSet(opcode, 23); 7296 7297 // if t == 15 then UNPREDICTABLE; 7298 if (t == 15) 7299 return false; 7300 break; 7301 } 7302 7303 default: 7304 return false; 7305 } 7306 7307 // base = Align(PC,4); 7308 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7309 if (!success) 7310 return false; 7311 7312 addr_t base = AlignPC(pc_value); 7313 addr_t address; 7314 7315 // address = if add then (base + imm32) else (base - imm32); 7316 if (add) 7317 address = base + imm32; 7318 else 7319 address = base - imm32; 7320 7321 // data = MemU[address,2]; 7322 RegisterInfo base_reg; 7323 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7324 7325 EmulateInstruction::Context context; 7326 context.type = eContextRegisterLoad; 7327 context.SetRegisterPlusOffset(base_reg, address - base); 7328 7329 uint64_t data = MemURead(context, address, 2, 0, &success); 7330 if (!success) 7331 return false; 7332 7333 // if UnalignedSupport() || address<0> = '0' then 7334 if (UnalignedSupport() || BitIsClear(address, 0)) { 7335 // R[t] = ZeroExtend(data, 32); 7336 context.type = eContextRegisterLoad; 7337 context.SetRegisterPlusOffset(base_reg, address - base); 7338 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7339 data)) 7340 return false; 7341 7342 } else // Can only apply before ARMv7 7343 { 7344 // R[t] = bits(32) UNKNOWN; 7345 WriteBits32Unknown(t); 7346 } 7347 } 7348 return true; 7349} 7350 7351// LDRH (literal) calculates an address from a base register value and an offset 7352// register value, loads a halfword 7353// from memory, zero-extends it to form a 32-bit word, and writes it to a 7354// register. The offset register value can be shifted left by 0, 1, 2, or 3 7355// bits. 7356bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode, 7357 const ARMEncoding encoding) { 7358#if 0 7359 if ConditionPassed() then 7360 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7361 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7362 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7363 address = if index then offset_addr else R[n]; 7364 data = MemU[address,2]; 7365 if wback then R[n] = offset_addr; 7366 if UnalignedSupport() || address<0> = '0' then 7367 R[t] = ZeroExtend(data, 32); 7368 else // Can only apply before ARMv7 7369 R[t] = bits(32) UNKNOWN; 7370#endif 7371 7372 bool success = false; 7373 7374 if (ConditionPassed(opcode)) { 7375 uint32_t t; 7376 uint32_t n; 7377 uint32_t m; 7378 bool index; 7379 bool add; 7380 bool wback; 7381 ARM_ShifterType shift_t; 7382 uint32_t shift_n; 7383 7384 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7385 switch (encoding) { 7386 case eEncodingT1: 7387 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 7388 // in ThumbEE"; 7389 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7390 t = Bits32(opcode, 2, 0); 7391 n = Bits32(opcode, 5, 3); 7392 m = Bits32(opcode, 8, 6); 7393 7394 // index = TRUE; add = TRUE; wback = FALSE; 7395 index = true; 7396 add = true; 7397 wback = false; 7398 7399 // (shift_t, shift_n) = (SRType_LSL, 0); 7400 shift_t = SRType_LSL; 7401 shift_n = 0; 7402 7403 break; 7404 7405 case eEncodingT2: 7406 // if Rn == '1111' then SEE LDRH (literal); 7407 // if Rt == '1111' then SEE "Unallocated memory hints"; 7408 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7409 t = Bits32(opcode, 15, 12); 7410 n = Bits32(opcode, 19, 16); 7411 m = Bits32(opcode, 3, 0); 7412 7413 // index = TRUE; add = TRUE; wback = FALSE; 7414 index = true; 7415 add = true; 7416 wback = false; 7417 7418 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7419 shift_t = SRType_LSL; 7420 shift_n = Bits32(opcode, 5, 4); 7421 7422 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7423 if ((t == 13) || BadReg(m)) 7424 return false; 7425 break; 7426 7427 case eEncodingA1: 7428 // if P == '0' && W == '1' then SEE LDRHT; 7429 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7430 t = Bits32(opcode, 15, 12); 7431 n = Bits32(opcode, 19, 16); 7432 m = Bits32(opcode, 3, 0); 7433 7434 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7435 // (W == '1'); 7436 index = BitIsSet(opcode, 24); 7437 add = BitIsSet(opcode, 23); 7438 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7439 7440 // (shift_t, shift_n) = (SRType_LSL, 0); 7441 shift_t = SRType_LSL; 7442 shift_n = 0; 7443 7444 // if t == 15 || m == 15 then UNPREDICTABLE; 7445 if ((t == 15) || (m == 15)) 7446 return false; 7447 7448 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7449 if (wback && ((n == 15) || (n == t))) 7450 return false; 7451 7452 break; 7453 7454 default: 7455 return false; 7456 } 7457 7458 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7459 7460 uint64_t Rm = 7461 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7462 if (!success) 7463 return false; 7464 7465 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7466 if (!success) 7467 return false; 7468 7469 addr_t offset_addr; 7470 addr_t address; 7471 7472 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7473 uint64_t Rn = 7474 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7475 if (!success) 7476 return false; 7477 7478 if (add) 7479 offset_addr = Rn + offset; 7480 else 7481 offset_addr = Rn - offset; 7482 7483 // address = if index then offset_addr else R[n]; 7484 if (index) 7485 address = offset_addr; 7486 else 7487 address = Rn; 7488 7489 // data = MemU[address,2]; 7490 RegisterInfo base_reg; 7491 RegisterInfo offset_reg; 7492 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7493 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7494 7495 EmulateInstruction::Context context; 7496 context.type = eContextRegisterLoad; 7497 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7498 uint64_t data = MemURead(context, address, 2, 0, &success); 7499 if (!success) 7500 return false; 7501 7502 // if wback then R[n] = offset_addr; 7503 if (wback) { 7504 context.type = eContextAdjustBaseRegister; 7505 context.SetAddress(offset_addr); 7506 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7507 offset_addr)) 7508 return false; 7509 } 7510 7511 // if UnalignedSupport() || address<0> = '0' then 7512 if (UnalignedSupport() || BitIsClear(address, 0)) { 7513 // R[t] = ZeroExtend(data, 32); 7514 context.type = eContextRegisterLoad; 7515 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7516 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7517 data)) 7518 return false; 7519 } else // Can only apply before ARMv7 7520 { 7521 // R[t] = bits(32) UNKNOWN; 7522 WriteBits32Unknown(t); 7523 } 7524 } 7525 return true; 7526} 7527 7528// LDRSB (immediate) calculates an address from a base register value and an 7529// immediate offset, loads a byte from 7530// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7531// It can use offset, post-indexed, or pre-indexed addressing. 7532bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode, 7533 const ARMEncoding encoding) { 7534#if 0 7535 if ConditionPassed() then 7536 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7537 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7538 address = if index then offset_addr else R[n]; 7539 R[t] = SignExtend(MemU[address,1], 32); 7540 if wback then R[n] = offset_addr; 7541#endif 7542 7543 bool success = false; 7544 7545 if (ConditionPassed(opcode)) { 7546 uint32_t t; 7547 uint32_t n; 7548 uint32_t imm32; 7549 bool index; 7550 bool add; 7551 bool wback; 7552 7553 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7554 switch (encoding) { 7555 case eEncodingT1: 7556 // if Rt == '1111' then SEE PLI; 7557 // if Rn == '1111' then SEE LDRSB (literal); 7558 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7559 t = Bits32(opcode, 15, 12); 7560 n = Bits32(opcode, 19, 16); 7561 imm32 = Bits32(opcode, 11, 0); 7562 7563 // index = TRUE; add = TRUE; wback = FALSE; 7564 index = true; 7565 add = true; 7566 wback = false; 7567 7568 // if t == 13 then UNPREDICTABLE; 7569 if (t == 13) 7570 return false; 7571 7572 break; 7573 7574 case eEncodingT2: 7575 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7576 // if Rn == '1111' then SEE LDRSB (literal); 7577 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7578 // if P == '0' && W == '0' then UNDEFINED; 7579 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7580 return false; 7581 7582 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7583 t = Bits32(opcode, 15, 12); 7584 n = Bits32(opcode, 19, 16); 7585 imm32 = Bits32(opcode, 7, 0); 7586 7587 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7588 index = BitIsSet(opcode, 10); 7589 add = BitIsSet(opcode, 9); 7590 wback = BitIsSet(opcode, 8); 7591 7592 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7593 if (((t == 13) || 7594 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) || 7595 BitIsSet(opcode, 8)))) || 7596 (wback && (n == t))) 7597 return false; 7598 7599 break; 7600 7601 case eEncodingA1: { 7602 // if Rn == '1111' then SEE LDRSB (literal); 7603 // if P == '0' && W == '1' then SEE LDRSBT; 7604 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7605 t = Bits32(opcode, 15, 12); 7606 n = Bits32(opcode, 19, 16); 7607 7608 uint32_t imm4H = Bits32(opcode, 11, 8); 7609 uint32_t imm4L = Bits32(opcode, 3, 0); 7610 imm32 = (imm4H << 4) | imm4L; 7611 7612 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7613 // (W == '1'); 7614 index = BitIsSet(opcode, 24); 7615 add = BitIsSet(opcode, 23); 7616 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7617 7618 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7619 if ((t == 15) || (wback && (n == t))) 7620 return false; 7621 7622 break; 7623 } 7624 7625 default: 7626 return false; 7627 } 7628 7629 uint64_t Rn = ReadCoreReg(n, &success); 7630 if (!success) 7631 return false; 7632 7633 addr_t offset_addr; 7634 addr_t address; 7635 7636 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7637 if (add) 7638 offset_addr = Rn + imm32; 7639 else 7640 offset_addr = Rn - imm32; 7641 7642 // address = if index then offset_addr else R[n]; 7643 if (index) 7644 address = offset_addr; 7645 else 7646 address = Rn; 7647 7648 // R[t] = SignExtend(MemU[address,1], 32); 7649 RegisterInfo base_reg; 7650 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7651 7652 EmulateInstruction::Context context; 7653 context.type = eContextRegisterLoad; 7654 context.SetRegisterPlusOffset(base_reg, address - Rn); 7655 7656 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7657 if (!success) 7658 return false; 7659 7660 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7661 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7662 (uint64_t)signed_data)) 7663 return false; 7664 7665 // if wback then R[n] = offset_addr; 7666 if (wback) { 7667 context.type = eContextAdjustBaseRegister; 7668 context.SetAddress(offset_addr); 7669 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7670 offset_addr)) 7671 return false; 7672 } 7673 } 7674 7675 return true; 7676} 7677 7678// LDRSB (literal) calculates an address from the PC value and an immediate 7679// offset, loads a byte from memory, 7680// sign-extends it to form a 32-bit word, and writes tit to a register. 7681bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode, 7682 const ARMEncoding encoding) { 7683#if 0 7684 if ConditionPassed() then 7685 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7686 base = Align(PC,4); 7687 address = if add then (base + imm32) else (base - imm32); 7688 R[t] = SignExtend(MemU[address,1], 32); 7689#endif 7690 7691 bool success = false; 7692 7693 if (ConditionPassed(opcode)) { 7694 uint32_t t; 7695 uint32_t imm32; 7696 bool add; 7697 7698 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7699 switch (encoding) { 7700 case eEncodingT1: 7701 // if Rt == '1111' then SEE PLI; 7702 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7703 t = Bits32(opcode, 15, 12); 7704 imm32 = Bits32(opcode, 11, 0); 7705 add = BitIsSet(opcode, 23); 7706 7707 // if t == 13 then UNPREDICTABLE; 7708 if (t == 13) 7709 return false; 7710 7711 break; 7712 7713 case eEncodingA1: { 7714 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7715 t = Bits32(opcode, 15, 12); 7716 uint32_t imm4H = Bits32(opcode, 11, 8); 7717 uint32_t imm4L = Bits32(opcode, 3, 0); 7718 imm32 = (imm4H << 4) | imm4L; 7719 add = BitIsSet(opcode, 23); 7720 7721 // if t == 15 then UNPREDICTABLE; 7722 if (t == 15) 7723 return false; 7724 7725 break; 7726 } 7727 7728 default: 7729 return false; 7730 } 7731 7732 // base = Align(PC,4); 7733 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7734 if (!success) 7735 return false; 7736 uint64_t base = AlignPC(pc_value); 7737 7738 // address = if add then (base + imm32) else (base - imm32); 7739 addr_t address; 7740 if (add) 7741 address = base + imm32; 7742 else 7743 address = base - imm32; 7744 7745 // R[t] = SignExtend(MemU[address,1], 32); 7746 RegisterInfo base_reg; 7747 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7748 7749 EmulateInstruction::Context context; 7750 context.type = eContextRegisterLoad; 7751 context.SetRegisterPlusOffset(base_reg, address - base); 7752 7753 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7754 if (!success) 7755 return false; 7756 7757 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7758 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7759 (uint64_t)signed_data)) 7760 return false; 7761 } 7762 return true; 7763} 7764 7765// LDRSB (register) calculates an address from a base register value and an 7766// offset register value, loadsa byte from 7767// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7768// The offset register value can be shifted left by 0, 1, 2, or 3 bits. 7769bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode, 7770 const ARMEncoding encoding) { 7771#if 0 7772 if ConditionPassed() then 7773 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7774 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7775 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7776 address = if index then offset_addr else R[n]; 7777 R[t] = SignExtend(MemU[address,1], 32); 7778 if wback then R[n] = offset_addr; 7779#endif 7780 7781 bool success = false; 7782 7783 if (ConditionPassed(opcode)) { 7784 uint32_t t; 7785 uint32_t n; 7786 uint32_t m; 7787 bool index; 7788 bool add; 7789 bool wback; 7790 ARM_ShifterType shift_t; 7791 uint32_t shift_n; 7792 7793 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7794 switch (encoding) { 7795 case eEncodingT1: 7796 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7797 t = Bits32(opcode, 2, 0); 7798 n = Bits32(opcode, 5, 3); 7799 m = Bits32(opcode, 8, 6); 7800 7801 // index = TRUE; add = TRUE; wback = FALSE; 7802 index = true; 7803 add = true; 7804 wback = false; 7805 7806 // (shift_t, shift_n) = (SRType_LSL, 0); 7807 shift_t = SRType_LSL; 7808 shift_n = 0; 7809 7810 break; 7811 7812 case eEncodingT2: 7813 // if Rt == '1111' then SEE PLI; 7814 // if Rn == '1111' then SEE LDRSB (literal); 7815 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7816 t = Bits32(opcode, 15, 12); 7817 n = Bits32(opcode, 19, 16); 7818 m = Bits32(opcode, 3, 0); 7819 7820 // index = TRUE; add = TRUE; wback = FALSE; 7821 index = true; 7822 add = true; 7823 wback = false; 7824 7825 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7826 shift_t = SRType_LSL; 7827 shift_n = Bits32(opcode, 5, 4); 7828 7829 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7830 if ((t == 13) || BadReg(m)) 7831 return false; 7832 break; 7833 7834 case eEncodingA1: 7835 // if P == '0' && W == '1' then SEE LDRSBT; 7836 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7837 t = Bits32(opcode, 15, 12); 7838 n = Bits32(opcode, 19, 16); 7839 m = Bits32(opcode, 3, 0); 7840 7841 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7842 // (W == '1'); 7843 index = BitIsSet(opcode, 24); 7844 add = BitIsSet(opcode, 23); 7845 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7846 7847 // (shift_t, shift_n) = (SRType_LSL, 0); 7848 shift_t = SRType_LSL; 7849 shift_n = 0; 7850 7851 // if t == 15 || m == 15 then UNPREDICTABLE; 7852 if ((t == 15) || (m == 15)) 7853 return false; 7854 7855 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7856 if (wback && ((n == 15) || (n == t))) 7857 return false; 7858 break; 7859 7860 default: 7861 return false; 7862 } 7863 7864 uint64_t Rm = 7865 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7866 if (!success) 7867 return false; 7868 7869 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7870 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7871 if (!success) 7872 return false; 7873 7874 addr_t offset_addr; 7875 addr_t address; 7876 7877 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7878 uint64_t Rn = 7879 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7880 if (!success) 7881 return false; 7882 7883 if (add) 7884 offset_addr = Rn + offset; 7885 else 7886 offset_addr = Rn - offset; 7887 7888 // address = if index then offset_addr else R[n]; 7889 if (index) 7890 address = offset_addr; 7891 else 7892 address = Rn; 7893 7894 // R[t] = SignExtend(MemU[address,1], 32); 7895 RegisterInfo base_reg; 7896 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7897 RegisterInfo offset_reg; 7898 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7899 7900 EmulateInstruction::Context context; 7901 context.type = eContextRegisterLoad; 7902 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7903 7904 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7905 if (!success) 7906 return false; 7907 7908 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7909 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7910 (uint64_t)signed_data)) 7911 return false; 7912 7913 // if wback then R[n] = offset_addr; 7914 if (wback) { 7915 context.type = eContextAdjustBaseRegister; 7916 context.SetAddress(offset_addr); 7917 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7918 offset_addr)) 7919 return false; 7920 } 7921 } 7922 return true; 7923} 7924 7925// LDRSH (immediate) calculates an address from a base register value and an 7926// immediate offset, loads a halfword from 7927// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7928// It can use offset, post-indexed, or pre-indexed addressing. 7929bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode, 7930 const ARMEncoding encoding) { 7931#if 0 7932 if ConditionPassed() then 7933 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7934 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7935 address = if index then offset_addr else R[n]; 7936 data = MemU[address,2]; 7937 if wback then R[n] = offset_addr; 7938 if UnalignedSupport() || address<0> = '0' then 7939 R[t] = SignExtend(data, 32); 7940 else // Can only apply before ARMv7 7941 R[t] = bits(32) UNKNOWN; 7942#endif 7943 7944 bool success = false; 7945 7946 if (ConditionPassed(opcode)) { 7947 uint32_t t; 7948 uint32_t n; 7949 uint32_t imm32; 7950 bool index; 7951 bool add; 7952 bool wback; 7953 7954 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7955 switch (encoding) { 7956 case eEncodingT1: 7957 // if Rn == '1111' then SEE LDRSH (literal); 7958 // if Rt == '1111' then SEE "Unallocated memory hints"; 7959 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7960 t = Bits32(opcode, 15, 12); 7961 n = Bits32(opcode, 19, 16); 7962 imm32 = Bits32(opcode, 11, 0); 7963 7964 // index = TRUE; add = TRUE; wback = FALSE; 7965 index = true; 7966 add = true; 7967 wback = false; 7968 7969 // if t == 13 then UNPREDICTABLE; 7970 if (t == 13) 7971 return false; 7972 7973 break; 7974 7975 case eEncodingT2: 7976 // if Rn == '1111' then SEE LDRSH (literal); 7977 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7978 // "Unallocated memory hints"; 7979 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7980 // if P == '0' && W == '0' then UNDEFINED; 7981 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7982 return false; 7983 7984 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7985 t = Bits32(opcode, 15, 12); 7986 n = Bits32(opcode, 19, 16); 7987 imm32 = Bits32(opcode, 7, 0); 7988 7989 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7990 index = BitIsSet(opcode, 10); 7991 add = BitIsSet(opcode, 9); 7992 wback = BitIsSet(opcode, 8); 7993 7994 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7995 if (BadReg(t) || (wback && (n == t))) 7996 return false; 7997 7998 break; 7999 8000 case eEncodingA1: { 8001 // if Rn == '1111' then SEE LDRSH (literal); 8002 // if P == '0' && W == '1' then SEE LDRSHT; 8003 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 8004 t = Bits32(opcode, 15, 12); 8005 n = Bits32(opcode, 19, 16); 8006 uint32_t imm4H = Bits32(opcode, 11, 8); 8007 uint32_t imm4L = Bits32(opcode, 3, 0); 8008 imm32 = (imm4H << 4) | imm4L; 8009 8010 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8011 // (W == '1'); 8012 index = BitIsSet(opcode, 24); 8013 add = BitIsSet(opcode, 23); 8014 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8015 8016 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 8017 if ((t == 15) || (wback && (n == t))) 8018 return false; 8019 8020 break; 8021 } 8022 8023 default: 8024 return false; 8025 } 8026 8027 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 8028 uint64_t Rn = 8029 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8030 if (!success) 8031 return false; 8032 8033 addr_t offset_addr; 8034 if (add) 8035 offset_addr = Rn + imm32; 8036 else 8037 offset_addr = Rn - imm32; 8038 8039 // address = if index then offset_addr else R[n]; 8040 addr_t address; 8041 if (index) 8042 address = offset_addr; 8043 else 8044 address = Rn; 8045 8046 // data = MemU[address,2]; 8047 RegisterInfo base_reg; 8048 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8049 8050 EmulateInstruction::Context context; 8051 context.type = eContextRegisterLoad; 8052 context.SetRegisterPlusOffset(base_reg, address - Rn); 8053 8054 uint64_t data = MemURead(context, address, 2, 0, &success); 8055 if (!success) 8056 return false; 8057 8058 // if wback then R[n] = offset_addr; 8059 if (wback) { 8060 context.type = eContextAdjustBaseRegister; 8061 context.SetAddress(offset_addr); 8062 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8063 offset_addr)) 8064 return false; 8065 } 8066 8067 // if UnalignedSupport() || address<0> = '0' then 8068 if (UnalignedSupport() || BitIsClear(address, 0)) { 8069 // R[t] = SignExtend(data, 32); 8070 int64_t signed_data = llvm::SignExtend64<16>(data); 8071 context.type = eContextRegisterLoad; 8072 context.SetRegisterPlusOffset(base_reg, address - Rn); 8073 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8074 (uint64_t)signed_data)) 8075 return false; 8076 } else // Can only apply before ARMv7 8077 { 8078 // R[t] = bits(32) UNKNOWN; 8079 WriteBits32Unknown(t); 8080 } 8081 } 8082 return true; 8083} 8084 8085// LDRSH (literal) calculates an address from the PC value and an immediate 8086// offset, loads a halfword from memory, 8087// sign-extends it to from a 32-bit word, and writes it to a register. 8088bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode, 8089 const ARMEncoding encoding) { 8090#if 0 8091 if ConditionPassed() then 8092 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8093 base = Align(PC,4); 8094 address = if add then (base + imm32) else (base - imm32); 8095 data = MemU[address,2]; 8096 if UnalignedSupport() || address<0> = '0' then 8097 R[t] = SignExtend(data, 32); 8098 else // Can only apply before ARMv7 8099 R[t] = bits(32) UNKNOWN; 8100#endif 8101 8102 bool success = false; 8103 8104 if (ConditionPassed(opcode)) { 8105 uint32_t t; 8106 uint32_t imm32; 8107 bool add; 8108 8109 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8110 switch (encoding) { 8111 case eEncodingT1: 8112 // if Rt == '1111' then SEE "Unallocated memory hints"; 8113 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 8114 t = Bits32(opcode, 15, 12); 8115 imm32 = Bits32(opcode, 11, 0); 8116 add = BitIsSet(opcode, 23); 8117 8118 // if t == 13 then UNPREDICTABLE; 8119 if (t == 13) 8120 return false; 8121 8122 break; 8123 8124 case eEncodingA1: { 8125 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 8126 t = Bits32(opcode, 15, 12); 8127 uint32_t imm4H = Bits32(opcode, 11, 8); 8128 uint32_t imm4L = Bits32(opcode, 3, 0); 8129 imm32 = (imm4H << 4) | imm4L; 8130 add = BitIsSet(opcode, 23); 8131 8132 // if t == 15 then UNPREDICTABLE; 8133 if (t == 15) 8134 return false; 8135 8136 break; 8137 } 8138 default: 8139 return false; 8140 } 8141 8142 // base = Align(PC,4); 8143 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 8144 if (!success) 8145 return false; 8146 8147 uint64_t base = AlignPC(pc_value); 8148 8149 addr_t address; 8150 // address = if add then (base + imm32) else (base - imm32); 8151 if (add) 8152 address = base + imm32; 8153 else 8154 address = base - imm32; 8155 8156 // data = MemU[address,2]; 8157 RegisterInfo base_reg; 8158 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 8159 8160 EmulateInstruction::Context context; 8161 context.type = eContextRegisterLoad; 8162 context.SetRegisterPlusOffset(base_reg, imm32); 8163 8164 uint64_t data = MemURead(context, address, 2, 0, &success); 8165 if (!success) 8166 return false; 8167 8168 // if UnalignedSupport() || address<0> = '0' then 8169 if (UnalignedSupport() || BitIsClear(address, 0)) { 8170 // R[t] = SignExtend(data, 32); 8171 int64_t signed_data = llvm::SignExtend64<16>(data); 8172 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8173 (uint64_t)signed_data)) 8174 return false; 8175 } else // Can only apply before ARMv7 8176 { 8177 // R[t] = bits(32) UNKNOWN; 8178 WriteBits32Unknown(t); 8179 } 8180 } 8181 return true; 8182} 8183 8184// LDRSH (register) calculates an address from a base register value and an 8185// offset register value, loads a halfword 8186// from memory, sign-extends it to form a 32-bit word, and writes it to a 8187// register. The offset register value can be shifted left by 0, 1, 2, or 3 8188// bits. 8189bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode, 8190 const ARMEncoding encoding) { 8191#if 0 8192 if ConditionPassed() then 8193 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8194 offset = Shift(R[m], shift_t, shift_n, APSR.C); 8195 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8196 address = if index then offset_addr else R[n]; 8197 data = MemU[address,2]; 8198 if wback then R[n] = offset_addr; 8199 if UnalignedSupport() || address<0> = '0' then 8200 R[t] = SignExtend(data, 32); 8201 else // Can only apply before ARMv7 8202 R[t] = bits(32) UNKNOWN; 8203#endif 8204 8205 bool success = false; 8206 8207 if (ConditionPassed(opcode)) { 8208 uint32_t t; 8209 uint32_t n; 8210 uint32_t m; 8211 bool index; 8212 bool add; 8213 bool wback; 8214 ARM_ShifterType shift_t; 8215 uint32_t shift_n; 8216 8217 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8218 switch (encoding) { 8219 case eEncodingT1: 8220 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 8221 // in ThumbEE"; 8222 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8223 t = Bits32(opcode, 2, 0); 8224 n = Bits32(opcode, 5, 3); 8225 m = Bits32(opcode, 8, 6); 8226 8227 // index = TRUE; add = TRUE; wback = FALSE; 8228 index = true; 8229 add = true; 8230 wback = false; 8231 8232 // (shift_t, shift_n) = (SRType_LSL, 0); 8233 shift_t = SRType_LSL; 8234 shift_n = 0; 8235 8236 break; 8237 8238 case eEncodingT2: 8239 // if Rn == '1111' then SEE LDRSH (literal); 8240 // if Rt == '1111' then SEE "Unallocated memory hints"; 8241 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8242 t = Bits32(opcode, 15, 12); 8243 n = Bits32(opcode, 19, 16); 8244 m = Bits32(opcode, 3, 0); 8245 8246 // index = TRUE; add = TRUE; wback = FALSE; 8247 index = true; 8248 add = true; 8249 wback = false; 8250 8251 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 8252 shift_t = SRType_LSL; 8253 shift_n = Bits32(opcode, 5, 4); 8254 8255 // if t == 13 || BadReg(m) then UNPREDICTABLE; 8256 if ((t == 13) || BadReg(m)) 8257 return false; 8258 8259 break; 8260 8261 case eEncodingA1: 8262 // if P == '0' && W == '1' then SEE LDRSHT; 8263 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8264 t = Bits32(opcode, 15, 12); 8265 n = Bits32(opcode, 19, 16); 8266 m = Bits32(opcode, 3, 0); 8267 8268 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8269 // (W == '1'); 8270 index = BitIsSet(opcode, 24); 8271 add = BitIsSet(opcode, 23); 8272 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8273 8274 // (shift_t, shift_n) = (SRType_LSL, 0); 8275 shift_t = SRType_LSL; 8276 shift_n = 0; 8277 8278 // if t == 15 || m == 15 then UNPREDICTABLE; 8279 if ((t == 15) || (m == 15)) 8280 return false; 8281 8282 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 8283 if (wback && ((n == 15) || (n == t))) 8284 return false; 8285 8286 break; 8287 8288 default: 8289 return false; 8290 } 8291 8292 uint64_t Rm = 8293 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8294 if (!success) 8295 return false; 8296 8297 uint64_t Rn = 8298 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8299 if (!success) 8300 return false; 8301 8302 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 8303 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 8304 if (!success) 8305 return false; 8306 8307 addr_t offset_addr; 8308 addr_t address; 8309 8310 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8311 if (add) 8312 offset_addr = Rn + offset; 8313 else 8314 offset_addr = Rn - offset; 8315 8316 // address = if index then offset_addr else R[n]; 8317 if (index) 8318 address = offset_addr; 8319 else 8320 address = Rn; 8321 8322 // data = MemU[address,2]; 8323 RegisterInfo base_reg; 8324 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8325 8326 RegisterInfo offset_reg; 8327 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 8328 8329 EmulateInstruction::Context context; 8330 context.type = eContextRegisterLoad; 8331 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8332 8333 uint64_t data = MemURead(context, address, 2, 0, &success); 8334 if (!success) 8335 return false; 8336 8337 // if wback then R[n] = offset_addr; 8338 if (wback) { 8339 context.type = eContextAdjustBaseRegister; 8340 context.SetAddress(offset_addr); 8341 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8342 offset_addr)) 8343 return false; 8344 } 8345 8346 // if UnalignedSupport() || address<0> = '0' then 8347 if (UnalignedSupport() || BitIsClear(address, 0)) { 8348 // R[t] = SignExtend(data, 32); 8349 context.type = eContextRegisterLoad; 8350 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8351 8352 int64_t signed_data = llvm::SignExtend64<16>(data); 8353 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8354 (uint64_t)signed_data)) 8355 return false; 8356 } else // Can only apply before ARMv7 8357 { 8358 // R[t] = bits(32) UNKNOWN; 8359 WriteBits32Unknown(t); 8360 } 8361 } 8362 return true; 8363} 8364 8365// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and 8366// writes the result to the destination 8367// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before 8368// extracting the 8-bit value. 8369bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode, 8370 const ARMEncoding encoding) { 8371#if 0 8372 if ConditionPassed() then 8373 EncodingSpecificOperations(); 8374 rotated = ROR(R[m], rotation); 8375 R[d] = SignExtend(rotated<7:0>, 32); 8376#endif 8377 8378 bool success = false; 8379 8380 if (ConditionPassed(opcode)) { 8381 uint32_t d; 8382 uint32_t m; 8383 uint32_t rotation; 8384 8385 // EncodingSpecificOperations(); 8386 switch (encoding) { 8387 case eEncodingT1: 8388 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8389 d = Bits32(opcode, 2, 0); 8390 m = Bits32(opcode, 5, 3); 8391 rotation = 0; 8392 8393 break; 8394 8395 case eEncodingT2: 8396 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8397 d = Bits32(opcode, 11, 8); 8398 m = Bits32(opcode, 3, 0); 8399 rotation = Bits32(opcode, 5, 4) << 3; 8400 8401 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8402 if (BadReg(d) || BadReg(m)) 8403 return false; 8404 8405 break; 8406 8407 case eEncodingA1: 8408 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8409 d = Bits32(opcode, 15, 12); 8410 m = Bits32(opcode, 3, 0); 8411 rotation = Bits32(opcode, 11, 10) << 3; 8412 8413 // if d == 15 || m == 15 then UNPREDICTABLE; 8414 if ((d == 15) || (m == 15)) 8415 return false; 8416 8417 break; 8418 8419 default: 8420 return false; 8421 } 8422 8423 uint64_t Rm = 8424 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8425 if (!success) 8426 return false; 8427 8428 // rotated = ROR(R[m], rotation); 8429 uint64_t rotated = ROR(Rm, rotation, &success); 8430 if (!success) 8431 return false; 8432 8433 // R[d] = SignExtend(rotated<7:0>, 32); 8434 int64_t data = llvm::SignExtend64<8>(rotated); 8435 8436 RegisterInfo source_reg; 8437 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8438 8439 EmulateInstruction::Context context; 8440 context.type = eContextRegisterLoad; 8441 context.SetRegister(source_reg); 8442 8443 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8444 (uint64_t)data)) 8445 return false; 8446 } 8447 return true; 8448} 8449 8450// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and 8451// writes the result to the destination 8452// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8453// extracting the 16-bit value. 8454bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode, 8455 const ARMEncoding encoding) { 8456#if 0 8457 if ConditionPassed() then 8458 EncodingSpecificOperations(); 8459 rotated = ROR(R[m], rotation); 8460 R[d] = SignExtend(rotated<15:0>, 32); 8461#endif 8462 8463 bool success = false; 8464 8465 if (ConditionPassed(opcode)) { 8466 uint32_t d; 8467 uint32_t m; 8468 uint32_t rotation; 8469 8470 // EncodingSpecificOperations(); 8471 switch (encoding) { 8472 case eEncodingT1: 8473 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8474 d = Bits32(opcode, 2, 0); 8475 m = Bits32(opcode, 5, 3); 8476 rotation = 0; 8477 8478 break; 8479 8480 case eEncodingT2: 8481 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8482 d = Bits32(opcode, 11, 8); 8483 m = Bits32(opcode, 3, 0); 8484 rotation = Bits32(opcode, 5, 4) << 3; 8485 8486 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8487 if (BadReg(d) || BadReg(m)) 8488 return false; 8489 8490 break; 8491 8492 case eEncodingA1: 8493 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8494 d = Bits32(opcode, 15, 12); 8495 m = Bits32(opcode, 3, 0); 8496 rotation = Bits32(opcode, 11, 10) << 3; 8497 8498 // if d == 15 || m == 15 then UNPREDICTABLE; 8499 if ((d == 15) || (m == 15)) 8500 return false; 8501 8502 break; 8503 8504 default: 8505 return false; 8506 } 8507 8508 uint64_t Rm = 8509 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8510 if (!success) 8511 return false; 8512 8513 // rotated = ROR(R[m], rotation); 8514 uint64_t rotated = ROR(Rm, rotation, &success); 8515 if (!success) 8516 return false; 8517 8518 // R[d] = SignExtend(rotated<15:0>, 32); 8519 RegisterInfo source_reg; 8520 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8521 8522 EmulateInstruction::Context context; 8523 context.type = eContextRegisterLoad; 8524 context.SetRegister(source_reg); 8525 8526 int64_t data = llvm::SignExtend64<16>(rotated); 8527 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8528 (uint64_t)data)) 8529 return false; 8530 } 8531 8532 return true; 8533} 8534 8535// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and 8536// writes the result to the destination 8537// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8538// extracting the 8-bit value. 8539bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode, 8540 const ARMEncoding encoding) { 8541#if 0 8542 if ConditionPassed() then 8543 EncodingSpecificOperations(); 8544 rotated = ROR(R[m], rotation); 8545 R[d] = ZeroExtend(rotated<7:0>, 32); 8546#endif 8547 8548 bool success = false; 8549 8550 if (ConditionPassed(opcode)) { 8551 uint32_t d; 8552 uint32_t m; 8553 uint32_t rotation; 8554 8555 // EncodingSpecificOperations(); 8556 switch (encoding) { 8557 case eEncodingT1: 8558 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8559 d = Bits32(opcode, 2, 0); 8560 m = Bits32(opcode, 5, 3); 8561 rotation = 0; 8562 8563 break; 8564 8565 case eEncodingT2: 8566 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8567 d = Bits32(opcode, 11, 8); 8568 m = Bits32(opcode, 3, 0); 8569 rotation = Bits32(opcode, 5, 4) << 3; 8570 8571 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8572 if (BadReg(d) || BadReg(m)) 8573 return false; 8574 8575 break; 8576 8577 case eEncodingA1: 8578 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8579 d = Bits32(opcode, 15, 12); 8580 m = Bits32(opcode, 3, 0); 8581 rotation = Bits32(opcode, 11, 10) << 3; 8582 8583 // if d == 15 || m == 15 then UNPREDICTABLE; 8584 if ((d == 15) || (m == 15)) 8585 return false; 8586 8587 break; 8588 8589 default: 8590 return false; 8591 } 8592 8593 uint64_t Rm = 8594 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8595 if (!success) 8596 return false; 8597 8598 // rotated = ROR(R[m], rotation); 8599 uint64_t rotated = ROR(Rm, rotation, &success); 8600 if (!success) 8601 return false; 8602 8603 // R[d] = ZeroExtend(rotated<7:0>, 32); 8604 RegisterInfo source_reg; 8605 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8606 8607 EmulateInstruction::Context context; 8608 context.type = eContextRegisterLoad; 8609 context.SetRegister(source_reg); 8610 8611 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8612 Bits32(rotated, 7, 0))) 8613 return false; 8614 } 8615 return true; 8616} 8617 8618// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and 8619// writes the result to the destination 8620// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8621// extracting the 16-bit value. 8622bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode, 8623 const ARMEncoding encoding) { 8624#if 0 8625 if ConditionPassed() then 8626 EncodingSpecificOperations(); 8627 rotated = ROR(R[m], rotation); 8628 R[d] = ZeroExtend(rotated<15:0>, 32); 8629#endif 8630 8631 bool success = false; 8632 8633 if (ConditionPassed(opcode)) { 8634 uint32_t d; 8635 uint32_t m; 8636 uint32_t rotation; 8637 8638 switch (encoding) { 8639 case eEncodingT1: 8640 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8641 d = Bits32(opcode, 2, 0); 8642 m = Bits32(opcode, 5, 3); 8643 rotation = 0; 8644 8645 break; 8646 8647 case eEncodingT2: 8648 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8649 d = Bits32(opcode, 11, 8); 8650 m = Bits32(opcode, 3, 0); 8651 rotation = Bits32(opcode, 5, 4) << 3; 8652 8653 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8654 if (BadReg(d) || BadReg(m)) 8655 return false; 8656 8657 break; 8658 8659 case eEncodingA1: 8660 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8661 d = Bits32(opcode, 15, 12); 8662 m = Bits32(opcode, 3, 0); 8663 rotation = Bits32(opcode, 11, 10) << 3; 8664 8665 // if d == 15 || m == 15 then UNPREDICTABLE; 8666 if ((d == 15) || (m == 15)) 8667 return false; 8668 8669 break; 8670 8671 default: 8672 return false; 8673 } 8674 8675 uint64_t Rm = 8676 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8677 if (!success) 8678 return false; 8679 8680 // rotated = ROR(R[m], rotation); 8681 uint64_t rotated = ROR(Rm, rotation, &success); 8682 if (!success) 8683 return false; 8684 8685 // R[d] = ZeroExtend(rotated<15:0>, 32); 8686 RegisterInfo source_reg; 8687 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8688 8689 EmulateInstruction::Context context; 8690 context.type = eContextRegisterLoad; 8691 context.SetRegister(source_reg); 8692 8693 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8694 Bits32(rotated, 15, 0))) 8695 return false; 8696 } 8697 return true; 8698} 8699 8700// RFE (Return From Exception) loads the PC and the CPSR from the word at the 8701// specified address and the following 8702// word respectively. 8703bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode, 8704 const ARMEncoding encoding) { 8705#if 0 8706 if ConditionPassed() then 8707 EncodingSpecificOperations(); 8708 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8709 UNPREDICTABLE; 8710 else 8711 address = if increment then R[n] else R[n]-8; 8712 if wordhigher then address = address+4; 8713 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8714 BranchWritePC(MemA[address,4]); 8715 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8716#endif 8717 8718 bool success = false; 8719 8720 if (ConditionPassed(opcode)) { 8721 uint32_t n; 8722 bool wback; 8723 bool increment; 8724 bool wordhigher; 8725 8726 // EncodingSpecificOperations(); 8727 switch (encoding) { 8728 case eEncodingT1: 8729 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = 8730 // FALSE; 8731 n = Bits32(opcode, 19, 16); 8732 wback = BitIsSet(opcode, 21); 8733 increment = false; 8734 wordhigher = false; 8735 8736 // if n == 15 then UNPREDICTABLE; 8737 if (n == 15) 8738 return false; 8739 8740 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8741 if (InITBlock() && !LastInITBlock()) 8742 return false; 8743 8744 break; 8745 8746 case eEncodingT2: 8747 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8748 n = Bits32(opcode, 19, 16); 8749 wback = BitIsSet(opcode, 21); 8750 increment = true; 8751 wordhigher = false; 8752 8753 // if n == 15 then UNPREDICTABLE; 8754 if (n == 15) 8755 return false; 8756 8757 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8758 if (InITBlock() && !LastInITBlock()) 8759 return false; 8760 8761 break; 8762 8763 case eEncodingA1: 8764 // n = UInt(Rn); 8765 n = Bits32(opcode, 19, 16); 8766 8767 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8768 wback = BitIsSet(opcode, 21); 8769 increment = BitIsSet(opcode, 23); 8770 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23)); 8771 8772 // if n == 15 then UNPREDICTABLE; 8773 if (n == 15) 8774 return false; 8775 8776 break; 8777 8778 default: 8779 return false; 8780 } 8781 8782 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE 8783 // then 8784 if (!CurrentModeIsPrivileged()) 8785 // UNPREDICTABLE; 8786 return false; 8787 else { 8788 uint64_t Rn = 8789 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8790 if (!success) 8791 return false; 8792 8793 addr_t address; 8794 // address = if increment then R[n] else R[n]-8; 8795 if (increment) 8796 address = Rn; 8797 else 8798 address = Rn - 8; 8799 8800 // if wordhigher then address = address+4; 8801 if (wordhigher) 8802 address = address + 4; 8803 8804 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8805 RegisterInfo base_reg; 8806 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8807 8808 EmulateInstruction::Context context; 8809 context.type = eContextReturnFromException; 8810 context.SetRegisterPlusOffset(base_reg, address - Rn); 8811 8812 uint64_t data = MemARead(context, address + 4, 4, 0, &success); 8813 if (!success) 8814 return false; 8815 8816 CPSRWriteByInstr(data, 15, true); 8817 8818 // BranchWritePC(MemA[address,4]); 8819 uint64_t data2 = MemARead(context, address, 4, 0, &success); 8820 if (!success) 8821 return false; 8822 8823 BranchWritePC(context, data2); 8824 8825 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8826 if (wback) { 8827 context.type = eContextAdjustBaseRegister; 8828 if (increment) { 8829 context.SetOffset(8); 8830 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8831 Rn + 8)) 8832 return false; 8833 } else { 8834 context.SetOffset(-8); 8835 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8836 Rn - 8)) 8837 return false; 8838 } 8839 } // if wback 8840 } 8841 } // if ConditionPassed() 8842 return true; 8843} 8844 8845// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a 8846// register value and an immediate value, and writes the result to the 8847// destination register. It can optionally update the condition flags based on 8848// the result. 8849bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode, 8850 const ARMEncoding encoding) { 8851#if 0 8852 // ARM pseudo code... 8853 if ConditionPassed() then 8854 EncodingSpecificOperations(); 8855 result = R[n] EOR imm32; 8856 if d == 15 then // Can only occur for ARM encoding 8857 ALUWritePC(result); // setflags is always FALSE here 8858 else 8859 R[d] = result; 8860 if setflags then 8861 APSR.N = result<31>; 8862 APSR.Z = IsZeroBit(result); 8863 APSR.C = carry; 8864 // APSR.V unchanged 8865#endif 8866 8867 bool success = false; 8868 8869 if (ConditionPassed(opcode)) { 8870 uint32_t Rd, Rn; 8871 uint32_t 8872 imm32; // the immediate value to be ORed to the value obtained from Rn 8873 bool setflags; 8874 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8875 switch (encoding) { 8876 case eEncodingT1: 8877 Rd = Bits32(opcode, 11, 8); 8878 Rn = Bits32(opcode, 19, 16); 8879 setflags = BitIsSet(opcode, 20); 8880 imm32 = ThumbExpandImm_C( 8881 opcode, APSR_C, 8882 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8883 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8884 if (Rd == 15 && setflags) 8885 return EmulateTEQImm(opcode, eEncodingT1); 8886 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8887 return false; 8888 break; 8889 case eEncodingA1: 8890 Rd = Bits32(opcode, 15, 12); 8891 Rn = Bits32(opcode, 19, 16); 8892 setflags = BitIsSet(opcode, 20); 8893 imm32 = 8894 ARMExpandImm_C(opcode, APSR_C, 8895 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8896 8897 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8898 // instructions; 8899 if (Rd == 15 && setflags) 8900 return EmulateSUBSPcLrEtc(opcode, encoding); 8901 break; 8902 default: 8903 return false; 8904 } 8905 8906 // Read the first operand. 8907 uint32_t val1 = ReadCoreReg(Rn, &success); 8908 if (!success) 8909 return false; 8910 8911 uint32_t result = val1 ^ imm32; 8912 8913 EmulateInstruction::Context context; 8914 context.type = EmulateInstruction::eContextImmediate; 8915 context.SetNoArgs(); 8916 8917 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8918 return false; 8919 } 8920 return true; 8921} 8922 8923// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a 8924// register value and an optionally-shifted register value, and writes the 8925// result to the destination register. It can optionally update the condition 8926// flags based on the result. 8927bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode, 8928 const ARMEncoding encoding) { 8929#if 0 8930 // ARM pseudo code... 8931 if ConditionPassed() then 8932 EncodingSpecificOperations(); 8933 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8934 result = R[n] EOR shifted; 8935 if d == 15 then // Can only occur for ARM encoding 8936 ALUWritePC(result); // setflags is always FALSE here 8937 else 8938 R[d] = result; 8939 if setflags then 8940 APSR.N = result<31>; 8941 APSR.Z = IsZeroBit(result); 8942 APSR.C = carry; 8943 // APSR.V unchanged 8944#endif 8945 8946 bool success = false; 8947 8948 if (ConditionPassed(opcode)) { 8949 uint32_t Rd, Rn, Rm; 8950 ARM_ShifterType shift_t; 8951 uint32_t shift_n; // the shift applied to the value read from Rm 8952 bool setflags; 8953 uint32_t carry; 8954 switch (encoding) { 8955 case eEncodingT1: 8956 Rd = Rn = Bits32(opcode, 2, 0); 8957 Rm = Bits32(opcode, 5, 3); 8958 setflags = !InITBlock(); 8959 shift_t = SRType_LSL; 8960 shift_n = 0; 8961 break; 8962 case eEncodingT2: 8963 Rd = Bits32(opcode, 11, 8); 8964 Rn = Bits32(opcode, 19, 16); 8965 Rm = Bits32(opcode, 3, 0); 8966 setflags = BitIsSet(opcode, 20); 8967 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8968 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8969 if (Rd == 15 && setflags) 8970 return EmulateTEQReg(opcode, eEncodingT1); 8971 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8972 return false; 8973 break; 8974 case eEncodingA1: 8975 Rd = Bits32(opcode, 15, 12); 8976 Rn = Bits32(opcode, 19, 16); 8977 Rm = Bits32(opcode, 3, 0); 8978 setflags = BitIsSet(opcode, 20); 8979 shift_n = DecodeImmShiftARM(opcode, shift_t); 8980 8981 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8982 // instructions; 8983 if (Rd == 15 && setflags) 8984 return EmulateSUBSPcLrEtc(opcode, encoding); 8985 break; 8986 default: 8987 return false; 8988 } 8989 8990 // Read the first operand. 8991 uint32_t val1 = ReadCoreReg(Rn, &success); 8992 if (!success) 8993 return false; 8994 8995 // Read the second operand. 8996 uint32_t val2 = ReadCoreReg(Rm, &success); 8997 if (!success) 8998 return false; 8999 9000 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9001 if (!success) 9002 return false; 9003 uint32_t result = val1 ^ shifted; 9004 9005 EmulateInstruction::Context context; 9006 context.type = EmulateInstruction::eContextImmediate; 9007 context.SetNoArgs(); 9008 9009 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9010 return false; 9011 } 9012 return true; 9013} 9014 9015// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value 9016// and an immediate value, and writes the result to the destination register. 9017// It can optionally update the condition flags based on the result. 9018bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode, 9019 const ARMEncoding encoding) { 9020#if 0 9021 // ARM pseudo code... 9022 if ConditionPassed() then 9023 EncodingSpecificOperations(); 9024 result = R[n] OR imm32; 9025 if d == 15 then // Can only occur for ARM encoding 9026 ALUWritePC(result); // setflags is always FALSE here 9027 else 9028 R[d] = result; 9029 if setflags then 9030 APSR.N = result<31>; 9031 APSR.Z = IsZeroBit(result); 9032 APSR.C = carry; 9033 // APSR.V unchanged 9034#endif 9035 9036 bool success = false; 9037 9038 if (ConditionPassed(opcode)) { 9039 uint32_t Rd, Rn; 9040 uint32_t 9041 imm32; // the immediate value to be ORed to the value obtained from Rn 9042 bool setflags; 9043 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9044 switch (encoding) { 9045 case eEncodingT1: 9046 Rd = Bits32(opcode, 11, 8); 9047 Rn = Bits32(opcode, 19, 16); 9048 setflags = BitIsSet(opcode, 20); 9049 imm32 = ThumbExpandImm_C( 9050 opcode, APSR_C, 9051 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9052 // if Rn == '1111' then SEE MOV (immediate); 9053 if (Rn == 15) 9054 return EmulateMOVRdImm(opcode, eEncodingT2); 9055 if (BadReg(Rd) || Rn == 13) 9056 return false; 9057 break; 9058 case eEncodingA1: 9059 Rd = Bits32(opcode, 15, 12); 9060 Rn = Bits32(opcode, 19, 16); 9061 setflags = BitIsSet(opcode, 20); 9062 imm32 = 9063 ARMExpandImm_C(opcode, APSR_C, 9064 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9065 9066 if (Rd == 15 && setflags) 9067 return EmulateSUBSPcLrEtc(opcode, encoding); 9068 break; 9069 default: 9070 return false; 9071 } 9072 9073 // Read the first operand. 9074 uint32_t val1 = ReadCoreReg(Rn, &success); 9075 if (!success) 9076 return false; 9077 9078 uint32_t result = val1 | imm32; 9079 9080 EmulateInstruction::Context context; 9081 context.type = EmulateInstruction::eContextImmediate; 9082 context.SetNoArgs(); 9083 9084 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9085 return false; 9086 } 9087 return true; 9088} 9089 9090// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value 9091// and an optionally-shifted register value, and writes the result to the 9092// destination register. It can optionally update the condition flags based on 9093// the result. 9094bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode, 9095 const ARMEncoding encoding) { 9096#if 0 9097 // ARM pseudo code... 9098 if ConditionPassed() then 9099 EncodingSpecificOperations(); 9100 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9101 result = R[n] OR shifted; 9102 if d == 15 then // Can only occur for ARM encoding 9103 ALUWritePC(result); // setflags is always FALSE here 9104 else 9105 R[d] = result; 9106 if setflags then 9107 APSR.N = result<31>; 9108 APSR.Z = IsZeroBit(result); 9109 APSR.C = carry; 9110 // APSR.V unchanged 9111#endif 9112 9113 bool success = false; 9114 9115 if (ConditionPassed(opcode)) { 9116 uint32_t Rd, Rn, Rm; 9117 ARM_ShifterType shift_t; 9118 uint32_t shift_n; // the shift applied to the value read from Rm 9119 bool setflags; 9120 uint32_t carry; 9121 switch (encoding) { 9122 case eEncodingT1: 9123 Rd = Rn = Bits32(opcode, 2, 0); 9124 Rm = Bits32(opcode, 5, 3); 9125 setflags = !InITBlock(); 9126 shift_t = SRType_LSL; 9127 shift_n = 0; 9128 break; 9129 case eEncodingT2: 9130 Rd = Bits32(opcode, 11, 8); 9131 Rn = Bits32(opcode, 19, 16); 9132 Rm = Bits32(opcode, 3, 0); 9133 setflags = BitIsSet(opcode, 20); 9134 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9135 // if Rn == '1111' then SEE MOV (register); 9136 if (Rn == 15) 9137 return EmulateMOVRdRm(opcode, eEncodingT3); 9138 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 9139 return false; 9140 break; 9141 case eEncodingA1: 9142 Rd = Bits32(opcode, 15, 12); 9143 Rn = Bits32(opcode, 19, 16); 9144 Rm = Bits32(opcode, 3, 0); 9145 setflags = BitIsSet(opcode, 20); 9146 shift_n = DecodeImmShiftARM(opcode, shift_t); 9147 9148 if (Rd == 15 && setflags) 9149 return EmulateSUBSPcLrEtc(opcode, encoding); 9150 break; 9151 default: 9152 return false; 9153 } 9154 9155 // Read the first operand. 9156 uint32_t val1 = ReadCoreReg(Rn, &success); 9157 if (!success) 9158 return false; 9159 9160 // Read the second operand. 9161 uint32_t val2 = ReadCoreReg(Rm, &success); 9162 if (!success) 9163 return false; 9164 9165 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9166 if (!success) 9167 return false; 9168 uint32_t result = val1 | shifted; 9169 9170 EmulateInstruction::Context context; 9171 context.type = EmulateInstruction::eContextImmediate; 9172 context.SetNoArgs(); 9173 9174 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9175 return false; 9176 } 9177 return true; 9178} 9179 9180// Reverse Subtract (immediate) subtracts a register value from an immediate 9181// value, and writes the result to the destination register. It can optionally 9182// update the condition flags based on the result. 9183bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode, 9184 const ARMEncoding encoding) { 9185#if 0 9186 // ARM pseudo code... 9187 if ConditionPassed() then 9188 EncodingSpecificOperations(); 9189 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 9190 if d == 15 then // Can only occur for ARM encoding 9191 ALUWritePC(result); // setflags is always FALSE here 9192 else 9193 R[d] = result; 9194 if setflags then 9195 APSR.N = result<31>; 9196 APSR.Z = IsZeroBit(result); 9197 APSR.C = carry; 9198 APSR.V = overflow; 9199#endif 9200 9201 bool success = false; 9202 9203 uint32_t Rd; // the destination register 9204 uint32_t Rn; // the first operand 9205 bool setflags; 9206 uint32_t 9207 imm32; // the immediate value to be added to the value obtained from Rn 9208 switch (encoding) { 9209 case eEncodingT1: 9210 Rd = Bits32(opcode, 2, 0); 9211 Rn = Bits32(opcode, 5, 3); 9212 setflags = !InITBlock(); 9213 imm32 = 0; 9214 break; 9215 case eEncodingT2: 9216 Rd = Bits32(opcode, 11, 8); 9217 Rn = Bits32(opcode, 19, 16); 9218 setflags = BitIsSet(opcode, 20); 9219 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9220 if (BadReg(Rd) || BadReg(Rn)) 9221 return false; 9222 break; 9223 case eEncodingA1: 9224 Rd = Bits32(opcode, 15, 12); 9225 Rn = Bits32(opcode, 19, 16); 9226 setflags = BitIsSet(opcode, 20); 9227 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9228 9229 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9230 // instructions; 9231 if (Rd == 15 && setflags) 9232 return EmulateSUBSPcLrEtc(opcode, encoding); 9233 break; 9234 default: 9235 return false; 9236 } 9237 // Read the register value from the operand register Rn. 9238 uint32_t reg_val = ReadCoreReg(Rn, &success); 9239 if (!success) 9240 return false; 9241 9242 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 9243 9244 EmulateInstruction::Context context; 9245 context.type = EmulateInstruction::eContextImmediate; 9246 context.SetNoArgs(); 9247 9248 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9249 res.carry_out, res.overflow)) 9250 return false; 9251 9252 return true; 9253} 9254 9255// Reverse Subtract (register) subtracts a register value from an optionally- 9256// shifted register value, and writes the result to the destination register. 9257// It can optionally update the condition flags based on the result. 9258bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode, 9259 const ARMEncoding encoding) { 9260#if 0 9261 // ARM pseudo code... 9262 if ConditionPassed() then 9263 EncodingSpecificOperations(); 9264 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9265 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 9266 if d == 15 then // Can only occur for ARM encoding 9267 ALUWritePC(result); // setflags is always FALSE here 9268 else 9269 R[d] = result; 9270 if setflags then 9271 APSR.N = result<31>; 9272 APSR.Z = IsZeroBit(result); 9273 APSR.C = carry; 9274 APSR.V = overflow; 9275#endif 9276 9277 bool success = false; 9278 9279 uint32_t Rd; // the destination register 9280 uint32_t Rn; // the first operand 9281 uint32_t Rm; // the second operand 9282 bool setflags; 9283 ARM_ShifterType shift_t; 9284 uint32_t shift_n; // the shift applied to the value read from Rm 9285 switch (encoding) { 9286 case eEncodingT1: 9287 Rd = Bits32(opcode, 11, 8); 9288 Rn = Bits32(opcode, 19, 16); 9289 Rm = Bits32(opcode, 3, 0); 9290 setflags = BitIsSet(opcode, 20); 9291 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9292 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 9293 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9294 return false; 9295 break; 9296 case eEncodingA1: 9297 Rd = Bits32(opcode, 15, 12); 9298 Rn = Bits32(opcode, 19, 16); 9299 Rm = Bits32(opcode, 3, 0); 9300 setflags = BitIsSet(opcode, 20); 9301 shift_n = DecodeImmShiftARM(opcode, shift_t); 9302 9303 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9304 // instructions; 9305 if (Rd == 15 && setflags) 9306 return EmulateSUBSPcLrEtc(opcode, encoding); 9307 break; 9308 default: 9309 return false; 9310 } 9311 // Read the register value from register Rn. 9312 uint32_t val1 = ReadCoreReg(Rn, &success); 9313 if (!success) 9314 return false; 9315 9316 // Read the register value from register Rm. 9317 uint32_t val2 = ReadCoreReg(Rm, &success); 9318 if (!success) 9319 return false; 9320 9321 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9322 if (!success) 9323 return false; 9324 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 9325 9326 EmulateInstruction::Context context; 9327 context.type = EmulateInstruction::eContextImmediate; 9328 context.SetNoArgs(); 9329 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9330 res.carry_out, res.overflow)) 9331 return false; 9332 9333 return true; 9334} 9335 9336// Reverse Subtract with Carry (immediate) subtracts a register value and the 9337// value of NOT (Carry flag) from an immediate value, and writes the result to 9338// the destination register. It can optionally update the condition flags based 9339// on the result. 9340bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode, 9341 const ARMEncoding encoding) { 9342#if 0 9343 // ARM pseudo code... 9344 if ConditionPassed() then 9345 EncodingSpecificOperations(); 9346 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 9347 if d == 15 then 9348 ALUWritePC(result); // setflags is always FALSE here 9349 else 9350 R[d] = result; 9351 if setflags then 9352 APSR.N = result<31>; 9353 APSR.Z = IsZeroBit(result); 9354 APSR.C = carry; 9355 APSR.V = overflow; 9356#endif 9357 9358 bool success = false; 9359 9360 uint32_t Rd; // the destination register 9361 uint32_t Rn; // the first operand 9362 bool setflags; 9363 uint32_t 9364 imm32; // the immediate value to be added to the value obtained from Rn 9365 switch (encoding) { 9366 case eEncodingA1: 9367 Rd = Bits32(opcode, 15, 12); 9368 Rn = Bits32(opcode, 19, 16); 9369 setflags = BitIsSet(opcode, 20); 9370 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9371 9372 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9373 // instructions; 9374 if (Rd == 15 && setflags) 9375 return EmulateSUBSPcLrEtc(opcode, encoding); 9376 break; 9377 default: 9378 return false; 9379 } 9380 // Read the register value from the operand register Rn. 9381 uint32_t reg_val = ReadCoreReg(Rn, &success); 9382 if (!success) 9383 return false; 9384 9385 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 9386 9387 EmulateInstruction::Context context; 9388 context.type = EmulateInstruction::eContextImmediate; 9389 context.SetNoArgs(); 9390 9391 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9392 res.carry_out, res.overflow)) 9393 return false; 9394 9395 return true; 9396} 9397 9398// Reverse Subtract with Carry (register) subtracts a register value and the 9399// value of NOT (Carry flag) from an optionally-shifted register value, and 9400// writes the result to the destination register. It can optionally update the 9401// condition flags based on the result. 9402bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode, 9403 const ARMEncoding encoding) { 9404#if 0 9405 // ARM pseudo code... 9406 if ConditionPassed() then 9407 EncodingSpecificOperations(); 9408 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9409 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 9410 if d == 15 then 9411 ALUWritePC(result); // setflags is always FALSE here 9412 else 9413 R[d] = result; 9414 if setflags then 9415 APSR.N = result<31>; 9416 APSR.Z = IsZeroBit(result); 9417 APSR.C = carry; 9418 APSR.V = overflow; 9419#endif 9420 9421 bool success = false; 9422 9423 uint32_t Rd; // the destination register 9424 uint32_t Rn; // the first operand 9425 uint32_t Rm; // the second operand 9426 bool setflags; 9427 ARM_ShifterType shift_t; 9428 uint32_t shift_n; // the shift applied to the value read from Rm 9429 switch (encoding) { 9430 case eEncodingA1: 9431 Rd = Bits32(opcode, 15, 12); 9432 Rn = Bits32(opcode, 19, 16); 9433 Rm = Bits32(opcode, 3, 0); 9434 setflags = BitIsSet(opcode, 20); 9435 shift_n = DecodeImmShiftARM(opcode, shift_t); 9436 9437 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9438 // instructions; 9439 if (Rd == 15 && setflags) 9440 return EmulateSUBSPcLrEtc(opcode, encoding); 9441 break; 9442 default: 9443 return false; 9444 } 9445 // Read the register value from register Rn. 9446 uint32_t val1 = ReadCoreReg(Rn, &success); 9447 if (!success) 9448 return false; 9449 9450 // Read the register value from register Rm. 9451 uint32_t val2 = ReadCoreReg(Rm, &success); 9452 if (!success) 9453 return false; 9454 9455 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9456 if (!success) 9457 return false; 9458 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 9459 9460 EmulateInstruction::Context context; 9461 context.type = EmulateInstruction::eContextImmediate; 9462 context.SetNoArgs(); 9463 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9464 res.carry_out, res.overflow)) 9465 return false; 9466 9467 return true; 9468} 9469 9470// Subtract with Carry (immediate) subtracts an immediate value and the value 9471// of 9472// NOT (Carry flag) from a register value, and writes the result to the 9473// destination register. 9474// It can optionally update the condition flags based on the result. 9475bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode, 9476 const ARMEncoding encoding) { 9477#if 0 9478 // ARM pseudo code... 9479 if ConditionPassed() then 9480 EncodingSpecificOperations(); 9481 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 9482 if d == 15 then // Can only occur for ARM encoding 9483 ALUWritePC(result); // setflags is always FALSE here 9484 else 9485 R[d] = result; 9486 if setflags then 9487 APSR.N = result<31>; 9488 APSR.Z = IsZeroBit(result); 9489 APSR.C = carry; 9490 APSR.V = overflow; 9491#endif 9492 9493 bool success = false; 9494 9495 uint32_t Rd; // the destination register 9496 uint32_t Rn; // the first operand 9497 bool setflags; 9498 uint32_t 9499 imm32; // the immediate value to be added to the value obtained from Rn 9500 switch (encoding) { 9501 case eEncodingT1: 9502 Rd = Bits32(opcode, 11, 8); 9503 Rn = Bits32(opcode, 19, 16); 9504 setflags = BitIsSet(opcode, 20); 9505 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9506 if (BadReg(Rd) || BadReg(Rn)) 9507 return false; 9508 break; 9509 case eEncodingA1: 9510 Rd = Bits32(opcode, 15, 12); 9511 Rn = Bits32(opcode, 19, 16); 9512 setflags = BitIsSet(opcode, 20); 9513 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9514 9515 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9516 // instructions; 9517 if (Rd == 15 && setflags) 9518 return EmulateSUBSPcLrEtc(opcode, encoding); 9519 break; 9520 default: 9521 return false; 9522 } 9523 // Read the register value from the operand register Rn. 9524 uint32_t reg_val = ReadCoreReg(Rn, &success); 9525 if (!success) 9526 return false; 9527 9528 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9529 9530 EmulateInstruction::Context context; 9531 context.type = EmulateInstruction::eContextImmediate; 9532 context.SetNoArgs(); 9533 9534 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9535 res.carry_out, res.overflow)) 9536 return false; 9537 9538 return true; 9539} 9540 9541// Subtract with Carry (register) subtracts an optionally-shifted register 9542// value and the value of 9543// NOT (Carry flag) from a register value, and writes the result to the 9544// destination register. 9545// It can optionally update the condition flags based on the result. 9546bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode, 9547 const ARMEncoding encoding) { 9548#if 0 9549 // ARM pseudo code... 9550 if ConditionPassed() then 9551 EncodingSpecificOperations(); 9552 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9553 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9554 if d == 15 then // Can only occur for ARM encoding 9555 ALUWritePC(result); // setflags is always FALSE here 9556 else 9557 R[d] = result; 9558 if setflags then 9559 APSR.N = result<31>; 9560 APSR.Z = IsZeroBit(result); 9561 APSR.C = carry; 9562 APSR.V = overflow; 9563#endif 9564 9565 bool success = false; 9566 9567 uint32_t Rd; // the destination register 9568 uint32_t Rn; // the first operand 9569 uint32_t Rm; // the second operand 9570 bool setflags; 9571 ARM_ShifterType shift_t; 9572 uint32_t shift_n; // the shift applied to the value read from Rm 9573 switch (encoding) { 9574 case eEncodingT1: 9575 Rd = Rn = Bits32(opcode, 2, 0); 9576 Rm = Bits32(opcode, 5, 3); 9577 setflags = !InITBlock(); 9578 shift_t = SRType_LSL; 9579 shift_n = 0; 9580 break; 9581 case eEncodingT2: 9582 Rd = Bits32(opcode, 11, 8); 9583 Rn = Bits32(opcode, 19, 16); 9584 Rm = Bits32(opcode, 3, 0); 9585 setflags = BitIsSet(opcode, 20); 9586 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9587 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9588 return false; 9589 break; 9590 case eEncodingA1: 9591 Rd = Bits32(opcode, 15, 12); 9592 Rn = Bits32(opcode, 19, 16); 9593 Rm = Bits32(opcode, 3, 0); 9594 setflags = BitIsSet(opcode, 20); 9595 shift_n = DecodeImmShiftARM(opcode, shift_t); 9596 9597 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9598 // instructions; 9599 if (Rd == 15 && setflags) 9600 return EmulateSUBSPcLrEtc(opcode, encoding); 9601 break; 9602 default: 9603 return false; 9604 } 9605 // Read the register value from register Rn. 9606 uint32_t val1 = ReadCoreReg(Rn, &success); 9607 if (!success) 9608 return false; 9609 9610 // Read the register value from register Rm. 9611 uint32_t val2 = ReadCoreReg(Rm, &success); 9612 if (!success) 9613 return false; 9614 9615 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9616 if (!success) 9617 return false; 9618 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9619 9620 EmulateInstruction::Context context; 9621 context.type = EmulateInstruction::eContextImmediate; 9622 context.SetNoArgs(); 9623 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9624 res.carry_out, res.overflow)) 9625 return false; 9626 9627 return true; 9628} 9629 9630// This instruction subtracts an immediate value from a register value, and 9631// writes the result to the destination register. It can optionally update the 9632// condition flags based on the result. 9633bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode, 9634 const ARMEncoding encoding) { 9635#if 0 9636 // ARM pseudo code... 9637 if ConditionPassed() then 9638 EncodingSpecificOperations(); 9639 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9640 R[d] = result; 9641 if setflags then 9642 APSR.N = result<31>; 9643 APSR.Z = IsZeroBit(result); 9644 APSR.C = carry; 9645 APSR.V = overflow; 9646#endif 9647 9648 bool success = false; 9649 9650 uint32_t Rd; // the destination register 9651 uint32_t Rn; // the first operand 9652 bool setflags; 9653 uint32_t imm32; // the immediate value to be subtracted from the value 9654 // obtained from Rn 9655 switch (encoding) { 9656 case eEncodingT1: 9657 Rd = Bits32(opcode, 2, 0); 9658 Rn = Bits32(opcode, 5, 3); 9659 setflags = !InITBlock(); 9660 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9661 break; 9662 case eEncodingT2: 9663 Rd = Rn = Bits32(opcode, 10, 8); 9664 setflags = !InITBlock(); 9665 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9666 break; 9667 case eEncodingT3: 9668 Rd = Bits32(opcode, 11, 8); 9669 Rn = Bits32(opcode, 19, 16); 9670 setflags = BitIsSet(opcode, 20); 9671 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9672 9673 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9674 if (Rd == 15 && setflags) 9675 return EmulateCMPImm(opcode, eEncodingT2); 9676 9677 // if Rn == '1101' then SEE SUB (SP minus immediate); 9678 if (Rn == 13) 9679 return EmulateSUBSPImm(opcode, eEncodingT2); 9680 9681 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9682 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9683 return false; 9684 break; 9685 case eEncodingT4: 9686 Rd = Bits32(opcode, 11, 8); 9687 Rn = Bits32(opcode, 19, 16); 9688 setflags = BitIsSet(opcode, 20); 9689 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9690 9691 // if Rn == '1111' then SEE ADR; 9692 if (Rn == 15) 9693 return EmulateADR(opcode, eEncodingT2); 9694 9695 // if Rn == '1101' then SEE SUB (SP minus immediate); 9696 if (Rn == 13) 9697 return EmulateSUBSPImm(opcode, eEncodingT3); 9698 9699 if (BadReg(Rd)) 9700 return false; 9701 break; 9702 default: 9703 return false; 9704 } 9705 // Read the register value from the operand register Rn. 9706 uint32_t reg_val = ReadCoreReg(Rn, &success); 9707 if (!success) 9708 return false; 9709 9710 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9711 9712 EmulateInstruction::Context context; 9713 context.type = EmulateInstruction::eContextImmediate; 9714 context.SetNoArgs(); 9715 9716 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9717 res.carry_out, res.overflow)) 9718 return false; 9719 9720 return true; 9721} 9722 9723// This instruction subtracts an immediate value from a register value, and 9724// writes the result to the destination register. It can optionally update the 9725// condition flags based on the result. 9726bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode, 9727 const ARMEncoding encoding) { 9728#if 0 9729 // ARM pseudo code... 9730 if ConditionPassed() then 9731 EncodingSpecificOperations(); 9732 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9733 if d == 15 then 9734 ALUWritePC(result); // setflags is always FALSE here 9735 else 9736 R[d] = result; 9737 if setflags then 9738 APSR.N = result<31>; 9739 APSR.Z = IsZeroBit(result); 9740 APSR.C = carry; 9741 APSR.V = overflow; 9742#endif 9743 9744 bool success = false; 9745 9746 if (ConditionPassed(opcode)) { 9747 uint32_t Rd; // the destination register 9748 uint32_t Rn; // the first operand 9749 bool setflags; 9750 uint32_t imm32; // the immediate value to be subtracted from the value 9751 // obtained from Rn 9752 switch (encoding) { 9753 case eEncodingA1: 9754 Rd = Bits32(opcode, 15, 12); 9755 Rn = Bits32(opcode, 19, 16); 9756 setflags = BitIsSet(opcode, 20); 9757 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9758 9759 // if Rn == '1111' && S == '0' then SEE ADR; 9760 if (Rn == 15 && !setflags) 9761 return EmulateADR(opcode, eEncodingA2); 9762 9763 // if Rn == '1101' then SEE SUB (SP minus immediate); 9764 if (Rn == 13) 9765 return EmulateSUBSPImm(opcode, eEncodingA1); 9766 9767 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9768 // instructions; 9769 if (Rd == 15 && setflags) 9770 return EmulateSUBSPcLrEtc(opcode, encoding); 9771 break; 9772 default: 9773 return false; 9774 } 9775 // Read the register value from the operand register Rn. 9776 uint32_t reg_val = ReadCoreReg(Rn, &success); 9777 if (!success) 9778 return false; 9779 9780 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9781 9782 EmulateInstruction::Context context; 9783 if (Rd == 13) 9784 context.type = EmulateInstruction::eContextAdjustStackPointer; 9785 else 9786 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9787 9788 RegisterInfo dwarf_reg; 9789 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 9790 int64_t imm32_signed = imm32; 9791 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed); 9792 9793 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9794 res.carry_out, res.overflow)) 9795 return false; 9796 } 9797 return true; 9798} 9799 9800// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a 9801// register value and an immediate value. It updates the condition flags based 9802// on the result, and discards the result. 9803bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode, 9804 const ARMEncoding encoding) { 9805#if 0 9806 // ARM pseudo code... 9807 if ConditionPassed() then 9808 EncodingSpecificOperations(); 9809 result = R[n] EOR imm32; 9810 APSR.N = result<31>; 9811 APSR.Z = IsZeroBit(result); 9812 APSR.C = carry; 9813 // APSR.V unchanged 9814#endif 9815 9816 bool success = false; 9817 9818 if (ConditionPassed(opcode)) { 9819 uint32_t Rn; 9820 uint32_t 9821 imm32; // the immediate value to be ANDed to the value obtained from Rn 9822 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9823 switch (encoding) { 9824 case eEncodingT1: 9825 Rn = Bits32(opcode, 19, 16); 9826 imm32 = ThumbExpandImm_C( 9827 opcode, APSR_C, 9828 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9829 if (BadReg(Rn)) 9830 return false; 9831 break; 9832 case eEncodingA1: 9833 Rn = Bits32(opcode, 19, 16); 9834 imm32 = 9835 ARMExpandImm_C(opcode, APSR_C, 9836 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9837 break; 9838 default: 9839 return false; 9840 } 9841 9842 // Read the first operand. 9843 uint32_t val1 = ReadCoreReg(Rn, &success); 9844 if (!success) 9845 return false; 9846 9847 uint32_t result = val1 ^ imm32; 9848 9849 EmulateInstruction::Context context; 9850 context.type = EmulateInstruction::eContextImmediate; 9851 context.SetNoArgs(); 9852 9853 if (!WriteFlags(context, result, carry)) 9854 return false; 9855 } 9856 return true; 9857} 9858 9859// Test Equivalence (register) performs a bitwise exclusive OR operation on a 9860// register value and an optionally-shifted register value. It updates the 9861// condition flags based on the result, and discards the result. 9862bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode, 9863 const ARMEncoding encoding) { 9864#if 0 9865 // ARM pseudo code... 9866 if ConditionPassed() then 9867 EncodingSpecificOperations(); 9868 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9869 result = R[n] EOR shifted; 9870 APSR.N = result<31>; 9871 APSR.Z = IsZeroBit(result); 9872 APSR.C = carry; 9873 // APSR.V unchanged 9874#endif 9875 9876 bool success = false; 9877 9878 if (ConditionPassed(opcode)) { 9879 uint32_t Rn, Rm; 9880 ARM_ShifterType shift_t; 9881 uint32_t shift_n; // the shift applied to the value read from Rm 9882 uint32_t carry; 9883 switch (encoding) { 9884 case eEncodingT1: 9885 Rn = Bits32(opcode, 19, 16); 9886 Rm = Bits32(opcode, 3, 0); 9887 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9888 if (BadReg(Rn) || BadReg(Rm)) 9889 return false; 9890 break; 9891 case eEncodingA1: 9892 Rn = Bits32(opcode, 19, 16); 9893 Rm = Bits32(opcode, 3, 0); 9894 shift_n = DecodeImmShiftARM(opcode, shift_t); 9895 break; 9896 default: 9897 return false; 9898 } 9899 9900 // Read the first operand. 9901 uint32_t val1 = ReadCoreReg(Rn, &success); 9902 if (!success) 9903 return false; 9904 9905 // Read the second operand. 9906 uint32_t val2 = ReadCoreReg(Rm, &success); 9907 if (!success) 9908 return false; 9909 9910 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9911 if (!success) 9912 return false; 9913 uint32_t result = val1 ^ shifted; 9914 9915 EmulateInstruction::Context context; 9916 context.type = EmulateInstruction::eContextImmediate; 9917 context.SetNoArgs(); 9918 9919 if (!WriteFlags(context, result, carry)) 9920 return false; 9921 } 9922 return true; 9923} 9924 9925// Test (immediate) performs a bitwise AND operation on a register value and an 9926// immediate value. It updates the condition flags based on the result, and 9927// discards the result. 9928bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode, 9929 const ARMEncoding encoding) { 9930#if 0 9931 // ARM pseudo code... 9932 if ConditionPassed() then 9933 EncodingSpecificOperations(); 9934 result = R[n] AND imm32; 9935 APSR.N = result<31>; 9936 APSR.Z = IsZeroBit(result); 9937 APSR.C = carry; 9938 // APSR.V unchanged 9939#endif 9940 9941 bool success = false; 9942 9943 if (ConditionPassed(opcode)) { 9944 uint32_t Rn; 9945 uint32_t 9946 imm32; // the immediate value to be ANDed to the value obtained from Rn 9947 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9948 switch (encoding) { 9949 case eEncodingT1: 9950 Rn = Bits32(opcode, 19, 16); 9951 imm32 = ThumbExpandImm_C( 9952 opcode, APSR_C, 9953 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9954 if (BadReg(Rn)) 9955 return false; 9956 break; 9957 case eEncodingA1: 9958 Rn = Bits32(opcode, 19, 16); 9959 imm32 = 9960 ARMExpandImm_C(opcode, APSR_C, 9961 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9962 break; 9963 default: 9964 return false; 9965 } 9966 9967 // Read the first operand. 9968 uint32_t val1 = ReadCoreReg(Rn, &success); 9969 if (!success) 9970 return false; 9971 9972 uint32_t result = val1 & imm32; 9973 9974 EmulateInstruction::Context context; 9975 context.type = EmulateInstruction::eContextImmediate; 9976 context.SetNoArgs(); 9977 9978 if (!WriteFlags(context, result, carry)) 9979 return false; 9980 } 9981 return true; 9982} 9983 9984// Test (register) performs a bitwise AND operation on a register value and an 9985// optionally-shifted register value. It updates the condition flags based on 9986// the result, and discards the result. 9987bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode, 9988 const ARMEncoding encoding) { 9989#if 0 9990 // ARM pseudo code... 9991 if ConditionPassed() then 9992 EncodingSpecificOperations(); 9993 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9994 result = R[n] AND shifted; 9995 APSR.N = result<31>; 9996 APSR.Z = IsZeroBit(result); 9997 APSR.C = carry; 9998 // APSR.V unchanged 9999#endif 10000 10001 bool success = false; 10002 10003 if (ConditionPassed(opcode)) { 10004 uint32_t Rn, Rm; 10005 ARM_ShifterType shift_t; 10006 uint32_t shift_n; // the shift applied to the value read from Rm 10007 uint32_t carry; 10008 switch (encoding) { 10009 case eEncodingT1: 10010 Rn = Bits32(opcode, 2, 0); 10011 Rm = Bits32(opcode, 5, 3); 10012 shift_t = SRType_LSL; 10013 shift_n = 0; 10014 break; 10015 case eEncodingT2: 10016 Rn = Bits32(opcode, 19, 16); 10017 Rm = Bits32(opcode, 3, 0); 10018 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10019 if (BadReg(Rn) || BadReg(Rm)) 10020 return false; 10021 break; 10022 case eEncodingA1: 10023 Rn = Bits32(opcode, 19, 16); 10024 Rm = Bits32(opcode, 3, 0); 10025 shift_n = DecodeImmShiftARM(opcode, shift_t); 10026 break; 10027 default: 10028 return false; 10029 } 10030 10031 // Read the first operand. 10032 uint32_t val1 = ReadCoreReg(Rn, &success); 10033 if (!success) 10034 return false; 10035 10036 // Read the second operand. 10037 uint32_t val2 = ReadCoreReg(Rm, &success); 10038 if (!success) 10039 return false; 10040 10041 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 10042 if (!success) 10043 return false; 10044 uint32_t result = val1 & shifted; 10045 10046 EmulateInstruction::Context context; 10047 context.type = EmulateInstruction::eContextImmediate; 10048 context.SetNoArgs(); 10049 10050 if (!WriteFlags(context, result, carry)) 10051 return false; 10052 } 10053 return true; 10054} 10055 10056// A8.6.216 SUB (SP minus register) 10057bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode, 10058 const ARMEncoding encoding) { 10059#if 0 10060 if ConditionPassed() then 10061 EncodingSpecificOperations(); 10062 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10063 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10064 if d == 15 then // Can only occur for ARM encoding 10065 ALUWritePC(result); // setflags is always FALSE here 10066 else 10067 R[d] = result; 10068 if setflags then 10069 APSR.N = result<31>; 10070 APSR.Z = IsZeroBit(result); 10071 APSR.C = carry; 10072 APSR.V = overflow; 10073#endif 10074 10075 bool success = false; 10076 10077 if (ConditionPassed(opcode)) { 10078 uint32_t d; 10079 uint32_t m; 10080 bool setflags; 10081 ARM_ShifterType shift_t; 10082 uint32_t shift_n; 10083 10084 switch (encoding) { 10085 case eEncodingT1: 10086 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10087 d = Bits32(opcode, 11, 8); 10088 m = Bits32(opcode, 3, 0); 10089 setflags = BitIsSet(opcode, 20); 10090 10091 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10092 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10093 10094 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then 10095 // UNPREDICTABLE; 10096 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 10097 return false; 10098 10099 // if d == 15 || BadReg(m) then UNPREDICTABLE; 10100 if ((d == 15) || BadReg(m)) 10101 return false; 10102 break; 10103 10104 case eEncodingA1: 10105 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10106 d = Bits32(opcode, 15, 12); 10107 m = Bits32(opcode, 3, 0); 10108 setflags = BitIsSet(opcode, 20); 10109 10110 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10111 // instructions; 10112 if (d == 15 && setflags) 10113 EmulateSUBSPcLrEtc(opcode, encoding); 10114 10115 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10116 shift_n = DecodeImmShiftARM(opcode, shift_t); 10117 break; 10118 10119 default: 10120 return false; 10121 } 10122 10123 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10124 uint32_t Rm = ReadCoreReg(m, &success); 10125 if (!success) 10126 return false; 10127 10128 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10129 if (!success) 10130 return false; 10131 10132 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10133 uint32_t sp_val = ReadCoreReg(SP_REG, &success); 10134 if (!success) 10135 return false; 10136 10137 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1); 10138 10139 EmulateInstruction::Context context; 10140 context.type = eContextArithmetic; 10141 RegisterInfo sp_reg; 10142 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 10143 RegisterInfo dwarf_reg; 10144 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 10145 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg); 10146 10147 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10148 res.carry_out, res.overflow)) 10149 return false; 10150 } 10151 return true; 10152} 10153 10154// A8.6.7 ADD (register-shifted register) 10155bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode, 10156 const ARMEncoding encoding) { 10157#if 0 10158 if ConditionPassed() then 10159 EncodingSpecificOperations(); 10160 shift_n = UInt(R[s]<7:0>); 10161 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10162 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10163 R[d] = result; 10164 if setflags then 10165 APSR.N = result<31>; 10166 APSR.Z = IsZeroBit(result); 10167 APSR.C = carry; 10168 APSR.V = overflow; 10169#endif 10170 10171 bool success = false; 10172 10173 if (ConditionPassed(opcode)) { 10174 uint32_t d; 10175 uint32_t n; 10176 uint32_t m; 10177 uint32_t s; 10178 bool setflags; 10179 ARM_ShifterType shift_t; 10180 10181 switch (encoding) { 10182 case eEncodingA1: 10183 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 10184 d = Bits32(opcode, 15, 12); 10185 n = Bits32(opcode, 19, 16); 10186 m = Bits32(opcode, 3, 0); 10187 s = Bits32(opcode, 11, 8); 10188 10189 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 10190 setflags = BitIsSet(opcode, 20); 10191 shift_t = DecodeRegShift(Bits32(opcode, 6, 5)); 10192 10193 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 10194 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 10195 return false; 10196 break; 10197 10198 default: 10199 return false; 10200 } 10201 10202 // shift_n = UInt(R[s]<7:0>); 10203 uint32_t Rs = ReadCoreReg(s, &success); 10204 if (!success) 10205 return false; 10206 10207 uint32_t shift_n = Bits32(Rs, 7, 0); 10208 10209 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10210 uint32_t Rm = ReadCoreReg(m, &success); 10211 if (!success) 10212 return false; 10213 10214 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10215 if (!success) 10216 return false; 10217 10218 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10219 uint32_t Rn = ReadCoreReg(n, &success); 10220 if (!success) 10221 return false; 10222 10223 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0); 10224 10225 // R[d] = result; 10226 EmulateInstruction::Context context; 10227 context.type = eContextArithmetic; 10228 RegisterInfo reg_n; 10229 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10230 RegisterInfo reg_m; 10231 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10232 10233 context.SetRegisterRegisterOperands(reg_n, reg_m); 10234 10235 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 10236 res.result)) 10237 return false; 10238 10239 // if setflags then 10240 // APSR.N = result<31>; 10241 // APSR.Z = IsZeroBit(result); 10242 // APSR.C = carry; 10243 // APSR.V = overflow; 10244 if (setflags) 10245 return WriteFlags(context, res.result, res.carry_out, res.overflow); 10246 } 10247 return true; 10248} 10249 10250// A8.6.213 SUB (register) 10251bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode, 10252 const ARMEncoding encoding) { 10253#if 0 10254 if ConditionPassed() then 10255 EncodingSpecificOperations(); 10256 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10257 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10258 if d == 15 then // Can only occur for ARM encoding 10259 ALUWritePC(result); // setflags is always FALSE here 10260 else 10261 R[d] = result; 10262 if setflags then 10263 APSR.N = result<31>; 10264 APSR.Z = IsZeroBit(result); 10265 APSR.C = carry; 10266 APSR.V = overflow; 10267#endif 10268 10269 bool success = false; 10270 10271 if (ConditionPassed(opcode)) { 10272 uint32_t d; 10273 uint32_t n; 10274 uint32_t m; 10275 bool setflags; 10276 ARM_ShifterType shift_t; 10277 uint32_t shift_n; 10278 10279 switch (encoding) { 10280 case eEncodingT1: 10281 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 10282 d = Bits32(opcode, 2, 0); 10283 n = Bits32(opcode, 5, 3); 10284 m = Bits32(opcode, 8, 6); 10285 setflags = !InITBlock(); 10286 10287 // (shift_t, shift_n) = (SRType_LSL, 0); 10288 shift_t = SRType_LSL; 10289 shift_n = 0; 10290 10291 break; 10292 10293 case eEncodingT2: 10294 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 10295 d = Bits32(opcode, 11, 8); 10296 n = Bits32(opcode, 19, 16); 10297 m = Bits32(opcode, 3, 0); 10298 setflags = BitIsSet(opcode, 20); 10299 10300 // if Rd == "1111" && S == "1" then SEE CMP (register); 10301 if (d == 15 && setflags == 1) 10302 return EmulateCMPImm(opcode, eEncodingT3); 10303 10304 // if Rn == "1101" then SEE SUB (SP minus register); 10305 if (n == 13) 10306 return EmulateSUBSPReg(opcode, eEncodingT1); 10307 10308 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10309 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10310 10311 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then 10312 // UNPREDICTABLE; 10313 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) || 10314 BadReg(m)) 10315 return false; 10316 10317 break; 10318 10319 case eEncodingA1: 10320 // if Rn == '1101' then SEE SUB (SP minus register); 10321 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 10322 d = Bits32(opcode, 15, 12); 10323 n = Bits32(opcode, 19, 16); 10324 m = Bits32(opcode, 3, 0); 10325 setflags = BitIsSet(opcode, 20); 10326 10327 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10328 // instructions; 10329 if ((d == 15) && setflags) 10330 EmulateSUBSPcLrEtc(opcode, encoding); 10331 10332 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10333 shift_n = DecodeImmShiftARM(opcode, shift_t); 10334 10335 break; 10336 10337 default: 10338 return false; 10339 } 10340 10341 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10342 uint32_t Rm = ReadCoreReg(m, &success); 10343 if (!success) 10344 return false; 10345 10346 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10347 if (!success) 10348 return false; 10349 10350 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10351 uint32_t Rn = ReadCoreReg(n, &success); 10352 if (!success) 10353 return false; 10354 10355 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1); 10356 10357 // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result); 10358 // // setflags is always FALSE here else 10359 // R[d] = result; 10360 // if setflags then 10361 // APSR.N = result<31>; 10362 // APSR.Z = IsZeroBit(result); 10363 // APSR.C = carry; 10364 // APSR.V = overflow; 10365 10366 EmulateInstruction::Context context; 10367 context.type = eContextArithmetic; 10368 RegisterInfo reg_n; 10369 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10370 RegisterInfo reg_m; 10371 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10372 context.SetRegisterRegisterOperands(reg_n, reg_m); 10373 10374 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10375 res.carry_out, res.overflow)) 10376 return false; 10377 } 10378 return true; 10379} 10380 10381// A8.6.202 STREX 10382// Store Register Exclusive calculates an address from a base register value 10383// and an immediate offset, and stores a word from a register to memory if the 10384// executing processor has exclusive access to the memory addressed. 10385bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode, 10386 const ARMEncoding encoding) { 10387#if 0 10388 if ConditionPassed() then 10389 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10390 address = R[n] + imm32; 10391 if ExclusiveMonitorsPass(address,4) then 10392 MemA[address,4] = R[t]; 10393 R[d] = 0; 10394 else 10395 R[d] = 1; 10396#endif 10397 10398 bool success = false; 10399 10400 if (ConditionPassed(opcode)) { 10401 uint32_t d; 10402 uint32_t t; 10403 uint32_t n; 10404 uint32_t imm32; 10405 const uint32_t addr_byte_size = GetAddressByteSize(); 10406 10407 switch (encoding) { 10408 case eEncodingT1: 10409 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = 10410 // ZeroExtend(imm8:'00', 10411 // 32); 10412 d = Bits32(opcode, 11, 8); 10413 t = Bits32(opcode, 15, 12); 10414 n = Bits32(opcode, 19, 16); 10415 imm32 = Bits32(opcode, 7, 0) << 2; 10416 10417 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 10418 if (BadReg(d) || BadReg(t) || (n == 15)) 10419 return false; 10420 10421 // if d == n || d == t then UNPREDICTABLE; 10422 if ((d == n) || (d == t)) 10423 return false; 10424 10425 break; 10426 10427 case eEncodingA1: 10428 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero 10429 // offset 10430 d = Bits32(opcode, 15, 12); 10431 t = Bits32(opcode, 3, 0); 10432 n = Bits32(opcode, 19, 16); 10433 imm32 = 0; 10434 10435 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 10436 if ((d == 15) || (t == 15) || (n == 15)) 10437 return false; 10438 10439 // if d == n || d == t then UNPREDICTABLE; 10440 if ((d == n) || (d == t)) 10441 return false; 10442 10443 break; 10444 10445 default: 10446 return false; 10447 } 10448 10449 // address = R[n] + imm32; 10450 uint32_t Rn = ReadCoreReg(n, &success); 10451 if (!success) 10452 return false; 10453 10454 addr_t address = Rn + imm32; 10455 10456 RegisterInfo base_reg; 10457 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10458 RegisterInfo data_reg; 10459 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10460 EmulateInstruction::Context context; 10461 context.type = eContextRegisterStore; 10462 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32); 10463 10464 // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass 10465 // (address, addr_byte_size)) -- For now, for the sake of emulation, we 10466 // will say this 10467 // always return 10468 // true. 10469 if (true) { 10470 // MemA[address,4] = R[t]; 10471 uint32_t Rt = 10472 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 10473 if (!success) 10474 return false; 10475 10476 if (!MemAWrite(context, address, Rt, addr_byte_size)) 10477 return false; 10478 10479 // R[d] = 0; 10480 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 10481 return false; 10482 } 10483#if 0 // unreachable because if true 10484 else 10485 { 10486 // R[d] = 1; 10487 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 10488 return false; 10489 } 10490#endif // unreachable because if true 10491 } 10492 return true; 10493} 10494 10495// A8.6.197 STRB (immediate, ARM) 10496bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode, 10497 const ARMEncoding encoding) { 10498#if 0 10499 if ConditionPassed() then 10500 EncodingSpecificOperations(); 10501 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10502 address = if index then offset_addr else R[n]; 10503 MemU[address,1] = R[t]<7:0>; 10504 if wback then R[n] = offset_addr; 10505#endif 10506 10507 bool success = false; 10508 10509 if (ConditionPassed(opcode)) { 10510 uint32_t t; 10511 uint32_t n; 10512 uint32_t imm32; 10513 bool index; 10514 bool add; 10515 bool wback; 10516 10517 switch (encoding) { 10518 case eEncodingA1: 10519 // if P == '0' && W == '1' then SEE STRBT; 10520 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10521 t = Bits32(opcode, 15, 12); 10522 n = Bits32(opcode, 19, 16); 10523 imm32 = Bits32(opcode, 11, 0); 10524 10525 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10526 index = BitIsSet(opcode, 24); 10527 add = BitIsSet(opcode, 23); 10528 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10529 10530 // if t == 15 then UNPREDICTABLE; 10531 if (t == 15) 10532 return false; 10533 10534 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10535 if (wback && ((n == 15) || (n == t))) 10536 return false; 10537 10538 break; 10539 10540 default: 10541 return false; 10542 } 10543 10544 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10545 uint32_t Rn = ReadCoreReg(n, &success); 10546 if (!success) 10547 return false; 10548 10549 addr_t offset_addr; 10550 if (add) 10551 offset_addr = Rn + imm32; 10552 else 10553 offset_addr = Rn - imm32; 10554 10555 // address = if index then offset_addr else R[n]; 10556 addr_t address; 10557 if (index) 10558 address = offset_addr; 10559 else 10560 address = Rn; 10561 10562 // MemU[address,1] = R[t]<7:0>; 10563 uint32_t Rt = ReadCoreReg(t, &success); 10564 if (!success) 10565 return false; 10566 10567 RegisterInfo base_reg; 10568 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10569 RegisterInfo data_reg; 10570 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10571 EmulateInstruction::Context context; 10572 context.type = eContextRegisterStore; 10573 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10574 10575 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1)) 10576 return false; 10577 10578 // if wback then R[n] = offset_addr; 10579 if (wback) { 10580 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10581 offset_addr)) 10582 return false; 10583 } 10584 } 10585 return true; 10586} 10587 10588// A8.6.194 STR (immediate, ARM) 10589bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode, 10590 const ARMEncoding encoding) { 10591#if 0 10592 if ConditionPassed() then 10593 EncodingSpecificOperations(); 10594 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10595 address = if index then offset_addr else R[n]; 10596 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10597 if wback then R[n] = offset_addr; 10598#endif 10599 10600 bool success = false; 10601 10602 if (ConditionPassed(opcode)) { 10603 uint32_t t; 10604 uint32_t n; 10605 uint32_t imm32; 10606 bool index; 10607 bool add; 10608 bool wback; 10609 10610 const uint32_t addr_byte_size = GetAddressByteSize(); 10611 10612 switch (encoding) { 10613 case eEncodingA1: 10614 // if P == '0' && W == '1' then SEE STRT; 10615 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == 10616 // '000000000100' then SEE PUSH; 10617 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10618 t = Bits32(opcode, 15, 12); 10619 n = Bits32(opcode, 19, 16); 10620 imm32 = Bits32(opcode, 11, 0); 10621 10622 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10623 index = BitIsSet(opcode, 24); 10624 add = BitIsSet(opcode, 23); 10625 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10626 10627 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10628 if (wback && ((n == 15) || (n == t))) 10629 return false; 10630 10631 break; 10632 10633 default: 10634 return false; 10635 } 10636 10637 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10638 uint32_t Rn = ReadCoreReg(n, &success); 10639 if (!success) 10640 return false; 10641 10642 addr_t offset_addr; 10643 if (add) 10644 offset_addr = Rn + imm32; 10645 else 10646 offset_addr = Rn - imm32; 10647 10648 // address = if index then offset_addr else R[n]; 10649 addr_t address; 10650 if (index) 10651 address = offset_addr; 10652 else 10653 address = Rn; 10654 10655 RegisterInfo base_reg; 10656 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10657 RegisterInfo data_reg; 10658 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10659 EmulateInstruction::Context context; 10660 context.type = eContextRegisterStore; 10661 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10662 10663 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10664 uint32_t Rt = ReadCoreReg(t, &success); 10665 if (!success) 10666 return false; 10667 10668 if (t == 15) { 10669 uint32_t pc_value = ReadCoreReg(PC_REG, &success); 10670 if (!success) 10671 return false; 10672 10673 if (!MemUWrite(context, address, pc_value, addr_byte_size)) 10674 return false; 10675 } else { 10676 if (!MemUWrite(context, address, Rt, addr_byte_size)) 10677 return false; 10678 } 10679 10680 // if wback then R[n] = offset_addr; 10681 if (wback) { 10682 context.type = eContextAdjustBaseRegister; 10683 context.SetImmediate(offset_addr); 10684 10685 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10686 offset_addr)) 10687 return false; 10688 } 10689 } 10690 return true; 10691} 10692 10693// A8.6.66 LDRD (immediate) 10694// Load Register Dual (immediate) calculates an address from a base register 10695// value and an immediate offset, loads two words from memory, and writes them 10696// to two registers. It can use offset, post-indexed, or pre-indexed 10697// addressing. 10698bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode, 10699 const ARMEncoding encoding) { 10700#if 0 10701 if ConditionPassed() then 10702 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10703 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10704 address = if index then offset_addr else R[n]; 10705 R[t] = MemA[address,4]; 10706 R[t2] = MemA[address+4,4]; 10707 if wback then R[n] = offset_addr; 10708#endif 10709 10710 bool success = false; 10711 10712 if (ConditionPassed(opcode)) { 10713 uint32_t t; 10714 uint32_t t2; 10715 uint32_t n; 10716 uint32_t imm32; 10717 bool index; 10718 bool add; 10719 bool wback; 10720 10721 switch (encoding) { 10722 case eEncodingT1: 10723 // if P == '0' && W == '0' then SEE 'Related encodings'; 10724 // if Rn == '1111' then SEE LDRD (literal); 10725 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10726 // ZeroExtend(imm8:'00', 32); 10727 t = Bits32(opcode, 15, 12); 10728 t2 = Bits32(opcode, 11, 8); 10729 n = Bits32(opcode, 19, 16); 10730 imm32 = Bits32(opcode, 7, 0) << 2; 10731 10732 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10733 index = BitIsSet(opcode, 24); 10734 add = BitIsSet(opcode, 23); 10735 wback = BitIsSet(opcode, 21); 10736 10737 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10738 if (wback && ((n == t) || (n == t2))) 10739 return false; 10740 10741 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10742 if (BadReg(t) || BadReg(t2) || (t == t2)) 10743 return false; 10744 10745 break; 10746 10747 case eEncodingA1: 10748 // if Rn == '1111' then SEE LDRD (literal); 10749 // if Rt<0> == '1' then UNPREDICTABLE; 10750 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10751 // 32); 10752 t = Bits32(opcode, 15, 12); 10753 if (BitIsSet(t, 0)) 10754 return false; 10755 t2 = t + 1; 10756 n = Bits32(opcode, 19, 16); 10757 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10758 10759 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10760 index = BitIsSet(opcode, 24); 10761 add = BitIsSet(opcode, 23); 10762 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10763 10764 // if P == '0' && W == '1' then UNPREDICTABLE; 10765 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10766 return false; 10767 10768 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10769 if (wback && ((n == t) || (n == t2))) 10770 return false; 10771 10772 // if t2 == 15 then UNPREDICTABLE; 10773 if (t2 == 15) 10774 return false; 10775 10776 break; 10777 10778 default: 10779 return false; 10780 } 10781 10782 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10783 uint32_t Rn = ReadCoreReg(n, &success); 10784 if (!success) 10785 return false; 10786 10787 addr_t offset_addr; 10788 if (add) 10789 offset_addr = Rn + imm32; 10790 else 10791 offset_addr = Rn - imm32; 10792 10793 // address = if index then offset_addr else R[n]; 10794 addr_t address; 10795 if (index) 10796 address = offset_addr; 10797 else 10798 address = Rn; 10799 10800 // R[t] = MemA[address,4]; 10801 RegisterInfo base_reg; 10802 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10803 10804 EmulateInstruction::Context context; 10805 if (n == 13) 10806 context.type = eContextPopRegisterOffStack; 10807 else 10808 context.type = eContextRegisterLoad; 10809 context.SetAddress(address); 10810 10811 const uint32_t addr_byte_size = GetAddressByteSize(); 10812 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10813 if (!success) 10814 return false; 10815 10816 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10817 return false; 10818 10819 // R[t2] = MemA[address+4,4]; 10820 context.SetAddress(address + 4); 10821 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10822 if (!success) 10823 return false; 10824 10825 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10826 data)) 10827 return false; 10828 10829 // if wback then R[n] = offset_addr; 10830 if (wback) { 10831 context.type = eContextAdjustBaseRegister; 10832 context.SetAddress(offset_addr); 10833 10834 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10835 offset_addr)) 10836 return false; 10837 } 10838 } 10839 return true; 10840} 10841 10842// A8.6.68 LDRD (register) 10843// Load Register Dual (register) calculates an address from a base register 10844// value and a register offset, loads two words from memory, and writes them to 10845// two registers. It can use offset, post-indexed or pre-indexed addressing. 10846bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode, 10847 const ARMEncoding encoding) { 10848#if 0 10849 if ConditionPassed() then 10850 EncodingSpecificOperations(); 10851 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10852 address = if index then offset_addr else R[n]; 10853 R[t] = MemA[address,4]; 10854 R[t2] = MemA[address+4,4]; 10855 if wback then R[n] = offset_addr; 10856#endif 10857 10858 bool success = false; 10859 10860 if (ConditionPassed(opcode)) { 10861 uint32_t t; 10862 uint32_t t2; 10863 uint32_t n; 10864 uint32_t m; 10865 bool index; 10866 bool add; 10867 bool wback; 10868 10869 switch (encoding) { 10870 case eEncodingA1: 10871 // if Rt<0> == '1' then UNPREDICTABLE; 10872 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10873 t = Bits32(opcode, 15, 12); 10874 if (BitIsSet(t, 0)) 10875 return false; 10876 t2 = t + 1; 10877 n = Bits32(opcode, 19, 16); 10878 m = Bits32(opcode, 3, 0); 10879 10880 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10881 index = BitIsSet(opcode, 24); 10882 add = BitIsSet(opcode, 23); 10883 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10884 10885 // if P == '0' && W == '1' then UNPREDICTABLE; 10886 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10887 return false; 10888 10889 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10890 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10891 return false; 10892 10893 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10894 if (wback && ((n == 15) || (n == t) || (n == t2))) 10895 return false; 10896 10897 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10898 if ((ArchVersion() < 6) && wback && (m == n)) 10899 return false; 10900 break; 10901 10902 default: 10903 return false; 10904 } 10905 10906 uint32_t Rn = ReadCoreReg(n, &success); 10907 if (!success) 10908 return false; 10909 RegisterInfo base_reg; 10910 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10911 10912 uint32_t Rm = ReadCoreReg(m, &success); 10913 if (!success) 10914 return false; 10915 RegisterInfo offset_reg; 10916 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10917 10918 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10919 addr_t offset_addr; 10920 if (add) 10921 offset_addr = Rn + Rm; 10922 else 10923 offset_addr = Rn - Rm; 10924 10925 // address = if index then offset_addr else R[n]; 10926 addr_t address; 10927 if (index) 10928 address = offset_addr; 10929 else 10930 address = Rn; 10931 10932 EmulateInstruction::Context context; 10933 if (n == 13) 10934 context.type = eContextPopRegisterOffStack; 10935 else 10936 context.type = eContextRegisterLoad; 10937 context.SetAddress(address); 10938 10939 // R[t] = MemA[address,4]; 10940 const uint32_t addr_byte_size = GetAddressByteSize(); 10941 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10942 if (!success) 10943 return false; 10944 10945 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10946 return false; 10947 10948 // R[t2] = MemA[address+4,4]; 10949 10950 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10951 if (!success) 10952 return false; 10953 10954 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10955 data)) 10956 return false; 10957 10958 // if wback then R[n] = offset_addr; 10959 if (wback) { 10960 context.type = eContextAdjustBaseRegister; 10961 context.SetAddress(offset_addr); 10962 10963 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10964 offset_addr)) 10965 return false; 10966 } 10967 } 10968 return true; 10969} 10970 10971// A8.6.200 STRD (immediate) 10972// Store Register Dual (immediate) calculates an address from a base register 10973// value and an immediate offset, and stores two words from two registers to 10974// memory. It can use offset, post-indexed, or pre-indexed addressing. 10975bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode, 10976 const ARMEncoding encoding) { 10977#if 0 10978 if ConditionPassed() then 10979 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10980 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10981 address = if index then offset_addr else R[n]; 10982 MemA[address,4] = R[t]; 10983 MemA[address+4,4] = R[t2]; 10984 if wback then R[n] = offset_addr; 10985#endif 10986 10987 bool success = false; 10988 10989 if (ConditionPassed(opcode)) { 10990 uint32_t t; 10991 uint32_t t2; 10992 uint32_t n; 10993 uint32_t imm32; 10994 bool index; 10995 bool add; 10996 bool wback; 10997 10998 switch (encoding) { 10999 case eEncodingT1: 11000 // if P == '0' && W == '0' then SEE 'Related encodings'; 11001 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 11002 // ZeroExtend(imm8:'00', 32); 11003 t = Bits32(opcode, 15, 12); 11004 t2 = Bits32(opcode, 11, 8); 11005 n = Bits32(opcode, 19, 16); 11006 imm32 = Bits32(opcode, 7, 0) << 2; 11007 11008 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 11009 index = BitIsSet(opcode, 24); 11010 add = BitIsSet(opcode, 23); 11011 wback = BitIsSet(opcode, 21); 11012 11013 // if wback && (n == t || n == t2) then UNPREDICTABLE; 11014 if (wback && ((n == t) || (n == t2))) 11015 return false; 11016 11017 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 11018 if ((n == 15) || BadReg(t) || BadReg(t2)) 11019 return false; 11020 11021 break; 11022 11023 case eEncodingA1: 11024 // if Rt<0> == '1' then UNPREDICTABLE; 11025 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 11026 // 32); 11027 t = Bits32(opcode, 15, 12); 11028 if (BitIsSet(t, 0)) 11029 return false; 11030 11031 t2 = t + 1; 11032 n = Bits32(opcode, 19, 16); 11033 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 11034 11035 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11036 index = BitIsSet(opcode, 24); 11037 add = BitIsSet(opcode, 23); 11038 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11039 11040 // if P == '0' && W == '1' then UNPREDICTABLE; 11041 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11042 return false; 11043 11044 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11045 if (wback && ((n == 15) || (n == t) || (n == t2))) 11046 return false; 11047 11048 // if t2 == 15 then UNPREDICTABLE; 11049 if (t2 == 15) 11050 return false; 11051 11052 break; 11053 11054 default: 11055 return false; 11056 } 11057 11058 RegisterInfo base_reg; 11059 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11060 11061 uint32_t Rn = ReadCoreReg(n, &success); 11062 if (!success) 11063 return false; 11064 11065 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11066 addr_t offset_addr; 11067 if (add) 11068 offset_addr = Rn + imm32; 11069 else 11070 offset_addr = Rn - imm32; 11071 11072 // address = if index then offset_addr else R[n]; 11073 addr_t address; 11074 if (index) 11075 address = offset_addr; 11076 else 11077 address = Rn; 11078 11079 // MemA[address,4] = R[t]; 11080 RegisterInfo data_reg; 11081 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11082 11083 uint32_t data = ReadCoreReg(t, &success); 11084 if (!success) 11085 return false; 11086 11087 EmulateInstruction::Context context; 11088 if (n == 13) 11089 context.type = eContextPushRegisterOnStack; 11090 else 11091 context.type = eContextRegisterStore; 11092 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11093 11094 const uint32_t addr_byte_size = GetAddressByteSize(); 11095 11096 if (!MemAWrite(context, address, data, addr_byte_size)) 11097 return false; 11098 11099 // MemA[address+4,4] = R[t2]; 11100 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11101 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11102 (address + 4) - Rn); 11103 11104 data = ReadCoreReg(t2, &success); 11105 if (!success) 11106 return false; 11107 11108 if (!MemAWrite(context, address + 4, data, addr_byte_size)) 11109 return false; 11110 11111 // if wback then R[n] = offset_addr; 11112 if (wback) { 11113 if (n == 13) 11114 context.type = eContextAdjustStackPointer; 11115 else 11116 context.type = eContextAdjustBaseRegister; 11117 context.SetAddress(offset_addr); 11118 11119 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11120 offset_addr)) 11121 return false; 11122 } 11123 } 11124 return true; 11125} 11126 11127// A8.6.201 STRD (register) 11128bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode, 11129 const ARMEncoding encoding) { 11130#if 0 11131 if ConditionPassed() then 11132 EncodingSpecificOperations(); 11133 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11134 address = if index then offset_addr else R[n]; 11135 MemA[address,4] = R[t]; 11136 MemA[address+4,4] = R[t2]; 11137 if wback then R[n] = offset_addr; 11138#endif 11139 11140 bool success = false; 11141 11142 if (ConditionPassed(opcode)) { 11143 uint32_t t; 11144 uint32_t t2; 11145 uint32_t n; 11146 uint32_t m; 11147 bool index; 11148 bool add; 11149 bool wback; 11150 11151 switch (encoding) { 11152 case eEncodingA1: 11153 // if Rt<0> == '1' then UNPREDICTABLE; 11154 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 11155 t = Bits32(opcode, 15, 12); 11156 if (BitIsSet(t, 0)) 11157 return false; 11158 11159 t2 = t + 1; 11160 n = Bits32(opcode, 19, 16); 11161 m = Bits32(opcode, 3, 0); 11162 11163 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11164 index = BitIsSet(opcode, 24); 11165 add = BitIsSet(opcode, 23); 11166 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11167 11168 // if P == '0' && W == '1' then UNPREDICTABLE; 11169 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11170 return false; 11171 11172 // if t2 == 15 || m == 15 then UNPREDICTABLE; 11173 if ((t2 == 15) || (m == 15)) 11174 return false; 11175 11176 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11177 if (wback && ((n == 15) || (n == t) || (n == t2))) 11178 return false; 11179 11180 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 11181 if ((ArchVersion() < 6) && wback && (m == n)) 11182 return false; 11183 11184 break; 11185 11186 default: 11187 return false; 11188 } 11189 11190 RegisterInfo base_reg; 11191 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11192 RegisterInfo offset_reg; 11193 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 11194 RegisterInfo data_reg; 11195 11196 uint32_t Rn = ReadCoreReg(n, &success); 11197 if (!success) 11198 return false; 11199 11200 uint32_t Rm = ReadCoreReg(m, &success); 11201 if (!success) 11202 return false; 11203 11204 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11205 addr_t offset_addr; 11206 if (add) 11207 offset_addr = Rn + Rm; 11208 else 11209 offset_addr = Rn - Rm; 11210 11211 // address = if index then offset_addr else R[n]; 11212 addr_t address; 11213 if (index) 11214 address = offset_addr; 11215 else 11216 address = Rn; 11217 // MemA[address,4] = R[t]; 11218 uint32_t Rt = ReadCoreReg(t, &success); 11219 if (!success) 11220 return false; 11221 11222 EmulateInstruction::Context context; 11223 if (t == 13) 11224 context.type = eContextPushRegisterOnStack; 11225 else 11226 context.type = eContextRegisterStore; 11227 11228 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11229 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11230 data_reg); 11231 11232 const uint32_t addr_byte_size = GetAddressByteSize(); 11233 11234 if (!MemAWrite(context, address, Rt, addr_byte_size)) 11235 return false; 11236 11237 // MemA[address+4,4] = R[t2]; 11238 uint32_t Rt2 = ReadCoreReg(t2, &success); 11239 if (!success) 11240 return false; 11241 11242 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11243 11244 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11245 data_reg); 11246 11247 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size)) 11248 return false; 11249 11250 // if wback then R[n] = offset_addr; 11251 if (wback) { 11252 context.type = eContextAdjustBaseRegister; 11253 context.SetAddress(offset_addr); 11254 11255 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11256 offset_addr)) 11257 return false; 11258 } 11259 } 11260 return true; 11261} 11262 11263// A8.6.319 VLDM 11264// Vector Load Multiple loads multiple extension registers from consecutive 11265// memory locations using an address from an ARM core register. 11266bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode, 11267 const ARMEncoding encoding) { 11268#if 0 11269 if ConditionPassed() then 11270 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11271 address = if add then R[n] else R[n]-imm32; 11272 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11273 for r = 0 to regs-1 11274 if single_regs then 11275 S[d+r] = MemA[address,4]; address = address+4; 11276 else 11277 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 11278 // Combine the word-aligned words in the correct order for 11279 // current endianness. 11280 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11281#endif 11282 11283 bool success = false; 11284 11285 if (ConditionPassed(opcode)) { 11286 bool single_regs; 11287 bool add; 11288 bool wback; 11289 uint32_t d; 11290 uint32_t n; 11291 uint32_t imm32; 11292 uint32_t regs; 11293 11294 switch (encoding) { 11295 case eEncodingT1: 11296 case eEncodingA1: 11297 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11298 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11299 // if P == '1' && W == '0' then SEE VLDR; 11300 // if P == U && W == '1' then UNDEFINED; 11301 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11302 return false; 11303 11304 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11305 // !), 101 (DB with !) 11306 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11307 single_regs = false; 11308 add = BitIsSet(opcode, 23); 11309 wback = BitIsSet(opcode, 21); 11310 11311 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11312 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11313 n = Bits32(opcode, 19, 16); 11314 imm32 = Bits32(opcode, 7, 0) << 2; 11315 11316 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 11317 regs = Bits32(opcode, 7, 0) / 2; 11318 11319 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11320 // UNPREDICTABLE; 11321 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 11322 return false; 11323 11324 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11325 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11326 return false; 11327 11328 break; 11329 11330 case eEncodingT2: 11331 case eEncodingA2: 11332 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11333 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11334 // if P == '1' && W == '0' then SEE VLDR; 11335 // if P == U && W == '1' then UNDEFINED; 11336 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11337 return false; 11338 11339 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11340 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11341 // == '1'); d = 11342 // UInt(Vd:D); n = UInt(Rn); 11343 single_regs = true; 11344 add = BitIsSet(opcode, 23); 11345 wback = BitIsSet(opcode, 21); 11346 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11347 n = Bits32(opcode, 19, 16); 11348 11349 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11350 imm32 = Bits32(opcode, 7, 0) << 2; 11351 regs = Bits32(opcode, 7, 0); 11352 11353 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11354 // UNPREDICTABLE; 11355 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11356 return false; 11357 11358 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11359 if ((regs == 0) || ((d + regs) > 32)) 11360 return false; 11361 break; 11362 11363 default: 11364 return false; 11365 } 11366 11367 RegisterInfo base_reg; 11368 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11369 11370 uint32_t Rn = ReadCoreReg(n, &success); 11371 if (!success) 11372 return false; 11373 11374 // address = if add then R[n] else R[n]-imm32; 11375 addr_t address; 11376 if (add) 11377 address = Rn; 11378 else 11379 address = Rn - imm32; 11380 11381 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11382 EmulateInstruction::Context context; 11383 11384 if (wback) { 11385 uint32_t value; 11386 if (add) 11387 value = Rn + imm32; 11388 else 11389 value = Rn - imm32; 11390 11391 context.type = eContextAdjustBaseRegister; 11392 context.SetImmediateSigned(value - Rn); 11393 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11394 value)) 11395 return false; 11396 } 11397 11398 const uint32_t addr_byte_size = GetAddressByteSize(); 11399 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11400 11401 context.type = eContextRegisterLoad; 11402 11403 // for r = 0 to regs-1 11404 for (uint32_t r = 0; r < regs; ++r) { 11405 if (single_regs) { 11406 // S[d+r] = MemA[address,4]; address = address+4; 11407 context.SetRegisterPlusOffset(base_reg, address - Rn); 11408 11409 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11410 if (!success) 11411 return false; 11412 11413 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11414 start_reg + d + r, data)) 11415 return false; 11416 11417 address = address + 4; 11418 } else { 11419 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = 11420 // address+8; 11421 context.SetRegisterPlusOffset(base_reg, address - Rn); 11422 uint32_t word1 = 11423 MemARead(context, address, addr_byte_size, 0, &success); 11424 if (!success) 11425 return false; 11426 11427 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn); 11428 uint32_t word2 = 11429 MemARead(context, address + 4, addr_byte_size, 0, &success); 11430 if (!success) 11431 return false; 11432 11433 address = address + 8; 11434 // // Combine the word-aligned words in the correct order for current 11435 // endianness. 11436 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11437 uint64_t data; 11438 if (GetByteOrder() == eByteOrderBig) { 11439 data = word1; 11440 data = (data << 32) | word2; 11441 } else { 11442 data = word2; 11443 data = (data << 32) | word1; 11444 } 11445 11446 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11447 start_reg + d + r, data)) 11448 return false; 11449 } 11450 } 11451 } 11452 return true; 11453} 11454 11455// A8.6.399 VSTM 11456// Vector Store Multiple stores multiple extension registers to consecutive 11457// memory locations using an address from an 11458// ARM core register. 11459bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode, 11460 const ARMEncoding encoding) { 11461#if 0 11462 if ConditionPassed() then 11463 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11464 address = if add then R[n] else R[n]-imm32; 11465 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11466 for r = 0 to regs-1 11467 if single_regs then 11468 MemA[address,4] = S[d+r]; address = address+4; 11469 else 11470 // Store as two word-aligned words in the correct order for 11471 // current endianness. 11472 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11473 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11474 address = address+8; 11475#endif 11476 11477 bool success = false; 11478 11479 if (ConditionPassed(opcode)) { 11480 bool single_regs; 11481 bool add; 11482 bool wback; 11483 uint32_t d; 11484 uint32_t n; 11485 uint32_t imm32; 11486 uint32_t regs; 11487 11488 switch (encoding) { 11489 case eEncodingT1: 11490 case eEncodingA1: 11491 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11492 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11493 // if P == '1' && W == '0' then SEE VSTR; 11494 // if P == U && W == '1' then UNDEFINED; 11495 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11496 return false; 11497 11498 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11499 // !), 101 (DB with !) 11500 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11501 single_regs = false; 11502 add = BitIsSet(opcode, 23); 11503 wback = BitIsSet(opcode, 21); 11504 11505 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11506 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11507 n = Bits32(opcode, 19, 16); 11508 imm32 = Bits32(opcode, 7, 0) << 2; 11509 11510 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11511 regs = Bits32(opcode, 7, 0) / 2; 11512 11513 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11514 // UNPREDICTABLE; 11515 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11516 return false; 11517 11518 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11519 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11520 return false; 11521 11522 break; 11523 11524 case eEncodingT2: 11525 case eEncodingA2: 11526 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11527 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11528 // if P == '1' && W == '0' then SEE VSTR; 11529 // if P == U && W == '1' then UNDEFINED; 11530 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11531 return false; 11532 11533 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11534 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11535 // == '1'); d = 11536 // UInt(Vd:D); n = UInt(Rn); 11537 single_regs = true; 11538 add = BitIsSet(opcode, 23); 11539 wback = BitIsSet(opcode, 21); 11540 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11541 n = Bits32(opcode, 19, 16); 11542 11543 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11544 imm32 = Bits32(opcode, 7, 0) << 2; 11545 regs = Bits32(opcode, 7, 0); 11546 11547 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11548 // UNPREDICTABLE; 11549 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11550 return false; 11551 11552 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11553 if ((regs == 0) || ((d + regs) > 32)) 11554 return false; 11555 11556 break; 11557 11558 default: 11559 return false; 11560 } 11561 11562 RegisterInfo base_reg; 11563 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11564 11565 uint32_t Rn = ReadCoreReg(n, &success); 11566 if (!success) 11567 return false; 11568 11569 // address = if add then R[n] else R[n]-imm32; 11570 addr_t address; 11571 if (add) 11572 address = Rn; 11573 else 11574 address = Rn - imm32; 11575 11576 EmulateInstruction::Context context; 11577 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11578 if (wback) { 11579 uint32_t value; 11580 if (add) 11581 value = Rn + imm32; 11582 else 11583 value = Rn - imm32; 11584 11585 context.type = eContextAdjustBaseRegister; 11586 context.SetRegisterPlusOffset(base_reg, value - Rn); 11587 11588 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11589 value)) 11590 return false; 11591 } 11592 11593 const uint32_t addr_byte_size = GetAddressByteSize(); 11594 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11595 11596 context.type = eContextRegisterStore; 11597 // for r = 0 to regs-1 11598 for (uint32_t r = 0; r < regs; ++r) { 11599 11600 if (single_regs) { 11601 // MemA[address,4] = S[d+r]; address = address+4; 11602 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11603 start_reg + d + r, 0, &success); 11604 if (!success) 11605 return false; 11606 11607 RegisterInfo data_reg; 11608 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11609 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11610 address - Rn); 11611 if (!MemAWrite(context, address, data, addr_byte_size)) 11612 return false; 11613 11614 address = address + 4; 11615 } else { 11616 // // Store as two word-aligned words in the correct order for current 11617 // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else 11618 // D[d+r]<31:0>; 11619 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else 11620 // D[d+r]<63:32>; 11621 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11622 start_reg + d + r, 0, &success); 11623 if (!success) 11624 return false; 11625 11626 RegisterInfo data_reg; 11627 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11628 11629 if (GetByteOrder() == eByteOrderBig) { 11630 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11631 address - Rn); 11632 if (!MemAWrite(context, address, Bits64(data, 63, 32), 11633 addr_byte_size)) 11634 return false; 11635 11636 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11637 (address + 4) - Rn); 11638 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11639 addr_byte_size)) 11640 return false; 11641 } else { 11642 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11643 address - Rn); 11644 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11645 return false; 11646 11647 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11648 (address + 4) - Rn); 11649 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11650 addr_byte_size)) 11651 return false; 11652 } 11653 // address = address+8; 11654 address = address + 8; 11655 } 11656 } 11657 } 11658 return true; 11659} 11660 11661// A8.6.320 11662// This instruction loads a single extension register from memory, using an 11663// address from an ARM core register, with an optional offset. 11664bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode, 11665 ARMEncoding encoding) { 11666#if 0 11667 if ConditionPassed() then 11668 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11669 base = if n == 15 then Align(PC,4) else R[n]; 11670 address = if add then (base + imm32) else (base - imm32); 11671 if single_reg then 11672 S[d] = MemA[address,4]; 11673 else 11674 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11675 // Combine the word-aligned words in the correct order for current 11676 // endianness. 11677 D[d] = if BigEndian() then word1:word2 else word2:word1; 11678#endif 11679 11680 bool success = false; 11681 11682 if (ConditionPassed(opcode)) { 11683 bool single_reg; 11684 bool add; 11685 uint32_t imm32; 11686 uint32_t d; 11687 uint32_t n; 11688 11689 switch (encoding) { 11690 case eEncodingT1: 11691 case eEncodingA1: 11692 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11693 // 32); 11694 single_reg = false; 11695 add = BitIsSet(opcode, 23); 11696 imm32 = Bits32(opcode, 7, 0) << 2; 11697 11698 // d = UInt(D:Vd); n = UInt(Rn); 11699 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11700 n = Bits32(opcode, 19, 16); 11701 11702 break; 11703 11704 case eEncodingT2: 11705 case eEncodingA2: 11706 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11707 single_reg = true; 11708 add = BitIsSet(opcode, 23); 11709 imm32 = Bits32(opcode, 7, 0) << 2; 11710 11711 // d = UInt(Vd:D); n = UInt(Rn); 11712 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11713 n = Bits32(opcode, 19, 16); 11714 11715 break; 11716 11717 default: 11718 return false; 11719 } 11720 RegisterInfo base_reg; 11721 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11722 11723 uint32_t Rn = ReadCoreReg(n, &success); 11724 if (!success) 11725 return false; 11726 11727 // base = if n == 15 then Align(PC,4) else R[n]; 11728 uint32_t base; 11729 if (n == 15) 11730 base = AlignPC(Rn); 11731 else 11732 base = Rn; 11733 11734 // address = if add then (base + imm32) else (base - imm32); 11735 addr_t address; 11736 if (add) 11737 address = base + imm32; 11738 else 11739 address = base - imm32; 11740 11741 const uint32_t addr_byte_size = GetAddressByteSize(); 11742 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11743 11744 EmulateInstruction::Context context; 11745 context.type = eContextRegisterLoad; 11746 context.SetRegisterPlusOffset(base_reg, address - base); 11747 11748 if (single_reg) { 11749 // S[d] = MemA[address,4]; 11750 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11751 if (!success) 11752 return false; 11753 11754 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11755 data)) 11756 return false; 11757 } else { 11758 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11759 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success); 11760 if (!success) 11761 return false; 11762 11763 context.SetRegisterPlusOffset(base_reg, (address + 4) - base); 11764 uint32_t word2 = 11765 MemARead(context, address + 4, addr_byte_size, 0, &success); 11766 if (!success) 11767 return false; 11768 // // Combine the word-aligned words in the correct order for current 11769 // endianness. 11770 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11771 uint64_t data64; 11772 if (GetByteOrder() == eByteOrderBig) { 11773 data64 = word1; 11774 data64 = (data64 << 32) | word2; 11775 } else { 11776 data64 = word2; 11777 data64 = (data64 << 32) | word1; 11778 } 11779 11780 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11781 data64)) 11782 return false; 11783 } 11784 } 11785 return true; 11786} 11787 11788// A8.6.400 VSTR 11789// This instruction stores a signle extension register to memory, using an 11790// address from an ARM core register, with an optional offset. 11791bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode, 11792 ARMEncoding encoding) { 11793#if 0 11794 if ConditionPassed() then 11795 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11796 address = if add then (R[n] + imm32) else (R[n] - imm32); 11797 if single_reg then 11798 MemA[address,4] = S[d]; 11799 else 11800 // Store as two word-aligned words in the correct order for current 11801 // endianness. 11802 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11803 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11804#endif 11805 11806 bool success = false; 11807 11808 if (ConditionPassed(opcode)) { 11809 bool single_reg; 11810 bool add; 11811 uint32_t imm32; 11812 uint32_t d; 11813 uint32_t n; 11814 11815 switch (encoding) { 11816 case eEncodingT1: 11817 case eEncodingA1: 11818 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11819 // 32); 11820 single_reg = false; 11821 add = BitIsSet(opcode, 23); 11822 imm32 = Bits32(opcode, 7, 0) << 2; 11823 11824 // d = UInt(D:Vd); n = UInt(Rn); 11825 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11826 n = Bits32(opcode, 19, 16); 11827 11828 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11829 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11830 return false; 11831 11832 break; 11833 11834 case eEncodingT2: 11835 case eEncodingA2: 11836 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11837 single_reg = true; 11838 add = BitIsSet(opcode, 23); 11839 imm32 = Bits32(opcode, 7, 0) << 2; 11840 11841 // d = UInt(Vd:D); n = UInt(Rn); 11842 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11843 n = Bits32(opcode, 19, 16); 11844 11845 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11846 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11847 return false; 11848 11849 break; 11850 11851 default: 11852 return false; 11853 } 11854 11855 RegisterInfo base_reg; 11856 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11857 11858 uint32_t Rn = ReadCoreReg(n, &success); 11859 if (!success) 11860 return false; 11861 11862 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11863 addr_t address; 11864 if (add) 11865 address = Rn + imm32; 11866 else 11867 address = Rn - imm32; 11868 11869 const uint32_t addr_byte_size = GetAddressByteSize(); 11870 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11871 11872 RegisterInfo data_reg; 11873 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg); 11874 EmulateInstruction::Context context; 11875 context.type = eContextRegisterStore; 11876 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11877 11878 if (single_reg) { 11879 // MemA[address,4] = S[d]; 11880 uint32_t data = 11881 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11882 if (!success) 11883 return false; 11884 11885 if (!MemAWrite(context, address, data, addr_byte_size)) 11886 return false; 11887 } else { 11888 // // Store as two word-aligned words in the correct order for current 11889 // endianness. 11890 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11891 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11892 uint64_t data = 11893 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11894 if (!success) 11895 return false; 11896 11897 if (GetByteOrder() == eByteOrderBig) { 11898 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size)) 11899 return false; 11900 11901 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11902 (address + 4) - Rn); 11903 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11904 addr_byte_size)) 11905 return false; 11906 } else { 11907 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11908 return false; 11909 11910 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11911 (address + 4) - Rn); 11912 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11913 addr_byte_size)) 11914 return false; 11915 } 11916 } 11917 } 11918 return true; 11919} 11920 11921// A8.6.307 VLDI1 (multiple single elements) This instruction loads elements 11922// from memory into one, two, three or four registers, without de-interleaving. 11923// Every element of each register is loaded. 11924bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode, 11925 ARMEncoding encoding) { 11926#if 0 11927 if ConditionPassed() then 11928 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11929 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11930 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11931 for r = 0 to regs-1 11932 for e = 0 to elements-1 11933 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11934 address = address + ebytes; 11935#endif 11936 11937 bool success = false; 11938 11939 if (ConditionPassed(opcode)) { 11940 uint32_t regs; 11941 uint32_t alignment; 11942 uint32_t ebytes; 11943 uint32_t esize; 11944 uint32_t elements; 11945 uint32_t d; 11946 uint32_t n; 11947 uint32_t m; 11948 bool wback; 11949 bool register_index; 11950 11951 switch (encoding) { 11952 case eEncodingT1: 11953 case eEncodingA1: { 11954 // case type of 11955 // when '0111' 11956 // regs = 1; if align<1> == '1' then UNDEFINED; 11957 // when '1010' 11958 // regs = 2; if align == '11' then UNDEFINED; 11959 // when '0110' 11960 // regs = 3; if align<1> == '1' then UNDEFINED; 11961 // when '0010' 11962 // regs = 4; 11963 // otherwise 11964 // SEE 'Related encodings'; 11965 uint32_t type = Bits32(opcode, 11, 8); 11966 uint32_t align = Bits32(opcode, 5, 4); 11967 if (type == 7) // '0111' 11968 { 11969 regs = 1; 11970 if (BitIsSet(align, 1)) 11971 return false; 11972 } else if (type == 10) // '1010' 11973 { 11974 regs = 2; 11975 if (align == 3) 11976 return false; 11977 11978 } else if (type == 6) // '0110' 11979 { 11980 regs = 3; 11981 if (BitIsSet(align, 1)) 11982 return false; 11983 } else if (type == 2) // '0010' 11984 { 11985 regs = 4; 11986 } else 11987 return false; 11988 11989 // alignment = if align == '00' then 1 else 4 << UInt(align); 11990 if (align == 0) 11991 alignment = 1; 11992 else 11993 alignment = 4 << align; 11994 11995 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11996 ebytes = 1 << Bits32(opcode, 7, 6); 11997 esize = 8 * ebytes; 11998 elements = 8 / ebytes; 11999 12000 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12001 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12002 n = Bits32(opcode, 19, 15); 12003 m = Bits32(opcode, 3, 0); 12004 12005 // wback = (m != 15); register_index = (m != 15 && m != 13); 12006 wback = (m != 15); 12007 register_index = ((m != 15) && (m != 13)); 12008 12009 // if d+regs > 32 then UNPREDICTABLE; 12010 if ((d + regs) > 32) 12011 return false; 12012 } break; 12013 12014 default: 12015 return false; 12016 } 12017 12018 RegisterInfo base_reg; 12019 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12020 12021 uint32_t Rn = ReadCoreReg(n, &success); 12022 if (!success) 12023 return false; 12024 12025 // address = R[n]; if (address MOD alignment) != 0 then 12026 // GenerateAlignmentException(); 12027 addr_t address = Rn; 12028 if ((address % alignment) != 0) 12029 return false; 12030 12031 EmulateInstruction::Context context; 12032 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12033 if (wback) { 12034 uint32_t Rm = ReadCoreReg(m, &success); 12035 if (!success) 12036 return false; 12037 12038 uint32_t offset; 12039 if (register_index) 12040 offset = Rm; 12041 else 12042 offset = 8 * regs; 12043 12044 uint32_t value = Rn + offset; 12045 context.type = eContextAdjustBaseRegister; 12046 context.SetRegisterPlusOffset(base_reg, offset); 12047 12048 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12049 value)) 12050 return false; 12051 } 12052 12053 // for r = 0 to regs-1 12054 for (uint32_t r = 0; r < regs; ++r) { 12055 // for e = 0 to elements-1 12056 uint64_t assembled_data = 0; 12057 for (uint32_t e = 0; e < elements; ++e) { 12058 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 12059 context.type = eContextRegisterLoad; 12060 context.SetRegisterPlusOffset(base_reg, address - Rn); 12061 uint64_t data = MemURead(context, address, ebytes, 0, &success); 12062 if (!success) 12063 return false; 12064 12065 assembled_data = 12066 (data << (e * esize)) | 12067 assembled_data; // New data goes to the left of existing data 12068 12069 // address = address + ebytes; 12070 address = address + ebytes; 12071 } 12072 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12073 assembled_data)) 12074 return false; 12075 } 12076 } 12077 return true; 12078} 12079 12080// A8.6.308 VLD1 (single element to one lane) 12081// 12082bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode, 12083 const ARMEncoding encoding) { 12084#if 0 12085 if ConditionPassed() then 12086 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12087 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12088 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12089 Elem[D[d],index,esize] = MemU[address,ebytes]; 12090#endif 12091 12092 bool success = false; 12093 12094 if (ConditionPassed(opcode)) { 12095 uint32_t ebytes; 12096 uint32_t esize; 12097 uint32_t index; 12098 uint32_t alignment; 12099 uint32_t d; 12100 uint32_t n; 12101 uint32_t m; 12102 bool wback; 12103 bool register_index; 12104 12105 switch (encoding) { 12106 case eEncodingT1: 12107 case eEncodingA1: { 12108 uint32_t size = Bits32(opcode, 11, 10); 12109 uint32_t index_align = Bits32(opcode, 7, 4); 12110 // if size == '11' then SEE VLD1 (single element to all lanes); 12111 if (size == 3) 12112 return EmulateVLD1SingleAll(opcode, encoding); 12113 // case size of 12114 if (size == 0) // when '00' 12115 { 12116 // if index_align<0> != '0' then UNDEFINED; 12117 if (BitIsClear(index_align, 0)) 12118 return false; 12119 12120 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12121 ebytes = 1; 12122 esize = 8; 12123 index = Bits32(index_align, 3, 1); 12124 alignment = 1; 12125 } else if (size == 1) // when '01' 12126 { 12127 // if index_align<1> != '0' then UNDEFINED; 12128 if (BitIsClear(index_align, 1)) 12129 return false; 12130 12131 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12132 ebytes = 2; 12133 esize = 16; 12134 index = Bits32(index_align, 3, 2); 12135 12136 // alignment = if index_align<0> == '0' then 1 else 2; 12137 if (BitIsClear(index_align, 0)) 12138 alignment = 1; 12139 else 12140 alignment = 2; 12141 } else if (size == 2) // when '10' 12142 { 12143 // if index_align<2> != '0' then UNDEFINED; 12144 if (BitIsClear(index_align, 2)) 12145 return false; 12146 12147 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12148 // UNDEFINED; 12149 if ((Bits32(index_align, 1, 0) != 0) && 12150 (Bits32(index_align, 1, 0) != 3)) 12151 return false; 12152 12153 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12154 ebytes = 4; 12155 esize = 32; 12156 index = Bit32(index_align, 3); 12157 12158 // alignment = if index_align<1:0> == '00' then 1 else 4; 12159 if (Bits32(index_align, 1, 0) == 0) 12160 alignment = 1; 12161 else 12162 alignment = 4; 12163 } else { 12164 return false; 12165 } 12166 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12167 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12168 n = Bits32(opcode, 19, 16); 12169 m = Bits32(opcode, 3, 0); 12170 12171 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12172 // then UNPREDICTABLE; 12173 wback = (m != 15); 12174 register_index = ((m != 15) && (m != 13)); 12175 12176 if (n == 15) 12177 return false; 12178 12179 } break; 12180 12181 default: 12182 return false; 12183 } 12184 12185 RegisterInfo base_reg; 12186 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12187 12188 uint32_t Rn = ReadCoreReg(n, &success); 12189 if (!success) 12190 return false; 12191 12192 // address = R[n]; if (address MOD alignment) != 0 then 12193 // GenerateAlignmentException(); 12194 addr_t address = Rn; 12195 if ((address % alignment) != 0) 12196 return false; 12197 12198 EmulateInstruction::Context context; 12199 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12200 if (wback) { 12201 uint32_t Rm = ReadCoreReg(m, &success); 12202 if (!success) 12203 return false; 12204 12205 uint32_t offset; 12206 if (register_index) 12207 offset = Rm; 12208 else 12209 offset = ebytes; 12210 12211 uint32_t value = Rn + offset; 12212 12213 context.type = eContextAdjustBaseRegister; 12214 context.SetRegisterPlusOffset(base_reg, offset); 12215 12216 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12217 value)) 12218 return false; 12219 } 12220 12221 // Elem[D[d],index,esize] = MemU[address,ebytes]; 12222 uint32_t element = MemURead(context, address, esize, 0, &success); 12223 if (!success) 12224 return false; 12225 12226 element = element << (index * esize); 12227 12228 uint64_t reg_data = 12229 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12230 if (!success) 12231 return false; 12232 12233 uint64_t all_ones = -1; 12234 uint64_t mask = all_ones 12235 << ((index + 1) * esize); // mask is all 1's to left of 12236 // where 'element' goes, & all 0's 12237 // at element & to the right of element. 12238 if (index > 0) 12239 mask = mask | Bits64(all_ones, (index * esize) - 1, 12240 0); // add 1's to the right of where 'element' goes. 12241 // now mask should be 0's where element goes & 1's everywhere else. 12242 12243 uint64_t masked_reg = 12244 reg_data & mask; // Take original reg value & zero out 'element' bits 12245 reg_data = 12246 masked_reg & element; // Put 'element' into those bits in reg_data. 12247 12248 context.type = eContextRegisterLoad; 12249 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 12250 reg_data)) 12251 return false; 12252 } 12253 return true; 12254} 12255 12256// A8.6.391 VST1 (multiple single elements) Vector Store (multiple single 12257// elements) stores elements to memory from one, two, three, or four registers, 12258// without interleaving. Every element of each register is stored. 12259bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode, 12260 ARMEncoding encoding) { 12261#if 0 12262 if ConditionPassed() then 12263 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12264 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12265 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12266 for r = 0 to regs-1 12267 for e = 0 to elements-1 12268 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12269 address = address + ebytes; 12270#endif 12271 12272 bool success = false; 12273 12274 if (ConditionPassed(opcode)) { 12275 uint32_t regs; 12276 uint32_t alignment; 12277 uint32_t ebytes; 12278 uint32_t esize; 12279 uint32_t elements; 12280 uint32_t d; 12281 uint32_t n; 12282 uint32_t m; 12283 bool wback; 12284 bool register_index; 12285 12286 switch (encoding) { 12287 case eEncodingT1: 12288 case eEncodingA1: { 12289 uint32_t type = Bits32(opcode, 11, 8); 12290 uint32_t align = Bits32(opcode, 5, 4); 12291 12292 // case type of 12293 if (type == 7) // when '0111' 12294 { 12295 // regs = 1; if align<1> == '1' then UNDEFINED; 12296 regs = 1; 12297 if (BitIsSet(align, 1)) 12298 return false; 12299 } else if (type == 10) // when '1010' 12300 { 12301 // regs = 2; if align == '11' then UNDEFINED; 12302 regs = 2; 12303 if (align == 3) 12304 return false; 12305 } else if (type == 6) // when '0110' 12306 { 12307 // regs = 3; if align<1> == '1' then UNDEFINED; 12308 regs = 3; 12309 if (BitIsSet(align, 1)) 12310 return false; 12311 } else if (type == 2) // when '0010' 12312 // regs = 4; 12313 regs = 4; 12314 else // otherwise 12315 // SEE 'Related encodings'; 12316 return false; 12317 12318 // alignment = if align == '00' then 1 else 4 << UInt(align); 12319 if (align == 0) 12320 alignment = 1; 12321 else 12322 alignment = 4 << align; 12323 12324 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 12325 ebytes = 1 << Bits32(opcode, 7, 6); 12326 esize = 8 * ebytes; 12327 elements = 8 / ebytes; 12328 12329 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12330 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12331 n = Bits32(opcode, 19, 16); 12332 m = Bits32(opcode, 3, 0); 12333 12334 // wback = (m != 15); register_index = (m != 15 && m != 13); 12335 wback = (m != 15); 12336 register_index = ((m != 15) && (m != 13)); 12337 12338 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12339 if ((d + regs) > 32) 12340 return false; 12341 12342 if (n == 15) 12343 return false; 12344 12345 } break; 12346 12347 default: 12348 return false; 12349 } 12350 12351 RegisterInfo base_reg; 12352 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12353 12354 uint32_t Rn = ReadCoreReg(n, &success); 12355 if (!success) 12356 return false; 12357 12358 // address = R[n]; if (address MOD alignment) != 0 then 12359 // GenerateAlignmentException(); 12360 addr_t address = Rn; 12361 if ((address % alignment) != 0) 12362 return false; 12363 12364 EmulateInstruction::Context context; 12365 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12366 if (wback) { 12367 uint32_t Rm = ReadCoreReg(m, &success); 12368 if (!success) 12369 return false; 12370 12371 uint32_t offset; 12372 if (register_index) 12373 offset = Rm; 12374 else 12375 offset = 8 * regs; 12376 12377 context.type = eContextAdjustBaseRegister; 12378 context.SetRegisterPlusOffset(base_reg, offset); 12379 12380 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12381 Rn + offset)) 12382 return false; 12383 } 12384 12385 RegisterInfo data_reg; 12386 context.type = eContextRegisterStore; 12387 // for r = 0 to regs-1 12388 for (uint32_t r = 0; r < regs; ++r) { 12389 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 12390 uint64_t register_data = ReadRegisterUnsigned( 12391 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 12392 if (!success) 12393 return false; 12394 12395 // for e = 0 to elements-1 12396 for (uint32_t e = 0; e < elements; ++e) { 12397 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12398 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize); 12399 12400 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12401 address - Rn); 12402 if (!MemUWrite(context, address, word, ebytes)) 12403 return false; 12404 12405 // address = address + ebytes; 12406 address = address + ebytes; 12407 } 12408 } 12409 } 12410 return true; 12411} 12412 12413// A8.6.392 VST1 (single element from one lane) This instruction stores one 12414// element to memory from one element of a register. 12415bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode, 12416 ARMEncoding encoding) { 12417#if 0 12418 if ConditionPassed() then 12419 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12420 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12421 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12422 MemU[address,ebytes] = Elem[D[d],index,esize]; 12423#endif 12424 12425 bool success = false; 12426 12427 if (ConditionPassed(opcode)) { 12428 uint32_t ebytes; 12429 uint32_t esize; 12430 uint32_t index; 12431 uint32_t alignment; 12432 uint32_t d; 12433 uint32_t n; 12434 uint32_t m; 12435 bool wback; 12436 bool register_index; 12437 12438 switch (encoding) { 12439 case eEncodingT1: 12440 case eEncodingA1: { 12441 uint32_t size = Bits32(opcode, 11, 10); 12442 uint32_t index_align = Bits32(opcode, 7, 4); 12443 12444 // if size == '11' then UNDEFINED; 12445 if (size == 3) 12446 return false; 12447 12448 // case size of 12449 if (size == 0) // when '00' 12450 { 12451 // if index_align<0> != '0' then UNDEFINED; 12452 if (BitIsClear(index_align, 0)) 12453 return false; 12454 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12455 ebytes = 1; 12456 esize = 8; 12457 index = Bits32(index_align, 3, 1); 12458 alignment = 1; 12459 } else if (size == 1) // when '01' 12460 { 12461 // if index_align<1> != '0' then UNDEFINED; 12462 if (BitIsClear(index_align, 1)) 12463 return false; 12464 12465 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12466 ebytes = 2; 12467 esize = 16; 12468 index = Bits32(index_align, 3, 2); 12469 12470 // alignment = if index_align<0> == '0' then 1 else 2; 12471 if (BitIsClear(index_align, 0)) 12472 alignment = 1; 12473 else 12474 alignment = 2; 12475 } else if (size == 2) // when '10' 12476 { 12477 // if index_align<2> != '0' then UNDEFINED; 12478 if (BitIsClear(index_align, 2)) 12479 return false; 12480 12481 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12482 // UNDEFINED; 12483 if ((Bits32(index_align, 1, 0) != 0) && 12484 (Bits32(index_align, 1, 0) != 3)) 12485 return false; 12486 12487 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12488 ebytes = 4; 12489 esize = 32; 12490 index = Bit32(index_align, 3); 12491 12492 // alignment = if index_align<1:0> == '00' then 1 else 4; 12493 if (Bits32(index_align, 1, 0) == 0) 12494 alignment = 1; 12495 else 12496 alignment = 4; 12497 } else { 12498 return false; 12499 } 12500 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12501 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12502 n = Bits32(opcode, 19, 16); 12503 m = Bits32(opcode, 3, 0); 12504 12505 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12506 // then UNPREDICTABLE; 12507 wback = (m != 15); 12508 register_index = ((m != 15) && (m != 13)); 12509 12510 if (n == 15) 12511 return false; 12512 } break; 12513 12514 default: 12515 return false; 12516 } 12517 12518 RegisterInfo base_reg; 12519 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12520 12521 uint32_t Rn = ReadCoreReg(n, &success); 12522 if (!success) 12523 return false; 12524 12525 // address = R[n]; if (address MOD alignment) != 0 then 12526 // GenerateAlignmentException(); 12527 addr_t address = Rn; 12528 if ((address % alignment) != 0) 12529 return false; 12530 12531 EmulateInstruction::Context context; 12532 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12533 if (wback) { 12534 uint32_t Rm = ReadCoreReg(m, &success); 12535 if (!success) 12536 return false; 12537 12538 uint32_t offset; 12539 if (register_index) 12540 offset = Rm; 12541 else 12542 offset = ebytes; 12543 12544 context.type = eContextAdjustBaseRegister; 12545 context.SetRegisterPlusOffset(base_reg, offset); 12546 12547 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12548 Rn + offset)) 12549 return false; 12550 } 12551 12552 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12553 uint64_t register_data = 12554 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12555 if (!success) 12556 return false; 12557 12558 uint64_t word = 12559 Bits64(register_data, ((index + 1) * esize) - 1, index * esize); 12560 12561 RegisterInfo data_reg; 12562 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12563 context.type = eContextRegisterStore; 12564 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 12565 12566 if (!MemUWrite(context, address, word, ebytes)) 12567 return false; 12568 } 12569 return true; 12570} 12571 12572// A8.6.309 VLD1 (single element to all lanes) This instruction loads one 12573// element from memory into every element of one or two vectors. 12574bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode, 12575 const ARMEncoding encoding) { 12576#if 0 12577 if ConditionPassed() then 12578 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12579 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12580 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12581 replicated_element = Replicate(MemU[address,ebytes], elements); 12582 for r = 0 to regs-1 12583 D[d+r] = replicated_element; 12584#endif 12585 12586 bool success = false; 12587 12588 if (ConditionPassed(opcode)) { 12589 uint32_t ebytes; 12590 uint32_t elements; 12591 uint32_t regs; 12592 uint32_t alignment; 12593 uint32_t d; 12594 uint32_t n; 12595 uint32_t m; 12596 bool wback; 12597 bool register_index; 12598 12599 switch (encoding) { 12600 case eEncodingT1: 12601 case eEncodingA1: { 12602 // if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12603 uint32_t size = Bits32(opcode, 7, 6); 12604 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4))) 12605 return false; 12606 12607 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' 12608 // then 1 else 2; 12609 ebytes = 1 << size; 12610 elements = 8 / ebytes; 12611 if (BitIsClear(opcode, 5)) 12612 regs = 1; 12613 else 12614 regs = 2; 12615 12616 // alignment = if a == '0' then 1 else ebytes; 12617 if (BitIsClear(opcode, 4)) 12618 alignment = 1; 12619 else 12620 alignment = ebytes; 12621 12622 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12623 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12624 n = Bits32(opcode, 19, 16); 12625 m = Bits32(opcode, 3, 0); 12626 12627 // wback = (m != 15); register_index = (m != 15 && m != 13); 12628 wback = (m != 15); 12629 register_index = ((m != 15) && (m != 13)); 12630 12631 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12632 if ((d + regs) > 32) 12633 return false; 12634 12635 if (n == 15) 12636 return false; 12637 } break; 12638 12639 default: 12640 return false; 12641 } 12642 12643 RegisterInfo base_reg; 12644 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12645 12646 uint32_t Rn = ReadCoreReg(n, &success); 12647 if (!success) 12648 return false; 12649 12650 // address = R[n]; if (address MOD alignment) != 0 then 12651 // GenerateAlignmentException(); 12652 addr_t address = Rn; 12653 if ((address % alignment) != 0) 12654 return false; 12655 12656 EmulateInstruction::Context context; 12657 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12658 if (wback) { 12659 uint32_t Rm = ReadCoreReg(m, &success); 12660 if (!success) 12661 return false; 12662 12663 uint32_t offset; 12664 if (register_index) 12665 offset = Rm; 12666 else 12667 offset = ebytes; 12668 12669 context.type = eContextAdjustBaseRegister; 12670 context.SetRegisterPlusOffset(base_reg, offset); 12671 12672 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12673 Rn + offset)) 12674 return false; 12675 } 12676 12677 // replicated_element = Replicate(MemU[address,ebytes], elements); 12678 12679 context.type = eContextRegisterLoad; 12680 uint64_t word = MemURead(context, address, ebytes, 0, &success); 12681 if (!success) 12682 return false; 12683 12684 uint64_t replicated_element = 0; 12685 uint32_t esize = ebytes * 8; 12686 for (uint32_t e = 0; e < elements; ++e) 12687 replicated_element = 12688 (replicated_element << esize) | Bits64(word, esize - 1, 0); 12689 12690 // for r = 0 to regs-1 12691 for (uint32_t r = 0; r < regs; ++r) { 12692 // D[d+r] = replicated_element; 12693 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12694 replicated_element)) 12695 return false; 12696 } 12697 } 12698 return true; 12699} 12700 12701// B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const? 12702// instruction provides an exception return without the use of the stack. It 12703// subtracts the immediate constant from the LR, branches to the resulting 12704// address, and also copies the SPSR to the CPSR. 12705bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode, 12706 const ARMEncoding encoding) { 12707#if 0 12708 if ConditionPassed() then 12709 EncodingSpecificOperations(); 12710 if CurrentInstrSet() == InstrSet_ThumbEE then 12711 UNPREDICTABLE; 12712 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12713 case opcode of 12714 when '0000' result = R[n] AND operand2; // AND 12715 when '0001' result = R[n] EOR operand2; // EOR 12716 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12717 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12718 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12719 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12720 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12721 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12722 when '1100' result = R[n] OR operand2; // ORR 12723 when '1101' result = operand2; // MOV 12724 when '1110' result = R[n] AND NOT(operand2); // BIC 12725 when '1111' result = NOT(operand2); // MVN 12726 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12727 BranchWritePC(result); 12728#endif 12729 12730 bool success = false; 12731 12732 if (ConditionPassed(opcode)) { 12733 uint32_t n; 12734 uint32_t m; 12735 uint32_t imm32; 12736 bool register_form; 12737 ARM_ShifterType shift_t; 12738 uint32_t shift_n; 12739 uint32_t code; 12740 12741 switch (encoding) { 12742 case eEncodingT1: 12743 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14; 12744 // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; 12745 // // = SUB 12746 n = 14; 12747 imm32 = Bits32(opcode, 7, 0); 12748 register_form = false; 12749 code = 2; 12750 12751 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12752 if (InITBlock() && !LastInITBlock()) 12753 return false; 12754 12755 break; 12756 12757 case eEncodingA1: 12758 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12759 n = Bits32(opcode, 19, 16); 12760 imm32 = ARMExpandImm(opcode); 12761 register_form = false; 12762 code = Bits32(opcode, 24, 21); 12763 12764 break; 12765 12766 case eEncodingA2: 12767 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12768 n = Bits32(opcode, 19, 16); 12769 m = Bits32(opcode, 3, 0); 12770 register_form = true; 12771 12772 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12773 shift_n = DecodeImmShiftARM(opcode, shift_t); 12774 12775 break; 12776 12777 default: 12778 return false; 12779 } 12780 12781 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) 12782 // else imm32; 12783 uint32_t operand2; 12784 if (register_form) { 12785 uint32_t Rm = ReadCoreReg(m, &success); 12786 if (!success) 12787 return false; 12788 12789 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success); 12790 if (!success) 12791 return false; 12792 } else { 12793 operand2 = imm32; 12794 } 12795 12796 uint32_t Rn = ReadCoreReg(n, &success); 12797 if (!success) 12798 return false; 12799 12800 AddWithCarryResult result; 12801 12802 // case opcode of 12803 switch (code) { 12804 case 0: // when '0000' 12805 // result = R[n] AND operand2; // AND 12806 result.result = Rn & operand2; 12807 break; 12808 12809 case 1: // when '0001' 12810 // result = R[n] EOR operand2; // EOR 12811 result.result = Rn ^ operand2; 12812 break; 12813 12814 case 2: // when '0010' 12815 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12816 result = AddWithCarry(Rn, ~(operand2), 1); 12817 break; 12818 12819 case 3: // when '0011' 12820 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12821 result = AddWithCarry(~(Rn), operand2, 1); 12822 break; 12823 12824 case 4: // when '0100' 12825 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12826 result = AddWithCarry(Rn, operand2, 0); 12827 break; 12828 12829 case 5: // when '0101' 12830 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12831 result = AddWithCarry(Rn, operand2, APSR_C); 12832 break; 12833 12834 case 6: // when '0110' 12835 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12836 result = AddWithCarry(Rn, ~(operand2), APSR_C); 12837 break; 12838 12839 case 7: // when '0111' 12840 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12841 result = AddWithCarry(~(Rn), operand2, APSR_C); 12842 break; 12843 12844 case 10: // when '1100' 12845 // result = R[n] OR operand2; // ORR 12846 result.result = Rn | operand2; 12847 break; 12848 12849 case 11: // when '1101' 12850 // result = operand2; // MOV 12851 result.result = operand2; 12852 break; 12853 12854 case 12: // when '1110' 12855 // result = R[n] AND NOT(operand2); // BIC 12856 result.result = Rn & ~(operand2); 12857 break; 12858 12859 case 15: // when '1111' 12860 // result = NOT(operand2); // MVN 12861 result.result = ~(operand2); 12862 break; 12863 12864 default: 12865 return false; 12866 } 12867 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12868 12869 // For now, in emulation mode, we don't have access to the SPSR, so we will 12870 // use the CPSR instead, and hope for the best. 12871 uint32_t spsr = 12872 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12873 if (!success) 12874 return false; 12875 12876 CPSRWriteByInstr(spsr, 15, true); 12877 12878 // BranchWritePC(result); 12879 EmulateInstruction::Context context; 12880 context.type = eContextAdjustPC; 12881 context.SetImmediate(result.result); 12882 12883 BranchWritePC(context, result.result); 12884 } 12885 return true; 12886} 12887 12888EmulateInstructionARM::ARMOpcode * 12889EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode, 12890 uint32_t arm_isa) { 12891 static ARMOpcode g_arm_opcodes[] = { 12892 //---------------------------------------------------------------------- 12893 // Prologue instructions 12894 //---------------------------------------------------------------------- 12895 12896 // push register(s) 12897 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12898 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 12899 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12900 &EmulateInstructionARM::EmulatePUSH, "push <register>"}, 12901 12902 // set r7 to point to a stack offset 12903 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12904 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"}, 12905 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12906 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12907 // copy the stack pointer to ip 12908 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, 12909 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"}, 12910 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12911 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"}, 12912 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12913 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12914 12915 // adjust the stack pointer 12916 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12917 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12918 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12919 &EmulateInstructionARM::EmulateSUBSPReg, 12920 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 12921 12922 // push one register 12923 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12924 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12925 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"}, 12926 12927 // vector push consecutive extension register(s) 12928 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12929 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12930 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12931 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12932 12933 //---------------------------------------------------------------------- 12934 // Epilogue instructions 12935 //---------------------------------------------------------------------- 12936 12937 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12938 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12939 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12940 &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12941 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12942 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12943 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12944 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12945 12946 //---------------------------------------------------------------------- 12947 // Supervisor Call (previously Software Interrupt) 12948 //---------------------------------------------------------------------- 12949 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12950 &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12951 12952 //---------------------------------------------------------------------- 12953 // Branch instructions 12954 //---------------------------------------------------------------------- 12955 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and 12956 // "bl <label>". 12957 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, 12958 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12959 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12960 &EmulateInstructionARM::EmulateB, "b #imm24"}, 12961 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12962 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12963 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, 12964 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12965 // for example, "bx lr" 12966 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, 12967 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12968 // bxj 12969 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, 12970 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12971 12972 //---------------------------------------------------------------------- 12973 // Data-processing instructions 12974 //---------------------------------------------------------------------- 12975 // adc (immediate) 12976 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12977 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12978 // adc (register) 12979 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12980 &EmulateInstructionARM::EmulateADCReg, 12981 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12982 // add (immediate) 12983 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12984 &EmulateInstructionARM::EmulateADDImmARM, 12985 "add{s}<c> <Rd>, <Rn>, #const"}, 12986 // add (register) 12987 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12988 &EmulateInstructionARM::EmulateADDReg, 12989 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12990 // add (register-shifted register) 12991 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, 12992 &EmulateInstructionARM::EmulateADDRegShift, 12993 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12994 // adr 12995 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12996 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12997 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, 12998 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12999 // and (immediate) 13000 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13001 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 13002 // and (register) 13003 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13004 &EmulateInstructionARM::EmulateANDReg, 13005 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13006 // bic (immediate) 13007 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13008 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 13009 // bic (register) 13010 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13011 &EmulateInstructionARM::EmulateBICReg, 13012 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13013 // eor (immediate) 13014 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13015 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 13016 // eor (register) 13017 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13018 &EmulateInstructionARM::EmulateEORReg, 13019 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13020 // orr (immediate) 13021 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13022 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 13023 // orr (register) 13024 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13025 &EmulateInstructionARM::EmulateORRReg, 13026 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13027 // rsb (immediate) 13028 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13029 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 13030 // rsb (register) 13031 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13032 &EmulateInstructionARM::EmulateRSBReg, 13033 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13034 // rsc (immediate) 13035 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13036 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 13037 // rsc (register) 13038 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13039 &EmulateInstructionARM::EmulateRSCReg, 13040 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13041 // sbc (immediate) 13042 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13043 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13044 // sbc (register) 13045 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13046 &EmulateInstructionARM::EmulateSBCReg, 13047 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13048 // sub (immediate, ARM) 13049 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13050 &EmulateInstructionARM::EmulateSUBImmARM, 13051 "sub{s}<c> <Rd>, <Rn>, #<const>"}, 13052 // sub (sp minus immediate) 13053 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13054 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 13055 // sub (register) 13056 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13057 &EmulateInstructionARM::EmulateSUBReg, 13058 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 13059 // teq (immediate) 13060 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13061 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 13062 // teq (register) 13063 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13064 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13065 // tst (immediate) 13066 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13067 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 13068 // tst (register) 13069 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13070 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 13071 13072 // mov (immediate) 13073 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13074 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 13075 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 13076 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"}, 13077 // mov (register) 13078 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13079 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 13080 // mvn (immediate) 13081 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13082 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 13083 // mvn (register) 13084 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13085 &EmulateInstructionARM::EmulateMVNReg, 13086 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 13087 // cmn (immediate) 13088 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13089 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13090 // cmn (register) 13091 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13092 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13093 // cmp (immediate) 13094 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13095 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 13096 // cmp (register) 13097 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13098 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 13099 // asr (immediate) 13100 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, 13101 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 13102 // asr (register) 13103 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13104 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 13105 // lsl (immediate) 13106 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13107 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 13108 // lsl (register) 13109 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, 13110 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 13111 // lsr (immediate) 13112 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, 13113 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 13114 // lsr (register) 13115 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13116 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 13117 // rrx is a special case encoding of ror (immediate) 13118 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13119 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 13120 // ror (immediate) 13121 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13122 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 13123 // ror (register) 13124 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, 13125 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 13126 // mul 13127 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, 13128 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"}, 13129 13130 // subs pc, lr and related instructions 13131 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13132 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13133 "<opc>S<c> PC,#<const> | <Rn>,#<const>"}, 13134 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, 13135 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13136 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"}, 13137 13138 //---------------------------------------------------------------------- 13139 // Load instructions 13140 //---------------------------------------------------------------------- 13141 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13142 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13143 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13144 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"}, 13145 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13146 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13147 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13148 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"}, 13149 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13150 &EmulateInstructionARM::EmulateLDRImmediateARM, 13151 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"}, 13152 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13153 &EmulateInstructionARM::EmulateLDRRegister, 13154 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"}, 13155 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13156 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 13157 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13158 &EmulateInstructionARM::EmulateLDRBRegister, 13159 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"}, 13160 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13161 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13162 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13163 &EmulateInstructionARM::EmulateLDRHRegister, 13164 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13165 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13166 &EmulateInstructionARM::EmulateLDRSBImmediate, 13167 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"}, 13168 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13169 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"}, 13170 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13171 &EmulateInstructionARM::EmulateLDRSBRegister, 13172 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13173 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13174 &EmulateInstructionARM::EmulateLDRSHImmediate, 13175 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 13176 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13177 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13178 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13179 &EmulateInstructionARM::EmulateLDRSHRegister, 13180 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13181 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13182 &EmulateInstructionARM::EmulateLDRDImmediate, 13183 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 13184 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13185 &EmulateInstructionARM::EmulateLDRDRegister, 13186 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13187 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13188 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13189 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13190 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13191 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13192 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13193 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13194 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13195 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13196 &EmulateInstructionARM::EmulateVLD1Multiple, 13197 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13198 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13199 &EmulateInstructionARM::EmulateVLD1Single, 13200 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13201 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13202 &EmulateInstructionARM::EmulateVLD1SingleAll, 13203 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13204 13205 //---------------------------------------------------------------------- 13206 // Store instructions 13207 //---------------------------------------------------------------------- 13208 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13209 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13210 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13211 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"}, 13212 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13213 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13214 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13215 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"}, 13216 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13217 &EmulateInstructionARM::EmulateSTRRegister, 13218 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"}, 13219 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13220 &EmulateInstructionARM::EmulateSTRHRegister, 13221 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"}, 13222 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13223 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 13224 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13225 &EmulateInstructionARM::EmulateSTRBImmARM, 13226 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13227 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13228 &EmulateInstructionARM::EmulateSTRImmARM, 13229 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13230 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13231 &EmulateInstructionARM::EmulateSTRDImm, 13232 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 13233 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13234 &EmulateInstructionARM::EmulateSTRDReg, 13235 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13236 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13237 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13238 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13239 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13240 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13241 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 13242 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13243 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 13244 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13245 &EmulateInstructionARM::EmulateVST1Multiple, 13246 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13247 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13248 &EmulateInstructionARM::EmulateVST1Single, 13249 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13250 13251 //---------------------------------------------------------------------- 13252 // Other instructions 13253 //---------------------------------------------------------------------- 13254 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13255 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13256 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13257 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"}, 13258 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13259 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13260 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13261 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"}, 13262 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13263 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"} 13264 13265 }; 13266 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 13267 13268 for (size_t i = 0; i < k_num_arm_opcodes; ++i) { 13269 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 13270 (g_arm_opcodes[i].variants & arm_isa) != 0) 13271 return &g_arm_opcodes[i]; 13272 } 13273 return NULL; 13274} 13275 13276EmulateInstructionARM::ARMOpcode * 13277EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode, 13278 uint32_t arm_isa) { 13279 13280 static ARMOpcode g_thumb_opcodes[] = { 13281 //---------------------------------------------------------------------- 13282 // Prologue instructions 13283 //---------------------------------------------------------------------- 13284 13285 // push register(s) 13286 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, 13287 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 13288 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13289 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"}, 13290 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13291 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"}, 13292 13293 // set r7 to point to a stack offset 13294 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13295 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"}, 13296 // copy the stack pointer to r7 13297 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, 13298 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"}, 13299 // move from high register to low register (comes after "mov r7, sp" to 13300 // resolve ambiguity) 13301 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, 13302 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"}, 13303 13304 // PC-relative load into register (see also EmulateADDSPRm) 13305 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13306 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 13307 13308 // adjust the stack pointer 13309 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, 13310 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 13311 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13312 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 13313 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13314 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 13315 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13316 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 13317 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13318 &EmulateInstructionARM::EmulateSUBSPReg, 13319 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 13320 13321 // vector push consecutive extension register(s) 13322 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13323 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 13324 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13325 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 13326 13327 //---------------------------------------------------------------------- 13328 // Epilogue instructions 13329 //---------------------------------------------------------------------- 13330 13331 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13332 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 13333 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13334 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 13335 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13336 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 13337 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13338 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"}, 13339 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13340 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"}, 13341 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13342 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 13343 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13344 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 13345 13346 //---------------------------------------------------------------------- 13347 // Supervisor Call (previously Software Interrupt) 13348 //---------------------------------------------------------------------- 13349 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13350 &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 13351 13352 //---------------------------------------------------------------------- 13353 // If Then makes up to four following instructions conditional. 13354 //---------------------------------------------------------------------- 13355 // The next 5 opcode _must_ come before the if then instruction 13356 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13357 &EmulateInstructionARM::EmulateNop, "nop"}, 13358 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13359 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 13360 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13361 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 13362 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13363 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 13364 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13365 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 13366 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13367 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 13368 13369 //---------------------------------------------------------------------- 13370 // Branch instructions 13371 //---------------------------------------------------------------------- 13372 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 13373 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13374 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 13375 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13376 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 13377 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13378 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 13379 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13380 &EmulateInstructionARM::EmulateB, 13381 "b<c>.w #imm8 (outside or last in IT)"}, 13382 // J1 == J2 == 1 13383 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, 13384 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 13385 // J1 == J2 == 1 13386 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, 13387 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 13388 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, 13389 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 13390 // for example, "bx lr" 13391 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, 13392 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 13393 // bxj 13394 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, 13395 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 13396 // compare and branch 13397 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13398 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 13399 // table branch byte 13400 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13401 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 13402 // table branch halfword 13403 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13404 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 13405 13406 //---------------------------------------------------------------------- 13407 // Data-processing instructions 13408 //---------------------------------------------------------------------- 13409 // adc (immediate) 13410 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13411 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 13412 // adc (register) 13413 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, 13414 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 13415 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13416 &EmulateInstructionARM::EmulateADCReg, 13417 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13418 // add (register) 13419 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13420 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 13421 // Make sure "add sp, <Rm>" comes before this instruction, so there's no 13422 // ambiguity decoding the two. 13423 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, 13424 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 13425 // adr 13426 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13427 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13428 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13429 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 13430 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13431 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13432 // and (immediate) 13433 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13434 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 13435 // and (register) 13436 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13437 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 13438 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13439 &EmulateInstructionARM::EmulateANDReg, 13440 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13441 // bic (immediate) 13442 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13443 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 13444 // bic (register) 13445 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, 13446 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 13447 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13448 &EmulateInstructionARM::EmulateBICReg, 13449 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13450 // eor (immediate) 13451 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13452 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 13453 // eor (register) 13454 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, 13455 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 13456 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13457 &EmulateInstructionARM::EmulateEORReg, 13458 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13459 // orr (immediate) 13460 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13461 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 13462 // orr (register) 13463 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, 13464 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 13465 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13466 &EmulateInstructionARM::EmulateORRReg, 13467 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13468 // rsb (immediate) 13469 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, 13470 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 13471 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13472 &EmulateInstructionARM::EmulateRSBImm, 13473 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 13474 // rsb (register) 13475 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13476 &EmulateInstructionARM::EmulateRSBReg, 13477 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13478 // sbc (immediate) 13479 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13480 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13481 // sbc (register) 13482 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, 13483 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 13484 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13485 &EmulateInstructionARM::EmulateSBCReg, 13486 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13487 // add (immediate, Thumb) 13488 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13489 &EmulateInstructionARM::EmulateADDImmThumb, 13490 "adds|add<c> <Rd>,<Rn>,#<imm3>"}, 13491 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13492 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"}, 13493 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13494 &EmulateInstructionARM::EmulateADDImmThumb, 13495 "add{s}<c>.w <Rd>,<Rn>,#<const>"}, 13496 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13497 &EmulateInstructionARM::EmulateADDImmThumb, 13498 "addw<c> <Rd>,<Rn>,#<imm12>"}, 13499 // sub (immediate, Thumb) 13500 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13501 &EmulateInstructionARM::EmulateSUBImmThumb, 13502 "subs|sub<c> <Rd>, <Rn> #imm3"}, 13503 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, 13504 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 13505 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13506 &EmulateInstructionARM::EmulateSUBImmThumb, 13507 "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 13508 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13509 &EmulateInstructionARM::EmulateSUBImmThumb, 13510 "subw<c> <Rd>, <Rn>, #imm12"}, 13511 // sub (sp minus immediate) 13512 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13513 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 13514 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13515 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 13516 // sub (register) 13517 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13518 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 13519 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13520 &EmulateInstructionARM::EmulateSUBReg, 13521 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 13522 // teq (immediate) 13523 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13524 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 13525 // teq (register) 13526 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13527 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13528 // tst (immediate) 13529 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13530 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 13531 // tst (register) 13532 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, 13533 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 13534 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13535 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 13536 13537 // move from high register to high register 13538 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, 13539 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 13540 // move from low register to low register 13541 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13542 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 13543 // mov{s}<c>.w <Rd>, <Rm> 13544 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13545 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 13546 // move immediate 13547 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13548 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 13549 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13550 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 13551 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13552 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 13553 // mvn (immediate) 13554 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13555 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 13556 // mvn (register) 13557 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13558 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 13559 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13560 &EmulateInstructionARM::EmulateMVNReg, 13561 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 13562 // cmn (immediate) 13563 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13564 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13565 // cmn (register) 13566 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13567 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 13568 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13569 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13570 // cmp (immediate) 13571 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13572 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 13573 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13574 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 13575 // cmp (register) (Rn and Rm both from r0-r7) 13576 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, 13577 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13578 // cmp (register) (Rn and Rm not both from r0-r7) 13579 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, 13580 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13581 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, 13582 &EmulateInstructionARM::EmulateCMPReg, 13583 "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 13584 // asr (immediate) 13585 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13586 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 13587 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13588 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 13589 // asr (register) 13590 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, 13591 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 13592 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13593 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13594 // lsl (immediate) 13595 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13596 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 13597 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13598 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 13599 // lsl (register) 13600 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13601 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 13602 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13603 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13604 // lsr (immediate) 13605 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13606 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 13607 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13608 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 13609 // lsr (register) 13610 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13611 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 13612 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13613 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13614 // rrx is a special case encoding of ror (immediate) 13615 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13616 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 13617 // ror (immediate) 13618 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13619 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 13620 // ror (register) 13621 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13622 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 13623 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13624 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13625 // mul 13626 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13627 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"}, 13628 // mul 13629 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13630 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"}, 13631 13632 // subs pc, lr and related instructions 13633 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13634 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"}, 13635 13636 //---------------------------------------------------------------------- 13637 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE 13638 // LDM.. Instructions in this table; 13639 // otherwise the wrong instructions will be selected. 13640 //---------------------------------------------------------------------- 13641 13642 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13643 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"}, 13644 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13645 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"}, 13646 13647 //---------------------------------------------------------------------- 13648 // Load instructions 13649 //---------------------------------------------------------------------- 13650 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13651 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13652 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13653 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"}, 13654 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13655 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13656 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13657 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 13658 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13659 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 13660 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13661 &EmulateInstructionARM::EmulateLDRRtRnImm, 13662 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 13663 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13664 &EmulateInstructionARM::EmulateLDRRtRnImm, 13665 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 13666 // Thumb2 PC-relative load into register 13667 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13668 &EmulateInstructionARM::EmulateLDRRtPCRelative, 13669 "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 13670 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13671 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"}, 13672 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13673 &EmulateInstructionARM::EmulateLDRRegister, 13674 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"}, 13675 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13676 &EmulateInstructionARM::EmulateLDRBImmediate, 13677 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"}, 13678 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13679 &EmulateInstructionARM::EmulateLDRBImmediate, 13680 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13681 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13682 &EmulateInstructionARM::EmulateLDRBImmediate, 13683 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"}, 13684 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13685 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"}, 13686 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13687 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"}, 13688 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13689 &EmulateInstructionARM::EmulateLDRBRegister, 13690 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13691 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13692 &EmulateInstructionARM::EmulateLDRHImmediate, 13693 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"}, 13694 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13695 &EmulateInstructionARM::EmulateLDRHImmediate, 13696 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13697 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13698 &EmulateInstructionARM::EmulateLDRHImmediate, 13699 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"}, 13700 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13701 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13702 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13703 &EmulateInstructionARM::EmulateLDRHRegister, 13704 "ldrh<c> <Rt>, [<Rn>,<Rm>]"}, 13705 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13706 &EmulateInstructionARM::EmulateLDRHRegister, 13707 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13708 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13709 &EmulateInstructionARM::EmulateLDRSBImmediate, 13710 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"}, 13711 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13712 &EmulateInstructionARM::EmulateLDRSBImmediate, 13713 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13714 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13715 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"}, 13716 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13717 &EmulateInstructionARM::EmulateLDRSBRegister, 13718 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"}, 13719 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13720 &EmulateInstructionARM::EmulateLDRSBRegister, 13721 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13722 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13723 &EmulateInstructionARM::EmulateLDRSHImmediate, 13724 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"}, 13725 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13726 &EmulateInstructionARM::EmulateLDRSHImmediate, 13727 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13728 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13729 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13730 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13731 &EmulateInstructionARM::EmulateLDRSHRegister, 13732 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"}, 13733 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13734 &EmulateInstructionARM::EmulateLDRSHRegister, 13735 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13736 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13737 &EmulateInstructionARM::EmulateLDRDImmediate, 13738 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 13739 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13740 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13741 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13742 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13743 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13744 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13745 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13746 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 13747 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13748 &EmulateInstructionARM::EmulateVLD1Multiple, 13749 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13750 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13751 &EmulateInstructionARM::EmulateVLD1Single, 13752 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13753 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13754 &EmulateInstructionARM::EmulateVLD1SingleAll, 13755 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13756 13757 //---------------------------------------------------------------------- 13758 // Store instructions 13759 //---------------------------------------------------------------------- 13760 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13761 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13762 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13763 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"}, 13764 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13765 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13766 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13767 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"}, 13768 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13769 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"}, 13770 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13771 &EmulateInstructionARM::EmulateSTRThumb, 13772 "str<c>.w <Rt>, [<Rn>,#<imm12>]"}, 13773 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13774 &EmulateInstructionARM::EmulateSTRThumb, 13775 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"}, 13776 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13777 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"}, 13778 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13779 &EmulateInstructionARM::EmulateSTRRegister, 13780 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"}, 13781 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13782 &EmulateInstructionARM::EmulateSTRBThumb, 13783 "strb<c> <Rt>, [<Rn>, #<imm5>]"}, 13784 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13785 &EmulateInstructionARM::EmulateSTRBThumb, 13786 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"}, 13787 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13788 &EmulateInstructionARM::EmulateSTRBThumb, 13789 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"}, 13790 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13791 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"}, 13792 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13793 &EmulateInstructionARM::EmulateSTRHRegister, 13794 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13795 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13796 &EmulateInstructionARM::EmulateSTREX, 13797 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"}, 13798 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13799 &EmulateInstructionARM::EmulateSTRDImm, 13800 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 13801 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13802 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13803 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13804 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13805 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13806 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13807 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13808 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13809 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13810 &EmulateInstructionARM::EmulateVST1Multiple, 13811 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13812 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13813 &EmulateInstructionARM::EmulateVST1Single, 13814 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13815 13816 //---------------------------------------------------------------------- 13817 // Other instructions 13818 //---------------------------------------------------------------------- 13819 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13820 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"}, 13821 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, 13822 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13823 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13824 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"}, 13825 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13826 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13827 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13828 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"}, 13829 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13830 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13831 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13832 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"}, 13833 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13834 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13835 }; 13836 13837 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 13838 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) { 13839 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 13840 (g_thumb_opcodes[i].variants & arm_isa) != 0) 13841 return &g_thumb_opcodes[i]; 13842 } 13843 return NULL; 13844} 13845 13846bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) { 13847 m_arch = arch; 13848 m_arm_isa = 0; 13849 const char *arch_cstr = arch.GetArchitectureName(); 13850 if (arch_cstr) { 13851 if (0 == ::strcasecmp(arch_cstr, "armv4t")) 13852 m_arm_isa = ARMv4T; 13853 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) 13854 m_arm_isa = ARMv5TEJ; 13855 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) 13856 m_arm_isa = ARMv5TE; 13857 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) 13858 m_arm_isa = ARMv5T; 13859 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) 13860 m_arm_isa = ARMv6K; 13861 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) 13862 m_arm_isa = ARMv6T2; 13863 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) 13864 m_arm_isa = ARMv7S; 13865 else if (0 == ::strcasecmp(arch_cstr, "arm")) 13866 m_arm_isa = ARMvAll; 13867 else if (0 == ::strcasecmp(arch_cstr, "thumb")) 13868 m_arm_isa = ARMvAll; 13869 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5)) 13870 m_arm_isa = ARMv4; 13871 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5)) 13872 m_arm_isa = ARMv6; 13873 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5)) 13874 m_arm_isa = ARMv7; 13875 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5)) 13876 m_arm_isa = ARMv8; 13877 } 13878 return m_arm_isa != 0; 13879} 13880 13881bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode, 13882 const Address &inst_addr, 13883 Target *target) { 13884 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { 13885 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || 13886 m_arch.IsAlwaysThumbInstructions()) 13887 m_opcode_mode = eModeThumb; 13888 else { 13889 AddressClass addr_class = inst_addr.GetAddressClass(); 13890 13891 if ((addr_class == AddressClass::eCode) || 13892 (addr_class == AddressClass::eUnknown)) 13893 m_opcode_mode = eModeARM; 13894 else if (addr_class == AddressClass::eCodeAlternateISA) 13895 m_opcode_mode = eModeThumb; 13896 else 13897 return false; 13898 } 13899 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions()) 13900 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13901 else 13902 m_opcode_cpsr = CPSR_MODE_USR; 13903 return true; 13904 } 13905 return false; 13906} 13907 13908bool EmulateInstructionARM::ReadInstruction() { 13909 bool success = false; 13910 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric, 13911 LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13912 if (success) { 13913 addr_t pc = 13914 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 13915 LLDB_INVALID_ADDRESS, &success); 13916 if (success) { 13917 Context read_inst_context; 13918 read_inst_context.type = eContextReadOpcode; 13919 read_inst_context.SetNoArgs(); 13920 13921 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) { 13922 m_opcode_mode = eModeThumb; 13923 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13924 13925 if (success) { 13926 if ((thumb_opcode & 0xe000) != 0xe000 || 13927 ((thumb_opcode & 0x1800u) == 0)) { 13928 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder()); 13929 } else { 13930 m_opcode.SetOpcode32( 13931 (thumb_opcode << 16) | 13932 MemARead(read_inst_context, pc + 2, 2, 0, &success), 13933 GetByteOrder()); 13934 } 13935 } 13936 } else { 13937 m_opcode_mode = eModeARM; 13938 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success), 13939 GetByteOrder()); 13940 } 13941 13942 if (!m_ignore_conditions) { 13943 // If we are not ignoreing the conditions then init the it session from 13944 // the current value of cpsr. 13945 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | 13946 Bits32(m_opcode_cpsr, 26, 25); 13947 if (it != 0) 13948 m_it_session.InitIT(it); 13949 } 13950 } 13951 } 13952 if (!success) { 13953 m_opcode_mode = eModeInvalid; 13954 m_addr = LLDB_INVALID_ADDRESS; 13955 } 13956 return success; 13957} 13958 13959uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; } 13960 13961bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) { 13962 // If we are ignoring conditions, then always return true. this allows us to 13963 // iterate over disassembly code and still emulate an instruction even if we 13964 // don't have all the right bits set in the CPSR register... 13965 if (m_ignore_conditions) 13966 return true; 13967 13968 const uint32_t cond = CurrentCond(opcode); 13969 if (cond == UINT32_MAX) 13970 return false; 13971 13972 bool result = false; 13973 switch (UnsignedBits(cond, 3, 1)) { 13974 case 0: 13975 if (m_opcode_cpsr == 0) 13976 result = true; 13977 else 13978 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13979 break; 13980 case 1: 13981 if (m_opcode_cpsr == 0) 13982 result = true; 13983 else 13984 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13985 break; 13986 case 2: 13987 if (m_opcode_cpsr == 0) 13988 result = true; 13989 else 13990 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13991 break; 13992 case 3: 13993 if (m_opcode_cpsr == 0) 13994 result = true; 13995 else 13996 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13997 break; 13998 case 4: 13999 if (m_opcode_cpsr == 0) 14000 result = true; 14001 else 14002 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && 14003 ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 14004 break; 14005 case 5: 14006 if (m_opcode_cpsr == 0) 14007 result = true; 14008 else { 14009 bool n = (m_opcode_cpsr & MASK_CPSR_N); 14010 bool v = (m_opcode_cpsr & MASK_CPSR_V); 14011 result = n == v; 14012 } 14013 break; 14014 case 6: 14015 if (m_opcode_cpsr == 0) 14016 result = true; 14017 else { 14018 bool n = (m_opcode_cpsr & MASK_CPSR_N); 14019 bool v = (m_opcode_cpsr & MASK_CPSR_V); 14020 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 14021 } 14022 break; 14023 case 7: 14024 // Always execute (cond == 0b1110, or the special 0b1111 which gives 14025 // opcodes different meanings, but always means execution happens. 14026 return true; 14027 } 14028 14029 if (cond & 1) 14030 result = !result; 14031 return result; 14032} 14033 14034uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) { 14035 switch (m_opcode_mode) { 14036 case eModeInvalid: 14037 break; 14038 14039 case eModeARM: 14040 return UnsignedBits(opcode, 31, 28); 14041 14042 case eModeThumb: 14043 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 14044 // 'cond' field of the encoding. 14045 { 14046 const uint32_t byte_size = m_opcode.GetByteSize(); 14047 if (byte_size == 2) { 14048 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 14049 return Bits32(opcode, 11, 8); 14050 } else if (byte_size == 4) { 14051 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 && 14052 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) { 14053 return Bits32(opcode, 25, 22); 14054 } 14055 } else 14056 // We have an invalid thumb instruction, let's bail out. 14057 break; 14058 14059 return m_it_session.GetCond(); 14060 } 14061 } 14062 return UINT32_MAX; // Return invalid value 14063} 14064 14065bool EmulateInstructionARM::InITBlock() { 14066 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 14067} 14068 14069bool EmulateInstructionARM::LastInITBlock() { 14070 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 14071} 14072 14073bool EmulateInstructionARM::BadMode(uint32_t mode) { 14074 14075 switch (mode) { 14076 case 16: 14077 return false; // '10000' 14078 case 17: 14079 return false; // '10001' 14080 case 18: 14081 return false; // '10010' 14082 case 19: 14083 return false; // '10011' 14084 case 22: 14085 return false; // '10110' 14086 case 23: 14087 return false; // '10111' 14088 case 27: 14089 return false; // '11011' 14090 case 31: 14091 return false; // '11111' 14092 default: 14093 return true; 14094 } 14095 return true; 14096} 14097 14098bool EmulateInstructionARM::CurrentModeIsPrivileged() { 14099 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0); 14100 14101 if (BadMode(mode)) 14102 return false; 14103 14104 if (mode == 16) 14105 return false; 14106 14107 return true; 14108} 14109 14110void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask, 14111 bool affect_execstate) { 14112 bool privileged = CurrentModeIsPrivileged(); 14113 14114 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20; 14115 14116 if (BitIsSet(bytemask, 3)) { 14117 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27); 14118 if (affect_execstate) 14119 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24); 14120 } 14121 14122 if (BitIsSet(bytemask, 2)) { 14123 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16); 14124 } 14125 14126 if (BitIsSet(bytemask, 1)) { 14127 if (affect_execstate) 14128 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10); 14129 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9); 14130 if (privileged) 14131 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8); 14132 } 14133 14134 if (BitIsSet(bytemask, 0)) { 14135 if (privileged) 14136 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6); 14137 if (affect_execstate) 14138 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5); 14139 if (privileged) 14140 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0); 14141 } 14142 14143 m_opcode_cpsr = tmp_cpsr; 14144} 14145 14146bool EmulateInstructionARM::BranchWritePC(const Context &context, 14147 uint32_t addr) { 14148 addr_t target; 14149 14150 // Check the current instruction set. 14151 if (CurrentInstrSet() == eModeARM) 14152 target = addr & 0xfffffffc; 14153 else 14154 target = addr & 0xfffffffe; 14155 14156 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14157 LLDB_REGNUM_GENERIC_PC, target)) 14158 return false; 14159 14160 return true; 14161} 14162 14163// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by 14164// inspecting addr. 14165bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) { 14166 addr_t target; 14167 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 14168 // we want to record it and issue a WriteRegister callback so the clients can 14169 // track the mode changes accordingly. 14170 bool cpsr_changed = false; 14171 14172 if (BitIsSet(addr, 0)) { 14173 if (CurrentInstrSet() != eModeThumb) { 14174 SelectInstrSet(eModeThumb); 14175 cpsr_changed = true; 14176 } 14177 target = addr & 0xfffffffe; 14178 context.SetISA(eModeThumb); 14179 } else if (BitIsClear(addr, 1)) { 14180 if (CurrentInstrSet() != eModeARM) { 14181 SelectInstrSet(eModeARM); 14182 cpsr_changed = true; 14183 } 14184 target = addr & 0xfffffffc; 14185 context.SetISA(eModeARM); 14186 } else 14187 return false; // address<1:0> == '10' => UNPREDICTABLE 14188 14189 if (cpsr_changed) { 14190 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14191 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14192 return false; 14193 } 14194 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14195 LLDB_REGNUM_GENERIC_PC, target)) 14196 return false; 14197 14198 return true; 14199} 14200 14201// Dispatches to either BXWritePC or BranchWritePC based on architecture 14202// versions. 14203bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) { 14204 if (ArchVersion() >= ARMv5T) 14205 return BXWritePC(context, addr); 14206 else 14207 return BranchWritePC((const Context)context, addr); 14208} 14209 14210// Dispatches to either BXWritePC or BranchWritePC based on architecture 14211// versions and current instruction set. 14212bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) { 14213 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 14214 return BXWritePC(context, addr); 14215 else 14216 return BranchWritePC((const Context)context, addr); 14217} 14218 14219EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() { 14220 return m_opcode_mode; 14221} 14222 14223// Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 14224// ReadInstruction() is performed. This function has a side effect of updating 14225// the m_new_inst_cpsr member variable if necessary. 14226bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) { 14227 m_new_inst_cpsr = m_opcode_cpsr; 14228 switch (arm_or_thumb) { 14229 default: 14230 return false; 14231 case eModeARM: 14232 // Clear the T bit. 14233 m_new_inst_cpsr &= ~MASK_CPSR_T; 14234 break; 14235 case eModeThumb: 14236 // Set the T bit. 14237 m_new_inst_cpsr |= MASK_CPSR_T; 14238 break; 14239 } 14240 return true; 14241} 14242 14243// This function returns TRUE if the processor currently provides support for 14244// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 14245// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 14246bool EmulateInstructionARM::UnalignedSupport() { 14247 return (ArchVersion() >= ARMv7); 14248} 14249 14250// The main addition and subtraction instructions can produce status 14251// information about both unsigned carry and signed overflow conditions. This 14252// status information can be used to synthesize multi-word additions and 14253// subtractions. 14254EmulateInstructionARM::AddWithCarryResult 14255EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) { 14256 uint32_t result; 14257 uint8_t carry_out; 14258 uint8_t overflow; 14259 14260 uint64_t unsigned_sum = x + y + carry_in; 14261 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 14262 14263 result = UnsignedBits(unsigned_sum, 31, 0); 14264 // carry_out = (result == unsigned_sum ? 0 : 1); 14265 overflow = ((int32_t)result == signed_sum ? 0 : 1); 14266 14267 if (carry_in) 14268 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0; 14269 else 14270 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0; 14271 14272 AddWithCarryResult res = {result, carry_out, overflow}; 14273 return res; 14274} 14275 14276uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) { 14277 lldb::RegisterKind reg_kind; 14278 uint32_t reg_num; 14279 switch (num) { 14280 case SP_REG: 14281 reg_kind = eRegisterKindGeneric; 14282 reg_num = LLDB_REGNUM_GENERIC_SP; 14283 break; 14284 case LR_REG: 14285 reg_kind = eRegisterKindGeneric; 14286 reg_num = LLDB_REGNUM_GENERIC_RA; 14287 break; 14288 case PC_REG: 14289 reg_kind = eRegisterKindGeneric; 14290 reg_num = LLDB_REGNUM_GENERIC_PC; 14291 break; 14292 default: 14293 if (num < SP_REG) { 14294 reg_kind = eRegisterKindDWARF; 14295 reg_num = dwarf_r0 + num; 14296 } else { 14297 // assert(0 && "Invalid register number"); 14298 *success = false; 14299 return UINT32_MAX; 14300 } 14301 break; 14302 } 14303 14304 // Read our register. 14305 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success); 14306 14307 // When executing an ARM instruction , PC reads as the address of the current 14308 // instruction plus 8. When executing a Thumb instruction , PC reads as the 14309 // address of the current instruction plus 4. 14310 if (num == 15) { 14311 if (CurrentInstrSet() == eModeARM) 14312 val += 8; 14313 else 14314 val += 4; 14315 } 14316 14317 return val; 14318} 14319 14320// Write the result to the ARM core register Rd, and optionally update the 14321// condition flags based on the result. 14322// 14323// This helper method tries to encapsulate the following pseudocode from the 14324// ARM Architecture Reference Manual: 14325// 14326// if d == 15 then // Can only occur for encoding A1 14327// ALUWritePC(result); // setflags is always FALSE here 14328// else 14329// R[d] = result; 14330// if setflags then 14331// APSR.N = result<31>; 14332// APSR.Z = IsZeroBit(result); 14333// APSR.C = carry; 14334// // APSR.V unchanged 14335// 14336// In the above case, the API client does not pass in the overflow arg, which 14337// defaults to ~0u. 14338bool EmulateInstructionARM::WriteCoreRegOptionalFlags( 14339 Context &context, const uint32_t result, const uint32_t Rd, bool setflags, 14340 const uint32_t carry, const uint32_t overflow) { 14341 if (Rd == 15) { 14342 if (!ALUWritePC(context, result)) 14343 return false; 14344 } else { 14345 lldb::RegisterKind reg_kind; 14346 uint32_t reg_num; 14347 switch (Rd) { 14348 case SP_REG: 14349 reg_kind = eRegisterKindGeneric; 14350 reg_num = LLDB_REGNUM_GENERIC_SP; 14351 break; 14352 case LR_REG: 14353 reg_kind = eRegisterKindGeneric; 14354 reg_num = LLDB_REGNUM_GENERIC_RA; 14355 break; 14356 default: 14357 reg_kind = eRegisterKindDWARF; 14358 reg_num = dwarf_r0 + Rd; 14359 } 14360 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result)) 14361 return false; 14362 if (setflags) 14363 return WriteFlags(context, result, carry, overflow); 14364 } 14365 return true; 14366} 14367 14368// This helper method tries to encapsulate the following pseudocode from the 14369// ARM Architecture Reference Manual: 14370// 14371// APSR.N = result<31>; 14372// APSR.Z = IsZeroBit(result); 14373// APSR.C = carry; 14374// APSR.V = overflow 14375// 14376// Default arguments can be specified for carry and overflow parameters, which 14377// means not to update the respective flags. 14378bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result, 14379 const uint32_t carry, 14380 const uint32_t overflow) { 14381 m_new_inst_cpsr = m_opcode_cpsr; 14382 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 14383 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 14384 if (carry != ~0u) 14385 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 14386 if (overflow != ~0u) 14387 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 14388 if (m_new_inst_cpsr != m_opcode_cpsr) { 14389 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14390 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14391 return false; 14392 } 14393 return true; 14394} 14395 14396bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) { 14397 ARMOpcode *opcode_data = NULL; 14398 14399 if (m_opcode_mode == eModeThumb) 14400 opcode_data = 14401 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14402 else if (m_opcode_mode == eModeARM) 14403 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14404 14405 const bool auto_advance_pc = 14406 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 14407 m_ignore_conditions = 14408 evaluate_options & eEmulateInstructionOptionIgnoreConditions; 14409 14410 bool success = false; 14411 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) { 14412 m_opcode_cpsr = 14413 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 14414 } 14415 14416 // Only return false if we are unable to read the CPSR if we care about 14417 // conditions 14418 if (success == false && m_ignore_conditions == false) 14419 return false; 14420 14421 uint32_t orig_pc_value = 0; 14422 if (auto_advance_pc) { 14423 orig_pc_value = 14424 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14425 if (!success) 14426 return false; 14427 } 14428 14429 // Call the Emulate... function if we managed to decode the opcode. 14430 if (opcode_data) { 14431 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(), 14432 opcode_data->encoding); 14433 if (!success) 14434 return false; 14435 } 14436 14437 // Advance the ITSTATE bits to their values for the next instruction if we 14438 // haven't just executed an IT instruction what initialized it. 14439 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() && 14440 (opcode_data == nullptr || 14441 opcode_data->callback != &EmulateInstructionARM::EmulateIT)) 14442 m_it_session.ITAdvance(); 14443 14444 if (auto_advance_pc) { 14445 uint32_t after_pc_value = 14446 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14447 if (!success) 14448 return false; 14449 14450 if (auto_advance_pc && (after_pc_value == orig_pc_value)) { 14451 after_pc_value += m_opcode.GetByteSize(); 14452 14453 EmulateInstruction::Context context; 14454 context.type = eContextAdvancePC; 14455 context.SetNoArgs(); 14456 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc, 14457 after_pc_value)) 14458 return false; 14459 } 14460 } 14461 return true; 14462} 14463 14464EmulateInstruction::InstructionCondition 14465EmulateInstructionARM::GetInstructionCondition() { 14466 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32()); 14467 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX) 14468 return EmulateInstruction::UnconditionalCondition; 14469 return cond; 14470} 14471 14472bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, 14473 OptionValueDictionary *test_data) { 14474 if (!test_data) { 14475 out_stream->Printf("TestEmulation: Missing test data.\n"); 14476 return false; 14477 } 14478 14479 static ConstString opcode_key("opcode"); 14480 static ConstString before_key("before_state"); 14481 static ConstString after_key("after_state"); 14482 14483 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key); 14484 14485 uint32_t test_opcode; 14486 if ((value_sp.get() == NULL) || 14487 (value_sp->GetType() != OptionValue::eTypeUInt64)) { 14488 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n"); 14489 return false; 14490 } 14491 test_opcode = value_sp->GetUInt64Value(); 14492 14493 if (arch.GetTriple().getArch() == llvm::Triple::thumb || 14494 arch.IsAlwaysThumbInstructions()) { 14495 m_opcode_mode = eModeThumb; 14496 if (test_opcode < 0x10000) 14497 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder()); 14498 else 14499 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14500 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) { 14501 m_opcode_mode = eModeARM; 14502 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14503 } else { 14504 out_stream->Printf("TestEmulation: Invalid arch.\n"); 14505 return false; 14506 } 14507 14508 EmulationStateARM before_state; 14509 EmulationStateARM after_state; 14510 14511 value_sp = test_data->GetValueForKey(before_key); 14512 if ((value_sp.get() == NULL) || 14513 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14514 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n"); 14515 return false; 14516 } 14517 14518 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary(); 14519 if (!before_state.LoadStateFromDictionary(state_dictionary)) { 14520 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n"); 14521 return false; 14522 } 14523 14524 value_sp = test_data->GetValueForKey(after_key); 14525 if ((value_sp.get() == NULL) || 14526 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14527 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n"); 14528 return false; 14529 } 14530 14531 state_dictionary = value_sp->GetAsDictionary(); 14532 if (!after_state.LoadStateFromDictionary(state_dictionary)) { 14533 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n"); 14534 return false; 14535 } 14536 14537 SetBaton((void *)&before_state); 14538 SetCallbacks(&EmulationStateARM::ReadPseudoMemory, 14539 &EmulationStateARM::WritePseudoMemory, 14540 &EmulationStateARM::ReadPseudoRegister, 14541 &EmulationStateARM::WritePseudoRegister); 14542 14543 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 14544 if (!success) { 14545 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n"); 14546 return false; 14547 } 14548 14549 success = before_state.CompareState(after_state); 14550 if (!success) 14551 out_stream->Printf( 14552 "TestEmulation: 'before' and 'after' states do not match.\n"); 14553 14554 return success; 14555} 14556// 14557// 14558// const char * 14559// EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 14560//{ 14561// if (reg_kind == eRegisterKindGeneric) 14562// { 14563// switch (reg_num) 14564// { 14565// case LLDB_REGNUM_GENERIC_PC: return "pc"; 14566// case LLDB_REGNUM_GENERIC_SP: return "sp"; 14567// case LLDB_REGNUM_GENERIC_FP: return "fp"; 14568// case LLDB_REGNUM_GENERIC_RA: return "lr"; 14569// case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 14570// default: return NULL; 14571// } 14572// } 14573// else if (reg_kind == eRegisterKindDWARF) 14574// { 14575// return GetARMDWARFRegisterName (reg_num); 14576// } 14577// return NULL; 14578//} 14579// 14580bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { 14581 unwind_plan.Clear(); 14582 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 14583 14584 UnwindPlan::RowSP row(new UnwindPlan::Row); 14585 14586 // Our previous Call Frame Address is the stack pointer 14587 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0); 14588 14589 unwind_plan.AppendRow(row); 14590 unwind_plan.SetSourceName("EmulateInstructionARM"); 14591 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 14592 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 14593 unwind_plan.SetReturnAddressRegister(dwarf_lr); 14594 return true; 14595} 14596