EmulateInstructionARM.cpp revision 353358
1//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include <stdlib.h> 10 11#include "EmulateInstructionARM.h" 12#include "EmulationStateARM.h" 13#include "lldb/Core/Address.h" 14#include "lldb/Core/PluginManager.h" 15#include "lldb/Host/PosixApi.h" 16#include "lldb/Interpreter/OptionValueArray.h" 17#include "lldb/Interpreter/OptionValueDictionary.h" 18#include "lldb/Symbol/UnwindPlan.h" 19#include "lldb/Utility/ArchSpec.h" 20#include "lldb/Utility/ConstString.h" 21#include "lldb/Utility/Stream.h" 22 23#include "Plugins/Process/Utility/ARMDefines.h" 24#include "Plugins/Process/Utility/ARMUtils.h" 25#include "Utility/ARM_DWARF_Registers.h" 26 27#include "llvm/ADT/STLExtras.h" 28#include "llvm/Support/MathExtras.h" 29 30using namespace lldb; 31using namespace lldb_private; 32 33// Convenient macro definitions. 34#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 35#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 36 37#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 38 39// 40// ITSession implementation 41// 42 43static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo ®_info) { 44 ::memset(®_info, 0, sizeof(RegisterInfo)); 45 ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); 46 47 if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) { 48 reg_info.byte_size = 16; 49 reg_info.format = eFormatVectorOfUInt8; 50 reg_info.encoding = eEncodingVector; 51 } 52 53 if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) { 54 reg_info.byte_size = 8; 55 reg_info.format = eFormatFloat; 56 reg_info.encoding = eEncodingIEEE754; 57 } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) { 58 reg_info.byte_size = 4; 59 reg_info.format = eFormatFloat; 60 reg_info.encoding = eEncodingIEEE754; 61 } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) { 62 reg_info.byte_size = 12; 63 reg_info.format = eFormatFloat; 64 reg_info.encoding = eEncodingIEEE754; 65 } else { 66 reg_info.byte_size = 4; 67 reg_info.format = eFormatHex; 68 reg_info.encoding = eEncodingUint; 69 } 70 71 reg_info.kinds[eRegisterKindDWARF] = reg_num; 72 73 switch (reg_num) { 74 case dwarf_r0: 75 reg_info.name = "r0"; 76 break; 77 case dwarf_r1: 78 reg_info.name = "r1"; 79 break; 80 case dwarf_r2: 81 reg_info.name = "r2"; 82 break; 83 case dwarf_r3: 84 reg_info.name = "r3"; 85 break; 86 case dwarf_r4: 87 reg_info.name = "r4"; 88 break; 89 case dwarf_r5: 90 reg_info.name = "r5"; 91 break; 92 case dwarf_r6: 93 reg_info.name = "r6"; 94 break; 95 case dwarf_r7: 96 reg_info.name = "r7"; 97 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; 98 break; 99 case dwarf_r8: 100 reg_info.name = "r8"; 101 break; 102 case dwarf_r9: 103 reg_info.name = "r9"; 104 break; 105 case dwarf_r10: 106 reg_info.name = "r10"; 107 break; 108 case dwarf_r11: 109 reg_info.name = "r11"; 110 break; 111 case dwarf_r12: 112 reg_info.name = "r12"; 113 break; 114 case dwarf_sp: 115 reg_info.name = "sp"; 116 reg_info.alt_name = "r13"; 117 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; 118 break; 119 case dwarf_lr: 120 reg_info.name = "lr"; 121 reg_info.alt_name = "r14"; 122 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; 123 break; 124 case dwarf_pc: 125 reg_info.name = "pc"; 126 reg_info.alt_name = "r15"; 127 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; 128 break; 129 case dwarf_cpsr: 130 reg_info.name = "cpsr"; 131 reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; 132 break; 133 134 case dwarf_s0: 135 reg_info.name = "s0"; 136 break; 137 case dwarf_s1: 138 reg_info.name = "s1"; 139 break; 140 case dwarf_s2: 141 reg_info.name = "s2"; 142 break; 143 case dwarf_s3: 144 reg_info.name = "s3"; 145 break; 146 case dwarf_s4: 147 reg_info.name = "s4"; 148 break; 149 case dwarf_s5: 150 reg_info.name = "s5"; 151 break; 152 case dwarf_s6: 153 reg_info.name = "s6"; 154 break; 155 case dwarf_s7: 156 reg_info.name = "s7"; 157 break; 158 case dwarf_s8: 159 reg_info.name = "s8"; 160 break; 161 case dwarf_s9: 162 reg_info.name = "s9"; 163 break; 164 case dwarf_s10: 165 reg_info.name = "s10"; 166 break; 167 case dwarf_s11: 168 reg_info.name = "s11"; 169 break; 170 case dwarf_s12: 171 reg_info.name = "s12"; 172 break; 173 case dwarf_s13: 174 reg_info.name = "s13"; 175 break; 176 case dwarf_s14: 177 reg_info.name = "s14"; 178 break; 179 case dwarf_s15: 180 reg_info.name = "s15"; 181 break; 182 case dwarf_s16: 183 reg_info.name = "s16"; 184 break; 185 case dwarf_s17: 186 reg_info.name = "s17"; 187 break; 188 case dwarf_s18: 189 reg_info.name = "s18"; 190 break; 191 case dwarf_s19: 192 reg_info.name = "s19"; 193 break; 194 case dwarf_s20: 195 reg_info.name = "s20"; 196 break; 197 case dwarf_s21: 198 reg_info.name = "s21"; 199 break; 200 case dwarf_s22: 201 reg_info.name = "s22"; 202 break; 203 case dwarf_s23: 204 reg_info.name = "s23"; 205 break; 206 case dwarf_s24: 207 reg_info.name = "s24"; 208 break; 209 case dwarf_s25: 210 reg_info.name = "s25"; 211 break; 212 case dwarf_s26: 213 reg_info.name = "s26"; 214 break; 215 case dwarf_s27: 216 reg_info.name = "s27"; 217 break; 218 case dwarf_s28: 219 reg_info.name = "s28"; 220 break; 221 case dwarf_s29: 222 reg_info.name = "s29"; 223 break; 224 case dwarf_s30: 225 reg_info.name = "s30"; 226 break; 227 case dwarf_s31: 228 reg_info.name = "s31"; 229 break; 230 231 // FPA Registers 0-7 232 case dwarf_f0: 233 reg_info.name = "f0"; 234 break; 235 case dwarf_f1: 236 reg_info.name = "f1"; 237 break; 238 case dwarf_f2: 239 reg_info.name = "f2"; 240 break; 241 case dwarf_f3: 242 reg_info.name = "f3"; 243 break; 244 case dwarf_f4: 245 reg_info.name = "f4"; 246 break; 247 case dwarf_f5: 248 reg_info.name = "f5"; 249 break; 250 case dwarf_f6: 251 reg_info.name = "f6"; 252 break; 253 case dwarf_f7: 254 reg_info.name = "f7"; 255 break; 256 257 // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator 258 // register 0 - 7 (they do overlap with wCGR0 - wCGR7) 259 case dwarf_wCGR0: 260 reg_info.name = "wCGR0/ACC0"; 261 break; 262 case dwarf_wCGR1: 263 reg_info.name = "wCGR1/ACC1"; 264 break; 265 case dwarf_wCGR2: 266 reg_info.name = "wCGR2/ACC2"; 267 break; 268 case dwarf_wCGR3: 269 reg_info.name = "wCGR3/ACC3"; 270 break; 271 case dwarf_wCGR4: 272 reg_info.name = "wCGR4/ACC4"; 273 break; 274 case dwarf_wCGR5: 275 reg_info.name = "wCGR5/ACC5"; 276 break; 277 case dwarf_wCGR6: 278 reg_info.name = "wCGR6/ACC6"; 279 break; 280 case dwarf_wCGR7: 281 reg_info.name = "wCGR7/ACC7"; 282 break; 283 284 // Intel wireless MMX data registers 0 - 15 285 case dwarf_wR0: 286 reg_info.name = "wR0"; 287 break; 288 case dwarf_wR1: 289 reg_info.name = "wR1"; 290 break; 291 case dwarf_wR2: 292 reg_info.name = "wR2"; 293 break; 294 case dwarf_wR3: 295 reg_info.name = "wR3"; 296 break; 297 case dwarf_wR4: 298 reg_info.name = "wR4"; 299 break; 300 case dwarf_wR5: 301 reg_info.name = "wR5"; 302 break; 303 case dwarf_wR6: 304 reg_info.name = "wR6"; 305 break; 306 case dwarf_wR7: 307 reg_info.name = "wR7"; 308 break; 309 case dwarf_wR8: 310 reg_info.name = "wR8"; 311 break; 312 case dwarf_wR9: 313 reg_info.name = "wR9"; 314 break; 315 case dwarf_wR10: 316 reg_info.name = "wR10"; 317 break; 318 case dwarf_wR11: 319 reg_info.name = "wR11"; 320 break; 321 case dwarf_wR12: 322 reg_info.name = "wR12"; 323 break; 324 case dwarf_wR13: 325 reg_info.name = "wR13"; 326 break; 327 case dwarf_wR14: 328 reg_info.name = "wR14"; 329 break; 330 case dwarf_wR15: 331 reg_info.name = "wR15"; 332 break; 333 334 case dwarf_spsr: 335 reg_info.name = "spsr"; 336 break; 337 case dwarf_spsr_fiq: 338 reg_info.name = "spsr_fiq"; 339 break; 340 case dwarf_spsr_irq: 341 reg_info.name = "spsr_irq"; 342 break; 343 case dwarf_spsr_abt: 344 reg_info.name = "spsr_abt"; 345 break; 346 case dwarf_spsr_und: 347 reg_info.name = "spsr_und"; 348 break; 349 case dwarf_spsr_svc: 350 reg_info.name = "spsr_svc"; 351 break; 352 353 case dwarf_r8_usr: 354 reg_info.name = "r8_usr"; 355 break; 356 case dwarf_r9_usr: 357 reg_info.name = "r9_usr"; 358 break; 359 case dwarf_r10_usr: 360 reg_info.name = "r10_usr"; 361 break; 362 case dwarf_r11_usr: 363 reg_info.name = "r11_usr"; 364 break; 365 case dwarf_r12_usr: 366 reg_info.name = "r12_usr"; 367 break; 368 case dwarf_r13_usr: 369 reg_info.name = "r13_usr"; 370 break; 371 case dwarf_r14_usr: 372 reg_info.name = "r14_usr"; 373 break; 374 case dwarf_r8_fiq: 375 reg_info.name = "r8_fiq"; 376 break; 377 case dwarf_r9_fiq: 378 reg_info.name = "r9_fiq"; 379 break; 380 case dwarf_r10_fiq: 381 reg_info.name = "r10_fiq"; 382 break; 383 case dwarf_r11_fiq: 384 reg_info.name = "r11_fiq"; 385 break; 386 case dwarf_r12_fiq: 387 reg_info.name = "r12_fiq"; 388 break; 389 case dwarf_r13_fiq: 390 reg_info.name = "r13_fiq"; 391 break; 392 case dwarf_r14_fiq: 393 reg_info.name = "r14_fiq"; 394 break; 395 case dwarf_r13_irq: 396 reg_info.name = "r13_irq"; 397 break; 398 case dwarf_r14_irq: 399 reg_info.name = "r14_irq"; 400 break; 401 case dwarf_r13_abt: 402 reg_info.name = "r13_abt"; 403 break; 404 case dwarf_r14_abt: 405 reg_info.name = "r14_abt"; 406 break; 407 case dwarf_r13_und: 408 reg_info.name = "r13_und"; 409 break; 410 case dwarf_r14_und: 411 reg_info.name = "r14_und"; 412 break; 413 case dwarf_r13_svc: 414 reg_info.name = "r13_svc"; 415 break; 416 case dwarf_r14_svc: 417 reg_info.name = "r14_svc"; 418 break; 419 420 // Intel wireless MMX control register in co-processor 0 - 7 421 case dwarf_wC0: 422 reg_info.name = "wC0"; 423 break; 424 case dwarf_wC1: 425 reg_info.name = "wC1"; 426 break; 427 case dwarf_wC2: 428 reg_info.name = "wC2"; 429 break; 430 case dwarf_wC3: 431 reg_info.name = "wC3"; 432 break; 433 case dwarf_wC4: 434 reg_info.name = "wC4"; 435 break; 436 case dwarf_wC5: 437 reg_info.name = "wC5"; 438 break; 439 case dwarf_wC6: 440 reg_info.name = "wC6"; 441 break; 442 case dwarf_wC7: 443 reg_info.name = "wC7"; 444 break; 445 446 // VFP-v3/Neon 447 case dwarf_d0: 448 reg_info.name = "d0"; 449 break; 450 case dwarf_d1: 451 reg_info.name = "d1"; 452 break; 453 case dwarf_d2: 454 reg_info.name = "d2"; 455 break; 456 case dwarf_d3: 457 reg_info.name = "d3"; 458 break; 459 case dwarf_d4: 460 reg_info.name = "d4"; 461 break; 462 case dwarf_d5: 463 reg_info.name = "d5"; 464 break; 465 case dwarf_d6: 466 reg_info.name = "d6"; 467 break; 468 case dwarf_d7: 469 reg_info.name = "d7"; 470 break; 471 case dwarf_d8: 472 reg_info.name = "d8"; 473 break; 474 case dwarf_d9: 475 reg_info.name = "d9"; 476 break; 477 case dwarf_d10: 478 reg_info.name = "d10"; 479 break; 480 case dwarf_d11: 481 reg_info.name = "d11"; 482 break; 483 case dwarf_d12: 484 reg_info.name = "d12"; 485 break; 486 case dwarf_d13: 487 reg_info.name = "d13"; 488 break; 489 case dwarf_d14: 490 reg_info.name = "d14"; 491 break; 492 case dwarf_d15: 493 reg_info.name = "d15"; 494 break; 495 case dwarf_d16: 496 reg_info.name = "d16"; 497 break; 498 case dwarf_d17: 499 reg_info.name = "d17"; 500 break; 501 case dwarf_d18: 502 reg_info.name = "d18"; 503 break; 504 case dwarf_d19: 505 reg_info.name = "d19"; 506 break; 507 case dwarf_d20: 508 reg_info.name = "d20"; 509 break; 510 case dwarf_d21: 511 reg_info.name = "d21"; 512 break; 513 case dwarf_d22: 514 reg_info.name = "d22"; 515 break; 516 case dwarf_d23: 517 reg_info.name = "d23"; 518 break; 519 case dwarf_d24: 520 reg_info.name = "d24"; 521 break; 522 case dwarf_d25: 523 reg_info.name = "d25"; 524 break; 525 case dwarf_d26: 526 reg_info.name = "d26"; 527 break; 528 case dwarf_d27: 529 reg_info.name = "d27"; 530 break; 531 case dwarf_d28: 532 reg_info.name = "d28"; 533 break; 534 case dwarf_d29: 535 reg_info.name = "d29"; 536 break; 537 case dwarf_d30: 538 reg_info.name = "d30"; 539 break; 540 case dwarf_d31: 541 reg_info.name = "d31"; 542 break; 543 544 // NEON 128-bit vector registers (overlays the d registers) 545 case dwarf_q0: 546 reg_info.name = "q0"; 547 break; 548 case dwarf_q1: 549 reg_info.name = "q1"; 550 break; 551 case dwarf_q2: 552 reg_info.name = "q2"; 553 break; 554 case dwarf_q3: 555 reg_info.name = "q3"; 556 break; 557 case dwarf_q4: 558 reg_info.name = "q4"; 559 break; 560 case dwarf_q5: 561 reg_info.name = "q5"; 562 break; 563 case dwarf_q6: 564 reg_info.name = "q6"; 565 break; 566 case dwarf_q7: 567 reg_info.name = "q7"; 568 break; 569 case dwarf_q8: 570 reg_info.name = "q8"; 571 break; 572 case dwarf_q9: 573 reg_info.name = "q9"; 574 break; 575 case dwarf_q10: 576 reg_info.name = "q10"; 577 break; 578 case dwarf_q11: 579 reg_info.name = "q11"; 580 break; 581 case dwarf_q12: 582 reg_info.name = "q12"; 583 break; 584 case dwarf_q13: 585 reg_info.name = "q13"; 586 break; 587 case dwarf_q14: 588 reg_info.name = "q14"; 589 break; 590 case dwarf_q15: 591 reg_info.name = "q15"; 592 break; 593 594 default: 595 return false; 596 } 597 return true; 598} 599 600// A8.6.50 601// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 602static uint32_t CountITSize(uint32_t ITMask) { 603 // First count the trailing zeros of the IT mask. 604 uint32_t TZ = llvm::countTrailingZeros(ITMask); 605 if (TZ > 3) { 606#ifdef LLDB_CONFIGURATION_DEBUG 607 printf("Encoding error: IT Mask '0000'\n"); 608#endif 609 return 0; 610 } 611 return (4 - TZ); 612} 613 614// Init ITState. Note that at least one bit is always 1 in mask. 615bool ITSession::InitIT(uint32_t bits7_0) { 616 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 617 if (ITCounter == 0) 618 return false; 619 620 // A8.6.50 IT 621 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 622 if (FirstCond == 0xF) { 623#ifdef LLDB_CONFIGURATION_DEBUG 624 printf("Encoding error: IT FirstCond '1111'\n"); 625#endif 626 return false; 627 } 628 if (FirstCond == 0xE && ITCounter != 1) { 629#ifdef LLDB_CONFIGURATION_DEBUG 630 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 631#endif 632 return false; 633 } 634 635 ITState = bits7_0; 636 return true; 637} 638 639// Update ITState if necessary. 640void ITSession::ITAdvance() { 641 // assert(ITCounter); 642 --ITCounter; 643 if (ITCounter == 0) 644 ITState = 0; 645 else { 646 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 647 SetBits32(ITState, 4, 0, NewITState4_0); 648 } 649} 650 651// Return true if we're inside an IT Block. 652bool ITSession::InITBlock() { return ITCounter != 0; } 653 654// Return true if we're the last instruction inside an IT Block. 655bool ITSession::LastInITBlock() { return ITCounter == 1; } 656 657// Get condition bits for the current thumb instruction. 658uint32_t ITSession::GetCond() { 659 if (InITBlock()) 660 return Bits32(ITState, 7, 4); 661 else 662 return COND_AL; 663} 664 665// ARM constants used during decoding 666#define REG_RD 0 667#define LDM_REGLIST 1 668#define SP_REG 13 669#define LR_REG 14 670#define PC_REG 15 671#define PC_REGLIST_BIT 0x8000 672 673#define ARMv4 (1u << 0) 674#define ARMv4T (1u << 1) 675#define ARMv5T (1u << 2) 676#define ARMv5TE (1u << 3) 677#define ARMv5TEJ (1u << 4) 678#define ARMv6 (1u << 5) 679#define ARMv6K (1u << 6) 680#define ARMv6T2 (1u << 7) 681#define ARMv7 (1u << 8) 682#define ARMv7S (1u << 9) 683#define ARMv8 (1u << 10) 684#define ARMvAll (0xffffffffu) 685 686#define ARMV4T_ABOVE \ 687 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \ 688 ARMv7S | ARMv8) 689#define ARMV5_ABOVE \ 690 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \ 691 ARMv8) 692#define ARMV5TE_ABOVE \ 693 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 694#define ARMV5J_ABOVE \ 695 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 696#define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 697#define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 698#define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8) 699 700#define No_VFP 0 701#define VFPv1 (1u << 1) 702#define VFPv2 (1u << 2) 703#define VFPv3 (1u << 3) 704#define AdvancedSIMD (1u << 4) 705 706#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 707#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 708#define VFPv2v3 (VFPv2 | VFPv3) 709 710// 711// EmulateInstructionARM implementation 712// 713 714void EmulateInstructionARM::Initialize() { 715 PluginManager::RegisterPlugin(GetPluginNameStatic(), 716 GetPluginDescriptionStatic(), CreateInstance); 717} 718 719void EmulateInstructionARM::Terminate() { 720 PluginManager::UnregisterPlugin(CreateInstance); 721} 722 723ConstString EmulateInstructionARM::GetPluginNameStatic() { 724 static ConstString g_name("arm"); 725 return g_name; 726} 727 728const char *EmulateInstructionARM::GetPluginDescriptionStatic() { 729 return "Emulate instructions for the ARM architecture."; 730} 731 732EmulateInstruction * 733EmulateInstructionARM::CreateInstance(const ArchSpec &arch, 734 InstructionType inst_type) { 735 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic( 736 inst_type)) { 737 if (arch.GetTriple().getArch() == llvm::Triple::arm) { 738 std::unique_ptr<EmulateInstructionARM> emulate_insn_up( 739 new EmulateInstructionARM(arch)); 740 741 if (emulate_insn_up) 742 return emulate_insn_up.release(); 743 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) { 744 std::unique_ptr<EmulateInstructionARM> emulate_insn_up( 745 new EmulateInstructionARM(arch)); 746 747 if (emulate_insn_up) 748 return emulate_insn_up.release(); 749 } 750 } 751 752 return nullptr; 753} 754 755bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) { 756 if (arch.GetTriple().getArch() == llvm::Triple::arm) 757 return true; 758 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 759 return true; 760 761 return false; 762} 763 764// Write "bits (32) UNKNOWN" to memory address "address". Helper function for 765// many ARM instructions. 766bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) { 767 EmulateInstruction::Context context; 768 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 769 context.SetNoArgs(); 770 771 uint32_t random_data = rand(); 772 const uint32_t addr_byte_size = GetAddressByteSize(); 773 774 return MemAWrite(context, address, random_data, addr_byte_size); 775} 776 777// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM 778// instructions. 779bool EmulateInstructionARM::WriteBits32Unknown(int n) { 780 EmulateInstruction::Context context; 781 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 782 context.SetNoArgs(); 783 784 bool success; 785 uint32_t data = 786 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 787 788 if (!success) 789 return false; 790 791 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data)) 792 return false; 793 794 return true; 795} 796 797bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind, 798 uint32_t reg_num, 799 RegisterInfo ®_info) { 800 if (reg_kind == eRegisterKindGeneric) { 801 switch (reg_num) { 802 case LLDB_REGNUM_GENERIC_PC: 803 reg_kind = eRegisterKindDWARF; 804 reg_num = dwarf_pc; 805 break; 806 case LLDB_REGNUM_GENERIC_SP: 807 reg_kind = eRegisterKindDWARF; 808 reg_num = dwarf_sp; 809 break; 810 case LLDB_REGNUM_GENERIC_FP: 811 reg_kind = eRegisterKindDWARF; 812 reg_num = dwarf_r7; 813 break; 814 case LLDB_REGNUM_GENERIC_RA: 815 reg_kind = eRegisterKindDWARF; 816 reg_num = dwarf_lr; 817 break; 818 case LLDB_REGNUM_GENERIC_FLAGS: 819 reg_kind = eRegisterKindDWARF; 820 reg_num = dwarf_cpsr; 821 break; 822 default: 823 return false; 824 } 825 } 826 827 if (reg_kind == eRegisterKindDWARF) 828 return GetARMDWARFRegisterInfo(reg_num, reg_info); 829 return false; 830} 831 832uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const { 833 if (m_arch.GetTriple().isAndroid()) 834 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android 835 bool is_apple = false; 836 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 837 is_apple = true; 838 switch (m_arch.GetTriple().getOS()) { 839 case llvm::Triple::Darwin: 840 case llvm::Triple::MacOSX: 841 case llvm::Triple::IOS: 842 case llvm::Triple::TvOS: 843 case llvm::Triple::WatchOS: 844 // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS: 845 is_apple = true; 846 break; 847 default: 848 break; 849 } 850 851 /* On Apple iOS et al, the frame pointer register is always r7. 852 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 853 */ 854 855 uint32_t fp_regnum = 11; 856 857 if (is_apple) 858 fp_regnum = 7; 859 860 if (m_opcode_mode == eModeThumb) 861 fp_regnum = 7; 862 863 return fp_regnum; 864} 865 866uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const { 867 bool is_apple = false; 868 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 869 is_apple = true; 870 switch (m_arch.GetTriple().getOS()) { 871 case llvm::Triple::Darwin: 872 case llvm::Triple::MacOSX: 873 case llvm::Triple::IOS: 874 is_apple = true; 875 break; 876 default: 877 break; 878 } 879 880 /* On Apple iOS et al, the frame pointer register is always r7. 881 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 882 */ 883 884 uint32_t fp_regnum = dwarf_r11; 885 886 if (is_apple) 887 fp_regnum = dwarf_r7; 888 889 if (m_opcode_mode == eModeThumb) 890 fp_regnum = dwarf_r7; 891 892 return fp_regnum; 893} 894 895// Push Multiple Registers stores multiple registers to the stack, storing to 896// consecutive memory locations ending just below the address in SP, and 897// updates 898// SP to point to the start of the stored data. 899bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode, 900 const ARMEncoding encoding) { 901#if 0 902 // ARM pseudo code... 903 if (ConditionPassed()) 904 { 905 EncodingSpecificOperations(); 906 NullCheckIfThumbEE(13); 907 address = SP - 4*BitCount(registers); 908 909 for (i = 0 to 14) 910 { 911 if (registers<i> == '1') 912 { 913 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 914 MemA[address,4] = bits(32) UNKNOWN; 915 else 916 MemA[address,4] = R[i]; 917 address = address + 4; 918 } 919 } 920 921 if (registers<15> == '1') // Only possible for encoding A1 or A2 922 MemA[address,4] = PCStoreValue(); 923 924 SP = SP - 4*BitCount(registers); 925 } 926#endif 927 928 bool success = false; 929 if (ConditionPassed(opcode)) { 930 const uint32_t addr_byte_size = GetAddressByteSize(); 931 const addr_t sp = ReadCoreReg(SP_REG, &success); 932 if (!success) 933 return false; 934 uint32_t registers = 0; 935 uint32_t Rt; // the source register 936 switch (encoding) { 937 case eEncodingT1: 938 registers = Bits32(opcode, 7, 0); 939 // The M bit represents LR. 940 if (Bit32(opcode, 8)) 941 registers |= (1u << 14); 942 // if BitCount(registers) < 1 then UNPREDICTABLE; 943 if (BitCount(registers) < 1) 944 return false; 945 break; 946 case eEncodingT2: 947 // Ignore bits 15 & 13. 948 registers = Bits32(opcode, 15, 0) & ~0xa000; 949 // if BitCount(registers) < 2 then UNPREDICTABLE; 950 if (BitCount(registers) < 2) 951 return false; 952 break; 953 case eEncodingT3: 954 Rt = Bits32(opcode, 15, 12); 955 // if BadReg(t) then UNPREDICTABLE; 956 if (BadReg(Rt)) 957 return false; 958 registers = (1u << Rt); 959 break; 960 case eEncodingA1: 961 registers = Bits32(opcode, 15, 0); 962 // Instead of return false, let's handle the following case as well, 963 // which amounts to pushing one reg onto the full descending stacks. 964 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 965 break; 966 case eEncodingA2: 967 Rt = Bits32(opcode, 15, 12); 968 // if t == 13 then UNPREDICTABLE; 969 if (Rt == dwarf_sp) 970 return false; 971 registers = (1u << Rt); 972 break; 973 default: 974 return false; 975 } 976 addr_t sp_offset = addr_byte_size * BitCount(registers); 977 addr_t addr = sp - sp_offset; 978 uint32_t i; 979 980 EmulateInstruction::Context context; 981 context.type = EmulateInstruction::eContextPushRegisterOnStack; 982 RegisterInfo reg_info; 983 RegisterInfo sp_reg; 984 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 985 for (i = 0; i < 15; ++i) { 986 if (BitIsSet(registers, i)) { 987 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info); 988 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 989 uint32_t reg_value = ReadCoreReg(i, &success); 990 if (!success) 991 return false; 992 if (!MemAWrite(context, addr, reg_value, addr_byte_size)) 993 return false; 994 addr += addr_byte_size; 995 } 996 } 997 998 if (BitIsSet(registers, 15)) { 999 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info); 1000 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 1001 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1002 if (!success) 1003 return false; 1004 if (!MemAWrite(context, addr, pc, addr_byte_size)) 1005 return false; 1006 } 1007 1008 context.type = EmulateInstruction::eContextAdjustStackPointer; 1009 context.SetImmediateSigned(-sp_offset); 1010 1011 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1012 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1013 return false; 1014 } 1015 return true; 1016} 1017 1018// Pop Multiple Registers loads multiple registers from the stack, loading from 1019// consecutive memory locations staring at the address in SP, and updates 1020// SP to point just above the loaded data. 1021bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode, 1022 const ARMEncoding encoding) { 1023#if 0 1024 // ARM pseudo code... 1025 if (ConditionPassed()) 1026 { 1027 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 1028 address = SP; 1029 for i = 0 to 14 1030 if registers<i> == '1' then 1031 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 1032 if registers<15> == '1' then 1033 if UnalignedAllowed then 1034 LoadWritePC(MemU[address,4]); 1035 else 1036 LoadWritePC(MemA[address,4]); 1037 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 1038 if registers<13> == '1' then SP = bits(32) UNKNOWN; 1039 } 1040#endif 1041 1042 bool success = false; 1043 1044 if (ConditionPassed(opcode)) { 1045 const uint32_t addr_byte_size = GetAddressByteSize(); 1046 const addr_t sp = ReadCoreReg(SP_REG, &success); 1047 if (!success) 1048 return false; 1049 uint32_t registers = 0; 1050 uint32_t Rt; // the destination register 1051 switch (encoding) { 1052 case eEncodingT1: 1053 registers = Bits32(opcode, 7, 0); 1054 // The P bit represents PC. 1055 if (Bit32(opcode, 8)) 1056 registers |= (1u << 15); 1057 // if BitCount(registers) < 1 then UNPREDICTABLE; 1058 if (BitCount(registers) < 1) 1059 return false; 1060 break; 1061 case eEncodingT2: 1062 // Ignore bit 13. 1063 registers = Bits32(opcode, 15, 0) & ~0x2000; 1064 // if BitCount(registers) < 2 || (P == '1' && M == '1') then 1065 // UNPREDICTABLE; 1066 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 1067 return false; 1068 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 1069 // UNPREDICTABLE; 1070 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 1071 return false; 1072 break; 1073 case eEncodingT3: 1074 Rt = Bits32(opcode, 15, 12); 1075 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then 1076 // UNPREDICTABLE; 1077 if (Rt == 13) 1078 return false; 1079 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1080 return false; 1081 registers = (1u << Rt); 1082 break; 1083 case eEncodingA1: 1084 registers = Bits32(opcode, 15, 0); 1085 // Instead of return false, let's handle the following case as well, 1086 // which amounts to popping one reg from the full descending stacks. 1087 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 1088 1089 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 1090 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 1091 return false; 1092 break; 1093 case eEncodingA2: 1094 Rt = Bits32(opcode, 15, 12); 1095 // if t == 13 then UNPREDICTABLE; 1096 if (Rt == dwarf_sp) 1097 return false; 1098 registers = (1u << Rt); 1099 break; 1100 default: 1101 return false; 1102 } 1103 addr_t sp_offset = addr_byte_size * BitCount(registers); 1104 addr_t addr = sp; 1105 uint32_t i, data; 1106 1107 EmulateInstruction::Context context; 1108 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1109 1110 RegisterInfo sp_reg; 1111 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1112 1113 for (i = 0; i < 15; ++i) { 1114 if (BitIsSet(registers, i)) { 1115 context.SetAddress(addr); 1116 data = MemARead(context, addr, 4, 0, &success); 1117 if (!success) 1118 return false; 1119 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 1120 data)) 1121 return false; 1122 addr += addr_byte_size; 1123 } 1124 } 1125 1126 if (BitIsSet(registers, 15)) { 1127 context.SetRegisterPlusOffset(sp_reg, addr - sp); 1128 data = MemARead(context, addr, 4, 0, &success); 1129 if (!success) 1130 return false; 1131 // In ARMv5T and above, this is an interworking branch. 1132 if (!LoadWritePC(context, data)) 1133 return false; 1134 // addr += addr_byte_size; 1135 } 1136 1137 context.type = EmulateInstruction::eContextAdjustStackPointer; 1138 context.SetImmediateSigned(sp_offset); 1139 1140 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1141 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1142 return false; 1143 } 1144 return true; 1145} 1146 1147// Set r7 or ip to point to saved value residing within the stack. 1148// ADD (SP plus immediate) 1149bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode, 1150 const ARMEncoding encoding) { 1151#if 0 1152 // ARM pseudo code... 1153 if (ConditionPassed()) 1154 { 1155 EncodingSpecificOperations(); 1156 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1157 if d == 15 then 1158 ALUWritePC(result); // setflags is always FALSE here 1159 else 1160 R[d] = result; 1161 if setflags then 1162 APSR.N = result<31>; 1163 APSR.Z = IsZeroBit(result); 1164 APSR.C = carry; 1165 APSR.V = overflow; 1166 } 1167#endif 1168 1169 bool success = false; 1170 1171 if (ConditionPassed(opcode)) { 1172 const addr_t sp = ReadCoreReg(SP_REG, &success); 1173 if (!success) 1174 return false; 1175 uint32_t Rd; // the destination register 1176 uint32_t imm32; 1177 switch (encoding) { 1178 case eEncodingT1: 1179 Rd = 7; 1180 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 1181 break; 1182 case eEncodingA1: 1183 Rd = Bits32(opcode, 15, 12); 1184 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1185 break; 1186 default: 1187 return false; 1188 } 1189 addr_t sp_offset = imm32; 1190 addr_t addr = sp + sp_offset; // a pointer to the stack area 1191 1192 EmulateInstruction::Context context; 1193 if (Rd == GetFramePointerRegisterNumber()) 1194 context.type = eContextSetFramePointer; 1195 else 1196 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1197 RegisterInfo sp_reg; 1198 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1199 context.SetRegisterPlusOffset(sp_reg, sp_offset); 1200 1201 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, 1202 addr)) 1203 return false; 1204 } 1205 return true; 1206} 1207 1208// Set r7 or ip to the current stack pointer. 1209// MOV (register) 1210bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode, 1211 const ARMEncoding encoding) { 1212#if 0 1213 // ARM pseudo code... 1214 if (ConditionPassed()) 1215 { 1216 EncodingSpecificOperations(); 1217 result = R[m]; 1218 if d == 15 then 1219 ALUWritePC(result); // setflags is always FALSE here 1220 else 1221 R[d] = result; 1222 if setflags then 1223 APSR.N = result<31>; 1224 APSR.Z = IsZeroBit(result); 1225 // APSR.C unchanged 1226 // APSR.V unchanged 1227 } 1228#endif 1229 1230 bool success = false; 1231 1232 if (ConditionPassed(opcode)) { 1233 const addr_t sp = ReadCoreReg(SP_REG, &success); 1234 if (!success) 1235 return false; 1236 uint32_t Rd; // the destination register 1237 switch (encoding) { 1238 case eEncodingT1: 1239 Rd = 7; 1240 break; 1241 case eEncodingA1: 1242 Rd = 12; 1243 break; 1244 default: 1245 return false; 1246 } 1247 1248 EmulateInstruction::Context context; 1249 if (Rd == GetFramePointerRegisterNumber()) 1250 context.type = EmulateInstruction::eContextSetFramePointer; 1251 else 1252 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1253 RegisterInfo sp_reg; 1254 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1255 context.SetRegisterPlusOffset(sp_reg, 0); 1256 1257 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 1258 return false; 1259 } 1260 return true; 1261} 1262 1263// Move from high register (r8-r15) to low register (r0-r7). 1264// MOV (register) 1265bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode, 1266 const ARMEncoding encoding) { 1267 return EmulateMOVRdRm(opcode, encoding); 1268} 1269 1270// Move from register to register. 1271// MOV (register) 1272bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode, 1273 const ARMEncoding encoding) { 1274#if 0 1275 // ARM pseudo code... 1276 if (ConditionPassed()) 1277 { 1278 EncodingSpecificOperations(); 1279 result = R[m]; 1280 if d == 15 then 1281 ALUWritePC(result); // setflags is always FALSE here 1282 else 1283 R[d] = result; 1284 if setflags then 1285 APSR.N = result<31>; 1286 APSR.Z = IsZeroBit(result); 1287 // APSR.C unchanged 1288 // APSR.V unchanged 1289 } 1290#endif 1291 1292 bool success = false; 1293 1294 if (ConditionPassed(opcode)) { 1295 uint32_t Rm; // the source register 1296 uint32_t Rd; // the destination register 1297 bool setflags; 1298 switch (encoding) { 1299 case eEncodingT1: 1300 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1301 Rm = Bits32(opcode, 6, 3); 1302 setflags = false; 1303 if (Rd == 15 && InITBlock() && !LastInITBlock()) 1304 return false; 1305 break; 1306 case eEncodingT2: 1307 Rd = Bits32(opcode, 2, 0); 1308 Rm = Bits32(opcode, 5, 3); 1309 setflags = true; 1310 if (InITBlock()) 1311 return false; 1312 break; 1313 case eEncodingT3: 1314 Rd = Bits32(opcode, 11, 8); 1315 Rm = Bits32(opcode, 3, 0); 1316 setflags = BitIsSet(opcode, 20); 1317 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1318 if (setflags && (BadReg(Rd) || BadReg(Rm))) 1319 return false; 1320 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then 1321 // UNPREDICTABLE; 1322 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 1323 return false; 1324 break; 1325 case eEncodingA1: 1326 Rd = Bits32(opcode, 15, 12); 1327 Rm = Bits32(opcode, 3, 0); 1328 setflags = BitIsSet(opcode, 20); 1329 1330 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1331 // instructions; 1332 if (Rd == 15 && setflags) 1333 return EmulateSUBSPcLrEtc(opcode, encoding); 1334 break; 1335 default: 1336 return false; 1337 } 1338 uint32_t result = ReadCoreReg(Rm, &success); 1339 if (!success) 1340 return false; 1341 1342 // The context specifies that Rm is to be moved into Rd. 1343 EmulateInstruction::Context context; 1344 if (Rd == 13) 1345 context.type = EmulateInstruction::eContextAdjustStackPointer; 1346 else 1347 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1348 RegisterInfo dwarf_reg; 1349 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1350 context.SetRegisterPlusOffset(dwarf_reg, 0); 1351 1352 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 1353 return false; 1354 } 1355 return true; 1356} 1357 1358// Move (immediate) writes an immediate value to the destination register. It 1359// can optionally update the condition flags based on the value. 1360// MOV (immediate) 1361bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode, 1362 const ARMEncoding encoding) { 1363#if 0 1364 // ARM pseudo code... 1365 if (ConditionPassed()) 1366 { 1367 EncodingSpecificOperations(); 1368 result = imm32; 1369 if d == 15 then // Can only occur for ARM encoding 1370 ALUWritePC(result); // setflags is always FALSE here 1371 else 1372 R[d] = result; 1373 if setflags then 1374 APSR.N = result<31>; 1375 APSR.Z = IsZeroBit(result); 1376 APSR.C = carry; 1377 // APSR.V unchanged 1378 } 1379#endif 1380 1381 if (ConditionPassed(opcode)) { 1382 uint32_t Rd; // the destination register 1383 uint32_t imm32; // the immediate value to be written to Rd 1384 uint32_t carry = 1385 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 1386 // for setflags == false, this value is a don't care initialized to 1387 // 0 to silence the static analyzer 1388 bool setflags; 1389 switch (encoding) { 1390 case eEncodingT1: 1391 Rd = Bits32(opcode, 10, 8); 1392 setflags = !InITBlock(); 1393 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 1394 carry = APSR_C; 1395 1396 break; 1397 1398 case eEncodingT2: 1399 Rd = Bits32(opcode, 11, 8); 1400 setflags = BitIsSet(opcode, 20); 1401 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1402 if (BadReg(Rd)) 1403 return false; 1404 1405 break; 1406 1407 case eEncodingT3: { 1408 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 1409 // 32); 1410 Rd = Bits32(opcode, 11, 8); 1411 setflags = false; 1412 uint32_t imm4 = Bits32(opcode, 19, 16); 1413 uint32_t imm3 = Bits32(opcode, 14, 12); 1414 uint32_t i = Bit32(opcode, 26); 1415 uint32_t imm8 = Bits32(opcode, 7, 0); 1416 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 1417 1418 // if BadReg(d) then UNPREDICTABLE; 1419 if (BadReg(Rd)) 1420 return false; 1421 } break; 1422 1423 case eEncodingA1: 1424 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = 1425 // ARMExpandImm_C(imm12, APSR.C); 1426 Rd = Bits32(opcode, 15, 12); 1427 setflags = BitIsSet(opcode, 20); 1428 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1429 1430 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1431 // instructions; 1432 if ((Rd == 15) && setflags) 1433 return EmulateSUBSPcLrEtc(opcode, encoding); 1434 1435 break; 1436 1437 case eEncodingA2: { 1438 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 1439 Rd = Bits32(opcode, 15, 12); 1440 setflags = false; 1441 uint32_t imm4 = Bits32(opcode, 19, 16); 1442 uint32_t imm12 = Bits32(opcode, 11, 0); 1443 imm32 = (imm4 << 12) | imm12; 1444 1445 // if d == 15 then UNPREDICTABLE; 1446 if (Rd == 15) 1447 return false; 1448 } break; 1449 1450 default: 1451 return false; 1452 } 1453 uint32_t result = imm32; 1454 1455 // The context specifies that an immediate is to be moved into Rd. 1456 EmulateInstruction::Context context; 1457 context.type = EmulateInstruction::eContextImmediate; 1458 context.SetNoArgs(); 1459 1460 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1461 return false; 1462 } 1463 return true; 1464} 1465 1466// MUL multiplies two register values. The least significant 32 bits of the 1467// result are written to the destination 1468// register. These 32 bits do not depend on whether the source register values 1469// are considered to be signed values or unsigned values. 1470// 1471// Optionally, it can update the condition flags based on the result. In the 1472// Thumb instruction set, this option is limited to only a few forms of the 1473// instruction. 1474bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode, 1475 const ARMEncoding encoding) { 1476#if 0 1477 if ConditionPassed() then 1478 EncodingSpecificOperations(); 1479 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1480 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1481 result = operand1 * operand2; 1482 R[d] = result<31:0>; 1483 if setflags then 1484 APSR.N = result<31>; 1485 APSR.Z = IsZeroBit(result); 1486 if ArchVersion() == 4 then 1487 APSR.C = bit UNKNOWN; 1488 // else APSR.C unchanged 1489 // APSR.V always unchanged 1490#endif 1491 1492 if (ConditionPassed(opcode)) { 1493 uint32_t d; 1494 uint32_t n; 1495 uint32_t m; 1496 bool setflags; 1497 1498 // EncodingSpecificOperations(); 1499 switch (encoding) { 1500 case eEncodingT1: 1501 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 1502 d = Bits32(opcode, 2, 0); 1503 n = Bits32(opcode, 5, 3); 1504 m = Bits32(opcode, 2, 0); 1505 setflags = !InITBlock(); 1506 1507 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1508 if ((ArchVersion() < ARMv6) && (d == n)) 1509 return false; 1510 1511 break; 1512 1513 case eEncodingT2: 1514 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 1515 d = Bits32(opcode, 11, 8); 1516 n = Bits32(opcode, 19, 16); 1517 m = Bits32(opcode, 3, 0); 1518 setflags = false; 1519 1520 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 1521 if (BadReg(d) || BadReg(n) || BadReg(m)) 1522 return false; 1523 1524 break; 1525 1526 case eEncodingA1: 1527 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 1528 d = Bits32(opcode, 19, 16); 1529 n = Bits32(opcode, 3, 0); 1530 m = Bits32(opcode, 11, 8); 1531 setflags = BitIsSet(opcode, 20); 1532 1533 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1534 if ((d == 15) || (n == 15) || (m == 15)) 1535 return false; 1536 1537 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1538 if ((ArchVersion() < ARMv6) && (d == n)) 1539 return false; 1540 1541 break; 1542 1543 default: 1544 return false; 1545 } 1546 1547 bool success = false; 1548 1549 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final 1550 // results 1551 uint64_t operand1 = 1552 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1553 if (!success) 1554 return false; 1555 1556 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final 1557 // results 1558 uint64_t operand2 = 1559 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1560 if (!success) 1561 return false; 1562 1563 // result = operand1 * operand2; 1564 uint64_t result = operand1 * operand2; 1565 1566 // R[d] = result<31:0>; 1567 RegisterInfo op1_reg; 1568 RegisterInfo op2_reg; 1569 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1570 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1571 1572 EmulateInstruction::Context context; 1573 context.type = eContextArithmetic; 1574 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 1575 1576 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 1577 (0x0000ffff & result))) 1578 return false; 1579 1580 // if setflags then 1581 if (setflags) { 1582 // APSR.N = result<31>; 1583 // APSR.Z = IsZeroBit(result); 1584 m_new_inst_cpsr = m_opcode_cpsr; 1585 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31)); 1586 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1587 if (m_new_inst_cpsr != m_opcode_cpsr) { 1588 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1589 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1590 return false; 1591 } 1592 1593 // if ArchVersion() == 4 then 1594 // APSR.C = bit UNKNOWN; 1595 } 1596 } 1597 return true; 1598} 1599 1600// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to 1601// the destination register. It can optionally update the condition flags based 1602// on the value. 1603bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode, 1604 const ARMEncoding encoding) { 1605#if 0 1606 // ARM pseudo code... 1607 if (ConditionPassed()) 1608 { 1609 EncodingSpecificOperations(); 1610 result = NOT(imm32); 1611 if d == 15 then // Can only occur for ARM encoding 1612 ALUWritePC(result); // setflags is always FALSE here 1613 else 1614 R[d] = result; 1615 if setflags then 1616 APSR.N = result<31>; 1617 APSR.Z = IsZeroBit(result); 1618 APSR.C = carry; 1619 // APSR.V unchanged 1620 } 1621#endif 1622 1623 if (ConditionPassed(opcode)) { 1624 uint32_t Rd; // the destination register 1625 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1626 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1627 bool setflags; 1628 switch (encoding) { 1629 case eEncodingT1: 1630 Rd = Bits32(opcode, 11, 8); 1631 setflags = BitIsSet(opcode, 20); 1632 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1633 break; 1634 case eEncodingA1: 1635 Rd = Bits32(opcode, 15, 12); 1636 setflags = BitIsSet(opcode, 20); 1637 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1638 1639 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1640 // instructions; 1641 if (Rd == 15 && setflags) 1642 return EmulateSUBSPcLrEtc(opcode, encoding); 1643 break; 1644 default: 1645 return false; 1646 } 1647 uint32_t result = ~imm32; 1648 1649 // The context specifies that an immediate is to be moved into Rd. 1650 EmulateInstruction::Context context; 1651 context.type = EmulateInstruction::eContextImmediate; 1652 context.SetNoArgs(); 1653 1654 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1655 return false; 1656 } 1657 return true; 1658} 1659 1660// Bitwise NOT (register) writes the bitwise inverse of a register value to the 1661// destination register. It can optionally update the condition flags based on 1662// the result. 1663bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode, 1664 const ARMEncoding encoding) { 1665#if 0 1666 // ARM pseudo code... 1667 if (ConditionPassed()) 1668 { 1669 EncodingSpecificOperations(); 1670 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1671 result = NOT(shifted); 1672 if d == 15 then // Can only occur for ARM encoding 1673 ALUWritePC(result); // setflags is always FALSE here 1674 else 1675 R[d] = result; 1676 if setflags then 1677 APSR.N = result<31>; 1678 APSR.Z = IsZeroBit(result); 1679 APSR.C = carry; 1680 // APSR.V unchanged 1681 } 1682#endif 1683 1684 if (ConditionPassed(opcode)) { 1685 uint32_t Rm; // the source register 1686 uint32_t Rd; // the destination register 1687 ARM_ShifterType shift_t; 1688 uint32_t shift_n; // the shift applied to the value read from Rm 1689 bool setflags; 1690 uint32_t carry; // the carry bit after the shift operation 1691 switch (encoding) { 1692 case eEncodingT1: 1693 Rd = Bits32(opcode, 2, 0); 1694 Rm = Bits32(opcode, 5, 3); 1695 setflags = !InITBlock(); 1696 shift_t = SRType_LSL; 1697 shift_n = 0; 1698 if (InITBlock()) 1699 return false; 1700 break; 1701 case eEncodingT2: 1702 Rd = Bits32(opcode, 11, 8); 1703 Rm = Bits32(opcode, 3, 0); 1704 setflags = BitIsSet(opcode, 20); 1705 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1706 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1707 if (BadReg(Rd) || BadReg(Rm)) 1708 return false; 1709 break; 1710 case eEncodingA1: 1711 Rd = Bits32(opcode, 15, 12); 1712 Rm = Bits32(opcode, 3, 0); 1713 setflags = BitIsSet(opcode, 20); 1714 shift_n = DecodeImmShiftARM(opcode, shift_t); 1715 break; 1716 default: 1717 return false; 1718 } 1719 bool success = false; 1720 uint32_t value = ReadCoreReg(Rm, &success); 1721 if (!success) 1722 return false; 1723 1724 uint32_t shifted = 1725 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1726 if (!success) 1727 return false; 1728 uint32_t result = ~shifted; 1729 1730 // The context specifies that an immediate is to be moved into Rd. 1731 EmulateInstruction::Context context; 1732 context.type = EmulateInstruction::eContextImmediate; 1733 context.SetNoArgs(); 1734 1735 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1736 return false; 1737 } 1738 return true; 1739} 1740 1741// PC relative immediate load into register, possibly followed by ADD (SP plus 1742// register). 1743// LDR (literal) 1744bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode, 1745 const ARMEncoding encoding) { 1746#if 0 1747 // ARM pseudo code... 1748 if (ConditionPassed()) 1749 { 1750 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1751 base = Align(PC,4); 1752 address = if add then (base + imm32) else (base - imm32); 1753 data = MemU[address,4]; 1754 if t == 15 then 1755 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1756 elsif UnalignedSupport() || address<1:0> = '00' then 1757 R[t] = data; 1758 else // Can only apply before ARMv7 1759 if CurrentInstrSet() == InstrSet_ARM then 1760 R[t] = ROR(data, 8*UInt(address<1:0>)); 1761 else 1762 R[t] = bits(32) UNKNOWN; 1763 } 1764#endif 1765 1766 if (ConditionPassed(opcode)) { 1767 bool success = false; 1768 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1769 if (!success) 1770 return false; 1771 1772 // PC relative immediate load context 1773 EmulateInstruction::Context context; 1774 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1775 RegisterInfo pc_reg; 1776 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 1777 context.SetRegisterPlusOffset(pc_reg, 0); 1778 1779 uint32_t Rt; // the destination register 1780 uint32_t imm32; // immediate offset from the PC 1781 bool add; // +imm32 or -imm32? 1782 addr_t base; // the base address 1783 addr_t address; // the PC relative address 1784 uint32_t data; // the literal data value from the PC relative load 1785 switch (encoding) { 1786 case eEncodingT1: 1787 Rt = Bits32(opcode, 10, 8); 1788 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1789 add = true; 1790 break; 1791 case eEncodingT2: 1792 Rt = Bits32(opcode, 15, 12); 1793 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1794 add = BitIsSet(opcode, 23); 1795 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1796 return false; 1797 break; 1798 default: 1799 return false; 1800 } 1801 1802 base = Align(pc, 4); 1803 if (add) 1804 address = base + imm32; 1805 else 1806 address = base - imm32; 1807 1808 context.SetRegisterPlusOffset(pc_reg, address - base); 1809 data = MemURead(context, address, 4, 0, &success); 1810 if (!success) 1811 return false; 1812 1813 if (Rt == 15) { 1814 if (Bits32(address, 1, 0) == 0) { 1815 // In ARMv5T and above, this is an interworking branch. 1816 if (!LoadWritePC(context, data)) 1817 return false; 1818 } else 1819 return false; 1820 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 1821 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 1822 data)) 1823 return false; 1824 } else // We don't handle ARM for now. 1825 return false; 1826 } 1827 return true; 1828} 1829 1830// An add operation to adjust the SP. 1831// ADD (SP plus immediate) 1832bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode, 1833 const ARMEncoding encoding) { 1834#if 0 1835 // ARM pseudo code... 1836 if (ConditionPassed()) 1837 { 1838 EncodingSpecificOperations(); 1839 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1840 if d == 15 then // Can only occur for ARM encoding 1841 ALUWritePC(result); // setflags is always FALSE here 1842 else 1843 R[d] = result; 1844 if setflags then 1845 APSR.N = result<31>; 1846 APSR.Z = IsZeroBit(result); 1847 APSR.C = carry; 1848 APSR.V = overflow; 1849 } 1850#endif 1851 1852 bool success = false; 1853 1854 if (ConditionPassed(opcode)) { 1855 const addr_t sp = ReadCoreReg(SP_REG, &success); 1856 if (!success) 1857 return false; 1858 uint32_t imm32; // the immediate operand 1859 uint32_t d; 1860 bool setflags; 1861 switch (encoding) { 1862 case eEncodingT1: 1863 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1864 d = Bits32(opcode, 10, 8); 1865 imm32 = (Bits32(opcode, 7, 0) << 2); 1866 setflags = false; 1867 break; 1868 1869 case eEncodingT2: 1870 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1871 d = 13; 1872 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1873 setflags = false; 1874 break; 1875 1876 case eEncodingT3: 1877 // d = UInt(Rd); setflags = (S == "1"); imm32 = 1878 // ThumbExpandImm(i:imm3:imm8); 1879 d = Bits32(opcode, 11, 8); 1880 imm32 = ThumbExpandImm(opcode); 1881 setflags = Bit32(opcode, 20); 1882 1883 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 1884 if (d == 15 && setflags == 1) 1885 return false; // CMN (immediate) not yet supported 1886 1887 // if d == 15 && S == "0" then UNPREDICTABLE; 1888 if (d == 15 && setflags == 0) 1889 return false; 1890 break; 1891 1892 case eEncodingT4: { 1893 // if Rn == '1111' then SEE ADR; 1894 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 1895 d = Bits32(opcode, 11, 8); 1896 setflags = false; 1897 uint32_t i = Bit32(opcode, 26); 1898 uint32_t imm3 = Bits32(opcode, 14, 12); 1899 uint32_t imm8 = Bits32(opcode, 7, 0); 1900 imm32 = (i << 11) | (imm3 << 8) | imm8; 1901 1902 // if d == 15 then UNPREDICTABLE; 1903 if (d == 15) 1904 return false; 1905 } break; 1906 1907 default: 1908 return false; 1909 } 1910 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 1911 AddWithCarryResult res = AddWithCarry(sp, imm32, 0); 1912 1913 EmulateInstruction::Context context; 1914 if (d == 13) 1915 context.type = EmulateInstruction::eContextAdjustStackPointer; 1916 else 1917 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1918 1919 RegisterInfo sp_reg; 1920 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1921 context.SetRegisterPlusOffset(sp_reg, res.result - sp); 1922 1923 if (d == 15) { 1924 if (!ALUWritePC(context, res.result)) 1925 return false; 1926 } else { 1927 // R[d] = result; 1928 // if setflags then 1929 // APSR.N = result<31>; 1930 // APSR.Z = IsZeroBit(result); 1931 // APSR.C = carry; 1932 // APSR.V = overflow; 1933 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 1934 res.carry_out, res.overflow)) 1935 return false; 1936 } 1937 } 1938 return true; 1939} 1940 1941// An add operation to adjust the SP. 1942// ADD (SP plus register) 1943bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode, 1944 const ARMEncoding encoding) { 1945#if 0 1946 // ARM pseudo code... 1947 if (ConditionPassed()) 1948 { 1949 EncodingSpecificOperations(); 1950 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1951 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1952 if d == 15 then 1953 ALUWritePC(result); // setflags is always FALSE here 1954 else 1955 R[d] = result; 1956 if setflags then 1957 APSR.N = result<31>; 1958 APSR.Z = IsZeroBit(result); 1959 APSR.C = carry; 1960 APSR.V = overflow; 1961 } 1962#endif 1963 1964 bool success = false; 1965 1966 if (ConditionPassed(opcode)) { 1967 const addr_t sp = ReadCoreReg(SP_REG, &success); 1968 if (!success) 1969 return false; 1970 uint32_t Rm; // the second operand 1971 switch (encoding) { 1972 case eEncodingT2: 1973 Rm = Bits32(opcode, 6, 3); 1974 break; 1975 default: 1976 return false; 1977 } 1978 int32_t reg_value = ReadCoreReg(Rm, &success); 1979 if (!success) 1980 return false; 1981 1982 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1983 1984 EmulateInstruction::Context context; 1985 context.type = eContextArithmetic; 1986 RegisterInfo sp_reg; 1987 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1988 1989 RegisterInfo other_reg; 1990 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1991 context.SetRegisterRegisterOperands(sp_reg, other_reg); 1992 1993 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1994 LLDB_REGNUM_GENERIC_SP, addr)) 1995 return false; 1996 } 1997 return true; 1998} 1999 2000// Branch with Link and Exchange Instruction Sets (immediate) calls a 2001// subroutine at a PC-relative address, and changes instruction set from ARM to 2002// Thumb, or from Thumb to ARM. 2003// BLX (immediate) 2004bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode, 2005 const ARMEncoding encoding) { 2006#if 0 2007 // ARM pseudo code... 2008 if (ConditionPassed()) 2009 { 2010 EncodingSpecificOperations(); 2011 if CurrentInstrSet() == InstrSet_ARM then 2012 LR = PC - 4; 2013 else 2014 LR = PC<31:1> : '1'; 2015 if targetInstrSet == InstrSet_ARM then 2016 targetAddress = Align(PC,4) + imm32; 2017 else 2018 targetAddress = PC + imm32; 2019 SelectInstrSet(targetInstrSet); 2020 BranchWritePC(targetAddress); 2021 } 2022#endif 2023 2024 bool success = true; 2025 2026 if (ConditionPassed(opcode)) { 2027 EmulateInstruction::Context context; 2028 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2029 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2030 if (!success) 2031 return false; 2032 addr_t lr; // next instruction address 2033 addr_t target; // target address 2034 int32_t imm32; // PC-relative offset 2035 switch (encoding) { 2036 case eEncodingT1: { 2037 lr = pc | 1u; // return address 2038 uint32_t S = Bit32(opcode, 26); 2039 uint32_t imm10 = Bits32(opcode, 25, 16); 2040 uint32_t J1 = Bit32(opcode, 13); 2041 uint32_t J2 = Bit32(opcode, 11); 2042 uint32_t imm11 = Bits32(opcode, 10, 0); 2043 uint32_t I1 = !(J1 ^ S); 2044 uint32_t I2 = !(J2 ^ S); 2045 uint32_t imm25 = 2046 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2047 imm32 = llvm::SignExtend32<25>(imm25); 2048 target = pc + imm32; 2049 SelectInstrSet(eModeThumb); 2050 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2051 if (InITBlock() && !LastInITBlock()) 2052 return false; 2053 break; 2054 } 2055 case eEncodingT2: { 2056 lr = pc | 1u; // return address 2057 uint32_t S = Bit32(opcode, 26); 2058 uint32_t imm10H = Bits32(opcode, 25, 16); 2059 uint32_t J1 = Bit32(opcode, 13); 2060 uint32_t J2 = Bit32(opcode, 11); 2061 uint32_t imm10L = Bits32(opcode, 10, 1); 2062 uint32_t I1 = !(J1 ^ S); 2063 uint32_t I2 = !(J2 ^ S); 2064 uint32_t imm25 = 2065 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 2066 imm32 = llvm::SignExtend32<25>(imm25); 2067 target = Align(pc, 4) + imm32; 2068 SelectInstrSet(eModeARM); 2069 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32); 2070 if (InITBlock() && !LastInITBlock()) 2071 return false; 2072 break; 2073 } 2074 case eEncodingA1: 2075 lr = pc - 4; // return address 2076 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2077 target = Align(pc, 4) + imm32; 2078 SelectInstrSet(eModeARM); 2079 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2080 break; 2081 case eEncodingA2: 2082 lr = pc - 4; // return address 2083 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | 2084 Bits32(opcode, 24, 24) << 1); 2085 target = pc + imm32; 2086 SelectInstrSet(eModeThumb); 2087 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32); 2088 break; 2089 default: 2090 return false; 2091 } 2092 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2093 LLDB_REGNUM_GENERIC_RA, lr)) 2094 return false; 2095 if (!BranchWritePC(context, target)) 2096 return false; 2097 if (m_opcode_cpsr != m_new_inst_cpsr) 2098 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2099 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2100 return false; 2101 } 2102 return true; 2103} 2104 2105// Branch with Link and Exchange (register) calls a subroutine at an address 2106// and instruction set specified by a register. 2107// BLX (register) 2108bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode, 2109 const ARMEncoding encoding) { 2110#if 0 2111 // ARM pseudo code... 2112 if (ConditionPassed()) 2113 { 2114 EncodingSpecificOperations(); 2115 target = R[m]; 2116 if CurrentInstrSet() == InstrSet_ARM then 2117 next_instr_addr = PC - 4; 2118 LR = next_instr_addr; 2119 else 2120 next_instr_addr = PC - 2; 2121 LR = next_instr_addr<31:1> : '1'; 2122 BXWritePC(target); 2123 } 2124#endif 2125 2126 bool success = false; 2127 2128 if (ConditionPassed(opcode)) { 2129 EmulateInstruction::Context context; 2130 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2131 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2132 addr_t lr; // next instruction address 2133 if (!success) 2134 return false; 2135 uint32_t Rm; // the register with the target address 2136 switch (encoding) { 2137 case eEncodingT1: 2138 lr = (pc - 2) | 1u; // return address 2139 Rm = Bits32(opcode, 6, 3); 2140 // if m == 15 then UNPREDICTABLE; 2141 if (Rm == 15) 2142 return false; 2143 if (InITBlock() && !LastInITBlock()) 2144 return false; 2145 break; 2146 case eEncodingA1: 2147 lr = pc - 4; // return address 2148 Rm = Bits32(opcode, 3, 0); 2149 // if m == 15 then UNPREDICTABLE; 2150 if (Rm == 15) 2151 return false; 2152 break; 2153 default: 2154 return false; 2155 } 2156 addr_t target = ReadCoreReg(Rm, &success); 2157 if (!success) 2158 return false; 2159 RegisterInfo dwarf_reg; 2160 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2161 context.SetRegister(dwarf_reg); 2162 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2163 LLDB_REGNUM_GENERIC_RA, lr)) 2164 return false; 2165 if (!BXWritePC(context, target)) 2166 return false; 2167 } 2168 return true; 2169} 2170 2171// Branch and Exchange causes a branch to an address and instruction set 2172// specified by a register. 2173bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode, 2174 const ARMEncoding encoding) { 2175#if 0 2176 // ARM pseudo code... 2177 if (ConditionPassed()) 2178 { 2179 EncodingSpecificOperations(); 2180 BXWritePC(R[m]); 2181 } 2182#endif 2183 2184 if (ConditionPassed(opcode)) { 2185 EmulateInstruction::Context context; 2186 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2187 uint32_t Rm; // the register with the target address 2188 switch (encoding) { 2189 case eEncodingT1: 2190 Rm = Bits32(opcode, 6, 3); 2191 if (InITBlock() && !LastInITBlock()) 2192 return false; 2193 break; 2194 case eEncodingA1: 2195 Rm = Bits32(opcode, 3, 0); 2196 break; 2197 default: 2198 return false; 2199 } 2200 bool success = false; 2201 addr_t target = ReadCoreReg(Rm, &success); 2202 if (!success) 2203 return false; 2204 2205 RegisterInfo dwarf_reg; 2206 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2207 context.SetRegister(dwarf_reg); 2208 if (!BXWritePC(context, target)) 2209 return false; 2210 } 2211 return true; 2212} 2213 2214// Branch and Exchange Jazelle attempts to change to Jazelle state. If the 2215// attempt fails, it branches to an address and instruction set specified by a 2216// register as though it were a BX instruction. 2217// 2218// TODO: Emulate Jazelle architecture? 2219// We currently assume that switching to Jazelle state fails, thus 2220// treating BXJ as a BX operation. 2221bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode, 2222 const ARMEncoding encoding) { 2223#if 0 2224 // ARM pseudo code... 2225 if (ConditionPassed()) 2226 { 2227 EncodingSpecificOperations(); 2228 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 2229 BXWritePC(R[m]); 2230 else 2231 if JazelleAcceptsExecution() then 2232 SwitchToJazelleExecution(); 2233 else 2234 SUBARCHITECTURE_DEFINED handler call; 2235 } 2236#endif 2237 2238 if (ConditionPassed(opcode)) { 2239 EmulateInstruction::Context context; 2240 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2241 uint32_t Rm; // the register with the target address 2242 switch (encoding) { 2243 case eEncodingT1: 2244 Rm = Bits32(opcode, 19, 16); 2245 if (BadReg(Rm)) 2246 return false; 2247 if (InITBlock() && !LastInITBlock()) 2248 return false; 2249 break; 2250 case eEncodingA1: 2251 Rm = Bits32(opcode, 3, 0); 2252 if (Rm == 15) 2253 return false; 2254 break; 2255 default: 2256 return false; 2257 } 2258 bool success = false; 2259 addr_t target = ReadCoreReg(Rm, &success); 2260 if (!success) 2261 return false; 2262 2263 RegisterInfo dwarf_reg; 2264 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2265 context.SetRegister(dwarf_reg); 2266 if (!BXWritePC(context, target)) 2267 return false; 2268 } 2269 return true; 2270} 2271 2272// Set r7 to point to some ip offset. 2273// SUB (immediate) 2274bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode, 2275 const ARMEncoding encoding) { 2276#if 0 2277 // ARM pseudo code... 2278 if (ConditionPassed()) 2279 { 2280 EncodingSpecificOperations(); 2281 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2282 if d == 15 then // Can only occur for ARM encoding 2283 ALUWritePC(result); // setflags is always FALSE here 2284 else 2285 R[d] = result; 2286 if setflags then 2287 APSR.N = result<31>; 2288 APSR.Z = IsZeroBit(result); 2289 APSR.C = carry; 2290 APSR.V = overflow; 2291 } 2292#endif 2293 2294 if (ConditionPassed(opcode)) { 2295 bool success = false; 2296 const addr_t ip = ReadCoreReg(12, &success); 2297 if (!success) 2298 return false; 2299 uint32_t imm32; 2300 switch (encoding) { 2301 case eEncodingA1: 2302 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2303 break; 2304 default: 2305 return false; 2306 } 2307 addr_t ip_offset = imm32; 2308 addr_t addr = ip - ip_offset; // the adjusted ip value 2309 2310 EmulateInstruction::Context context; 2311 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2312 RegisterInfo dwarf_reg; 2313 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg); 2314 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset); 2315 2316 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr)) 2317 return false; 2318 } 2319 return true; 2320} 2321 2322// Set ip to point to some stack offset. 2323// SUB (SP minus immediate) 2324bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode, 2325 const ARMEncoding encoding) { 2326#if 0 2327 // ARM pseudo code... 2328 if (ConditionPassed()) 2329 { 2330 EncodingSpecificOperations(); 2331 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2332 if d == 15 then // Can only occur for ARM encoding 2333 ALUWritePC(result); // setflags is always FALSE here 2334 else 2335 R[d] = result; 2336 if setflags then 2337 APSR.N = result<31>; 2338 APSR.Z = IsZeroBit(result); 2339 APSR.C = carry; 2340 APSR.V = overflow; 2341 } 2342#endif 2343 2344 if (ConditionPassed(opcode)) { 2345 bool success = false; 2346 const addr_t sp = ReadCoreReg(SP_REG, &success); 2347 if (!success) 2348 return false; 2349 uint32_t imm32; 2350 switch (encoding) { 2351 case eEncodingA1: 2352 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2353 break; 2354 default: 2355 return false; 2356 } 2357 addr_t sp_offset = imm32; 2358 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 2359 2360 EmulateInstruction::Context context; 2361 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2362 RegisterInfo dwarf_reg; 2363 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 2364 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset); 2365 2366 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr)) 2367 return false; 2368 } 2369 return true; 2370} 2371 2372// This instruction subtracts an immediate value from the SP value, and writes 2373// the result to the destination register. 2374// 2375// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local 2376// storage. 2377bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode, 2378 const ARMEncoding encoding) { 2379#if 0 2380 // ARM pseudo code... 2381 if (ConditionPassed()) 2382 { 2383 EncodingSpecificOperations(); 2384 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2385 if d == 15 then // Can only occur for ARM encoding 2386 ALUWritePC(result); // setflags is always FALSE here 2387 else 2388 R[d] = result; 2389 if setflags then 2390 APSR.N = result<31>; 2391 APSR.Z = IsZeroBit(result); 2392 APSR.C = carry; 2393 APSR.V = overflow; 2394 } 2395#endif 2396 2397 bool success = false; 2398 if (ConditionPassed(opcode)) { 2399 const addr_t sp = ReadCoreReg(SP_REG, &success); 2400 if (!success) 2401 return false; 2402 2403 uint32_t Rd; 2404 bool setflags; 2405 uint32_t imm32; 2406 switch (encoding) { 2407 case eEncodingT1: 2408 Rd = 13; 2409 setflags = false; 2410 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 2411 break; 2412 case eEncodingT2: 2413 Rd = Bits32(opcode, 11, 8); 2414 setflags = BitIsSet(opcode, 20); 2415 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2416 if (Rd == 15 && setflags) 2417 return EmulateCMPImm(opcode, eEncodingT2); 2418 if (Rd == 15 && !setflags) 2419 return false; 2420 break; 2421 case eEncodingT3: 2422 Rd = Bits32(opcode, 11, 8); 2423 setflags = false; 2424 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 2425 if (Rd == 15) 2426 return false; 2427 break; 2428 case eEncodingA1: 2429 Rd = Bits32(opcode, 15, 12); 2430 setflags = BitIsSet(opcode, 20); 2431 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2432 2433 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 2434 // instructions; 2435 if (Rd == 15 && setflags) 2436 return EmulateSUBSPcLrEtc(opcode, encoding); 2437 break; 2438 default: 2439 return false; 2440 } 2441 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 2442 2443 EmulateInstruction::Context context; 2444 if (Rd == 13) { 2445 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting 2446 // to negate it, or the wrong 2447 // value gets passed down to context.SetImmediateSigned. 2448 context.type = EmulateInstruction::eContextAdjustStackPointer; 2449 context.SetImmediateSigned(-imm64); // the stack pointer offset 2450 } else { 2451 context.type = EmulateInstruction::eContextImmediate; 2452 context.SetNoArgs(); 2453 } 2454 2455 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 2456 res.carry_out, res.overflow)) 2457 return false; 2458 } 2459 return true; 2460} 2461 2462// A store operation to the stack that also updates the SP. 2463bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode, 2464 const ARMEncoding encoding) { 2465#if 0 2466 // ARM pseudo code... 2467 if (ConditionPassed()) 2468 { 2469 EncodingSpecificOperations(); 2470 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2471 address = if index then offset_addr else R[n]; 2472 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 2473 if wback then R[n] = offset_addr; 2474 } 2475#endif 2476 2477 bool success = false; 2478 if (ConditionPassed(opcode)) { 2479 const uint32_t addr_byte_size = GetAddressByteSize(); 2480 const addr_t sp = ReadCoreReg(SP_REG, &success); 2481 if (!success) 2482 return false; 2483 uint32_t Rt; // the source register 2484 uint32_t imm12; 2485 uint32_t 2486 Rn; // This function assumes Rn is the SP, but we should verify that. 2487 2488 bool index; 2489 bool add; 2490 bool wback; 2491 switch (encoding) { 2492 case eEncodingA1: 2493 Rt = Bits32(opcode, 15, 12); 2494 imm12 = Bits32(opcode, 11, 0); 2495 Rn = Bits32(opcode, 19, 16); 2496 2497 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 2498 return false; 2499 2500 index = BitIsSet(opcode, 24); 2501 add = BitIsSet(opcode, 23); 2502 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 2503 2504 if (wback && ((Rn == 15) || (Rn == Rt))) 2505 return false; 2506 break; 2507 default: 2508 return false; 2509 } 2510 addr_t offset_addr; 2511 if (add) 2512 offset_addr = sp + imm12; 2513 else 2514 offset_addr = sp - imm12; 2515 2516 addr_t addr; 2517 if (index) 2518 addr = offset_addr; 2519 else 2520 addr = sp; 2521 2522 EmulateInstruction::Context context; 2523 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2524 RegisterInfo sp_reg; 2525 RegisterInfo dwarf_reg; 2526 2527 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2528 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2529 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2530 if (Rt != 15) { 2531 uint32_t reg_value = ReadCoreReg(Rt, &success); 2532 if (!success) 2533 return false; 2534 if (!MemUWrite(context, addr, reg_value, addr_byte_size)) 2535 return false; 2536 } else { 2537 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2538 if (!success) 2539 return false; 2540 if (!MemUWrite(context, addr, pc, addr_byte_size)) 2541 return false; 2542 } 2543 2544 if (wback) { 2545 context.type = EmulateInstruction::eContextAdjustStackPointer; 2546 context.SetImmediateSigned(addr - sp); 2547 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2548 LLDB_REGNUM_GENERIC_SP, offset_addr)) 2549 return false; 2550 } 2551 } 2552 return true; 2553} 2554 2555// Vector Push stores multiple extension registers to the stack. It also 2556// updates SP to point to the start of the stored data. 2557bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode, 2558 const ARMEncoding encoding) { 2559#if 0 2560 // ARM pseudo code... 2561 if (ConditionPassed()) 2562 { 2563 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2564 address = SP - imm32; 2565 SP = SP - imm32; 2566 if single_regs then 2567 for r = 0 to regs-1 2568 MemA[address,4] = S[d+r]; address = address+4; 2569 else 2570 for r = 0 to regs-1 2571 // Store as two word-aligned words in the correct order for 2572 // current endianness. 2573 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2574 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2575 address = address+8; 2576 } 2577#endif 2578 2579 bool success = false; 2580 if (ConditionPassed(opcode)) { 2581 const uint32_t addr_byte_size = GetAddressByteSize(); 2582 const addr_t sp = ReadCoreReg(SP_REG, &success); 2583 if (!success) 2584 return false; 2585 bool single_regs; 2586 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2587 uint32_t imm32; // stack offset 2588 uint32_t regs; // number of registers 2589 switch (encoding) { 2590 case eEncodingT1: 2591 case eEncodingA1: 2592 single_regs = false; 2593 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2594 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2595 // If UInt(imm8) is odd, see "FSTMX". 2596 regs = Bits32(opcode, 7, 0) / 2; 2597 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2598 if (regs == 0 || regs > 16 || (d + regs) > 32) 2599 return false; 2600 break; 2601 case eEncodingT2: 2602 case eEncodingA2: 2603 single_regs = true; 2604 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2605 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2606 regs = Bits32(opcode, 7, 0); 2607 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2608 if (regs == 0 || regs > 16 || (d + regs) > 32) 2609 return false; 2610 break; 2611 default: 2612 return false; 2613 } 2614 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2615 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2616 addr_t sp_offset = imm32; 2617 addr_t addr = sp - sp_offset; 2618 uint32_t i; 2619 2620 EmulateInstruction::Context context; 2621 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2622 2623 RegisterInfo dwarf_reg; 2624 RegisterInfo sp_reg; 2625 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2626 for (i = 0; i < regs; ++i) { 2627 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2628 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2629 // uint64_t to accommodate 64-bit registers. 2630 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success); 2631 if (!success) 2632 return false; 2633 if (!MemAWrite(context, addr, reg_value, reg_byte_size)) 2634 return false; 2635 addr += reg_byte_size; 2636 } 2637 2638 context.type = EmulateInstruction::eContextAdjustStackPointer; 2639 context.SetImmediateSigned(-sp_offset); 2640 2641 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2642 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2643 return false; 2644 } 2645 return true; 2646} 2647 2648// Vector Pop loads multiple extension registers from the stack. It also 2649// updates SP to point just above the loaded data. 2650bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode, 2651 const ARMEncoding encoding) { 2652#if 0 2653 // ARM pseudo code... 2654 if (ConditionPassed()) 2655 { 2656 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2657 address = SP; 2658 SP = SP + imm32; 2659 if single_regs then 2660 for r = 0 to regs-1 2661 S[d+r] = MemA[address,4]; address = address+4; 2662 else 2663 for r = 0 to regs-1 2664 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2665 // Combine the word-aligned words in the correct order for 2666 // current endianness. 2667 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2668 } 2669#endif 2670 2671 bool success = false; 2672 if (ConditionPassed(opcode)) { 2673 const uint32_t addr_byte_size = GetAddressByteSize(); 2674 const addr_t sp = ReadCoreReg(SP_REG, &success); 2675 if (!success) 2676 return false; 2677 bool single_regs; 2678 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2679 uint32_t imm32; // stack offset 2680 uint32_t regs; // number of registers 2681 switch (encoding) { 2682 case eEncodingT1: 2683 case eEncodingA1: 2684 single_regs = false; 2685 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2686 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2687 // If UInt(imm8) is odd, see "FLDMX". 2688 regs = Bits32(opcode, 7, 0) / 2; 2689 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2690 if (regs == 0 || regs > 16 || (d + regs) > 32) 2691 return false; 2692 break; 2693 case eEncodingT2: 2694 case eEncodingA2: 2695 single_regs = true; 2696 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2697 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2698 regs = Bits32(opcode, 7, 0); 2699 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2700 if (regs == 0 || regs > 16 || (d + regs) > 32) 2701 return false; 2702 break; 2703 default: 2704 return false; 2705 } 2706 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2707 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2708 addr_t sp_offset = imm32; 2709 addr_t addr = sp; 2710 uint32_t i; 2711 uint64_t data; // uint64_t to accommodate 64-bit registers. 2712 2713 EmulateInstruction::Context context; 2714 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2715 2716 RegisterInfo dwarf_reg; 2717 RegisterInfo sp_reg; 2718 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2719 for (i = 0; i < regs; ++i) { 2720 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2721 context.SetAddress(addr); 2722 data = MemARead(context, addr, reg_byte_size, 0, &success); 2723 if (!success) 2724 return false; 2725 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2726 return false; 2727 addr += reg_byte_size; 2728 } 2729 2730 context.type = EmulateInstruction::eContextAdjustStackPointer; 2731 context.SetImmediateSigned(sp_offset); 2732 2733 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2734 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2735 return false; 2736 } 2737 return true; 2738} 2739 2740// SVC (previously SWI) 2741bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode, 2742 const ARMEncoding encoding) { 2743#if 0 2744 // ARM pseudo code... 2745 if (ConditionPassed()) 2746 { 2747 EncodingSpecificOperations(); 2748 CallSupervisor(); 2749 } 2750#endif 2751 2752 bool success = false; 2753 2754 if (ConditionPassed(opcode)) { 2755 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2756 addr_t lr; // next instruction address 2757 if (!success) 2758 return false; 2759 uint32_t imm32; // the immediate constant 2760 uint32_t mode; // ARM or Thumb mode 2761 switch (encoding) { 2762 case eEncodingT1: 2763 lr = (pc + 2) | 1u; // return address 2764 imm32 = Bits32(opcode, 7, 0); 2765 mode = eModeThumb; 2766 break; 2767 case eEncodingA1: 2768 lr = pc + 4; // return address 2769 imm32 = Bits32(opcode, 23, 0); 2770 mode = eModeARM; 2771 break; 2772 default: 2773 return false; 2774 } 2775 2776 EmulateInstruction::Context context; 2777 context.type = EmulateInstruction::eContextSupervisorCall; 2778 context.SetISAAndImmediate(mode, imm32); 2779 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2780 LLDB_REGNUM_GENERIC_RA, lr)) 2781 return false; 2782 } 2783 return true; 2784} 2785 2786// If Then makes up to four following instructions (the IT block) conditional. 2787bool EmulateInstructionARM::EmulateIT(const uint32_t opcode, 2788 const ARMEncoding encoding) { 2789#if 0 2790 // ARM pseudo code... 2791 EncodingSpecificOperations(); 2792 ITSTATE.IT<7:0> = firstcond:mask; 2793#endif 2794 2795 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2796 return true; 2797} 2798 2799bool EmulateInstructionARM::EmulateNop(const uint32_t opcode, 2800 const ARMEncoding encoding) { 2801 // NOP, nothing to do... 2802 return true; 2803} 2804 2805// Branch causes a branch to a target address. 2806bool EmulateInstructionARM::EmulateB(const uint32_t opcode, 2807 const ARMEncoding encoding) { 2808#if 0 2809 // ARM pseudo code... 2810 if (ConditionPassed()) 2811 { 2812 EncodingSpecificOperations(); 2813 BranchWritePC(PC + imm32); 2814 } 2815#endif 2816 2817 bool success = false; 2818 2819 if (ConditionPassed(opcode)) { 2820 EmulateInstruction::Context context; 2821 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2822 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2823 if (!success) 2824 return false; 2825 addr_t target; // target address 2826 int32_t imm32; // PC-relative offset 2827 switch (encoding) { 2828 case eEncodingT1: 2829 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2830 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2831 target = pc + imm32; 2832 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2833 break; 2834 case eEncodingT2: 2835 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2836 target = pc + imm32; 2837 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2838 break; 2839 case eEncodingT3: 2840 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2841 { 2842 if (Bits32(opcode, 25, 23) == 7) 2843 return false; // See Branches and miscellaneous control on page 2844 // A6-235. 2845 2846 uint32_t S = Bit32(opcode, 26); 2847 uint32_t imm6 = Bits32(opcode, 21, 16); 2848 uint32_t J1 = Bit32(opcode, 13); 2849 uint32_t J2 = Bit32(opcode, 11); 2850 uint32_t imm11 = Bits32(opcode, 10, 0); 2851 uint32_t imm21 = 2852 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2853 imm32 = llvm::SignExtend32<21>(imm21); 2854 target = pc + imm32; 2855 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2856 break; 2857 } 2858 case eEncodingT4: { 2859 uint32_t S = Bit32(opcode, 26); 2860 uint32_t imm10 = Bits32(opcode, 25, 16); 2861 uint32_t J1 = Bit32(opcode, 13); 2862 uint32_t J2 = Bit32(opcode, 11); 2863 uint32_t imm11 = Bits32(opcode, 10, 0); 2864 uint32_t I1 = !(J1 ^ S); 2865 uint32_t I2 = !(J2 ^ S); 2866 uint32_t imm25 = 2867 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2868 imm32 = llvm::SignExtend32<25>(imm25); 2869 target = pc + imm32; 2870 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2871 break; 2872 } 2873 case eEncodingA1: 2874 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2875 target = pc + imm32; 2876 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2877 break; 2878 default: 2879 return false; 2880 } 2881 if (!BranchWritePC(context, target)) 2882 return false; 2883 } 2884 return true; 2885} 2886 2887// Compare and Branch on Nonzero and Compare and Branch on Zero compare the 2888// value in a register with zero and conditionally branch forward a constant 2889// value. They do not affect the condition flags. CBNZ, CBZ 2890bool EmulateInstructionARM::EmulateCB(const uint32_t opcode, 2891 const ARMEncoding encoding) { 2892#if 0 2893 // ARM pseudo code... 2894 EncodingSpecificOperations(); 2895 if nonzero ^ IsZero(R[n]) then 2896 BranchWritePC(PC + imm32); 2897#endif 2898 2899 bool success = false; 2900 2901 // Read the register value from the operand register Rn. 2902 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2903 if (!success) 2904 return false; 2905 2906 EmulateInstruction::Context context; 2907 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2908 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2909 if (!success) 2910 return false; 2911 2912 addr_t target; // target address 2913 uint32_t imm32; // PC-relative offset to branch forward 2914 bool nonzero; 2915 switch (encoding) { 2916 case eEncodingT1: 2917 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2918 nonzero = BitIsSet(opcode, 11); 2919 target = pc + imm32; 2920 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2921 break; 2922 default: 2923 return false; 2924 } 2925 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2926 if (!BranchWritePC(context, target)) 2927 return false; 2928 2929 return true; 2930} 2931 2932// Table Branch Byte causes a PC-relative forward branch using a table of 2933// single byte offsets. 2934// A base register provides a pointer to the table, and a second register 2935// supplies an index into the table. 2936// The branch length is twice the value of the byte returned from the table. 2937// 2938// Table Branch Halfword causes a PC-relative forward branch using a table of 2939// single halfword offsets. 2940// A base register provides a pointer to the table, and a second register 2941// supplies an index into the table. 2942// The branch length is twice the value of the halfword returned from the 2943// table. TBB, TBH 2944bool EmulateInstructionARM::EmulateTB(const uint32_t opcode, 2945 const ARMEncoding encoding) { 2946#if 0 2947 // ARM pseudo code... 2948 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2949 if is_tbh then 2950 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2951 else 2952 halfwords = UInt(MemU[R[n]+R[m], 1]); 2953 BranchWritePC(PC + 2*halfwords); 2954#endif 2955 2956 bool success = false; 2957 2958 if (ConditionPassed(opcode)) { 2959 uint32_t Rn; // the base register which contains the address of the table of 2960 // branch lengths 2961 uint32_t Rm; // the index register which contains an integer pointing to a 2962 // byte/halfword in the table 2963 bool is_tbh; // true if table branch halfword 2964 switch (encoding) { 2965 case eEncodingT1: 2966 Rn = Bits32(opcode, 19, 16); 2967 Rm = Bits32(opcode, 3, 0); 2968 is_tbh = BitIsSet(opcode, 4); 2969 if (Rn == 13 || BadReg(Rm)) 2970 return false; 2971 if (InITBlock() && !LastInITBlock()) 2972 return false; 2973 break; 2974 default: 2975 return false; 2976 } 2977 2978 // Read the address of the table from the operand register Rn. The PC can 2979 // be used, in which case the table immediately follows this instruction. 2980 uint32_t base = ReadCoreReg(Rn, &success); 2981 if (!success) 2982 return false; 2983 2984 // the table index 2985 uint32_t index = ReadCoreReg(Rm, &success); 2986 if (!success) 2987 return false; 2988 2989 // the offsetted table address 2990 addr_t addr = base + (is_tbh ? index * 2 : index); 2991 2992 // PC-relative offset to branch forward 2993 EmulateInstruction::Context context; 2994 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2995 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2996 if (!success) 2997 return false; 2998 2999 const uint32_t pc = ReadCoreReg(PC_REG, &success); 3000 if (!success) 3001 return false; 3002 3003 // target address 3004 addr_t target = pc + offset; 3005 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 3006 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset); 3007 3008 if (!BranchWritePC(context, target)) 3009 return false; 3010 } 3011 3012 return true; 3013} 3014 3015// This instruction adds an immediate value to a register value, and writes the 3016// result to the destination register. It can optionally update the condition 3017// flags based on the result. 3018bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode, 3019 const ARMEncoding encoding) { 3020#if 0 3021 if ConditionPassed() then 3022 EncodingSpecificOperations(); 3023 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3024 R[d] = result; 3025 if setflags then 3026 APSR.N = result<31>; 3027 APSR.Z = IsZeroBit(result); 3028 APSR.C = carry; 3029 APSR.V = overflow; 3030#endif 3031 3032 bool success = false; 3033 3034 if (ConditionPassed(opcode)) { 3035 uint32_t d; 3036 uint32_t n; 3037 bool setflags; 3038 uint32_t imm32; 3039 uint32_t carry_out; 3040 3041 // EncodingSpecificOperations(); 3042 switch (encoding) { 3043 case eEncodingT1: 3044 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = 3045 // ZeroExtend(imm3, 32); 3046 d = Bits32(opcode, 2, 0); 3047 n = Bits32(opcode, 5, 3); 3048 setflags = !InITBlock(); 3049 imm32 = Bits32(opcode, 8, 6); 3050 3051 break; 3052 3053 case eEncodingT2: 3054 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = 3055 // ZeroExtend(imm8, 32); 3056 d = Bits32(opcode, 10, 8); 3057 n = Bits32(opcode, 10, 8); 3058 setflags = !InITBlock(); 3059 imm32 = Bits32(opcode, 7, 0); 3060 3061 break; 3062 3063 case eEncodingT3: 3064 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 3065 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = 3066 // ThumbExpandImm(i:imm3:imm8); 3067 d = Bits32(opcode, 11, 8); 3068 n = Bits32(opcode, 19, 16); 3069 setflags = BitIsSet(opcode, 20); 3070 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out); 3071 3072 // if Rn == '1101' then SEE ADD (SP plus immediate); 3073 if (n == 13) 3074 return EmulateADDSPImm(opcode, eEncodingT3); 3075 3076 // if BadReg(d) || n == 15 then UNPREDICTABLE; 3077 if (BadReg(d) || (n == 15)) 3078 return false; 3079 3080 break; 3081 3082 case eEncodingT4: { 3083 // if Rn == '1111' then SEE ADR; 3084 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = 3085 // ZeroExtend(i:imm3:imm8, 32); 3086 d = Bits32(opcode, 11, 8); 3087 n = Bits32(opcode, 19, 16); 3088 setflags = false; 3089 uint32_t i = Bit32(opcode, 26); 3090 uint32_t imm3 = Bits32(opcode, 14, 12); 3091 uint32_t imm8 = Bits32(opcode, 7, 0); 3092 imm32 = (i << 11) | (imm3 << 8) | imm8; 3093 3094 // if Rn == '1101' then SEE ADD (SP plus immediate); 3095 if (n == 13) 3096 return EmulateADDSPImm(opcode, eEncodingT4); 3097 3098 // if BadReg(d) then UNPREDICTABLE; 3099 if (BadReg(d)) 3100 return false; 3101 3102 break; 3103 } 3104 3105 default: 3106 return false; 3107 } 3108 3109 uint64_t Rn = 3110 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3111 if (!success) 3112 return false; 3113 3114 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3115 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0); 3116 3117 RegisterInfo reg_n; 3118 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 3119 3120 EmulateInstruction::Context context; 3121 context.type = eContextArithmetic; 3122 context.SetRegisterPlusOffset(reg_n, imm32); 3123 3124 // R[d] = result; 3125 // if setflags then 3126 // APSR.N = result<31>; 3127 // APSR.Z = IsZeroBit(result); 3128 // APSR.C = carry; 3129 // APSR.V = overflow; 3130 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 3131 res.carry_out, res.overflow)) 3132 return false; 3133 } 3134 return true; 3135} 3136 3137// This instruction adds an immediate value to a register value, and writes the 3138// result to the destination register. It can optionally update the condition 3139// flags based on the result. 3140bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode, 3141 const ARMEncoding encoding) { 3142#if 0 3143 // ARM pseudo code... 3144 if ConditionPassed() then 3145 EncodingSpecificOperations(); 3146 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3147 if d == 15 then 3148 ALUWritePC(result); // setflags is always FALSE here 3149 else 3150 R[d] = result; 3151 if setflags then 3152 APSR.N = result<31>; 3153 APSR.Z = IsZeroBit(result); 3154 APSR.C = carry; 3155 APSR.V = overflow; 3156#endif 3157 3158 bool success = false; 3159 3160 if (ConditionPassed(opcode)) { 3161 uint32_t Rd, Rn; 3162 uint32_t 3163 imm32; // the immediate value to be added to the value obtained from Rn 3164 bool setflags; 3165 switch (encoding) { 3166 case eEncodingA1: 3167 Rd = Bits32(opcode, 15, 12); 3168 Rn = Bits32(opcode, 19, 16); 3169 setflags = BitIsSet(opcode, 20); 3170 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3171 break; 3172 default: 3173 return false; 3174 } 3175 3176 // Read the first operand. 3177 uint32_t val1 = ReadCoreReg(Rn, &success); 3178 if (!success) 3179 return false; 3180 3181 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 3182 3183 EmulateInstruction::Context context; 3184 if (Rd == 13) 3185 context.type = EmulateInstruction::eContextAdjustStackPointer; 3186 else if (Rd == GetFramePointerRegisterNumber()) 3187 context.type = EmulateInstruction::eContextSetFramePointer; 3188 else 3189 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3190 3191 RegisterInfo dwarf_reg; 3192 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 3193 context.SetRegisterPlusOffset(dwarf_reg, imm32); 3194 3195 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3196 res.carry_out, res.overflow)) 3197 return false; 3198 } 3199 return true; 3200} 3201 3202// This instruction adds a register value and an optionally-shifted register 3203// value, and writes the result to the destination register. It can optionally 3204// update the condition flags based on the result. 3205bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode, 3206 const ARMEncoding encoding) { 3207#if 0 3208 // ARM pseudo code... 3209 if ConditionPassed() then 3210 EncodingSpecificOperations(); 3211 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3212 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3213 if d == 15 then 3214 ALUWritePC(result); // setflags is always FALSE here 3215 else 3216 R[d] = result; 3217 if setflags then 3218 APSR.N = result<31>; 3219 APSR.Z = IsZeroBit(result); 3220 APSR.C = carry; 3221 APSR.V = overflow; 3222#endif 3223 3224 bool success = false; 3225 3226 if (ConditionPassed(opcode)) { 3227 uint32_t Rd, Rn, Rm; 3228 ARM_ShifterType shift_t; 3229 uint32_t shift_n; // the shift applied to the value read from Rm 3230 bool setflags; 3231 switch (encoding) { 3232 case eEncodingT1: 3233 Rd = Bits32(opcode, 2, 0); 3234 Rn = Bits32(opcode, 5, 3); 3235 Rm = Bits32(opcode, 8, 6); 3236 setflags = !InITBlock(); 3237 shift_t = SRType_LSL; 3238 shift_n = 0; 3239 break; 3240 case eEncodingT2: 3241 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3242 Rm = Bits32(opcode, 6, 3); 3243 setflags = false; 3244 shift_t = SRType_LSL; 3245 shift_n = 0; 3246 if (Rn == 15 && Rm == 15) 3247 return false; 3248 if (Rd == 15 && InITBlock() && !LastInITBlock()) 3249 return false; 3250 break; 3251 case eEncodingA1: 3252 Rd = Bits32(opcode, 15, 12); 3253 Rn = Bits32(opcode, 19, 16); 3254 Rm = Bits32(opcode, 3, 0); 3255 setflags = BitIsSet(opcode, 20); 3256 shift_n = DecodeImmShiftARM(opcode, shift_t); 3257 break; 3258 default: 3259 return false; 3260 } 3261 3262 // Read the first operand. 3263 uint32_t val1 = ReadCoreReg(Rn, &success); 3264 if (!success) 3265 return false; 3266 3267 // Read the second operand. 3268 uint32_t val2 = ReadCoreReg(Rm, &success); 3269 if (!success) 3270 return false; 3271 3272 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3273 if (!success) 3274 return false; 3275 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3276 3277 EmulateInstruction::Context context; 3278 context.type = eContextArithmetic; 3279 RegisterInfo op1_reg; 3280 RegisterInfo op2_reg; 3281 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 3282 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 3283 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 3284 3285 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3286 res.carry_out, res.overflow)) 3287 return false; 3288 } 3289 return true; 3290} 3291 3292// Compare Negative (immediate) adds a register value and an immediate value. 3293// It updates the condition flags based on the result, and discards the result. 3294bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode, 3295 const ARMEncoding encoding) { 3296#if 0 3297 // ARM pseudo code... 3298 if ConditionPassed() then 3299 EncodingSpecificOperations(); 3300 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3301 APSR.N = result<31>; 3302 APSR.Z = IsZeroBit(result); 3303 APSR.C = carry; 3304 APSR.V = overflow; 3305#endif 3306 3307 bool success = false; 3308 3309 uint32_t Rn; // the first operand 3310 uint32_t imm32; // the immediate value to be compared with 3311 switch (encoding) { 3312 case eEncodingT1: 3313 Rn = Bits32(opcode, 19, 16); 3314 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3315 if (Rn == 15) 3316 return false; 3317 break; 3318 case eEncodingA1: 3319 Rn = Bits32(opcode, 19, 16); 3320 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3321 break; 3322 default: 3323 return false; 3324 } 3325 // Read the register value from the operand register Rn. 3326 uint32_t reg_val = ReadCoreReg(Rn, &success); 3327 if (!success) 3328 return false; 3329 3330 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 3331 3332 EmulateInstruction::Context context; 3333 context.type = EmulateInstruction::eContextImmediate; 3334 context.SetNoArgs(); 3335 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3336} 3337 3338// Compare Negative (register) adds a register value and an optionally-shifted 3339// register value. It updates the condition flags based on the result, and 3340// discards the result. 3341bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode, 3342 const ARMEncoding encoding) { 3343#if 0 3344 // ARM pseudo code... 3345 if ConditionPassed() then 3346 EncodingSpecificOperations(); 3347 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3348 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3349 APSR.N = result<31>; 3350 APSR.Z = IsZeroBit(result); 3351 APSR.C = carry; 3352 APSR.V = overflow; 3353#endif 3354 3355 bool success = false; 3356 3357 uint32_t Rn; // the first operand 3358 uint32_t Rm; // the second operand 3359 ARM_ShifterType shift_t; 3360 uint32_t shift_n; // the shift applied to the value read from Rm 3361 switch (encoding) { 3362 case eEncodingT1: 3363 Rn = Bits32(opcode, 2, 0); 3364 Rm = Bits32(opcode, 5, 3); 3365 shift_t = SRType_LSL; 3366 shift_n = 0; 3367 break; 3368 case eEncodingT2: 3369 Rn = Bits32(opcode, 19, 16); 3370 Rm = Bits32(opcode, 3, 0); 3371 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3372 // if n == 15 || BadReg(m) then UNPREDICTABLE; 3373 if (Rn == 15 || BadReg(Rm)) 3374 return false; 3375 break; 3376 case eEncodingA1: 3377 Rn = Bits32(opcode, 19, 16); 3378 Rm = Bits32(opcode, 3, 0); 3379 shift_n = DecodeImmShiftARM(opcode, shift_t); 3380 break; 3381 default: 3382 return false; 3383 } 3384 // Read the register value from register Rn. 3385 uint32_t val1 = ReadCoreReg(Rn, &success); 3386 if (!success) 3387 return false; 3388 3389 // Read the register value from register Rm. 3390 uint32_t val2 = ReadCoreReg(Rm, &success); 3391 if (!success) 3392 return false; 3393 3394 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3395 if (!success) 3396 return false; 3397 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3398 3399 EmulateInstruction::Context context; 3400 context.type = EmulateInstruction::eContextImmediate; 3401 context.SetNoArgs(); 3402 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3403} 3404 3405// Compare (immediate) subtracts an immediate value from a register value. It 3406// updates the condition flags based on the result, and discards the result. 3407bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode, 3408 const ARMEncoding encoding) { 3409#if 0 3410 // ARM pseudo code... 3411 if ConditionPassed() then 3412 EncodingSpecificOperations(); 3413 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 3414 APSR.N = result<31>; 3415 APSR.Z = IsZeroBit(result); 3416 APSR.C = carry; 3417 APSR.V = overflow; 3418#endif 3419 3420 bool success = false; 3421 3422 uint32_t Rn; // the first operand 3423 uint32_t imm32; // the immediate value to be compared with 3424 switch (encoding) { 3425 case eEncodingT1: 3426 Rn = Bits32(opcode, 10, 8); 3427 imm32 = Bits32(opcode, 7, 0); 3428 break; 3429 case eEncodingT2: 3430 Rn = Bits32(opcode, 19, 16); 3431 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3432 if (Rn == 15) 3433 return false; 3434 break; 3435 case eEncodingA1: 3436 Rn = Bits32(opcode, 19, 16); 3437 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3438 break; 3439 default: 3440 return false; 3441 } 3442 // Read the register value from the operand register Rn. 3443 uint32_t reg_val = ReadCoreReg(Rn, &success); 3444 if (!success) 3445 return false; 3446 3447 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 3448 3449 EmulateInstruction::Context context; 3450 context.type = EmulateInstruction::eContextImmediate; 3451 context.SetNoArgs(); 3452 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3453} 3454 3455// Compare (register) subtracts an optionally-shifted register value from a 3456// register value. It updates the condition flags based on the result, and 3457// discards the result. 3458bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode, 3459 const ARMEncoding encoding) { 3460#if 0 3461 // ARM pseudo code... 3462 if ConditionPassed() then 3463 EncodingSpecificOperations(); 3464 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3465 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 3466 APSR.N = result<31>; 3467 APSR.Z = IsZeroBit(result); 3468 APSR.C = carry; 3469 APSR.V = overflow; 3470#endif 3471 3472 bool success = false; 3473 3474 uint32_t Rn; // the first operand 3475 uint32_t Rm; // the second operand 3476 ARM_ShifterType shift_t; 3477 uint32_t shift_n; // the shift applied to the value read from Rm 3478 switch (encoding) { 3479 case eEncodingT1: 3480 Rn = Bits32(opcode, 2, 0); 3481 Rm = Bits32(opcode, 5, 3); 3482 shift_t = SRType_LSL; 3483 shift_n = 0; 3484 break; 3485 case eEncodingT2: 3486 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3487 Rm = Bits32(opcode, 6, 3); 3488 shift_t = SRType_LSL; 3489 shift_n = 0; 3490 if (Rn < 8 && Rm < 8) 3491 return false; 3492 if (Rn == 15 || Rm == 15) 3493 return false; 3494 break; 3495 case eEncodingT3: 3496 Rn = Bits32(opcode, 19, 16); 3497 Rm = Bits32(opcode, 3, 0); 3498 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3499 if (Rn == 15 || BadReg(Rm)) 3500 return false; 3501 break; 3502 case eEncodingA1: 3503 Rn = Bits32(opcode, 19, 16); 3504 Rm = Bits32(opcode, 3, 0); 3505 shift_n = DecodeImmShiftARM(opcode, shift_t); 3506 break; 3507 default: 3508 return false; 3509 } 3510 // Read the register value from register Rn. 3511 uint32_t val1 = ReadCoreReg(Rn, &success); 3512 if (!success) 3513 return false; 3514 3515 // Read the register value from register Rm. 3516 uint32_t val2 = ReadCoreReg(Rm, &success); 3517 if (!success) 3518 return false; 3519 3520 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3521 if (!success) 3522 return false; 3523 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3524 3525 EmulateInstruction::Context context; 3526 context.type = EmulateInstruction::eContextImmediate; 3527 context.SetNoArgs(); 3528 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3529} 3530 3531// Arithmetic Shift Right (immediate) shifts a register value right by an 3532// immediate number of bits, shifting in copies of its sign bit, and writes the 3533// result to the destination register. It can optionally update the condition 3534// flags based on the result. 3535bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode, 3536 const ARMEncoding encoding) { 3537#if 0 3538 // ARM pseudo code... 3539 if ConditionPassed() then 3540 EncodingSpecificOperations(); 3541 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3542 if d == 15 then // Can only occur for ARM encoding 3543 ALUWritePC(result); // setflags is always FALSE here 3544 else 3545 R[d] = result; 3546 if setflags then 3547 APSR.N = result<31>; 3548 APSR.Z = IsZeroBit(result); 3549 APSR.C = carry; 3550 // APSR.V unchanged 3551#endif 3552 3553 return EmulateShiftImm(opcode, encoding, SRType_ASR); 3554} 3555 3556// Arithmetic Shift Right (register) shifts a register value right by a 3557// variable number of bits, shifting in copies of its sign bit, and writes the 3558// result to the destination register. The variable number of bits is read from 3559// the bottom byte of a register. It can optionally update the condition flags 3560// based on the result. 3561bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode, 3562 const ARMEncoding encoding) { 3563#if 0 3564 // ARM pseudo code... 3565 if ConditionPassed() then 3566 EncodingSpecificOperations(); 3567 shift_n = UInt(R[m]<7:0>); 3568 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3569 R[d] = result; 3570 if setflags then 3571 APSR.N = result<31>; 3572 APSR.Z = IsZeroBit(result); 3573 APSR.C = carry; 3574 // APSR.V unchanged 3575#endif 3576 3577 return EmulateShiftReg(opcode, encoding, SRType_ASR); 3578} 3579 3580// Logical Shift Left (immediate) shifts a register value left by an immediate 3581// number of bits, shifting in zeros, and writes the result to the destination 3582// register. It can optionally update the condition flags based on the result. 3583bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode, 3584 const ARMEncoding encoding) { 3585#if 0 3586 // ARM pseudo code... 3587 if ConditionPassed() then 3588 EncodingSpecificOperations(); 3589 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3590 if d == 15 then // Can only occur for ARM encoding 3591 ALUWritePC(result); // setflags is always FALSE here 3592 else 3593 R[d] = result; 3594 if setflags then 3595 APSR.N = result<31>; 3596 APSR.Z = IsZeroBit(result); 3597 APSR.C = carry; 3598 // APSR.V unchanged 3599#endif 3600 3601 return EmulateShiftImm(opcode, encoding, SRType_LSL); 3602} 3603 3604// Logical Shift Left (register) shifts a register value left by a variable 3605// number of bits, shifting in zeros, and writes the result to the destination 3606// register. The variable number of bits is read from the bottom byte of a 3607// register. It can optionally update the condition flags based on the result. 3608bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode, 3609 const ARMEncoding encoding) { 3610#if 0 3611 // ARM pseudo code... 3612 if ConditionPassed() then 3613 EncodingSpecificOperations(); 3614 shift_n = UInt(R[m]<7:0>); 3615 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3616 R[d] = result; 3617 if setflags then 3618 APSR.N = result<31>; 3619 APSR.Z = IsZeroBit(result); 3620 APSR.C = carry; 3621 // APSR.V unchanged 3622#endif 3623 3624 return EmulateShiftReg(opcode, encoding, SRType_LSL); 3625} 3626 3627// Logical Shift Right (immediate) shifts a register value right by an 3628// immediate number of bits, shifting in zeros, and writes the result to the 3629// destination register. It can optionally update the condition flags based on 3630// the result. 3631bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode, 3632 const ARMEncoding encoding) { 3633#if 0 3634 // ARM pseudo code... 3635 if ConditionPassed() then 3636 EncodingSpecificOperations(); 3637 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3638 if d == 15 then // Can only occur for ARM encoding 3639 ALUWritePC(result); // setflags is always FALSE here 3640 else 3641 R[d] = result; 3642 if setflags then 3643 APSR.N = result<31>; 3644 APSR.Z = IsZeroBit(result); 3645 APSR.C = carry; 3646 // APSR.V unchanged 3647#endif 3648 3649 return EmulateShiftImm(opcode, encoding, SRType_LSR); 3650} 3651 3652// Logical Shift Right (register) shifts a register value right by a variable 3653// number of bits, shifting in zeros, and writes the result to the destination 3654// register. The variable number of bits is read from the bottom byte of a 3655// register. It can optionally update the condition flags based on the result. 3656bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode, 3657 const ARMEncoding encoding) { 3658#if 0 3659 // ARM pseudo code... 3660 if ConditionPassed() then 3661 EncodingSpecificOperations(); 3662 shift_n = UInt(R[m]<7:0>); 3663 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3664 R[d] = result; 3665 if setflags then 3666 APSR.N = result<31>; 3667 APSR.Z = IsZeroBit(result); 3668 APSR.C = carry; 3669 // APSR.V unchanged 3670#endif 3671 3672 return EmulateShiftReg(opcode, encoding, SRType_LSR); 3673} 3674 3675// Rotate Right (immediate) provides the value of the contents of a register 3676// rotated by a constant value. The bits that are rotated off the right end are 3677// inserted into the vacated bit positions on the left. It can optionally 3678// update the condition flags based on the result. 3679bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode, 3680 const ARMEncoding encoding) { 3681#if 0 3682 // ARM pseudo code... 3683 if ConditionPassed() then 3684 EncodingSpecificOperations(); 3685 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3686 if d == 15 then // Can only occur for ARM encoding 3687 ALUWritePC(result); // setflags is always FALSE here 3688 else 3689 R[d] = result; 3690 if setflags then 3691 APSR.N = result<31>; 3692 APSR.Z = IsZeroBit(result); 3693 APSR.C = carry; 3694 // APSR.V unchanged 3695#endif 3696 3697 return EmulateShiftImm(opcode, encoding, SRType_ROR); 3698} 3699 3700// Rotate Right (register) provides the value of the contents of a register 3701// rotated by a variable number of bits. The bits that are rotated off the 3702// right end are inserted into the vacated bit positions on the left. The 3703// variable number of bits is read from the bottom byte of a register. It can 3704// optionally update the condition flags based on the result. 3705bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode, 3706 const ARMEncoding encoding) { 3707#if 0 3708 // ARM pseudo code... 3709 if ConditionPassed() then 3710 EncodingSpecificOperations(); 3711 shift_n = UInt(R[m]<7:0>); 3712 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3713 R[d] = result; 3714 if setflags then 3715 APSR.N = result<31>; 3716 APSR.Z = IsZeroBit(result); 3717 APSR.C = carry; 3718 // APSR.V unchanged 3719#endif 3720 3721 return EmulateShiftReg(opcode, encoding, SRType_ROR); 3722} 3723 3724// Rotate Right with Extend provides the value of the contents of a register 3725// shifted right by one place, with the carry flag shifted into bit [31]. 3726// 3727// RRX can optionally update the condition flags based on the result. 3728// In that case, bit [0] is shifted into the carry flag. 3729bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode, 3730 const ARMEncoding encoding) { 3731#if 0 3732 // ARM pseudo code... 3733 if ConditionPassed() then 3734 EncodingSpecificOperations(); 3735 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3736 if d == 15 then // Can only occur for ARM encoding 3737 ALUWritePC(result); // setflags is always FALSE here 3738 else 3739 R[d] = result; 3740 if setflags then 3741 APSR.N = result<31>; 3742 APSR.Z = IsZeroBit(result); 3743 APSR.C = carry; 3744 // APSR.V unchanged 3745#endif 3746 3747 return EmulateShiftImm(opcode, encoding, SRType_RRX); 3748} 3749 3750bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode, 3751 const ARMEncoding encoding, 3752 ARM_ShifterType shift_type) { 3753 // assert(shift_type == SRType_ASR 3754 // || shift_type == SRType_LSL 3755 // || shift_type == SRType_LSR 3756 // || shift_type == SRType_ROR 3757 // || shift_type == SRType_RRX); 3758 3759 bool success = false; 3760 3761 if (ConditionPassed(opcode)) { 3762 uint32_t Rd; // the destination register 3763 uint32_t Rm; // the first operand register 3764 uint32_t imm5; // encoding for the shift amount 3765 uint32_t carry; // the carry bit after the shift operation 3766 bool setflags; 3767 3768 // Special case handling! 3769 // A8.6.139 ROR (immediate) -- Encoding T1 3770 ARMEncoding use_encoding = encoding; 3771 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) { 3772 // Morph the T1 encoding from the ARM Architecture Manual into T2 3773 // encoding to have the same decoding of bit fields as the other Thumb2 3774 // shift operations. 3775 use_encoding = eEncodingT2; 3776 } 3777 3778 switch (use_encoding) { 3779 case eEncodingT1: 3780 // Due to the above special case handling! 3781 if (shift_type == SRType_ROR) 3782 return false; 3783 3784 Rd = Bits32(opcode, 2, 0); 3785 Rm = Bits32(opcode, 5, 3); 3786 setflags = !InITBlock(); 3787 imm5 = Bits32(opcode, 10, 6); 3788 break; 3789 case eEncodingT2: 3790 // A8.6.141 RRX 3791 // There's no imm form of RRX instructions. 3792 if (shift_type == SRType_RRX) 3793 return false; 3794 3795 Rd = Bits32(opcode, 11, 8); 3796 Rm = Bits32(opcode, 3, 0); 3797 setflags = BitIsSet(opcode, 20); 3798 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3799 if (BadReg(Rd) || BadReg(Rm)) 3800 return false; 3801 break; 3802 case eEncodingA1: 3803 Rd = Bits32(opcode, 15, 12); 3804 Rm = Bits32(opcode, 3, 0); 3805 setflags = BitIsSet(opcode, 20); 3806 imm5 = Bits32(opcode, 11, 7); 3807 break; 3808 default: 3809 return false; 3810 } 3811 3812 // A8.6.139 ROR (immediate) 3813 if (shift_type == SRType_ROR && imm5 == 0) 3814 shift_type = SRType_RRX; 3815 3816 // Get the first operand. 3817 uint32_t value = ReadCoreReg(Rm, &success); 3818 if (!success) 3819 return false; 3820 3821 // Decode the shift amount if not RRX. 3822 uint32_t amt = 3823 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3824 3825 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3826 if (!success) 3827 return false; 3828 3829 // The context specifies that an immediate is to be moved into Rd. 3830 EmulateInstruction::Context context; 3831 context.type = EmulateInstruction::eContextImmediate; 3832 context.SetNoArgs(); 3833 3834 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3835 return false; 3836 } 3837 return true; 3838} 3839 3840bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode, 3841 const ARMEncoding encoding, 3842 ARM_ShifterType shift_type) { 3843 // assert(shift_type == SRType_ASR 3844 // || shift_type == SRType_LSL 3845 // || shift_type == SRType_LSR 3846 // || shift_type == SRType_ROR); 3847 3848 bool success = false; 3849 3850 if (ConditionPassed(opcode)) { 3851 uint32_t Rd; // the destination register 3852 uint32_t Rn; // the first operand register 3853 uint32_t 3854 Rm; // the register whose bottom byte contains the amount to shift by 3855 uint32_t carry; // the carry bit after the shift operation 3856 bool setflags; 3857 switch (encoding) { 3858 case eEncodingT1: 3859 Rd = Bits32(opcode, 2, 0); 3860 Rn = Rd; 3861 Rm = Bits32(opcode, 5, 3); 3862 setflags = !InITBlock(); 3863 break; 3864 case eEncodingT2: 3865 Rd = Bits32(opcode, 11, 8); 3866 Rn = Bits32(opcode, 19, 16); 3867 Rm = Bits32(opcode, 3, 0); 3868 setflags = BitIsSet(opcode, 20); 3869 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3870 return false; 3871 break; 3872 case eEncodingA1: 3873 Rd = Bits32(opcode, 15, 12); 3874 Rn = Bits32(opcode, 3, 0); 3875 Rm = Bits32(opcode, 11, 8); 3876 setflags = BitIsSet(opcode, 20); 3877 if (Rd == 15 || Rn == 15 || Rm == 15) 3878 return false; 3879 break; 3880 default: 3881 return false; 3882 } 3883 3884 // Get the first operand. 3885 uint32_t value = ReadCoreReg(Rn, &success); 3886 if (!success) 3887 return false; 3888 // Get the Rm register content. 3889 uint32_t val = ReadCoreReg(Rm, &success); 3890 if (!success) 3891 return false; 3892 3893 // Get the shift amount. 3894 uint32_t amt = Bits32(val, 7, 0); 3895 3896 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3897 if (!success) 3898 return false; 3899 3900 // The context specifies that an immediate is to be moved into Rd. 3901 EmulateInstruction::Context context; 3902 context.type = EmulateInstruction::eContextImmediate; 3903 context.SetNoArgs(); 3904 3905 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3906 return false; 3907 } 3908 return true; 3909} 3910 3911// LDM loads multiple registers from consecutive memory locations, using an 3912// address from a base register. Optionally the address just above the highest 3913// of those locations can be written back to the base register. 3914bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode, 3915 const ARMEncoding encoding) { 3916#if 0 3917 // ARM pseudo code... 3918 if ConditionPassed() 3919 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3920 address = R[n]; 3921 3922 for i = 0 to 14 3923 if registers<i> == '1' then 3924 R[i] = MemA[address, 4]; address = address + 4; 3925 if registers<15> == '1' then 3926 LoadWritePC (MemA[address, 4]); 3927 3928 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3929 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3930 3931#endif 3932 3933 bool success = false; 3934 if (ConditionPassed(opcode)) { 3935 uint32_t n; 3936 uint32_t registers = 0; 3937 bool wback; 3938 const uint32_t addr_byte_size = GetAddressByteSize(); 3939 switch (encoding) { 3940 case eEncodingT1: 3941 // n = UInt(Rn); registers = '00000000':register_list; wback = 3942 // (registers<n> == '0'); 3943 n = Bits32(opcode, 10, 8); 3944 registers = Bits32(opcode, 7, 0); 3945 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3946 wback = BitIsClear(registers, n); 3947 // if BitCount(registers) < 1 then UNPREDICTABLE; 3948 if (BitCount(registers) < 1) 3949 return false; 3950 break; 3951 case eEncodingT2: 3952 // if W == '1' && Rn == '1101' then SEE POP; 3953 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3954 n = Bits32(opcode, 19, 16); 3955 registers = Bits32(opcode, 15, 0); 3956 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3957 wback = BitIsSet(opcode, 21); 3958 3959 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 3960 // UNPREDICTABLE; 3961 if ((n == 15) || (BitCount(registers) < 2) || 3962 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 3963 return false; 3964 3965 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 3966 // UNPREDICTABLE; 3967 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 3968 return false; 3969 3970 // if wback && registers<n> == '1' then UNPREDICTABLE; 3971 if (wback && BitIsSet(registers, n)) 3972 return false; 3973 break; 3974 3975 case eEncodingA1: 3976 n = Bits32(opcode, 19, 16); 3977 registers = Bits32(opcode, 15, 0); 3978 wback = BitIsSet(opcode, 21); 3979 if ((n == 15) || (BitCount(registers) < 1)) 3980 return false; 3981 break; 3982 default: 3983 return false; 3984 } 3985 3986 int32_t offset = 0; 3987 const addr_t base_address = 3988 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3989 if (!success) 3990 return false; 3991 3992 EmulateInstruction::Context context; 3993 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3994 RegisterInfo dwarf_reg; 3995 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3996 context.SetRegisterPlusOffset(dwarf_reg, offset); 3997 3998 for (int i = 0; i < 14; ++i) { 3999 if (BitIsSet(registers, i)) { 4000 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4001 context.SetRegisterPlusOffset(dwarf_reg, offset); 4002 if (wback && (n == 13)) // Pop Instruction 4003 { 4004 context.type = EmulateInstruction::eContextPopRegisterOffStack; 4005 context.SetAddress(base_address + offset); 4006 } 4007 4008 // R[i] = MemA [address, 4]; address = address + 4; 4009 uint32_t data = MemARead(context, base_address + offset, addr_byte_size, 4010 0, &success); 4011 if (!success) 4012 return false; 4013 4014 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4015 data)) 4016 return false; 4017 4018 offset += addr_byte_size; 4019 } 4020 } 4021 4022 if (BitIsSet(registers, 15)) { 4023 // LoadWritePC (MemA [address, 4]); 4024 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4025 context.SetRegisterPlusOffset(dwarf_reg, offset); 4026 uint32_t data = 4027 MemARead(context, base_address + offset, addr_byte_size, 0, &success); 4028 if (!success) 4029 return false; 4030 // In ARMv5T and above, this is an interworking branch. 4031 if (!LoadWritePC(context, data)) 4032 return false; 4033 } 4034 4035 if (wback && BitIsClear(registers, n)) { 4036 // R[n] = R[n] + 4 * BitCount (registers) 4037 int32_t offset = addr_byte_size * BitCount(registers); 4038 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4039 context.SetRegisterPlusOffset(dwarf_reg, offset); 4040 4041 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4042 base_address + offset)) 4043 return false; 4044 } 4045 if (wback && BitIsSet(registers, n)) 4046 // R[n] bits(32) UNKNOWN; 4047 return WriteBits32Unknown(n); 4048 } 4049 return true; 4050} 4051 4052// LDMDA loads multiple registers from consecutive memory locations using an 4053// address from a base register. 4054// The consecutive memory locations end at this address and the address just 4055// below the lowest of those locations can optionally be written back to the 4056// base register. 4057bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode, 4058 const ARMEncoding encoding) { 4059#if 0 4060 // ARM pseudo code... 4061 if ConditionPassed() then 4062 EncodingSpecificOperations(); 4063 address = R[n] - 4*BitCount(registers) + 4; 4064 4065 for i = 0 to 14 4066 if registers<i> == '1' then 4067 R[i] = MemA[address,4]; address = address + 4; 4068 4069 if registers<15> == '1' then 4070 LoadWritePC(MemA[address,4]); 4071 4072 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4073 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4074#endif 4075 4076 bool success = false; 4077 4078 if (ConditionPassed(opcode)) { 4079 uint32_t n; 4080 uint32_t registers = 0; 4081 bool wback; 4082 const uint32_t addr_byte_size = GetAddressByteSize(); 4083 4084 // EncodingSpecificOperations(); 4085 switch (encoding) { 4086 case eEncodingA1: 4087 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4088 n = Bits32(opcode, 19, 16); 4089 registers = Bits32(opcode, 15, 0); 4090 wback = BitIsSet(opcode, 21); 4091 4092 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4093 if ((n == 15) || (BitCount(registers) < 1)) 4094 return false; 4095 4096 break; 4097 4098 default: 4099 return false; 4100 } 4101 // address = R[n] - 4*BitCount(registers) + 4; 4102 4103 int32_t offset = 0; 4104 addr_t Rn = ReadCoreReg(n, &success); 4105 4106 if (!success) 4107 return false; 4108 4109 addr_t address = 4110 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size; 4111 4112 EmulateInstruction::Context context; 4113 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4114 RegisterInfo dwarf_reg; 4115 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4116 context.SetRegisterPlusOffset(dwarf_reg, offset); 4117 4118 // for i = 0 to 14 4119 for (int i = 0; i < 14; ++i) { 4120 // if registers<i> == '1' then 4121 if (BitIsSet(registers, i)) { 4122 // R[i] = MemA[address,4]; address = address + 4; 4123 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4124 uint32_t data = 4125 MemARead(context, address + offset, addr_byte_size, 0, &success); 4126 if (!success) 4127 return false; 4128 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4129 data)) 4130 return false; 4131 offset += addr_byte_size; 4132 } 4133 } 4134 4135 // if registers<15> == '1' then 4136 // LoadWritePC(MemA[address,4]); 4137 if (BitIsSet(registers, 15)) { 4138 context.SetRegisterPlusOffset(dwarf_reg, offset); 4139 uint32_t data = 4140 MemARead(context, address + offset, addr_byte_size, 0, &success); 4141 if (!success) 4142 return false; 4143 // In ARMv5T and above, this is an interworking branch. 4144 if (!LoadWritePC(context, data)) 4145 return false; 4146 } 4147 4148 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4149 if (wback && BitIsClear(registers, n)) { 4150 if (!success) 4151 return false; 4152 4153 offset = (addr_byte_size * BitCount(registers)) * -1; 4154 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4155 context.SetImmediateSigned(offset); 4156 addr_t addr = Rn + offset; 4157 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4158 addr)) 4159 return false; 4160 } 4161 4162 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4163 if (wback && BitIsSet(registers, n)) 4164 return WriteBits32Unknown(n); 4165 } 4166 return true; 4167} 4168 4169// LDMDB loads multiple registers from consecutive memory locations using an 4170// address from a base register. The 4171// consecutive memory locations end just below this address, and the address of 4172// the lowest of those locations can be optionally written back to the base 4173// register. 4174bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode, 4175 const ARMEncoding encoding) { 4176#if 0 4177 // ARM pseudo code... 4178 if ConditionPassed() then 4179 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4180 address = R[n] - 4*BitCount(registers); 4181 4182 for i = 0 to 14 4183 if registers<i> == '1' then 4184 R[i] = MemA[address,4]; address = address + 4; 4185 if registers<15> == '1' then 4186 LoadWritePC(MemA[address,4]); 4187 4188 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4189 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 4190#endif 4191 4192 bool success = false; 4193 4194 if (ConditionPassed(opcode)) { 4195 uint32_t n; 4196 uint32_t registers = 0; 4197 bool wback; 4198 const uint32_t addr_byte_size = GetAddressByteSize(); 4199 switch (encoding) { 4200 case eEncodingT1: 4201 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 4202 n = Bits32(opcode, 19, 16); 4203 registers = Bits32(opcode, 15, 0); 4204 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 4205 wback = BitIsSet(opcode, 21); 4206 4207 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 4208 // UNPREDICTABLE; 4209 if ((n == 15) || (BitCount(registers) < 2) || 4210 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 4211 return false; 4212 4213 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 4214 // UNPREDICTABLE; 4215 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 4216 return false; 4217 4218 // if wback && registers<n> == '1' then UNPREDICTABLE; 4219 if (wback && BitIsSet(registers, n)) 4220 return false; 4221 4222 break; 4223 4224 case eEncodingA1: 4225 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4226 n = Bits32(opcode, 19, 16); 4227 registers = Bits32(opcode, 15, 0); 4228 wback = BitIsSet(opcode, 21); 4229 4230 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4231 if ((n == 15) || (BitCount(registers) < 1)) 4232 return false; 4233 4234 break; 4235 4236 default: 4237 return false; 4238 } 4239 4240 // address = R[n] - 4*BitCount(registers); 4241 4242 int32_t offset = 0; 4243 addr_t Rn = 4244 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4245 4246 if (!success) 4247 return false; 4248 4249 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4250 EmulateInstruction::Context context; 4251 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4252 RegisterInfo dwarf_reg; 4253 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4254 context.SetRegisterPlusOffset(dwarf_reg, Rn - address); 4255 4256 for (int i = 0; i < 14; ++i) { 4257 if (BitIsSet(registers, i)) { 4258 // R[i] = MemA[address,4]; address = address + 4; 4259 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4260 uint32_t data = 4261 MemARead(context, address + offset, addr_byte_size, 0, &success); 4262 if (!success) 4263 return false; 4264 4265 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4266 data)) 4267 return false; 4268 4269 offset += addr_byte_size; 4270 } 4271 } 4272 4273 // if registers<15> == '1' then 4274 // LoadWritePC(MemA[address,4]); 4275 if (BitIsSet(registers, 15)) { 4276 context.SetRegisterPlusOffset(dwarf_reg, offset); 4277 uint32_t data = 4278 MemARead(context, address + offset, addr_byte_size, 0, &success); 4279 if (!success) 4280 return false; 4281 // In ARMv5T and above, this is an interworking branch. 4282 if (!LoadWritePC(context, data)) 4283 return false; 4284 } 4285 4286 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4287 if (wback && BitIsClear(registers, n)) { 4288 if (!success) 4289 return false; 4290 4291 offset = (addr_byte_size * BitCount(registers)) * -1; 4292 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4293 context.SetImmediateSigned(offset); 4294 addr_t addr = Rn + offset; 4295 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4296 addr)) 4297 return false; 4298 } 4299 4300 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4301 // possible for encoding A1 4302 if (wback && BitIsSet(registers, n)) 4303 return WriteBits32Unknown(n); 4304 } 4305 return true; 4306} 4307 4308// LDMIB loads multiple registers from consecutive memory locations using an 4309// address from a base register. The 4310// consecutive memory locations start just above this address, and thea ddress 4311// of the last of those locations can optinoally be written back to the base 4312// register. 4313bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode, 4314 const ARMEncoding encoding) { 4315#if 0 4316 if ConditionPassed() then 4317 EncodingSpecificOperations(); 4318 address = R[n] + 4; 4319 4320 for i = 0 to 14 4321 if registers<i> == '1' then 4322 R[i] = MemA[address,4]; address = address + 4; 4323 if registers<15> == '1' then 4324 LoadWritePC(MemA[address,4]); 4325 4326 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4327 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4328#endif 4329 4330 bool success = false; 4331 4332 if (ConditionPassed(opcode)) { 4333 uint32_t n; 4334 uint32_t registers = 0; 4335 bool wback; 4336 const uint32_t addr_byte_size = GetAddressByteSize(); 4337 switch (encoding) { 4338 case eEncodingA1: 4339 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4340 n = Bits32(opcode, 19, 16); 4341 registers = Bits32(opcode, 15, 0); 4342 wback = BitIsSet(opcode, 21); 4343 4344 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4345 if ((n == 15) || (BitCount(registers) < 1)) 4346 return false; 4347 4348 break; 4349 default: 4350 return false; 4351 } 4352 // address = R[n] + 4; 4353 4354 int32_t offset = 0; 4355 addr_t Rn = 4356 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4357 4358 if (!success) 4359 return false; 4360 4361 addr_t address = Rn + addr_byte_size; 4362 4363 EmulateInstruction::Context context; 4364 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4365 RegisterInfo dwarf_reg; 4366 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4367 context.SetRegisterPlusOffset(dwarf_reg, offset); 4368 4369 for (int i = 0; i < 14; ++i) { 4370 if (BitIsSet(registers, i)) { 4371 // R[i] = MemA[address,4]; address = address + 4; 4372 4373 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size); 4374 uint32_t data = 4375 MemARead(context, address + offset, addr_byte_size, 0, &success); 4376 if (!success) 4377 return false; 4378 4379 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4380 data)) 4381 return false; 4382 4383 offset += addr_byte_size; 4384 } 4385 } 4386 4387 // if registers<15> == '1' then 4388 // LoadWritePC(MemA[address,4]); 4389 if (BitIsSet(registers, 15)) { 4390 context.SetRegisterPlusOffset(dwarf_reg, offset); 4391 uint32_t data = 4392 MemARead(context, address + offset, addr_byte_size, 0, &success); 4393 if (!success) 4394 return false; 4395 // In ARMv5T and above, this is an interworking branch. 4396 if (!LoadWritePC(context, data)) 4397 return false; 4398 } 4399 4400 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4401 if (wback && BitIsClear(registers, n)) { 4402 if (!success) 4403 return false; 4404 4405 offset = addr_byte_size * BitCount(registers); 4406 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4407 context.SetImmediateSigned(offset); 4408 addr_t addr = Rn + offset; 4409 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4410 addr)) 4411 return false; 4412 } 4413 4414 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4415 // possible for encoding A1 4416 if (wback && BitIsSet(registers, n)) 4417 return WriteBits32Unknown(n); 4418 } 4419 return true; 4420} 4421 4422// Load Register (immediate) calculates an address from a base register value 4423// and an immediate offset, loads a word from memory, and writes to a register. 4424// LDR (immediate, Thumb) 4425bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode, 4426 const ARMEncoding encoding) { 4427#if 0 4428 // ARM pseudo code... 4429 if (ConditionPassed()) 4430 { 4431 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 4432 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4433 address = if index then offset_addr else R[n]; 4434 data = MemU[address,4]; 4435 if wback then R[n] = offset_addr; 4436 if t == 15 then 4437 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 4438 elsif UnalignedSupport() || address<1:0> = '00' then 4439 R[t] = data; 4440 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 4441 } 4442#endif 4443 4444 bool success = false; 4445 4446 if (ConditionPassed(opcode)) { 4447 uint32_t Rt; // the destination register 4448 uint32_t Rn; // the base register 4449 uint32_t imm32; // the immediate offset used to form the address 4450 addr_t offset_addr; // the offset address 4451 addr_t address; // the calculated address 4452 uint32_t data; // the literal data value from memory load 4453 bool add, index, wback; 4454 switch (encoding) { 4455 case eEncodingT1: 4456 Rt = Bits32(opcode, 2, 0); 4457 Rn = Bits32(opcode, 5, 3); 4458 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 4459 // index = TRUE; add = TRUE; wback = FALSE 4460 add = true; 4461 index = true; 4462 wback = false; 4463 4464 break; 4465 4466 case eEncodingT2: 4467 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4468 Rt = Bits32(opcode, 10, 8); 4469 Rn = 13; 4470 imm32 = Bits32(opcode, 7, 0) << 2; 4471 4472 // index = TRUE; add = TRUE; wback = FALSE; 4473 index = true; 4474 add = true; 4475 wback = false; 4476 4477 break; 4478 4479 case eEncodingT3: 4480 // if Rn == '1111' then SEE LDR (literal); 4481 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4482 Rt = Bits32(opcode, 15, 12); 4483 Rn = Bits32(opcode, 19, 16); 4484 imm32 = Bits32(opcode, 11, 0); 4485 4486 // index = TRUE; add = TRUE; wback = FALSE; 4487 index = true; 4488 add = true; 4489 wback = false; 4490 4491 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4492 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4493 return false; 4494 4495 break; 4496 4497 case eEncodingT4: 4498 // if Rn == '1111' then SEE LDR (literal); 4499 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4500 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == 4501 // '00000100' then SEE POP; 4502 // if P == '0' && W == '0' then UNDEFINED; 4503 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 4504 return false; 4505 4506 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4507 Rt = Bits32(opcode, 15, 12); 4508 Rn = Bits32(opcode, 19, 16); 4509 imm32 = Bits32(opcode, 7, 0); 4510 4511 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4512 index = BitIsSet(opcode, 10); 4513 add = BitIsSet(opcode, 9); 4514 wback = BitIsSet(opcode, 8); 4515 4516 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) 4517 // then UNPREDICTABLE; 4518 if ((wback && (Rn == Rt)) || 4519 ((Rt == 15) && InITBlock() && !LastInITBlock())) 4520 return false; 4521 4522 break; 4523 4524 default: 4525 return false; 4526 } 4527 uint32_t base = ReadCoreReg(Rn, &success); 4528 if (!success) 4529 return false; 4530 if (add) 4531 offset_addr = base + imm32; 4532 else 4533 offset_addr = base - imm32; 4534 4535 address = (index ? offset_addr : base); 4536 4537 RegisterInfo base_reg; 4538 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4539 if (wback) { 4540 EmulateInstruction::Context ctx; 4541 if (Rn == 13) { 4542 ctx.type = eContextAdjustStackPointer; 4543 ctx.SetImmediateSigned((int32_t)(offset_addr - base)); 4544 } else if (Rn == GetFramePointerRegisterNumber()) { 4545 ctx.type = eContextSetFramePointer; 4546 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4547 } else { 4548 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4549 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4550 } 4551 4552 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn, 4553 offset_addr)) 4554 return false; 4555 } 4556 4557 // Prepare to write to the Rt register. 4558 EmulateInstruction::Context context; 4559 context.type = EmulateInstruction::eContextRegisterLoad; 4560 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4561 4562 // Read memory from the address. 4563 data = MemURead(context, address, 4, 0, &success); 4564 if (!success) 4565 return false; 4566 4567 if (Rt == 15) { 4568 if (Bits32(address, 1, 0) == 0) { 4569 if (!LoadWritePC(context, data)) 4570 return false; 4571 } else 4572 return false; 4573 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 4574 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 4575 data)) 4576 return false; 4577 } else 4578 WriteBits32Unknown(Rt); 4579 } 4580 return true; 4581} 4582 4583// STM (Store Multiple Increment After) stores multiple registers to consecutive 4584// memory locations using an address 4585// from a base register. The consecutive memory locations start at this 4586// address, and the address just above the last of those locations can 4587// optionally be written back to the base register. 4588bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode, 4589 const ARMEncoding encoding) { 4590#if 0 4591 if ConditionPassed() then 4592 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4593 address = R[n]; 4594 4595 for i = 0 to 14 4596 if registers<i> == '1' then 4597 if i == n && wback && i != LowestSetBit(registers) then 4598 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4599 else 4600 MemA[address,4] = R[i]; 4601 address = address + 4; 4602 4603 if registers<15> == '1' then // Only possible for encoding A1 4604 MemA[address,4] = PCStoreValue(); 4605 if wback then R[n] = R[n] + 4*BitCount(registers); 4606#endif 4607 4608 bool success = false; 4609 4610 if (ConditionPassed(opcode)) { 4611 uint32_t n; 4612 uint32_t registers = 0; 4613 bool wback; 4614 const uint32_t addr_byte_size = GetAddressByteSize(); 4615 4616 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4617 switch (encoding) { 4618 case eEncodingT1: 4619 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4620 n = Bits32(opcode, 10, 8); 4621 registers = Bits32(opcode, 7, 0); 4622 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4623 wback = true; 4624 4625 // if BitCount(registers) < 1 then UNPREDICTABLE; 4626 if (BitCount(registers) < 1) 4627 return false; 4628 4629 break; 4630 4631 case eEncodingT2: 4632 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4633 n = Bits32(opcode, 19, 16); 4634 registers = Bits32(opcode, 15, 0); 4635 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4636 wback = BitIsSet(opcode, 21); 4637 4638 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4639 if ((n == 15) || (BitCount(registers) < 2)) 4640 return false; 4641 4642 // if wback && registers<n> == '1' then UNPREDICTABLE; 4643 if (wback && BitIsSet(registers, n)) 4644 return false; 4645 4646 break; 4647 4648 case eEncodingA1: 4649 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4650 n = Bits32(opcode, 19, 16); 4651 registers = Bits32(opcode, 15, 0); 4652 wback = BitIsSet(opcode, 21); 4653 4654 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4655 if ((n == 15) || (BitCount(registers) < 1)) 4656 return false; 4657 4658 break; 4659 4660 default: 4661 return false; 4662 } 4663 4664 // address = R[n]; 4665 int32_t offset = 0; 4666 const addr_t address = 4667 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4668 if (!success) 4669 return false; 4670 4671 EmulateInstruction::Context context; 4672 context.type = EmulateInstruction::eContextRegisterStore; 4673 RegisterInfo base_reg; 4674 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4675 4676 // for i = 0 to 14 4677 uint32_t lowest_set_bit = 14; 4678 for (uint32_t i = 0; i < 14; ++i) { 4679 // if registers<i> == '1' then 4680 if (BitIsSet(registers, i)) { 4681 if (i < lowest_set_bit) 4682 lowest_set_bit = i; 4683 // if i == n && wback && i != LowestSetBit(registers) then 4684 if ((i == n) && wback && (i != lowest_set_bit)) 4685 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings 4686 // T1 and A1 4687 WriteBits32UnknownToMemory(address + offset); 4688 else { 4689 // MemA[address,4] = R[i]; 4690 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4691 0, &success); 4692 if (!success) 4693 return false; 4694 4695 RegisterInfo data_reg; 4696 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4697 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 4698 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4699 return false; 4700 } 4701 4702 // address = address + 4; 4703 offset += addr_byte_size; 4704 } 4705 } 4706 4707 // if registers<15> == '1' then // Only possible for encoding A1 4708 // MemA[address,4] = PCStoreValue(); 4709 if (BitIsSet(registers, 15)) { 4710 RegisterInfo pc_reg; 4711 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4712 context.SetRegisterPlusOffset(pc_reg, 8); 4713 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4714 if (!success) 4715 return false; 4716 4717 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4718 return false; 4719 } 4720 4721 // if wback then R[n] = R[n] + 4*BitCount(registers); 4722 if (wback) { 4723 offset = addr_byte_size * BitCount(registers); 4724 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4725 context.SetImmediateSigned(offset); 4726 addr_t data = address + offset; 4727 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4728 data)) 4729 return false; 4730 } 4731 } 4732 return true; 4733} 4734 4735// STMDA (Store Multiple Decrement After) stores multiple registers to 4736// consecutive memory locations using an address from a base register. The 4737// consecutive memory locations end at this address, and the address just below 4738// the lowest of those locations can optionally be written back to the base 4739// register. 4740bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode, 4741 const ARMEncoding encoding) { 4742#if 0 4743 if ConditionPassed() then 4744 EncodingSpecificOperations(); 4745 address = R[n] - 4*BitCount(registers) + 4; 4746 4747 for i = 0 to 14 4748 if registers<i> == '1' then 4749 if i == n && wback && i != LowestSetBit(registers) then 4750 MemA[address,4] = bits(32) UNKNOWN; 4751 else 4752 MemA[address,4] = R[i]; 4753 address = address + 4; 4754 4755 if registers<15> == '1' then 4756 MemA[address,4] = PCStoreValue(); 4757 4758 if wback then R[n] = R[n] - 4*BitCount(registers); 4759#endif 4760 4761 bool success = false; 4762 4763 if (ConditionPassed(opcode)) { 4764 uint32_t n; 4765 uint32_t registers = 0; 4766 bool wback; 4767 const uint32_t addr_byte_size = GetAddressByteSize(); 4768 4769 // EncodingSpecificOperations(); 4770 switch (encoding) { 4771 case eEncodingA1: 4772 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4773 n = Bits32(opcode, 19, 16); 4774 registers = Bits32(opcode, 15, 0); 4775 wback = BitIsSet(opcode, 21); 4776 4777 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4778 if ((n == 15) || (BitCount(registers) < 1)) 4779 return false; 4780 break; 4781 default: 4782 return false; 4783 } 4784 4785 // address = R[n] - 4*BitCount(registers) + 4; 4786 int32_t offset = 0; 4787 addr_t Rn = ReadCoreReg(n, &success); 4788 if (!success) 4789 return false; 4790 4791 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4; 4792 4793 EmulateInstruction::Context context; 4794 context.type = EmulateInstruction::eContextRegisterStore; 4795 RegisterInfo base_reg; 4796 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4797 4798 // for i = 0 to 14 4799 uint32_t lowest_bit_set = 14; 4800 for (uint32_t i = 0; i < 14; ++i) { 4801 // if registers<i> == '1' then 4802 if (BitIsSet(registers, i)) { 4803 if (i < lowest_bit_set) 4804 lowest_bit_set = i; 4805 // if i == n && wback && i != LowestSetBit(registers) then 4806 if ((i == n) && wback && (i != lowest_bit_set)) 4807 // MemA[address,4] = bits(32) UNKNOWN; 4808 WriteBits32UnknownToMemory(address + offset); 4809 else { 4810 // MemA[address,4] = R[i]; 4811 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4812 0, &success); 4813 if (!success) 4814 return false; 4815 4816 RegisterInfo data_reg; 4817 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4818 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4819 Rn - (address + offset)); 4820 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4821 return false; 4822 } 4823 4824 // address = address + 4; 4825 offset += addr_byte_size; 4826 } 4827 } 4828 4829 // if registers<15> == '1' then 4830 // MemA[address,4] = PCStoreValue(); 4831 if (BitIsSet(registers, 15)) { 4832 RegisterInfo pc_reg; 4833 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4834 context.SetRegisterPlusOffset(pc_reg, 8); 4835 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4836 if (!success) 4837 return false; 4838 4839 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4840 return false; 4841 } 4842 4843 // if wback then R[n] = R[n] - 4*BitCount(registers); 4844 if (wback) { 4845 offset = (addr_byte_size * BitCount(registers)) * -1; 4846 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4847 context.SetImmediateSigned(offset); 4848 addr_t data = Rn + offset; 4849 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4850 data)) 4851 return false; 4852 } 4853 } 4854 return true; 4855} 4856 4857// STMDB (Store Multiple Decrement Before) stores multiple registers to 4858// consecutive memory locations using an address from a base register. The 4859// consecutive memory locations end just below this address, and the address of 4860// the first of those locations can optionally be written back to the base 4861// register. 4862bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode, 4863 const ARMEncoding encoding) { 4864#if 0 4865 if ConditionPassed() then 4866 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4867 address = R[n] - 4*BitCount(registers); 4868 4869 for i = 0 to 14 4870 if registers<i> == '1' then 4871 if i == n && wback && i != LowestSetBit(registers) then 4872 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4873 else 4874 MemA[address,4] = R[i]; 4875 address = address + 4; 4876 4877 if registers<15> == '1' then // Only possible for encoding A1 4878 MemA[address,4] = PCStoreValue(); 4879 4880 if wback then R[n] = R[n] - 4*BitCount(registers); 4881#endif 4882 4883 bool success = false; 4884 4885 if (ConditionPassed(opcode)) { 4886 uint32_t n; 4887 uint32_t registers = 0; 4888 bool wback; 4889 const uint32_t addr_byte_size = GetAddressByteSize(); 4890 4891 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4892 switch (encoding) { 4893 case eEncodingT1: 4894 // if W == '1' && Rn == '1101' then SEE PUSH; 4895 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) { 4896 // See PUSH 4897 } 4898 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4899 n = Bits32(opcode, 19, 16); 4900 registers = Bits32(opcode, 15, 0); 4901 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4902 wback = BitIsSet(opcode, 21); 4903 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4904 if ((n == 15) || BitCount(registers) < 2) 4905 return false; 4906 // if wback && registers<n> == '1' then UNPREDICTABLE; 4907 if (wback && BitIsSet(registers, n)) 4908 return false; 4909 break; 4910 4911 case eEncodingA1: 4912 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE 4913 // PUSH; 4914 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) && 4915 BitCount(Bits32(opcode, 15, 0)) >= 2) { 4916 // See Push 4917 } 4918 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4919 n = Bits32(opcode, 19, 16); 4920 registers = Bits32(opcode, 15, 0); 4921 wback = BitIsSet(opcode, 21); 4922 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4923 if ((n == 15) || BitCount(registers) < 1) 4924 return false; 4925 break; 4926 4927 default: 4928 return false; 4929 } 4930 4931 // address = R[n] - 4*BitCount(registers); 4932 4933 int32_t offset = 0; 4934 addr_t Rn = 4935 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4936 if (!success) 4937 return false; 4938 4939 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4940 4941 EmulateInstruction::Context context; 4942 context.type = EmulateInstruction::eContextRegisterStore; 4943 RegisterInfo base_reg; 4944 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4945 4946 // for i = 0 to 14 4947 uint32_t lowest_set_bit = 14; 4948 for (uint32_t i = 0; i < 14; ++i) { 4949 // if registers<i> == '1' then 4950 if (BitIsSet(registers, i)) { 4951 if (i < lowest_set_bit) 4952 lowest_set_bit = i; 4953 // if i == n && wback && i != LowestSetBit(registers) then 4954 if ((i == n) && wback && (i != lowest_set_bit)) 4955 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding 4956 // A1 4957 WriteBits32UnknownToMemory(address + offset); 4958 else { 4959 // MemA[address,4] = R[i]; 4960 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4961 0, &success); 4962 if (!success) 4963 return false; 4964 4965 RegisterInfo data_reg; 4966 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4967 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4968 Rn - (address + offset)); 4969 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4970 return false; 4971 } 4972 4973 // address = address + 4; 4974 offset += addr_byte_size; 4975 } 4976 } 4977 4978 // if registers<15> == '1' then // Only possible for encoding A1 4979 // MemA[address,4] = PCStoreValue(); 4980 if (BitIsSet(registers, 15)) { 4981 RegisterInfo pc_reg; 4982 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4983 context.SetRegisterPlusOffset(pc_reg, 8); 4984 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4985 if (!success) 4986 return false; 4987 4988 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4989 return false; 4990 } 4991 4992 // if wback then R[n] = R[n] - 4*BitCount(registers); 4993 if (wback) { 4994 offset = (addr_byte_size * BitCount(registers)) * -1; 4995 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4996 context.SetImmediateSigned(offset); 4997 addr_t data = Rn + offset; 4998 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4999 data)) 5000 return false; 5001 } 5002 } 5003 return true; 5004} 5005 5006// STMIB (Store Multiple Increment Before) stores multiple registers to 5007// consecutive memory locations using an address from a base register. The 5008// consecutive memory locations start just above this address, and the address 5009// of the last of those locations can optionally be written back to the base 5010// register. 5011bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode, 5012 const ARMEncoding encoding) { 5013#if 0 5014 if ConditionPassed() then 5015 EncodingSpecificOperations(); 5016 address = R[n] + 4; 5017 5018 for i = 0 to 14 5019 if registers<i> == '1' then 5020 if i == n && wback && i != LowestSetBit(registers) then 5021 MemA[address,4] = bits(32) UNKNOWN; 5022 else 5023 MemA[address,4] = R[i]; 5024 address = address + 4; 5025 5026 if registers<15> == '1' then 5027 MemA[address,4] = PCStoreValue(); 5028 5029 if wback then R[n] = R[n] + 4*BitCount(registers); 5030#endif 5031 5032 bool success = false; 5033 5034 if (ConditionPassed(opcode)) { 5035 uint32_t n; 5036 uint32_t registers = 0; 5037 bool wback; 5038 const uint32_t addr_byte_size = GetAddressByteSize(); 5039 5040 // EncodingSpecificOperations(); 5041 switch (encoding) { 5042 case eEncodingA1: 5043 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 5044 n = Bits32(opcode, 19, 16); 5045 registers = Bits32(opcode, 15, 0); 5046 wback = BitIsSet(opcode, 21); 5047 5048 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 5049 if ((n == 15) && (BitCount(registers) < 1)) 5050 return false; 5051 break; 5052 default: 5053 return false; 5054 } 5055 // address = R[n] + 4; 5056 5057 int32_t offset = 0; 5058 addr_t Rn = ReadCoreReg(n, &success); 5059 if (!success) 5060 return false; 5061 5062 addr_t address = Rn + addr_byte_size; 5063 5064 EmulateInstruction::Context context; 5065 context.type = EmulateInstruction::eContextRegisterStore; 5066 RegisterInfo base_reg; 5067 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5068 5069 uint32_t lowest_set_bit = 14; 5070 // for i = 0 to 14 5071 for (uint32_t i = 0; i < 14; ++i) { 5072 // if registers<i> == '1' then 5073 if (BitIsSet(registers, i)) { 5074 if (i < lowest_set_bit) 5075 lowest_set_bit = i; 5076 // if i == n && wback && i != LowestSetBit(registers) then 5077 if ((i == n) && wback && (i != lowest_set_bit)) 5078 // MemA[address,4] = bits(32) UNKNOWN; 5079 WriteBits32UnknownToMemory(address + offset); 5080 // else 5081 else { 5082 // MemA[address,4] = R[i]; 5083 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5084 0, &success); 5085 if (!success) 5086 return false; 5087 5088 RegisterInfo data_reg; 5089 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5090 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5091 offset + addr_byte_size); 5092 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5093 return false; 5094 } 5095 5096 // address = address + 4; 5097 offset += addr_byte_size; 5098 } 5099 } 5100 5101 // if registers<15> == '1' then 5102 // MemA[address,4] = PCStoreValue(); 5103 if (BitIsSet(registers, 15)) { 5104 RegisterInfo pc_reg; 5105 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5106 context.SetRegisterPlusOffset(pc_reg, 8); 5107 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5108 if (!success) 5109 return false; 5110 5111 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5112 return false; 5113 } 5114 5115 // if wback then R[n] = R[n] + 4*BitCount(registers); 5116 if (wback) { 5117 offset = addr_byte_size * BitCount(registers); 5118 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5119 context.SetImmediateSigned(offset); 5120 addr_t data = Rn + offset; 5121 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5122 data)) 5123 return false; 5124 } 5125 } 5126 return true; 5127} 5128 5129// STR (store immediate) calculates an address from a base register value and an 5130// immediate offset, and stores a word 5131// from a register to memory. It can use offset, post-indexed, or pre-indexed 5132// addressing. 5133bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode, 5134 const ARMEncoding encoding) { 5135#if 0 5136 if ConditionPassed() then 5137 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5138 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5139 address = if index then offset_addr else R[n]; 5140 if UnalignedSupport() || address<1:0> == '00' then 5141 MemU[address,4] = R[t]; 5142 else // Can only occur before ARMv7 5143 MemU[address,4] = bits(32) UNKNOWN; 5144 if wback then R[n] = offset_addr; 5145#endif 5146 5147 bool success = false; 5148 5149 if (ConditionPassed(opcode)) { 5150 const uint32_t addr_byte_size = GetAddressByteSize(); 5151 5152 uint32_t t; 5153 uint32_t n; 5154 uint32_t imm32; 5155 bool index; 5156 bool add; 5157 bool wback; 5158 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5159 switch (encoding) { 5160 case eEncodingT1: 5161 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 5162 t = Bits32(opcode, 2, 0); 5163 n = Bits32(opcode, 5, 3); 5164 imm32 = Bits32(opcode, 10, 6) << 2; 5165 5166 // index = TRUE; add = TRUE; wback = FALSE; 5167 index = true; 5168 add = false; 5169 wback = false; 5170 break; 5171 5172 case eEncodingT2: 5173 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 5174 t = Bits32(opcode, 10, 8); 5175 n = 13; 5176 imm32 = Bits32(opcode, 7, 0) << 2; 5177 5178 // index = TRUE; add = TRUE; wback = FALSE; 5179 index = true; 5180 add = true; 5181 wback = false; 5182 break; 5183 5184 case eEncodingT3: 5185 // if Rn == '1111' then UNDEFINED; 5186 if (Bits32(opcode, 19, 16) == 15) 5187 return false; 5188 5189 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5190 t = Bits32(opcode, 15, 12); 5191 n = Bits32(opcode, 19, 16); 5192 imm32 = Bits32(opcode, 11, 0); 5193 5194 // index = TRUE; add = TRUE; wback = FALSE; 5195 index = true; 5196 add = true; 5197 wback = false; 5198 5199 // if t == 15 then UNPREDICTABLE; 5200 if (t == 15) 5201 return false; 5202 break; 5203 5204 case eEncodingT4: 5205 // if P == '1' && U == '1' && W == '0' then SEE STRT; 5206 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == 5207 // '00000100' then SEE PUSH; 5208 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5209 if ((Bits32(opcode, 19, 16) == 15) || 5210 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))) 5211 return false; 5212 5213 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5214 t = Bits32(opcode, 15, 12); 5215 n = Bits32(opcode, 19, 16); 5216 imm32 = Bits32(opcode, 7, 0); 5217 5218 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5219 index = BitIsSet(opcode, 10); 5220 add = BitIsSet(opcode, 9); 5221 wback = BitIsSet(opcode, 8); 5222 5223 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 5224 if ((t == 15) || (wback && (n == t))) 5225 return false; 5226 break; 5227 5228 default: 5229 return false; 5230 } 5231 5232 addr_t offset_addr; 5233 addr_t address; 5234 5235 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5236 uint32_t base_address = ReadCoreReg(n, &success); 5237 if (!success) 5238 return false; 5239 5240 if (add) 5241 offset_addr = base_address + imm32; 5242 else 5243 offset_addr = base_address - imm32; 5244 5245 // address = if index then offset_addr else R[n]; 5246 if (index) 5247 address = offset_addr; 5248 else 5249 address = base_address; 5250 5251 EmulateInstruction::Context context; 5252 if (n == 13) 5253 context.type = eContextPushRegisterOnStack; 5254 else 5255 context.type = eContextRegisterStore; 5256 5257 RegisterInfo base_reg; 5258 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5259 5260 // if UnalignedSupport() || address<1:0> == '00' then 5261 if (UnalignedSupport() || 5262 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 5263 // MemU[address,4] = R[t]; 5264 uint32_t data = 5265 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5266 if (!success) 5267 return false; 5268 5269 RegisterInfo data_reg; 5270 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5271 int32_t offset = address - base_address; 5272 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 5273 if (!MemUWrite(context, address, data, addr_byte_size)) 5274 return false; 5275 } else { 5276 // MemU[address,4] = bits(32) UNKNOWN; 5277 WriteBits32UnknownToMemory(address); 5278 } 5279 5280 // if wback then R[n] = offset_addr; 5281 if (wback) { 5282 if (n == 13) 5283 context.type = eContextAdjustStackPointer; 5284 else 5285 context.type = eContextAdjustBaseRegister; 5286 context.SetAddress(offset_addr); 5287 5288 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5289 offset_addr)) 5290 return false; 5291 } 5292 } 5293 return true; 5294} 5295 5296// STR (Store Register) calculates an address from a base register value and an 5297// offset register value, stores a 5298// word from a register to memory. The offset register value can optionally 5299// be shifted. 5300bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode, 5301 const ARMEncoding encoding) { 5302#if 0 5303 if ConditionPassed() then 5304 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5305 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5306 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5307 address = if index then offset_addr else R[n]; 5308 if t == 15 then // Only possible for encoding A1 5309 data = PCStoreValue(); 5310 else 5311 data = R[t]; 5312 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 5313 MemU[address,4] = data; 5314 else // Can only occur before ARMv7 5315 MemU[address,4] = bits(32) UNKNOWN; 5316 if wback then R[n] = offset_addr; 5317#endif 5318 5319 bool success = false; 5320 5321 if (ConditionPassed(opcode)) { 5322 const uint32_t addr_byte_size = GetAddressByteSize(); 5323 5324 uint32_t t; 5325 uint32_t n; 5326 uint32_t m; 5327 ARM_ShifterType shift_t; 5328 uint32_t shift_n; 5329 bool index; 5330 bool add; 5331 bool wback; 5332 5333 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5334 switch (encoding) { 5335 case eEncodingT1: 5336 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5337 // in ThumbEE"; 5338 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5339 t = Bits32(opcode, 2, 0); 5340 n = Bits32(opcode, 5, 3); 5341 m = Bits32(opcode, 8, 6); 5342 5343 // index = TRUE; add = TRUE; wback = FALSE; 5344 index = true; 5345 add = true; 5346 wback = false; 5347 5348 // (shift_t, shift_n) = (SRType_LSL, 0); 5349 shift_t = SRType_LSL; 5350 shift_n = 0; 5351 break; 5352 5353 case eEncodingT2: 5354 // if Rn == '1111' then UNDEFINED; 5355 if (Bits32(opcode, 19, 16) == 15) 5356 return false; 5357 5358 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5359 t = Bits32(opcode, 15, 12); 5360 n = Bits32(opcode, 19, 16); 5361 m = Bits32(opcode, 3, 0); 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, UInt(imm2)); 5369 shift_t = SRType_LSL; 5370 shift_n = Bits32(opcode, 5, 4); 5371 5372 // if t == 15 || BadReg(m) then UNPREDICTABLE; 5373 if ((t == 15) || (BadReg(m))) 5374 return false; 5375 break; 5376 5377 case eEncodingA1: { 5378 // if P == '0' && W == '1' then SEE STRT; 5379 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5380 t = Bits32(opcode, 15, 12); 5381 n = Bits32(opcode, 19, 16); 5382 m = Bits32(opcode, 3, 0); 5383 5384 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5385 // (W == '1'); 5386 index = BitIsSet(opcode, 24); 5387 add = BitIsSet(opcode, 23); 5388 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5389 5390 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5391 uint32_t typ = Bits32(opcode, 6, 5); 5392 uint32_t imm5 = Bits32(opcode, 11, 7); 5393 shift_n = DecodeImmShift(typ, imm5, shift_t); 5394 5395 // if m == 15 then UNPREDICTABLE; 5396 if (m == 15) 5397 return false; 5398 5399 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5400 if (wback && ((n == 15) || (n == t))) 5401 return false; 5402 5403 break; 5404 } 5405 default: 5406 return false; 5407 } 5408 5409 addr_t offset_addr; 5410 addr_t address; 5411 int32_t offset = 0; 5412 5413 addr_t base_address = 5414 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5415 if (!success) 5416 return false; 5417 5418 uint32_t Rm_data = 5419 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5420 if (!success) 5421 return false; 5422 5423 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5424 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success); 5425 if (!success) 5426 return false; 5427 5428 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5429 if (add) 5430 offset_addr = base_address + offset; 5431 else 5432 offset_addr = base_address - offset; 5433 5434 // address = if index then offset_addr else R[n]; 5435 if (index) 5436 address = offset_addr; 5437 else 5438 address = base_address; 5439 5440 uint32_t data; 5441 // if t == 15 then // Only possible for encoding A1 5442 if (t == 15) 5443 // data = PCStoreValue(); 5444 data = ReadCoreReg(PC_REG, &success); 5445 else 5446 // data = R[t]; 5447 data = 5448 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5449 5450 if (!success) 5451 return false; 5452 5453 EmulateInstruction::Context context; 5454 context.type = eContextRegisterStore; 5455 5456 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == 5457 // InstrSet_ARM then 5458 if (UnalignedSupport() || 5459 (BitIsClear(address, 1) && BitIsClear(address, 0)) || 5460 CurrentInstrSet() == eModeARM) { 5461 // MemU[address,4] = data; 5462 5463 RegisterInfo base_reg; 5464 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5465 5466 RegisterInfo data_reg; 5467 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5468 5469 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5470 address - base_address); 5471 if (!MemUWrite(context, address, data, addr_byte_size)) 5472 return false; 5473 5474 } else 5475 // MemU[address,4] = bits(32) UNKNOWN; 5476 WriteBits32UnknownToMemory(address); 5477 5478 // if wback then R[n] = offset_addr; 5479 if (wback) { 5480 context.type = eContextRegisterLoad; 5481 context.SetAddress(offset_addr); 5482 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5483 offset_addr)) 5484 return false; 5485 } 5486 } 5487 return true; 5488} 5489 5490bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode, 5491 const ARMEncoding encoding) { 5492#if 0 5493 if ConditionPassed() then 5494 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5495 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5496 address = if index then offset_addr else R[n]; 5497 MemU[address,1] = R[t]<7:0>; 5498 if wback then R[n] = offset_addr; 5499#endif 5500 5501 bool success = false; 5502 5503 if (ConditionPassed(opcode)) { 5504 uint32_t t; 5505 uint32_t n; 5506 uint32_t imm32; 5507 bool index; 5508 bool add; 5509 bool wback; 5510 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5511 switch (encoding) { 5512 case eEncodingT1: 5513 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5514 t = Bits32(opcode, 2, 0); 5515 n = Bits32(opcode, 5, 3); 5516 imm32 = Bits32(opcode, 10, 6); 5517 5518 // index = TRUE; add = TRUE; wback = FALSE; 5519 index = true; 5520 add = true; 5521 wback = false; 5522 break; 5523 5524 case eEncodingT2: 5525 // if Rn == '1111' then UNDEFINED; 5526 if (Bits32(opcode, 19, 16) == 15) 5527 return false; 5528 5529 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5530 t = Bits32(opcode, 15, 12); 5531 n = Bits32(opcode, 19, 16); 5532 imm32 = Bits32(opcode, 11, 0); 5533 5534 // index = TRUE; add = TRUE; wback = FALSE; 5535 index = true; 5536 add = true; 5537 wback = false; 5538 5539 // if BadReg(t) then UNPREDICTABLE; 5540 if (BadReg(t)) 5541 return false; 5542 break; 5543 5544 case eEncodingT3: 5545 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5546 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5547 if (Bits32(opcode, 19, 16) == 15) 5548 return false; 5549 5550 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5551 t = Bits32(opcode, 15, 12); 5552 n = Bits32(opcode, 19, 16); 5553 imm32 = Bits32(opcode, 7, 0); 5554 5555 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5556 index = BitIsSet(opcode, 10); 5557 add = BitIsSet(opcode, 9); 5558 wback = BitIsSet(opcode, 8); 5559 5560 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5561 if ((BadReg(t)) || (wback && (n == t))) 5562 return false; 5563 break; 5564 5565 default: 5566 return false; 5567 } 5568 5569 addr_t offset_addr; 5570 addr_t address; 5571 addr_t base_address = 5572 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5573 if (!success) 5574 return false; 5575 5576 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5577 if (add) 5578 offset_addr = base_address + imm32; 5579 else 5580 offset_addr = base_address - imm32; 5581 5582 // address = if index then offset_addr else R[n]; 5583 if (index) 5584 address = offset_addr; 5585 else 5586 address = base_address; 5587 5588 // MemU[address,1] = R[t]<7:0> 5589 RegisterInfo base_reg; 5590 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5591 5592 RegisterInfo data_reg; 5593 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5594 5595 EmulateInstruction::Context context; 5596 context.type = eContextRegisterStore; 5597 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5598 address - base_address); 5599 5600 uint32_t data = 5601 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5602 if (!success) 5603 return false; 5604 5605 data = Bits32(data, 7, 0); 5606 5607 if (!MemUWrite(context, address, data, 1)) 5608 return false; 5609 5610 // if wback then R[n] = offset_addr; 5611 if (wback) { 5612 context.type = eContextRegisterLoad; 5613 context.SetAddress(offset_addr); 5614 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5615 offset_addr)) 5616 return false; 5617 } 5618 } 5619 5620 return true; 5621} 5622 5623// STRH (register) calculates an address from a base register value and an 5624// offset register value, and stores a 5625// halfword from a register to memory. The offset register value can be 5626// shifted left by 0, 1, 2, or 3 bits. 5627bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode, 5628 const ARMEncoding encoding) { 5629#if 0 5630 if ConditionPassed() then 5631 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5632 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5633 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5634 address = if index then offset_addr else R[n]; 5635 if UnalignedSupport() || address<0> == '0' then 5636 MemU[address,2] = R[t]<15:0>; 5637 else // Can only occur before ARMv7 5638 MemU[address,2] = bits(16) UNKNOWN; 5639 if wback then R[n] = offset_addr; 5640#endif 5641 5642 bool success = false; 5643 5644 if (ConditionPassed(opcode)) { 5645 uint32_t t; 5646 uint32_t n; 5647 uint32_t m; 5648 bool index; 5649 bool add; 5650 bool wback; 5651 ARM_ShifterType shift_t; 5652 uint32_t shift_n; 5653 5654 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5655 switch (encoding) { 5656 case eEncodingT1: 5657 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5658 // in ThumbEE"; 5659 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5660 t = Bits32(opcode, 2, 0); 5661 n = Bits32(opcode, 5, 3); 5662 m = Bits32(opcode, 8, 6); 5663 5664 // index = TRUE; add = TRUE; wback = FALSE; 5665 index = true; 5666 add = true; 5667 wback = false; 5668 5669 // (shift_t, shift_n) = (SRType_LSL, 0); 5670 shift_t = SRType_LSL; 5671 shift_n = 0; 5672 5673 break; 5674 5675 case eEncodingT2: 5676 // if Rn == '1111' then UNDEFINED; 5677 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5678 t = Bits32(opcode, 15, 12); 5679 n = Bits32(opcode, 19, 16); 5680 m = Bits32(opcode, 3, 0); 5681 if (n == 15) 5682 return false; 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, UInt(imm2)); 5690 shift_t = SRType_LSL; 5691 shift_n = Bits32(opcode, 5, 4); 5692 5693 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5694 if (BadReg(t) || BadReg(m)) 5695 return false; 5696 5697 break; 5698 5699 case eEncodingA1: 5700 // if P == '0' && W == '1' then SEE STRHT; 5701 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5702 t = Bits32(opcode, 15, 12); 5703 n = Bits32(opcode, 19, 16); 5704 m = Bits32(opcode, 3, 0); 5705 5706 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5707 // (W == '1'); 5708 index = BitIsSet(opcode, 24); 5709 add = BitIsSet(opcode, 23); 5710 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5711 5712 // (shift_t, shift_n) = (SRType_LSL, 0); 5713 shift_t = SRType_LSL; 5714 shift_n = 0; 5715 5716 // if t == 15 || m == 15 then UNPREDICTABLE; 5717 if ((t == 15) || (m == 15)) 5718 return false; 5719 5720 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5721 if (wback && ((n == 15) || (n == t))) 5722 return false; 5723 5724 break; 5725 5726 default: 5727 return false; 5728 } 5729 5730 uint32_t Rm = ReadCoreReg(m, &success); 5731 if (!success) 5732 return false; 5733 5734 uint32_t Rn = ReadCoreReg(n, &success); 5735 if (!success) 5736 return false; 5737 5738 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5739 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 5740 if (!success) 5741 return false; 5742 5743 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5744 addr_t offset_addr; 5745 if (add) 5746 offset_addr = Rn + offset; 5747 else 5748 offset_addr = Rn - offset; 5749 5750 // address = if index then offset_addr else R[n]; 5751 addr_t address; 5752 if (index) 5753 address = offset_addr; 5754 else 5755 address = Rn; 5756 5757 EmulateInstruction::Context context; 5758 context.type = eContextRegisterStore; 5759 RegisterInfo base_reg; 5760 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5761 RegisterInfo offset_reg; 5762 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5763 5764 // if UnalignedSupport() || address<0> == '0' then 5765 if (UnalignedSupport() || BitIsClear(address, 0)) { 5766 // MemU[address,2] = R[t]<15:0>; 5767 uint32_t Rt = ReadCoreReg(t, &success); 5768 if (!success) 5769 return false; 5770 5771 EmulateInstruction::Context context; 5772 context.type = eContextRegisterStore; 5773 RegisterInfo base_reg; 5774 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5775 RegisterInfo offset_reg; 5776 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5777 RegisterInfo data_reg; 5778 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5779 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 5780 data_reg); 5781 5782 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2)) 5783 return false; 5784 } else // Can only occur before ARMv7 5785 { 5786 // MemU[address,2] = bits(16) UNKNOWN; 5787 } 5788 5789 // if wback then R[n] = offset_addr; 5790 if (wback) { 5791 context.type = eContextAdjustBaseRegister; 5792 context.SetAddress(offset_addr); 5793 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5794 offset_addr)) 5795 return false; 5796 } 5797 } 5798 5799 return true; 5800} 5801 5802// Add with Carry (immediate) adds an immediate value and the carry flag value 5803// to a register value, and writes the result to the destination register. It 5804// can optionally update the condition flags based on the result. 5805bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode, 5806 const ARMEncoding encoding) { 5807#if 0 5808 // ARM pseudo code... 5809 if ConditionPassed() then 5810 EncodingSpecificOperations(); 5811 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5812 if d == 15 then // Can only occur for ARM encoding 5813 ALUWritePC(result); // setflags is always FALSE here 5814 else 5815 R[d] = result; 5816 if setflags then 5817 APSR.N = result<31>; 5818 APSR.Z = IsZeroBit(result); 5819 APSR.C = carry; 5820 APSR.V = overflow; 5821#endif 5822 5823 bool success = false; 5824 5825 if (ConditionPassed(opcode)) { 5826 uint32_t Rd, Rn; 5827 uint32_t 5828 imm32; // the immediate value to be added to the value obtained from Rn 5829 bool setflags; 5830 switch (encoding) { 5831 case eEncodingT1: 5832 Rd = Bits32(opcode, 11, 8); 5833 Rn = Bits32(opcode, 19, 16); 5834 setflags = BitIsSet(opcode, 20); 5835 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5836 if (BadReg(Rd) || BadReg(Rn)) 5837 return false; 5838 break; 5839 case eEncodingA1: 5840 Rd = Bits32(opcode, 15, 12); 5841 Rn = Bits32(opcode, 19, 16); 5842 setflags = BitIsSet(opcode, 20); 5843 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5844 5845 if (Rd == 15 && setflags) 5846 return EmulateSUBSPcLrEtc(opcode, encoding); 5847 break; 5848 default: 5849 return false; 5850 } 5851 5852 // Read the first operand. 5853 int32_t val1 = ReadCoreReg(Rn, &success); 5854 if (!success) 5855 return false; 5856 5857 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5858 5859 EmulateInstruction::Context context; 5860 context.type = EmulateInstruction::eContextImmediate; 5861 context.SetNoArgs(); 5862 5863 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5864 res.carry_out, res.overflow)) 5865 return false; 5866 } 5867 return true; 5868} 5869 5870// Add with Carry (register) adds a register value, the carry flag value, and 5871// an optionally-shifted register value, and writes the result to the 5872// destination register. It can optionally update the condition flags based on 5873// the result. 5874bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode, 5875 const ARMEncoding encoding) { 5876#if 0 5877 // ARM pseudo code... 5878 if ConditionPassed() then 5879 EncodingSpecificOperations(); 5880 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5881 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5882 if d == 15 then // Can only occur for ARM encoding 5883 ALUWritePC(result); // setflags is always FALSE here 5884 else 5885 R[d] = result; 5886 if setflags then 5887 APSR.N = result<31>; 5888 APSR.Z = IsZeroBit(result); 5889 APSR.C = carry; 5890 APSR.V = overflow; 5891#endif 5892 5893 bool success = false; 5894 5895 if (ConditionPassed(opcode)) { 5896 uint32_t Rd, Rn, Rm; 5897 ARM_ShifterType shift_t; 5898 uint32_t shift_n; // the shift applied to the value read from Rm 5899 bool setflags; 5900 switch (encoding) { 5901 case eEncodingT1: 5902 Rd = Rn = Bits32(opcode, 2, 0); 5903 Rm = Bits32(opcode, 5, 3); 5904 setflags = !InITBlock(); 5905 shift_t = SRType_LSL; 5906 shift_n = 0; 5907 break; 5908 case eEncodingT2: 5909 Rd = Bits32(opcode, 11, 8); 5910 Rn = Bits32(opcode, 19, 16); 5911 Rm = Bits32(opcode, 3, 0); 5912 setflags = BitIsSet(opcode, 20); 5913 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5914 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5915 return false; 5916 break; 5917 case eEncodingA1: 5918 Rd = Bits32(opcode, 15, 12); 5919 Rn = Bits32(opcode, 19, 16); 5920 Rm = Bits32(opcode, 3, 0); 5921 setflags = BitIsSet(opcode, 20); 5922 shift_n = DecodeImmShiftARM(opcode, shift_t); 5923 5924 if (Rd == 15 && setflags) 5925 return EmulateSUBSPcLrEtc(opcode, encoding); 5926 break; 5927 default: 5928 return false; 5929 } 5930 5931 // Read the first operand. 5932 int32_t val1 = ReadCoreReg(Rn, &success); 5933 if (!success) 5934 return false; 5935 5936 // Read the second operand. 5937 int32_t val2 = ReadCoreReg(Rm, &success); 5938 if (!success) 5939 return false; 5940 5941 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5942 if (!success) 5943 return false; 5944 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5945 5946 EmulateInstruction::Context context; 5947 context.type = EmulateInstruction::eContextImmediate; 5948 context.SetNoArgs(); 5949 5950 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5951 res.carry_out, res.overflow)) 5952 return false; 5953 } 5954 return true; 5955} 5956 5957// This instruction adds an immediate value to the PC value to form a PC- 5958// relative address, and writes the result to the destination register. 5959bool EmulateInstructionARM::EmulateADR(const uint32_t opcode, 5960 const ARMEncoding encoding) { 5961#if 0 5962 // ARM pseudo code... 5963 if ConditionPassed() then 5964 EncodingSpecificOperations(); 5965 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5966 if d == 15 then // Can only occur for ARM encodings 5967 ALUWritePC(result); 5968 else 5969 R[d] = result; 5970#endif 5971 5972 bool success = false; 5973 5974 if (ConditionPassed(opcode)) { 5975 uint32_t Rd; 5976 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5977 bool add; 5978 switch (encoding) { 5979 case eEncodingT1: 5980 Rd = Bits32(opcode, 10, 8); 5981 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5982 add = true; 5983 break; 5984 case eEncodingT2: 5985 case eEncodingT3: 5986 Rd = Bits32(opcode, 11, 8); 5987 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5988 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5989 if (BadReg(Rd)) 5990 return false; 5991 break; 5992 case eEncodingA1: 5993 case eEncodingA2: 5994 Rd = Bits32(opcode, 15, 12); 5995 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5996 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5997 break; 5998 default: 5999 return false; 6000 } 6001 6002 // Read the PC value. 6003 uint32_t pc = ReadCoreReg(PC_REG, &success); 6004 if (!success) 6005 return false; 6006 6007 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 6008 6009 EmulateInstruction::Context context; 6010 context.type = EmulateInstruction::eContextImmediate; 6011 context.SetNoArgs(); 6012 6013 if (!WriteCoreReg(context, result, Rd)) 6014 return false; 6015 } 6016 return true; 6017} 6018 6019// This instruction performs a bitwise AND of a register value and an immediate 6020// value, and writes the result to the destination register. It can optionally 6021// update the condition flags based on the result. 6022bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode, 6023 const ARMEncoding encoding) { 6024#if 0 6025 // ARM pseudo code... 6026 if ConditionPassed() then 6027 EncodingSpecificOperations(); 6028 result = R[n] AND imm32; 6029 if d == 15 then // Can only occur for ARM encoding 6030 ALUWritePC(result); // setflags is always FALSE here 6031 else 6032 R[d] = result; 6033 if setflags then 6034 APSR.N = result<31>; 6035 APSR.Z = IsZeroBit(result); 6036 APSR.C = carry; 6037 // APSR.V unchanged 6038#endif 6039 6040 bool success = false; 6041 6042 if (ConditionPassed(opcode)) { 6043 uint32_t Rd, Rn; 6044 uint32_t 6045 imm32; // the immediate value to be ANDed to the value obtained from Rn 6046 bool setflags; 6047 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6048 switch (encoding) { 6049 case eEncodingT1: 6050 Rd = Bits32(opcode, 11, 8); 6051 Rn = Bits32(opcode, 19, 16); 6052 setflags = BitIsSet(opcode, 20); 6053 imm32 = ThumbExpandImm_C( 6054 opcode, APSR_C, 6055 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6056 // if Rd == '1111' && S == '1' then SEE TST (immediate); 6057 if (Rd == 15 && setflags) 6058 return EmulateTSTImm(opcode, eEncodingT1); 6059 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 6060 return false; 6061 break; 6062 case eEncodingA1: 6063 Rd = Bits32(opcode, 15, 12); 6064 Rn = Bits32(opcode, 19, 16); 6065 setflags = BitIsSet(opcode, 20); 6066 imm32 = 6067 ARMExpandImm_C(opcode, APSR_C, 6068 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6069 6070 if (Rd == 15 && setflags) 6071 return EmulateSUBSPcLrEtc(opcode, encoding); 6072 break; 6073 default: 6074 return false; 6075 } 6076 6077 // Read the first operand. 6078 uint32_t val1 = ReadCoreReg(Rn, &success); 6079 if (!success) 6080 return false; 6081 6082 uint32_t result = val1 & imm32; 6083 6084 EmulateInstruction::Context context; 6085 context.type = EmulateInstruction::eContextImmediate; 6086 context.SetNoArgs(); 6087 6088 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6089 return false; 6090 } 6091 return true; 6092} 6093 6094// This instruction performs a bitwise AND of a register value and an 6095// optionally-shifted register value, and writes the result to the destination 6096// register. It can optionally update the condition flags based on the result. 6097bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode, 6098 const ARMEncoding encoding) { 6099#if 0 6100 // ARM pseudo code... 6101 if ConditionPassed() then 6102 EncodingSpecificOperations(); 6103 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6104 result = R[n] AND shifted; 6105 if d == 15 then // Can only occur for ARM encoding 6106 ALUWritePC(result); // setflags is always FALSE here 6107 else 6108 R[d] = result; 6109 if setflags then 6110 APSR.N = result<31>; 6111 APSR.Z = IsZeroBit(result); 6112 APSR.C = carry; 6113 // APSR.V unchanged 6114#endif 6115 6116 bool success = false; 6117 6118 if (ConditionPassed(opcode)) { 6119 uint32_t Rd, Rn, Rm; 6120 ARM_ShifterType shift_t; 6121 uint32_t shift_n; // the shift applied to the value read from Rm 6122 bool setflags; 6123 uint32_t carry; 6124 switch (encoding) { 6125 case eEncodingT1: 6126 Rd = Rn = Bits32(opcode, 2, 0); 6127 Rm = Bits32(opcode, 5, 3); 6128 setflags = !InITBlock(); 6129 shift_t = SRType_LSL; 6130 shift_n = 0; 6131 break; 6132 case eEncodingT2: 6133 Rd = Bits32(opcode, 11, 8); 6134 Rn = Bits32(opcode, 19, 16); 6135 Rm = Bits32(opcode, 3, 0); 6136 setflags = BitIsSet(opcode, 20); 6137 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6138 // if Rd == '1111' && S == '1' then SEE TST (register); 6139 if (Rd == 15 && setflags) 6140 return EmulateTSTReg(opcode, eEncodingT2); 6141 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 6142 return false; 6143 break; 6144 case eEncodingA1: 6145 Rd = Bits32(opcode, 15, 12); 6146 Rn = Bits32(opcode, 19, 16); 6147 Rm = Bits32(opcode, 3, 0); 6148 setflags = BitIsSet(opcode, 20); 6149 shift_n = DecodeImmShiftARM(opcode, shift_t); 6150 6151 if (Rd == 15 && setflags) 6152 return EmulateSUBSPcLrEtc(opcode, encoding); 6153 break; 6154 default: 6155 return false; 6156 } 6157 6158 // Read the first operand. 6159 uint32_t val1 = ReadCoreReg(Rn, &success); 6160 if (!success) 6161 return false; 6162 6163 // Read the second operand. 6164 uint32_t val2 = ReadCoreReg(Rm, &success); 6165 if (!success) 6166 return false; 6167 6168 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6169 if (!success) 6170 return false; 6171 uint32_t result = val1 & shifted; 6172 6173 EmulateInstruction::Context context; 6174 context.type = EmulateInstruction::eContextImmediate; 6175 context.SetNoArgs(); 6176 6177 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6178 return false; 6179 } 6180 return true; 6181} 6182 6183// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and 6184// the complement of an immediate value, and writes the result to the 6185// destination register. It can optionally update the condition flags based on 6186// the result. 6187bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode, 6188 const ARMEncoding encoding) { 6189#if 0 6190 // ARM pseudo code... 6191 if ConditionPassed() then 6192 EncodingSpecificOperations(); 6193 result = R[n] AND NOT(imm32); 6194 if d == 15 then // Can only occur for ARM encoding 6195 ALUWritePC(result); // setflags is always FALSE here 6196 else 6197 R[d] = result; 6198 if setflags then 6199 APSR.N = result<31>; 6200 APSR.Z = IsZeroBit(result); 6201 APSR.C = carry; 6202 // APSR.V unchanged 6203#endif 6204 6205 bool success = false; 6206 6207 if (ConditionPassed(opcode)) { 6208 uint32_t Rd, Rn; 6209 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to 6210 // the value obtained from Rn 6211 bool setflags; 6212 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6213 switch (encoding) { 6214 case eEncodingT1: 6215 Rd = Bits32(opcode, 11, 8); 6216 Rn = Bits32(opcode, 19, 16); 6217 setflags = BitIsSet(opcode, 20); 6218 imm32 = ThumbExpandImm_C( 6219 opcode, APSR_C, 6220 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6221 if (BadReg(Rd) || BadReg(Rn)) 6222 return false; 6223 break; 6224 case eEncodingA1: 6225 Rd = Bits32(opcode, 15, 12); 6226 Rn = Bits32(opcode, 19, 16); 6227 setflags = BitIsSet(opcode, 20); 6228 imm32 = 6229 ARMExpandImm_C(opcode, APSR_C, 6230 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6231 6232 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6233 // instructions; 6234 if (Rd == 15 && setflags) 6235 return EmulateSUBSPcLrEtc(opcode, encoding); 6236 break; 6237 default: 6238 return false; 6239 } 6240 6241 // Read the first operand. 6242 uint32_t val1 = ReadCoreReg(Rn, &success); 6243 if (!success) 6244 return false; 6245 6246 uint32_t result = val1 & ~imm32; 6247 6248 EmulateInstruction::Context context; 6249 context.type = EmulateInstruction::eContextImmediate; 6250 context.SetNoArgs(); 6251 6252 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6253 return false; 6254 } 6255 return true; 6256} 6257 6258// Bitwise Bit Clear (register) performs a bitwise AND of a register value and 6259// the complement of an optionally-shifted register value, and writes the 6260// result to the destination register. It can optionally update the condition 6261// flags based on the result. 6262bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode, 6263 const ARMEncoding encoding) { 6264#if 0 6265 // ARM pseudo code... 6266 if ConditionPassed() then 6267 EncodingSpecificOperations(); 6268 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6269 result = R[n] AND NOT(shifted); 6270 if d == 15 then // Can only occur for ARM encoding 6271 ALUWritePC(result); // setflags is always FALSE here 6272 else 6273 R[d] = result; 6274 if setflags then 6275 APSR.N = result<31>; 6276 APSR.Z = IsZeroBit(result); 6277 APSR.C = carry; 6278 // APSR.V unchanged 6279#endif 6280 6281 bool success = false; 6282 6283 if (ConditionPassed(opcode)) { 6284 uint32_t Rd, Rn, Rm; 6285 ARM_ShifterType shift_t; 6286 uint32_t shift_n; // the shift applied to the value read from Rm 6287 bool setflags; 6288 uint32_t carry; 6289 switch (encoding) { 6290 case eEncodingT1: 6291 Rd = Rn = Bits32(opcode, 2, 0); 6292 Rm = Bits32(opcode, 5, 3); 6293 setflags = !InITBlock(); 6294 shift_t = SRType_LSL; 6295 shift_n = 0; 6296 break; 6297 case eEncodingT2: 6298 Rd = Bits32(opcode, 11, 8); 6299 Rn = Bits32(opcode, 19, 16); 6300 Rm = Bits32(opcode, 3, 0); 6301 setflags = BitIsSet(opcode, 20); 6302 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6303 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 6304 return false; 6305 break; 6306 case eEncodingA1: 6307 Rd = Bits32(opcode, 15, 12); 6308 Rn = Bits32(opcode, 19, 16); 6309 Rm = Bits32(opcode, 3, 0); 6310 setflags = BitIsSet(opcode, 20); 6311 shift_n = DecodeImmShiftARM(opcode, shift_t); 6312 6313 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6314 // instructions; 6315 if (Rd == 15 && setflags) 6316 return EmulateSUBSPcLrEtc(opcode, encoding); 6317 break; 6318 default: 6319 return false; 6320 } 6321 6322 // Read the first operand. 6323 uint32_t val1 = ReadCoreReg(Rn, &success); 6324 if (!success) 6325 return false; 6326 6327 // Read the second operand. 6328 uint32_t val2 = ReadCoreReg(Rm, &success); 6329 if (!success) 6330 return false; 6331 6332 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6333 if (!success) 6334 return false; 6335 uint32_t result = val1 & ~shifted; 6336 6337 EmulateInstruction::Context context; 6338 context.type = EmulateInstruction::eContextImmediate; 6339 context.SetNoArgs(); 6340 6341 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6342 return false; 6343 } 6344 return true; 6345} 6346 6347// LDR (immediate, ARM) calculates an address from a base register value and an 6348// immediate offset, loads a word 6349// from memory, and writes it to a register. It can use offset, post-indexed, 6350// or pre-indexed addressing. 6351bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode, 6352 const ARMEncoding encoding) { 6353#if 0 6354 if ConditionPassed() then 6355 EncodingSpecificOperations(); 6356 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6357 address = if index then offset_addr else R[n]; 6358 data = MemU[address,4]; 6359 if wback then R[n] = offset_addr; 6360 if t == 15 then 6361 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6362 elsif UnalignedSupport() || address<1:0> = '00' then 6363 R[t] = data; 6364 else // Can only apply before ARMv7 6365 R[t] = ROR(data, 8*UInt(address<1:0>)); 6366#endif 6367 6368 bool success = false; 6369 6370 if (ConditionPassed(opcode)) { 6371 const uint32_t addr_byte_size = GetAddressByteSize(); 6372 6373 uint32_t t; 6374 uint32_t n; 6375 uint32_t imm32; 6376 bool index; 6377 bool add; 6378 bool wback; 6379 6380 switch (encoding) { 6381 case eEncodingA1: 6382 // if Rn == '1111' then SEE LDR (literal); 6383 // if P == '0' && W == '1' then SEE LDRT; 6384 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == 6385 // '000000000100' then SEE POP; 6386 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6387 t = Bits32(opcode, 15, 12); 6388 n = Bits32(opcode, 19, 16); 6389 imm32 = Bits32(opcode, 11, 0); 6390 6391 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6392 // (W == '1'); 6393 index = BitIsSet(opcode, 24); 6394 add = BitIsSet(opcode, 23); 6395 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6396 6397 // if wback && n == t then UNPREDICTABLE; 6398 if (wback && (n == t)) 6399 return false; 6400 6401 break; 6402 6403 default: 6404 return false; 6405 } 6406 6407 addr_t address; 6408 addr_t offset_addr; 6409 addr_t base_address = ReadCoreReg(n, &success); 6410 if (!success) 6411 return false; 6412 6413 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6414 if (add) 6415 offset_addr = base_address + imm32; 6416 else 6417 offset_addr = base_address - imm32; 6418 6419 // address = if index then offset_addr else R[n]; 6420 if (index) 6421 address = offset_addr; 6422 else 6423 address = base_address; 6424 6425 // data = MemU[address,4]; 6426 6427 RegisterInfo base_reg; 6428 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6429 6430 EmulateInstruction::Context context; 6431 context.type = eContextRegisterLoad; 6432 context.SetRegisterPlusOffset(base_reg, address - base_address); 6433 6434 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6435 if (!success) 6436 return false; 6437 6438 // if wback then R[n] = offset_addr; 6439 if (wback) { 6440 context.type = eContextAdjustBaseRegister; 6441 context.SetAddress(offset_addr); 6442 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6443 offset_addr)) 6444 return false; 6445 } 6446 6447 // if t == 15 then 6448 if (t == 15) { 6449 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6450 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6451 // LoadWritePC (data); 6452 context.type = eContextRegisterLoad; 6453 context.SetRegisterPlusOffset(base_reg, address - base_address); 6454 LoadWritePC(context, data); 6455 } else 6456 return false; 6457 } 6458 // elsif UnalignedSupport() || address<1:0> = '00' then 6459 else if (UnalignedSupport() || 6460 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6461 // R[t] = data; 6462 context.type = eContextRegisterLoad; 6463 context.SetRegisterPlusOffset(base_reg, address - base_address); 6464 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6465 data)) 6466 return false; 6467 } 6468 // else // Can only apply before ARMv7 6469 else { 6470 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6471 data = ROR(data, Bits32(address, 1, 0), &success); 6472 if (!success) 6473 return false; 6474 context.type = eContextRegisterLoad; 6475 context.SetImmediate(data); 6476 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6477 data)) 6478 return false; 6479 } 6480 } 6481 return true; 6482} 6483 6484// LDR (register) calculates an address from a base register value and an offset 6485// register value, loads a word 6486// from memory, and writes it to a register. The offset register value can 6487// optionally be shifted. 6488bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode, 6489 const ARMEncoding encoding) { 6490#if 0 6491 if ConditionPassed() then 6492 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6493 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6494 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6495 address = if index then offset_addr else R[n]; 6496 data = MemU[address,4]; 6497 if wback then R[n] = offset_addr; 6498 if t == 15 then 6499 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6500 elsif UnalignedSupport() || address<1:0> = '00' then 6501 R[t] = data; 6502 else // Can only apply before ARMv7 6503 if CurrentInstrSet() == InstrSet_ARM then 6504 R[t] = ROR(data, 8*UInt(address<1:0>)); 6505 else 6506 R[t] = bits(32) UNKNOWN; 6507#endif 6508 6509 bool success = false; 6510 6511 if (ConditionPassed(opcode)) { 6512 const uint32_t addr_byte_size = GetAddressByteSize(); 6513 6514 uint32_t t; 6515 uint32_t n; 6516 uint32_t m; 6517 bool index; 6518 bool add; 6519 bool wback; 6520 ARM_ShifterType shift_t; 6521 uint32_t shift_n; 6522 6523 switch (encoding) { 6524 case eEncodingT1: 6525 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 6526 // in ThumbEE"; 6527 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6528 t = Bits32(opcode, 2, 0); 6529 n = Bits32(opcode, 5, 3); 6530 m = Bits32(opcode, 8, 6); 6531 6532 // index = TRUE; add = TRUE; wback = FALSE; 6533 index = true; 6534 add = true; 6535 wback = false; 6536 6537 // (shift_t, shift_n) = (SRType_LSL, 0); 6538 shift_t = SRType_LSL; 6539 shift_n = 0; 6540 6541 break; 6542 6543 case eEncodingT2: 6544 // if Rn == '1111' then SEE LDR (literal); 6545 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6546 t = Bits32(opcode, 15, 12); 6547 n = Bits32(opcode, 19, 16); 6548 m = Bits32(opcode, 3, 0); 6549 6550 // index = TRUE; add = TRUE; wback = FALSE; 6551 index = true; 6552 add = true; 6553 wback = false; 6554 6555 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6556 shift_t = SRType_LSL; 6557 shift_n = Bits32(opcode, 5, 4); 6558 6559 // if BadReg(m) then UNPREDICTABLE; 6560 if (BadReg(m)) 6561 return false; 6562 6563 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6564 if ((t == 15) && InITBlock() && !LastInITBlock()) 6565 return false; 6566 6567 break; 6568 6569 case eEncodingA1: { 6570 // if P == '0' && W == '1' then SEE LDRT; 6571 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6572 t = Bits32(opcode, 15, 12); 6573 n = Bits32(opcode, 19, 16); 6574 m = Bits32(opcode, 3, 0); 6575 6576 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6577 // (W == '1'); 6578 index = BitIsSet(opcode, 24); 6579 add = BitIsSet(opcode, 23); 6580 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6581 6582 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6583 uint32_t type = Bits32(opcode, 6, 5); 6584 uint32_t imm5 = Bits32(opcode, 11, 7); 6585 shift_n = DecodeImmShift(type, imm5, shift_t); 6586 6587 // if m == 15 then UNPREDICTABLE; 6588 if (m == 15) 6589 return false; 6590 6591 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6592 if (wback && ((n == 15) || (n == t))) 6593 return false; 6594 } break; 6595 6596 default: 6597 return false; 6598 } 6599 6600 uint32_t Rm = 6601 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6602 if (!success) 6603 return false; 6604 6605 uint32_t Rn = 6606 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6607 if (!success) 6608 return false; 6609 6610 addr_t offset_addr; 6611 addr_t address; 6612 6613 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is 6614 // an application level alias for the CPSR". 6615 addr_t offset = 6616 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success); 6617 if (!success) 6618 return false; 6619 6620 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6621 if (add) 6622 offset_addr = Rn + offset; 6623 else 6624 offset_addr = Rn - offset; 6625 6626 // address = if index then offset_addr else R[n]; 6627 if (index) 6628 address = offset_addr; 6629 else 6630 address = Rn; 6631 6632 // data = MemU[address,4]; 6633 RegisterInfo base_reg; 6634 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6635 6636 EmulateInstruction::Context context; 6637 context.type = eContextRegisterLoad; 6638 context.SetRegisterPlusOffset(base_reg, address - Rn); 6639 6640 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6641 if (!success) 6642 return false; 6643 6644 // if wback then R[n] = offset_addr; 6645 if (wback) { 6646 context.type = eContextAdjustBaseRegister; 6647 context.SetAddress(offset_addr); 6648 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6649 offset_addr)) 6650 return false; 6651 } 6652 6653 // if t == 15 then 6654 if (t == 15) { 6655 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6656 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6657 context.type = eContextRegisterLoad; 6658 context.SetRegisterPlusOffset(base_reg, address - Rn); 6659 LoadWritePC(context, data); 6660 } else 6661 return false; 6662 } 6663 // elsif UnalignedSupport() || address<1:0> = '00' then 6664 else if (UnalignedSupport() || 6665 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6666 // R[t] = data; 6667 context.type = eContextRegisterLoad; 6668 context.SetRegisterPlusOffset(base_reg, address - Rn); 6669 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6670 data)) 6671 return false; 6672 } else // Can only apply before ARMv7 6673 { 6674 // if CurrentInstrSet() == InstrSet_ARM then 6675 if (CurrentInstrSet() == eModeARM) { 6676 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6677 data = ROR(data, Bits32(address, 1, 0), &success); 6678 if (!success) 6679 return false; 6680 context.type = eContextRegisterLoad; 6681 context.SetImmediate(data); 6682 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6683 data)) 6684 return false; 6685 } else { 6686 // R[t] = bits(32) UNKNOWN; 6687 WriteBits32Unknown(t); 6688 } 6689 } 6690 } 6691 return true; 6692} 6693 6694// LDRB (immediate, Thumb) 6695bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode, 6696 const ARMEncoding encoding) { 6697#if 0 6698 if ConditionPassed() then 6699 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6700 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6701 address = if index then offset_addr else R[n]; 6702 R[t] = ZeroExtend(MemU[address,1], 32); 6703 if wback then R[n] = offset_addr; 6704#endif 6705 6706 bool success = false; 6707 6708 if (ConditionPassed(opcode)) { 6709 uint32_t t; 6710 uint32_t n; 6711 uint32_t imm32; 6712 bool index; 6713 bool add; 6714 bool wback; 6715 6716 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6717 switch (encoding) { 6718 case eEncodingT1: 6719 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6720 t = Bits32(opcode, 2, 0); 6721 n = Bits32(opcode, 5, 3); 6722 imm32 = Bits32(opcode, 10, 6); 6723 6724 // index = TRUE; add = TRUE; wback = FALSE; 6725 index = true; 6726 add = true; 6727 wback = false; 6728 6729 break; 6730 6731 case eEncodingT2: 6732 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6733 t = Bits32(opcode, 15, 12); 6734 n = Bits32(opcode, 19, 16); 6735 imm32 = Bits32(opcode, 11, 0); 6736 6737 // index = TRUE; add = TRUE; wback = FALSE; 6738 index = true; 6739 add = true; 6740 wback = false; 6741 6742 // if Rt == '1111' then SEE PLD; 6743 if (t == 15) 6744 return false; // PLD is not implemented yet 6745 6746 // if Rn == '1111' then SEE LDRB (literal); 6747 if (n == 15) 6748 return EmulateLDRBLiteral(opcode, eEncodingT1); 6749 6750 // if t == 13 then UNPREDICTABLE; 6751 if (t == 13) 6752 return false; 6753 6754 break; 6755 6756 case eEncodingT3: 6757 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6758 // if P == '0' && W == '0' then UNDEFINED; 6759 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 6760 return false; 6761 6762 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6763 t = Bits32(opcode, 15, 12); 6764 n = Bits32(opcode, 19, 16); 6765 imm32 = Bits32(opcode, 7, 0); 6766 6767 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6768 index = BitIsSet(opcode, 10); 6769 add = BitIsSet(opcode, 9); 6770 wback = BitIsSet(opcode, 8); 6771 6772 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6773 if (t == 15) 6774 return false; // PLD is not implemented yet 6775 6776 // if Rn == '1111' then SEE LDRB (literal); 6777 if (n == 15) 6778 return EmulateLDRBLiteral(opcode, eEncodingT1); 6779 6780 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6781 if (BadReg(t) || (wback && (n == t))) 6782 return false; 6783 6784 break; 6785 6786 default: 6787 return false; 6788 } 6789 6790 uint32_t Rn = 6791 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6792 if (!success) 6793 return false; 6794 6795 addr_t address; 6796 addr_t offset_addr; 6797 6798 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6799 if (add) 6800 offset_addr = Rn + imm32; 6801 else 6802 offset_addr = Rn - imm32; 6803 6804 // address = if index then offset_addr else R[n]; 6805 if (index) 6806 address = offset_addr; 6807 else 6808 address = Rn; 6809 6810 // R[t] = ZeroExtend(MemU[address,1], 32); 6811 RegisterInfo base_reg; 6812 RegisterInfo data_reg; 6813 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6814 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6815 6816 EmulateInstruction::Context context; 6817 context.type = eContextRegisterLoad; 6818 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 6819 6820 uint64_t data = MemURead(context, address, 1, 0, &success); 6821 if (!success) 6822 return false; 6823 6824 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6825 return false; 6826 6827 // if wback then R[n] = offset_addr; 6828 if (wback) { 6829 context.type = eContextAdjustBaseRegister; 6830 context.SetAddress(offset_addr); 6831 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6832 offset_addr)) 6833 return false; 6834 } 6835 } 6836 return true; 6837} 6838 6839// LDRB (literal) calculates an address from the PC value and an immediate 6840// offset, loads a byte from memory, 6841// zero-extends it to form a 32-bit word and writes it to a register. 6842bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode, 6843 const ARMEncoding encoding) { 6844#if 0 6845 if ConditionPassed() then 6846 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6847 base = Align(PC,4); 6848 address = if add then (base + imm32) else (base - imm32); 6849 R[t] = ZeroExtend(MemU[address,1], 32); 6850#endif 6851 6852 bool success = false; 6853 6854 if (ConditionPassed(opcode)) { 6855 uint32_t t; 6856 uint32_t imm32; 6857 bool add; 6858 switch (encoding) { 6859 case eEncodingT1: 6860 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6861 t = Bits32(opcode, 15, 12); 6862 imm32 = Bits32(opcode, 11, 0); 6863 add = BitIsSet(opcode, 23); 6864 6865 // if Rt == '1111' then SEE PLD; 6866 if (t == 15) 6867 return false; // PLD is not implemented yet 6868 6869 // if t == 13 then UNPREDICTABLE; 6870 if (t == 13) 6871 return false; 6872 6873 break; 6874 6875 case eEncodingA1: 6876 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6877 t = Bits32(opcode, 15, 12); 6878 imm32 = Bits32(opcode, 11, 0); 6879 add = BitIsSet(opcode, 23); 6880 6881 // if t == 15 then UNPREDICTABLE; 6882 if (t == 15) 6883 return false; 6884 break; 6885 6886 default: 6887 return false; 6888 } 6889 6890 // base = Align(PC,4); 6891 uint32_t pc_val = ReadCoreReg(PC_REG, &success); 6892 if (!success) 6893 return false; 6894 6895 uint32_t base = AlignPC(pc_val); 6896 6897 addr_t address; 6898 // address = if add then (base + imm32) else (base - imm32); 6899 if (add) 6900 address = base + imm32; 6901 else 6902 address = base - imm32; 6903 6904 // R[t] = ZeroExtend(MemU[address,1], 32); 6905 EmulateInstruction::Context context; 6906 context.type = eContextRelativeBranchImmediate; 6907 context.SetImmediate(address - base); 6908 6909 uint64_t data = MemURead(context, address, 1, 0, &success); 6910 if (!success) 6911 return false; 6912 6913 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6914 return false; 6915 } 6916 return true; 6917} 6918 6919// LDRB (register) calculates an address from a base register value and an 6920// offset rigister value, loads a byte from memory, zero-extends it to form a 6921// 32-bit word, and writes it to a register. The offset register value can 6922// optionally be shifted. 6923bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode, 6924 const ARMEncoding encoding) { 6925#if 0 6926 if ConditionPassed() then 6927 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6928 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6929 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6930 address = if index then offset_addr else R[n]; 6931 R[t] = ZeroExtend(MemU[address,1],32); 6932 if wback then R[n] = offset_addr; 6933#endif 6934 6935 bool success = false; 6936 6937 if (ConditionPassed(opcode)) { 6938 uint32_t t; 6939 uint32_t n; 6940 uint32_t m; 6941 bool index; 6942 bool add; 6943 bool wback; 6944 ARM_ShifterType shift_t; 6945 uint32_t shift_n; 6946 6947 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6948 switch (encoding) { 6949 case eEncodingT1: 6950 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6951 t = Bits32(opcode, 2, 0); 6952 n = Bits32(opcode, 5, 3); 6953 m = Bits32(opcode, 8, 6); 6954 6955 // index = TRUE; add = TRUE; wback = FALSE; 6956 index = true; 6957 add = true; 6958 wback = false; 6959 6960 // (shift_t, shift_n) = (SRType_LSL, 0); 6961 shift_t = SRType_LSL; 6962 shift_n = 0; 6963 break; 6964 6965 case eEncodingT2: 6966 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6967 t = Bits32(opcode, 15, 12); 6968 n = Bits32(opcode, 19, 16); 6969 m = Bits32(opcode, 3, 0); 6970 6971 // index = TRUE; add = TRUE; wback = FALSE; 6972 index = true; 6973 add = true; 6974 wback = false; 6975 6976 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6977 shift_t = SRType_LSL; 6978 shift_n = Bits32(opcode, 5, 4); 6979 6980 // if Rt == '1111' then SEE PLD; 6981 if (t == 15) 6982 return false; // PLD is not implemented yet 6983 6984 // if Rn == '1111' then SEE LDRB (literal); 6985 if (n == 15) 6986 return EmulateLDRBLiteral(opcode, eEncodingT1); 6987 6988 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6989 if ((t == 13) || BadReg(m)) 6990 return false; 6991 break; 6992 6993 case eEncodingA1: { 6994 // if P == '0' && W == '1' then SEE LDRBT; 6995 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6996 t = Bits32(opcode, 15, 12); 6997 n = Bits32(opcode, 19, 16); 6998 m = Bits32(opcode, 3, 0); 6999 7000 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7001 // (W == '1'); 7002 index = BitIsSet(opcode, 24); 7003 add = BitIsSet(opcode, 23); 7004 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7005 7006 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 7007 uint32_t type = Bits32(opcode, 6, 5); 7008 uint32_t imm5 = Bits32(opcode, 11, 7); 7009 shift_n = DecodeImmShift(type, imm5, shift_t); 7010 7011 // if t == 15 || m == 15 then UNPREDICTABLE; 7012 if ((t == 15) || (m == 15)) 7013 return false; 7014 7015 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7016 if (wback && ((n == 15) || (n == t))) 7017 return false; 7018 } break; 7019 7020 default: 7021 return false; 7022 } 7023 7024 addr_t offset_addr; 7025 addr_t address; 7026 7027 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7028 uint32_t Rm = 7029 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7030 if (!success) 7031 return false; 7032 7033 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7034 if (!success) 7035 return false; 7036 7037 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7038 uint32_t Rn = 7039 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7040 if (!success) 7041 return false; 7042 7043 if (add) 7044 offset_addr = Rn + offset; 7045 else 7046 offset_addr = Rn - offset; 7047 7048 // address = if index then offset_addr else R[n]; 7049 if (index) 7050 address = offset_addr; 7051 else 7052 address = Rn; 7053 7054 // R[t] = ZeroExtend(MemU[address,1],32); 7055 RegisterInfo base_reg; 7056 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7057 7058 EmulateInstruction::Context context; 7059 context.type = eContextRegisterLoad; 7060 context.SetRegisterPlusOffset(base_reg, address - Rn); 7061 7062 uint64_t data = MemURead(context, address, 1, 0, &success); 7063 if (!success) 7064 return false; 7065 7066 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7067 return false; 7068 7069 // if wback then R[n] = offset_addr; 7070 if (wback) { 7071 context.type = eContextAdjustBaseRegister; 7072 context.SetAddress(offset_addr); 7073 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7074 offset_addr)) 7075 return false; 7076 } 7077 } 7078 return true; 7079} 7080 7081// LDRH (immediate, Thumb) calculates an address from a base register value and 7082// an immediate offset, loads a 7083// halfword from memory, zero-extends it to form a 32-bit word, and writes it 7084// to a register. It can use offset, post-indexed, or pre-indexed addressing. 7085bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode, 7086 const ARMEncoding encoding) { 7087#if 0 7088 if ConditionPassed() then 7089 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7090 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7091 address = if index then offset_addr else R[n]; 7092 data = MemU[address,2]; 7093 if wback then R[n] = offset_addr; 7094 if UnalignedSupport() || address<0> = '0' then 7095 R[t] = ZeroExtend(data, 32); 7096 else // Can only apply before ARMv7 7097 R[t] = bits(32) UNKNOWN; 7098#endif 7099 7100 bool success = false; 7101 7102 if (ConditionPassed(opcode)) { 7103 uint32_t t; 7104 uint32_t n; 7105 uint32_t imm32; 7106 bool index; 7107 bool add; 7108 bool wback; 7109 7110 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7111 switch (encoding) { 7112 case eEncodingT1: 7113 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 7114 t = Bits32(opcode, 2, 0); 7115 n = Bits32(opcode, 5, 3); 7116 imm32 = Bits32(opcode, 10, 6) << 1; 7117 7118 // index = TRUE; add = TRUE; wback = FALSE; 7119 index = true; 7120 add = true; 7121 wback = false; 7122 7123 break; 7124 7125 case eEncodingT2: 7126 // if Rt == '1111' then SEE "Unallocated memory hints"; 7127 // if Rn == '1111' then SEE LDRH (literal); 7128 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7129 t = Bits32(opcode, 15, 12); 7130 n = Bits32(opcode, 19, 16); 7131 imm32 = Bits32(opcode, 11, 0); 7132 7133 // index = TRUE; add = TRUE; wback = FALSE; 7134 index = true; 7135 add = true; 7136 wback = false; 7137 7138 // if t == 13 then UNPREDICTABLE; 7139 if (t == 13) 7140 return false; 7141 break; 7142 7143 case eEncodingT3: 7144 // if Rn == '1111' then SEE LDRH (literal); 7145 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7146 // "Unallocated memory hints"; 7147 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 7148 // if P == '0' && W == '0' then UNDEFINED; 7149 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7150 return false; 7151 7152 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7153 t = Bits32(opcode, 15, 12); 7154 n = Bits32(opcode, 19, 16); 7155 imm32 = Bits32(opcode, 7, 0); 7156 7157 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7158 index = BitIsSet(opcode, 10); 7159 add = BitIsSet(opcode, 9); 7160 wback = BitIsSet(opcode, 8); 7161 7162 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7163 if (BadReg(t) || (wback && (n == t))) 7164 return false; 7165 break; 7166 7167 default: 7168 return false; 7169 } 7170 7171 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7172 uint32_t Rn = 7173 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7174 if (!success) 7175 return false; 7176 7177 addr_t offset_addr; 7178 addr_t address; 7179 7180 if (add) 7181 offset_addr = Rn + imm32; 7182 else 7183 offset_addr = Rn - imm32; 7184 7185 // address = if index then offset_addr else R[n]; 7186 if (index) 7187 address = offset_addr; 7188 else 7189 address = Rn; 7190 7191 // data = MemU[address,2]; 7192 RegisterInfo base_reg; 7193 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7194 7195 EmulateInstruction::Context context; 7196 context.type = eContextRegisterLoad; 7197 context.SetRegisterPlusOffset(base_reg, address - Rn); 7198 7199 uint64_t data = MemURead(context, address, 2, 0, &success); 7200 if (!success) 7201 return false; 7202 7203 // if wback then R[n] = offset_addr; 7204 if (wback) { 7205 context.type = eContextAdjustBaseRegister; 7206 context.SetAddress(offset_addr); 7207 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7208 offset_addr)) 7209 return false; 7210 } 7211 7212 // if UnalignedSupport() || address<0> = '0' then 7213 if (UnalignedSupport() || BitIsClear(address, 0)) { 7214 // R[t] = ZeroExtend(data, 32); 7215 context.type = eContextRegisterLoad; 7216 context.SetRegisterPlusOffset(base_reg, address - Rn); 7217 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7218 data)) 7219 return false; 7220 } else // Can only apply before ARMv7 7221 { 7222 // R[t] = bits(32) UNKNOWN; 7223 WriteBits32Unknown(t); 7224 } 7225 } 7226 return true; 7227} 7228 7229// LDRH (literal) caculates an address from the PC value and an immediate 7230// offset, loads a halfword from memory, 7231// zero-extends it to form a 32-bit word, and writes it to a register. 7232bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode, 7233 const ARMEncoding encoding) { 7234#if 0 7235 if ConditionPassed() then 7236 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7237 base = Align(PC,4); 7238 address = if add then (base + imm32) else (base - imm32); 7239 data = MemU[address,2]; 7240 if UnalignedSupport() || address<0> = '0' then 7241 R[t] = ZeroExtend(data, 32); 7242 else // Can only apply before ARMv7 7243 R[t] = bits(32) UNKNOWN; 7244#endif 7245 7246 bool success = false; 7247 7248 if (ConditionPassed(opcode)) { 7249 uint32_t t; 7250 uint32_t imm32; 7251 bool add; 7252 7253 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7254 switch (encoding) { 7255 case eEncodingT1: 7256 // if Rt == '1111' then SEE "Unallocated memory hints"; 7257 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7258 t = Bits32(opcode, 15, 12); 7259 imm32 = Bits32(opcode, 11, 0); 7260 add = BitIsSet(opcode, 23); 7261 7262 // if t == 13 then UNPREDICTABLE; 7263 if (t == 13) 7264 return false; 7265 7266 break; 7267 7268 case eEncodingA1: { 7269 uint32_t imm4H = Bits32(opcode, 11, 8); 7270 uint32_t imm4L = Bits32(opcode, 3, 0); 7271 7272 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7273 t = Bits32(opcode, 15, 12); 7274 imm32 = (imm4H << 4) | imm4L; 7275 add = BitIsSet(opcode, 23); 7276 7277 // if t == 15 then UNPREDICTABLE; 7278 if (t == 15) 7279 return false; 7280 break; 7281 } 7282 7283 default: 7284 return false; 7285 } 7286 7287 // base = Align(PC,4); 7288 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7289 if (!success) 7290 return false; 7291 7292 addr_t base = AlignPC(pc_value); 7293 addr_t address; 7294 7295 // address = if add then (base + imm32) else (base - imm32); 7296 if (add) 7297 address = base + imm32; 7298 else 7299 address = base - imm32; 7300 7301 // data = MemU[address,2]; 7302 RegisterInfo base_reg; 7303 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7304 7305 EmulateInstruction::Context context; 7306 context.type = eContextRegisterLoad; 7307 context.SetRegisterPlusOffset(base_reg, address - base); 7308 7309 uint64_t data = MemURead(context, address, 2, 0, &success); 7310 if (!success) 7311 return false; 7312 7313 // if UnalignedSupport() || address<0> = '0' then 7314 if (UnalignedSupport() || BitIsClear(address, 0)) { 7315 // R[t] = ZeroExtend(data, 32); 7316 context.type = eContextRegisterLoad; 7317 context.SetRegisterPlusOffset(base_reg, address - base); 7318 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7319 data)) 7320 return false; 7321 7322 } else // Can only apply before ARMv7 7323 { 7324 // R[t] = bits(32) UNKNOWN; 7325 WriteBits32Unknown(t); 7326 } 7327 } 7328 return true; 7329} 7330 7331// LDRH (literal) calculates an address from a base register value and an offset 7332// register value, loads a halfword 7333// from memory, zero-extends it to form a 32-bit word, and writes it to a 7334// register. The offset register value can be shifted left by 0, 1, 2, or 3 7335// bits. 7336bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode, 7337 const ARMEncoding encoding) { 7338#if 0 7339 if ConditionPassed() then 7340 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7341 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7342 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7343 address = if index then offset_addr else R[n]; 7344 data = MemU[address,2]; 7345 if wback then R[n] = offset_addr; 7346 if UnalignedSupport() || address<0> = '0' then 7347 R[t] = ZeroExtend(data, 32); 7348 else // Can only apply before ARMv7 7349 R[t] = bits(32) UNKNOWN; 7350#endif 7351 7352 bool success = false; 7353 7354 if (ConditionPassed(opcode)) { 7355 uint32_t t; 7356 uint32_t n; 7357 uint32_t m; 7358 bool index; 7359 bool add; 7360 bool wback; 7361 ARM_ShifterType shift_t; 7362 uint32_t shift_n; 7363 7364 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7365 switch (encoding) { 7366 case eEncodingT1: 7367 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 7368 // in ThumbEE"; 7369 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7370 t = Bits32(opcode, 2, 0); 7371 n = Bits32(opcode, 5, 3); 7372 m = Bits32(opcode, 8, 6); 7373 7374 // index = TRUE; add = TRUE; wback = FALSE; 7375 index = true; 7376 add = true; 7377 wback = false; 7378 7379 // (shift_t, shift_n) = (SRType_LSL, 0); 7380 shift_t = SRType_LSL; 7381 shift_n = 0; 7382 7383 break; 7384 7385 case eEncodingT2: 7386 // if Rn == '1111' then SEE LDRH (literal); 7387 // if Rt == '1111' then SEE "Unallocated memory hints"; 7388 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7389 t = Bits32(opcode, 15, 12); 7390 n = Bits32(opcode, 19, 16); 7391 m = Bits32(opcode, 3, 0); 7392 7393 // index = TRUE; add = TRUE; wback = FALSE; 7394 index = true; 7395 add = true; 7396 wback = false; 7397 7398 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7399 shift_t = SRType_LSL; 7400 shift_n = Bits32(opcode, 5, 4); 7401 7402 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7403 if ((t == 13) || BadReg(m)) 7404 return false; 7405 break; 7406 7407 case eEncodingA1: 7408 // if P == '0' && W == '1' then SEE LDRHT; 7409 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7410 t = Bits32(opcode, 15, 12); 7411 n = Bits32(opcode, 19, 16); 7412 m = Bits32(opcode, 3, 0); 7413 7414 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7415 // (W == '1'); 7416 index = BitIsSet(opcode, 24); 7417 add = BitIsSet(opcode, 23); 7418 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7419 7420 // (shift_t, shift_n) = (SRType_LSL, 0); 7421 shift_t = SRType_LSL; 7422 shift_n = 0; 7423 7424 // if t == 15 || m == 15 then UNPREDICTABLE; 7425 if ((t == 15) || (m == 15)) 7426 return false; 7427 7428 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7429 if (wback && ((n == 15) || (n == t))) 7430 return false; 7431 7432 break; 7433 7434 default: 7435 return false; 7436 } 7437 7438 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7439 7440 uint64_t Rm = 7441 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7442 if (!success) 7443 return false; 7444 7445 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7446 if (!success) 7447 return false; 7448 7449 addr_t offset_addr; 7450 addr_t address; 7451 7452 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7453 uint64_t Rn = 7454 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7455 if (!success) 7456 return false; 7457 7458 if (add) 7459 offset_addr = Rn + offset; 7460 else 7461 offset_addr = Rn - offset; 7462 7463 // address = if index then offset_addr else R[n]; 7464 if (index) 7465 address = offset_addr; 7466 else 7467 address = Rn; 7468 7469 // data = MemU[address,2]; 7470 RegisterInfo base_reg; 7471 RegisterInfo offset_reg; 7472 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7473 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7474 7475 EmulateInstruction::Context context; 7476 context.type = eContextRegisterLoad; 7477 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7478 uint64_t data = MemURead(context, address, 2, 0, &success); 7479 if (!success) 7480 return false; 7481 7482 // if wback then R[n] = offset_addr; 7483 if (wback) { 7484 context.type = eContextAdjustBaseRegister; 7485 context.SetAddress(offset_addr); 7486 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7487 offset_addr)) 7488 return false; 7489 } 7490 7491 // if UnalignedSupport() || address<0> = '0' then 7492 if (UnalignedSupport() || BitIsClear(address, 0)) { 7493 // R[t] = ZeroExtend(data, 32); 7494 context.type = eContextRegisterLoad; 7495 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7496 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7497 data)) 7498 return false; 7499 } else // Can only apply before ARMv7 7500 { 7501 // R[t] = bits(32) UNKNOWN; 7502 WriteBits32Unknown(t); 7503 } 7504 } 7505 return true; 7506} 7507 7508// LDRSB (immediate) calculates an address from a base register value and an 7509// immediate offset, loads a byte from 7510// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7511// It can use offset, post-indexed, or pre-indexed addressing. 7512bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode, 7513 const ARMEncoding encoding) { 7514#if 0 7515 if ConditionPassed() then 7516 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7517 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7518 address = if index then offset_addr else R[n]; 7519 R[t] = SignExtend(MemU[address,1], 32); 7520 if wback then R[n] = offset_addr; 7521#endif 7522 7523 bool success = false; 7524 7525 if (ConditionPassed(opcode)) { 7526 uint32_t t; 7527 uint32_t n; 7528 uint32_t imm32; 7529 bool index; 7530 bool add; 7531 bool wback; 7532 7533 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7534 switch (encoding) { 7535 case eEncodingT1: 7536 // if Rt == '1111' then SEE PLI; 7537 // if Rn == '1111' then SEE LDRSB (literal); 7538 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7539 t = Bits32(opcode, 15, 12); 7540 n = Bits32(opcode, 19, 16); 7541 imm32 = Bits32(opcode, 11, 0); 7542 7543 // index = TRUE; add = TRUE; wback = FALSE; 7544 index = true; 7545 add = true; 7546 wback = false; 7547 7548 // if t == 13 then UNPREDICTABLE; 7549 if (t == 13) 7550 return false; 7551 7552 break; 7553 7554 case eEncodingT2: 7555 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7556 // if Rn == '1111' then SEE LDRSB (literal); 7557 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7558 // if P == '0' && W == '0' then UNDEFINED; 7559 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7560 return false; 7561 7562 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7563 t = Bits32(opcode, 15, 12); 7564 n = Bits32(opcode, 19, 16); 7565 imm32 = Bits32(opcode, 7, 0); 7566 7567 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7568 index = BitIsSet(opcode, 10); 7569 add = BitIsSet(opcode, 9); 7570 wback = BitIsSet(opcode, 8); 7571 7572 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7573 if (((t == 13) || 7574 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) || 7575 BitIsSet(opcode, 8)))) || 7576 (wback && (n == t))) 7577 return false; 7578 7579 break; 7580 7581 case eEncodingA1: { 7582 // if Rn == '1111' then SEE LDRSB (literal); 7583 // if P == '0' && W == '1' then SEE LDRSBT; 7584 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7585 t = Bits32(opcode, 15, 12); 7586 n = Bits32(opcode, 19, 16); 7587 7588 uint32_t imm4H = Bits32(opcode, 11, 8); 7589 uint32_t imm4L = Bits32(opcode, 3, 0); 7590 imm32 = (imm4H << 4) | imm4L; 7591 7592 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7593 // (W == '1'); 7594 index = BitIsSet(opcode, 24); 7595 add = BitIsSet(opcode, 23); 7596 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7597 7598 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7599 if ((t == 15) || (wback && (n == t))) 7600 return false; 7601 7602 break; 7603 } 7604 7605 default: 7606 return false; 7607 } 7608 7609 uint64_t Rn = ReadCoreReg(n, &success); 7610 if (!success) 7611 return false; 7612 7613 addr_t offset_addr; 7614 addr_t address; 7615 7616 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7617 if (add) 7618 offset_addr = Rn + imm32; 7619 else 7620 offset_addr = Rn - imm32; 7621 7622 // address = if index then offset_addr else R[n]; 7623 if (index) 7624 address = offset_addr; 7625 else 7626 address = Rn; 7627 7628 // R[t] = SignExtend(MemU[address,1], 32); 7629 RegisterInfo base_reg; 7630 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7631 7632 EmulateInstruction::Context context; 7633 context.type = eContextRegisterLoad; 7634 context.SetRegisterPlusOffset(base_reg, address - Rn); 7635 7636 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7637 if (!success) 7638 return false; 7639 7640 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7641 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7642 (uint64_t)signed_data)) 7643 return false; 7644 7645 // if wback then R[n] = offset_addr; 7646 if (wback) { 7647 context.type = eContextAdjustBaseRegister; 7648 context.SetAddress(offset_addr); 7649 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7650 offset_addr)) 7651 return false; 7652 } 7653 } 7654 7655 return true; 7656} 7657 7658// LDRSB (literal) calculates an address from the PC value and an immediate 7659// offset, loads a byte from memory, 7660// sign-extends it to form a 32-bit word, and writes tit to a register. 7661bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode, 7662 const ARMEncoding encoding) { 7663#if 0 7664 if ConditionPassed() then 7665 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7666 base = Align(PC,4); 7667 address = if add then (base + imm32) else (base - imm32); 7668 R[t] = SignExtend(MemU[address,1], 32); 7669#endif 7670 7671 bool success = false; 7672 7673 if (ConditionPassed(opcode)) { 7674 uint32_t t; 7675 uint32_t imm32; 7676 bool add; 7677 7678 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7679 switch (encoding) { 7680 case eEncodingT1: 7681 // if Rt == '1111' then SEE PLI; 7682 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7683 t = Bits32(opcode, 15, 12); 7684 imm32 = Bits32(opcode, 11, 0); 7685 add = BitIsSet(opcode, 23); 7686 7687 // if t == 13 then UNPREDICTABLE; 7688 if (t == 13) 7689 return false; 7690 7691 break; 7692 7693 case eEncodingA1: { 7694 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7695 t = Bits32(opcode, 15, 12); 7696 uint32_t imm4H = Bits32(opcode, 11, 8); 7697 uint32_t imm4L = Bits32(opcode, 3, 0); 7698 imm32 = (imm4H << 4) | imm4L; 7699 add = BitIsSet(opcode, 23); 7700 7701 // if t == 15 then UNPREDICTABLE; 7702 if (t == 15) 7703 return false; 7704 7705 break; 7706 } 7707 7708 default: 7709 return false; 7710 } 7711 7712 // base = Align(PC,4); 7713 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7714 if (!success) 7715 return false; 7716 uint64_t base = AlignPC(pc_value); 7717 7718 // address = if add then (base + imm32) else (base - imm32); 7719 addr_t address; 7720 if (add) 7721 address = base + imm32; 7722 else 7723 address = base - imm32; 7724 7725 // R[t] = SignExtend(MemU[address,1], 32); 7726 RegisterInfo base_reg; 7727 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7728 7729 EmulateInstruction::Context context; 7730 context.type = eContextRegisterLoad; 7731 context.SetRegisterPlusOffset(base_reg, address - base); 7732 7733 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7734 if (!success) 7735 return false; 7736 7737 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7738 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7739 (uint64_t)signed_data)) 7740 return false; 7741 } 7742 return true; 7743} 7744 7745// LDRSB (register) calculates an address from a base register value and an 7746// offset register value, loadsa byte from 7747// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7748// The offset register value can be shifted left by 0, 1, 2, or 3 bits. 7749bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode, 7750 const ARMEncoding encoding) { 7751#if 0 7752 if ConditionPassed() then 7753 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7754 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7755 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7756 address = if index then offset_addr else R[n]; 7757 R[t] = SignExtend(MemU[address,1], 32); 7758 if wback then R[n] = offset_addr; 7759#endif 7760 7761 bool success = false; 7762 7763 if (ConditionPassed(opcode)) { 7764 uint32_t t; 7765 uint32_t n; 7766 uint32_t m; 7767 bool index; 7768 bool add; 7769 bool wback; 7770 ARM_ShifterType shift_t; 7771 uint32_t shift_n; 7772 7773 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7774 switch (encoding) { 7775 case eEncodingT1: 7776 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7777 t = Bits32(opcode, 2, 0); 7778 n = Bits32(opcode, 5, 3); 7779 m = Bits32(opcode, 8, 6); 7780 7781 // index = TRUE; add = TRUE; wback = FALSE; 7782 index = true; 7783 add = true; 7784 wback = false; 7785 7786 // (shift_t, shift_n) = (SRType_LSL, 0); 7787 shift_t = SRType_LSL; 7788 shift_n = 0; 7789 7790 break; 7791 7792 case eEncodingT2: 7793 // if Rt == '1111' then SEE PLI; 7794 // if Rn == '1111' then SEE LDRSB (literal); 7795 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7796 t = Bits32(opcode, 15, 12); 7797 n = Bits32(opcode, 19, 16); 7798 m = Bits32(opcode, 3, 0); 7799 7800 // index = TRUE; add = TRUE; wback = FALSE; 7801 index = true; 7802 add = true; 7803 wback = false; 7804 7805 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7806 shift_t = SRType_LSL; 7807 shift_n = Bits32(opcode, 5, 4); 7808 7809 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7810 if ((t == 13) || BadReg(m)) 7811 return false; 7812 break; 7813 7814 case eEncodingA1: 7815 // if P == '0' && W == '1' then SEE LDRSBT; 7816 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7817 t = Bits32(opcode, 15, 12); 7818 n = Bits32(opcode, 19, 16); 7819 m = Bits32(opcode, 3, 0); 7820 7821 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7822 // (W == '1'); 7823 index = BitIsSet(opcode, 24); 7824 add = BitIsSet(opcode, 23); 7825 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7826 7827 // (shift_t, shift_n) = (SRType_LSL, 0); 7828 shift_t = SRType_LSL; 7829 shift_n = 0; 7830 7831 // if t == 15 || m == 15 then UNPREDICTABLE; 7832 if ((t == 15) || (m == 15)) 7833 return false; 7834 7835 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7836 if (wback && ((n == 15) || (n == t))) 7837 return false; 7838 break; 7839 7840 default: 7841 return false; 7842 } 7843 7844 uint64_t Rm = 7845 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7846 if (!success) 7847 return false; 7848 7849 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7850 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7851 if (!success) 7852 return false; 7853 7854 addr_t offset_addr; 7855 addr_t address; 7856 7857 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7858 uint64_t Rn = 7859 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7860 if (!success) 7861 return false; 7862 7863 if (add) 7864 offset_addr = Rn + offset; 7865 else 7866 offset_addr = Rn - offset; 7867 7868 // address = if index then offset_addr else R[n]; 7869 if (index) 7870 address = offset_addr; 7871 else 7872 address = Rn; 7873 7874 // R[t] = SignExtend(MemU[address,1], 32); 7875 RegisterInfo base_reg; 7876 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7877 RegisterInfo offset_reg; 7878 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7879 7880 EmulateInstruction::Context context; 7881 context.type = eContextRegisterLoad; 7882 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7883 7884 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7885 if (!success) 7886 return false; 7887 7888 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7889 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7890 (uint64_t)signed_data)) 7891 return false; 7892 7893 // if wback then R[n] = offset_addr; 7894 if (wback) { 7895 context.type = eContextAdjustBaseRegister; 7896 context.SetAddress(offset_addr); 7897 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7898 offset_addr)) 7899 return false; 7900 } 7901 } 7902 return true; 7903} 7904 7905// LDRSH (immediate) calculates an address from a base register value and an 7906// immediate offset, loads a halfword from 7907// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7908// It can use offset, post-indexed, or pre-indexed addressing. 7909bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode, 7910 const ARMEncoding encoding) { 7911#if 0 7912 if ConditionPassed() then 7913 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7914 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7915 address = if index then offset_addr else R[n]; 7916 data = MemU[address,2]; 7917 if wback then R[n] = offset_addr; 7918 if UnalignedSupport() || address<0> = '0' then 7919 R[t] = SignExtend(data, 32); 7920 else // Can only apply before ARMv7 7921 R[t] = bits(32) UNKNOWN; 7922#endif 7923 7924 bool success = false; 7925 7926 if (ConditionPassed(opcode)) { 7927 uint32_t t; 7928 uint32_t n; 7929 uint32_t imm32; 7930 bool index; 7931 bool add; 7932 bool wback; 7933 7934 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7935 switch (encoding) { 7936 case eEncodingT1: 7937 // if Rn == '1111' then SEE LDRSH (literal); 7938 // if Rt == '1111' then SEE "Unallocated memory hints"; 7939 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7940 t = Bits32(opcode, 15, 12); 7941 n = Bits32(opcode, 19, 16); 7942 imm32 = Bits32(opcode, 11, 0); 7943 7944 // index = TRUE; add = TRUE; wback = FALSE; 7945 index = true; 7946 add = true; 7947 wback = false; 7948 7949 // if t == 13 then UNPREDICTABLE; 7950 if (t == 13) 7951 return false; 7952 7953 break; 7954 7955 case eEncodingT2: 7956 // if Rn == '1111' then SEE LDRSH (literal); 7957 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7958 // "Unallocated memory hints"; 7959 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7960 // if P == '0' && W == '0' then UNDEFINED; 7961 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7962 return false; 7963 7964 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7965 t = Bits32(opcode, 15, 12); 7966 n = Bits32(opcode, 19, 16); 7967 imm32 = Bits32(opcode, 7, 0); 7968 7969 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7970 index = BitIsSet(opcode, 10); 7971 add = BitIsSet(opcode, 9); 7972 wback = BitIsSet(opcode, 8); 7973 7974 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7975 if (BadReg(t) || (wback && (n == t))) 7976 return false; 7977 7978 break; 7979 7980 case eEncodingA1: { 7981 // if Rn == '1111' then SEE LDRSH (literal); 7982 // if P == '0' && W == '1' then SEE LDRSHT; 7983 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7984 t = Bits32(opcode, 15, 12); 7985 n = Bits32(opcode, 19, 16); 7986 uint32_t imm4H = Bits32(opcode, 11, 8); 7987 uint32_t imm4L = Bits32(opcode, 3, 0); 7988 imm32 = (imm4H << 4) | imm4L; 7989 7990 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7991 // (W == '1'); 7992 index = BitIsSet(opcode, 24); 7993 add = BitIsSet(opcode, 23); 7994 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7995 7996 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7997 if ((t == 15) || (wback && (n == t))) 7998 return false; 7999 8000 break; 8001 } 8002 8003 default: 8004 return false; 8005 } 8006 8007 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 8008 uint64_t Rn = 8009 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8010 if (!success) 8011 return false; 8012 8013 addr_t offset_addr; 8014 if (add) 8015 offset_addr = Rn + imm32; 8016 else 8017 offset_addr = Rn - imm32; 8018 8019 // address = if index then offset_addr else R[n]; 8020 addr_t address; 8021 if (index) 8022 address = offset_addr; 8023 else 8024 address = Rn; 8025 8026 // data = MemU[address,2]; 8027 RegisterInfo base_reg; 8028 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8029 8030 EmulateInstruction::Context context; 8031 context.type = eContextRegisterLoad; 8032 context.SetRegisterPlusOffset(base_reg, address - Rn); 8033 8034 uint64_t data = MemURead(context, address, 2, 0, &success); 8035 if (!success) 8036 return false; 8037 8038 // if wback then R[n] = offset_addr; 8039 if (wback) { 8040 context.type = eContextAdjustBaseRegister; 8041 context.SetAddress(offset_addr); 8042 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8043 offset_addr)) 8044 return false; 8045 } 8046 8047 // if UnalignedSupport() || address<0> = '0' then 8048 if (UnalignedSupport() || BitIsClear(address, 0)) { 8049 // R[t] = SignExtend(data, 32); 8050 int64_t signed_data = llvm::SignExtend64<16>(data); 8051 context.type = eContextRegisterLoad; 8052 context.SetRegisterPlusOffset(base_reg, address - Rn); 8053 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8054 (uint64_t)signed_data)) 8055 return false; 8056 } else // Can only apply before ARMv7 8057 { 8058 // R[t] = bits(32) UNKNOWN; 8059 WriteBits32Unknown(t); 8060 } 8061 } 8062 return true; 8063} 8064 8065// LDRSH (literal) calculates an address from the PC value and an immediate 8066// offset, loads a halfword from memory, 8067// sign-extends it to from a 32-bit word, and writes it to a register. 8068bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode, 8069 const ARMEncoding encoding) { 8070#if 0 8071 if ConditionPassed() then 8072 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8073 base = Align(PC,4); 8074 address = if add then (base + imm32) else (base - imm32); 8075 data = MemU[address,2]; 8076 if UnalignedSupport() || address<0> = '0' then 8077 R[t] = SignExtend(data, 32); 8078 else // Can only apply before ARMv7 8079 R[t] = bits(32) UNKNOWN; 8080#endif 8081 8082 bool success = false; 8083 8084 if (ConditionPassed(opcode)) { 8085 uint32_t t; 8086 uint32_t imm32; 8087 bool add; 8088 8089 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8090 switch (encoding) { 8091 case eEncodingT1: 8092 // if Rt == '1111' then SEE "Unallocated memory hints"; 8093 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 8094 t = Bits32(opcode, 15, 12); 8095 imm32 = Bits32(opcode, 11, 0); 8096 add = BitIsSet(opcode, 23); 8097 8098 // if t == 13 then UNPREDICTABLE; 8099 if (t == 13) 8100 return false; 8101 8102 break; 8103 8104 case eEncodingA1: { 8105 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 8106 t = Bits32(opcode, 15, 12); 8107 uint32_t imm4H = Bits32(opcode, 11, 8); 8108 uint32_t imm4L = Bits32(opcode, 3, 0); 8109 imm32 = (imm4H << 4) | imm4L; 8110 add = BitIsSet(opcode, 23); 8111 8112 // if t == 15 then UNPREDICTABLE; 8113 if (t == 15) 8114 return false; 8115 8116 break; 8117 } 8118 default: 8119 return false; 8120 } 8121 8122 // base = Align(PC,4); 8123 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 8124 if (!success) 8125 return false; 8126 8127 uint64_t base = AlignPC(pc_value); 8128 8129 addr_t address; 8130 // address = if add then (base + imm32) else (base - imm32); 8131 if (add) 8132 address = base + imm32; 8133 else 8134 address = base - imm32; 8135 8136 // data = MemU[address,2]; 8137 RegisterInfo base_reg; 8138 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 8139 8140 EmulateInstruction::Context context; 8141 context.type = eContextRegisterLoad; 8142 context.SetRegisterPlusOffset(base_reg, imm32); 8143 8144 uint64_t data = MemURead(context, address, 2, 0, &success); 8145 if (!success) 8146 return false; 8147 8148 // if UnalignedSupport() || address<0> = '0' then 8149 if (UnalignedSupport() || BitIsClear(address, 0)) { 8150 // R[t] = SignExtend(data, 32); 8151 int64_t signed_data = llvm::SignExtend64<16>(data); 8152 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8153 (uint64_t)signed_data)) 8154 return false; 8155 } else // Can only apply before ARMv7 8156 { 8157 // R[t] = bits(32) UNKNOWN; 8158 WriteBits32Unknown(t); 8159 } 8160 } 8161 return true; 8162} 8163 8164// LDRSH (register) calculates an address from a base register value and an 8165// offset register value, loads a halfword 8166// from memory, sign-extends it to form a 32-bit word, and writes it to a 8167// register. The offset register value can be shifted left by 0, 1, 2, or 3 8168// bits. 8169bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode, 8170 const ARMEncoding encoding) { 8171#if 0 8172 if ConditionPassed() then 8173 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8174 offset = Shift(R[m], shift_t, shift_n, APSR.C); 8175 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8176 address = if index then offset_addr else R[n]; 8177 data = MemU[address,2]; 8178 if wback then R[n] = offset_addr; 8179 if UnalignedSupport() || address<0> = '0' then 8180 R[t] = SignExtend(data, 32); 8181 else // Can only apply before ARMv7 8182 R[t] = bits(32) UNKNOWN; 8183#endif 8184 8185 bool success = false; 8186 8187 if (ConditionPassed(opcode)) { 8188 uint32_t t; 8189 uint32_t n; 8190 uint32_t m; 8191 bool index; 8192 bool add; 8193 bool wback; 8194 ARM_ShifterType shift_t; 8195 uint32_t shift_n; 8196 8197 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8198 switch (encoding) { 8199 case eEncodingT1: 8200 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 8201 // in ThumbEE"; 8202 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8203 t = Bits32(opcode, 2, 0); 8204 n = Bits32(opcode, 5, 3); 8205 m = Bits32(opcode, 8, 6); 8206 8207 // index = TRUE; add = TRUE; wback = FALSE; 8208 index = true; 8209 add = true; 8210 wback = false; 8211 8212 // (shift_t, shift_n) = (SRType_LSL, 0); 8213 shift_t = SRType_LSL; 8214 shift_n = 0; 8215 8216 break; 8217 8218 case eEncodingT2: 8219 // if Rn == '1111' then SEE LDRSH (literal); 8220 // if Rt == '1111' then SEE "Unallocated memory hints"; 8221 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8222 t = Bits32(opcode, 15, 12); 8223 n = Bits32(opcode, 19, 16); 8224 m = Bits32(opcode, 3, 0); 8225 8226 // index = TRUE; add = TRUE; wback = FALSE; 8227 index = true; 8228 add = true; 8229 wback = false; 8230 8231 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 8232 shift_t = SRType_LSL; 8233 shift_n = Bits32(opcode, 5, 4); 8234 8235 // if t == 13 || BadReg(m) then UNPREDICTABLE; 8236 if ((t == 13) || BadReg(m)) 8237 return false; 8238 8239 break; 8240 8241 case eEncodingA1: 8242 // if P == '0' && W == '1' then SEE LDRSHT; 8243 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8244 t = Bits32(opcode, 15, 12); 8245 n = Bits32(opcode, 19, 16); 8246 m = Bits32(opcode, 3, 0); 8247 8248 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8249 // (W == '1'); 8250 index = BitIsSet(opcode, 24); 8251 add = BitIsSet(opcode, 23); 8252 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8253 8254 // (shift_t, shift_n) = (SRType_LSL, 0); 8255 shift_t = SRType_LSL; 8256 shift_n = 0; 8257 8258 // if t == 15 || m == 15 then UNPREDICTABLE; 8259 if ((t == 15) || (m == 15)) 8260 return false; 8261 8262 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 8263 if (wback && ((n == 15) || (n == t))) 8264 return false; 8265 8266 break; 8267 8268 default: 8269 return false; 8270 } 8271 8272 uint64_t Rm = 8273 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8274 if (!success) 8275 return false; 8276 8277 uint64_t Rn = 8278 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8279 if (!success) 8280 return false; 8281 8282 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 8283 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 8284 if (!success) 8285 return false; 8286 8287 addr_t offset_addr; 8288 addr_t address; 8289 8290 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8291 if (add) 8292 offset_addr = Rn + offset; 8293 else 8294 offset_addr = Rn - offset; 8295 8296 // address = if index then offset_addr else R[n]; 8297 if (index) 8298 address = offset_addr; 8299 else 8300 address = Rn; 8301 8302 // data = MemU[address,2]; 8303 RegisterInfo base_reg; 8304 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8305 8306 RegisterInfo offset_reg; 8307 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 8308 8309 EmulateInstruction::Context context; 8310 context.type = eContextRegisterLoad; 8311 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8312 8313 uint64_t data = MemURead(context, address, 2, 0, &success); 8314 if (!success) 8315 return false; 8316 8317 // if wback then R[n] = offset_addr; 8318 if (wback) { 8319 context.type = eContextAdjustBaseRegister; 8320 context.SetAddress(offset_addr); 8321 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8322 offset_addr)) 8323 return false; 8324 } 8325 8326 // if UnalignedSupport() || address<0> = '0' then 8327 if (UnalignedSupport() || BitIsClear(address, 0)) { 8328 // R[t] = SignExtend(data, 32); 8329 context.type = eContextRegisterLoad; 8330 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8331 8332 int64_t signed_data = llvm::SignExtend64<16>(data); 8333 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8334 (uint64_t)signed_data)) 8335 return false; 8336 } else // Can only apply before ARMv7 8337 { 8338 // R[t] = bits(32) UNKNOWN; 8339 WriteBits32Unknown(t); 8340 } 8341 } 8342 return true; 8343} 8344 8345// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and 8346// writes the result to the destination 8347// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before 8348// extracting the 8-bit value. 8349bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode, 8350 const ARMEncoding encoding) { 8351#if 0 8352 if ConditionPassed() then 8353 EncodingSpecificOperations(); 8354 rotated = ROR(R[m], rotation); 8355 R[d] = SignExtend(rotated<7:0>, 32); 8356#endif 8357 8358 bool success = false; 8359 8360 if (ConditionPassed(opcode)) { 8361 uint32_t d; 8362 uint32_t m; 8363 uint32_t rotation; 8364 8365 // EncodingSpecificOperations(); 8366 switch (encoding) { 8367 case eEncodingT1: 8368 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8369 d = Bits32(opcode, 2, 0); 8370 m = Bits32(opcode, 5, 3); 8371 rotation = 0; 8372 8373 break; 8374 8375 case eEncodingT2: 8376 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8377 d = Bits32(opcode, 11, 8); 8378 m = Bits32(opcode, 3, 0); 8379 rotation = Bits32(opcode, 5, 4) << 3; 8380 8381 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8382 if (BadReg(d) || BadReg(m)) 8383 return false; 8384 8385 break; 8386 8387 case eEncodingA1: 8388 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8389 d = Bits32(opcode, 15, 12); 8390 m = Bits32(opcode, 3, 0); 8391 rotation = Bits32(opcode, 11, 10) << 3; 8392 8393 // if d == 15 || m == 15 then UNPREDICTABLE; 8394 if ((d == 15) || (m == 15)) 8395 return false; 8396 8397 break; 8398 8399 default: 8400 return false; 8401 } 8402 8403 uint64_t Rm = 8404 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8405 if (!success) 8406 return false; 8407 8408 // rotated = ROR(R[m], rotation); 8409 uint64_t rotated = ROR(Rm, rotation, &success); 8410 if (!success) 8411 return false; 8412 8413 // R[d] = SignExtend(rotated<7:0>, 32); 8414 int64_t data = llvm::SignExtend64<8>(rotated); 8415 8416 RegisterInfo source_reg; 8417 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8418 8419 EmulateInstruction::Context context; 8420 context.type = eContextRegisterLoad; 8421 context.SetRegister(source_reg); 8422 8423 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8424 (uint64_t)data)) 8425 return false; 8426 } 8427 return true; 8428} 8429 8430// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and 8431// writes the result to the destination 8432// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8433// extracting the 16-bit value. 8434bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode, 8435 const ARMEncoding encoding) { 8436#if 0 8437 if ConditionPassed() then 8438 EncodingSpecificOperations(); 8439 rotated = ROR(R[m], rotation); 8440 R[d] = SignExtend(rotated<15:0>, 32); 8441#endif 8442 8443 bool success = false; 8444 8445 if (ConditionPassed(opcode)) { 8446 uint32_t d; 8447 uint32_t m; 8448 uint32_t rotation; 8449 8450 // EncodingSpecificOperations(); 8451 switch (encoding) { 8452 case eEncodingT1: 8453 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8454 d = Bits32(opcode, 2, 0); 8455 m = Bits32(opcode, 5, 3); 8456 rotation = 0; 8457 8458 break; 8459 8460 case eEncodingT2: 8461 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8462 d = Bits32(opcode, 11, 8); 8463 m = Bits32(opcode, 3, 0); 8464 rotation = Bits32(opcode, 5, 4) << 3; 8465 8466 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8467 if (BadReg(d) || BadReg(m)) 8468 return false; 8469 8470 break; 8471 8472 case eEncodingA1: 8473 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8474 d = Bits32(opcode, 15, 12); 8475 m = Bits32(opcode, 3, 0); 8476 rotation = Bits32(opcode, 11, 10) << 3; 8477 8478 // if d == 15 || m == 15 then UNPREDICTABLE; 8479 if ((d == 15) || (m == 15)) 8480 return false; 8481 8482 break; 8483 8484 default: 8485 return false; 8486 } 8487 8488 uint64_t Rm = 8489 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8490 if (!success) 8491 return false; 8492 8493 // rotated = ROR(R[m], rotation); 8494 uint64_t rotated = ROR(Rm, rotation, &success); 8495 if (!success) 8496 return false; 8497 8498 // R[d] = SignExtend(rotated<15:0>, 32); 8499 RegisterInfo source_reg; 8500 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8501 8502 EmulateInstruction::Context context; 8503 context.type = eContextRegisterLoad; 8504 context.SetRegister(source_reg); 8505 8506 int64_t data = llvm::SignExtend64<16>(rotated); 8507 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8508 (uint64_t)data)) 8509 return false; 8510 } 8511 8512 return true; 8513} 8514 8515// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and 8516// writes the result to the destination 8517// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8518// extracting the 8-bit value. 8519bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode, 8520 const ARMEncoding encoding) { 8521#if 0 8522 if ConditionPassed() then 8523 EncodingSpecificOperations(); 8524 rotated = ROR(R[m], rotation); 8525 R[d] = ZeroExtend(rotated<7:0>, 32); 8526#endif 8527 8528 bool success = false; 8529 8530 if (ConditionPassed(opcode)) { 8531 uint32_t d; 8532 uint32_t m; 8533 uint32_t rotation; 8534 8535 // EncodingSpecificOperations(); 8536 switch (encoding) { 8537 case eEncodingT1: 8538 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8539 d = Bits32(opcode, 2, 0); 8540 m = Bits32(opcode, 5, 3); 8541 rotation = 0; 8542 8543 break; 8544 8545 case eEncodingT2: 8546 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8547 d = Bits32(opcode, 11, 8); 8548 m = Bits32(opcode, 3, 0); 8549 rotation = Bits32(opcode, 5, 4) << 3; 8550 8551 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8552 if (BadReg(d) || BadReg(m)) 8553 return false; 8554 8555 break; 8556 8557 case eEncodingA1: 8558 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8559 d = Bits32(opcode, 15, 12); 8560 m = Bits32(opcode, 3, 0); 8561 rotation = Bits32(opcode, 11, 10) << 3; 8562 8563 // if d == 15 || m == 15 then UNPREDICTABLE; 8564 if ((d == 15) || (m == 15)) 8565 return false; 8566 8567 break; 8568 8569 default: 8570 return false; 8571 } 8572 8573 uint64_t Rm = 8574 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8575 if (!success) 8576 return false; 8577 8578 // rotated = ROR(R[m], rotation); 8579 uint64_t rotated = ROR(Rm, rotation, &success); 8580 if (!success) 8581 return false; 8582 8583 // R[d] = ZeroExtend(rotated<7:0>, 32); 8584 RegisterInfo source_reg; 8585 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8586 8587 EmulateInstruction::Context context; 8588 context.type = eContextRegisterLoad; 8589 context.SetRegister(source_reg); 8590 8591 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8592 Bits32(rotated, 7, 0))) 8593 return false; 8594 } 8595 return true; 8596} 8597 8598// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and 8599// writes the result to the destination 8600// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8601// extracting the 16-bit value. 8602bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode, 8603 const ARMEncoding encoding) { 8604#if 0 8605 if ConditionPassed() then 8606 EncodingSpecificOperations(); 8607 rotated = ROR(R[m], rotation); 8608 R[d] = ZeroExtend(rotated<15:0>, 32); 8609#endif 8610 8611 bool success = false; 8612 8613 if (ConditionPassed(opcode)) { 8614 uint32_t d; 8615 uint32_t m; 8616 uint32_t rotation; 8617 8618 switch (encoding) { 8619 case eEncodingT1: 8620 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8621 d = Bits32(opcode, 2, 0); 8622 m = Bits32(opcode, 5, 3); 8623 rotation = 0; 8624 8625 break; 8626 8627 case eEncodingT2: 8628 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8629 d = Bits32(opcode, 11, 8); 8630 m = Bits32(opcode, 3, 0); 8631 rotation = Bits32(opcode, 5, 4) << 3; 8632 8633 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8634 if (BadReg(d) || BadReg(m)) 8635 return false; 8636 8637 break; 8638 8639 case eEncodingA1: 8640 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8641 d = Bits32(opcode, 15, 12); 8642 m = Bits32(opcode, 3, 0); 8643 rotation = Bits32(opcode, 11, 10) << 3; 8644 8645 // if d == 15 || m == 15 then UNPREDICTABLE; 8646 if ((d == 15) || (m == 15)) 8647 return false; 8648 8649 break; 8650 8651 default: 8652 return false; 8653 } 8654 8655 uint64_t Rm = 8656 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8657 if (!success) 8658 return false; 8659 8660 // rotated = ROR(R[m], rotation); 8661 uint64_t rotated = ROR(Rm, rotation, &success); 8662 if (!success) 8663 return false; 8664 8665 // R[d] = ZeroExtend(rotated<15:0>, 32); 8666 RegisterInfo source_reg; 8667 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8668 8669 EmulateInstruction::Context context; 8670 context.type = eContextRegisterLoad; 8671 context.SetRegister(source_reg); 8672 8673 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8674 Bits32(rotated, 15, 0))) 8675 return false; 8676 } 8677 return true; 8678} 8679 8680// RFE (Return From Exception) loads the PC and the CPSR from the word at the 8681// specified address and the following 8682// word respectively. 8683bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode, 8684 const ARMEncoding encoding) { 8685#if 0 8686 if ConditionPassed() then 8687 EncodingSpecificOperations(); 8688 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8689 UNPREDICTABLE; 8690 else 8691 address = if increment then R[n] else R[n]-8; 8692 if wordhigher then address = address+4; 8693 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8694 BranchWritePC(MemA[address,4]); 8695 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8696#endif 8697 8698 bool success = false; 8699 8700 if (ConditionPassed(opcode)) { 8701 uint32_t n; 8702 bool wback; 8703 bool increment; 8704 bool wordhigher; 8705 8706 // EncodingSpecificOperations(); 8707 switch (encoding) { 8708 case eEncodingT1: 8709 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = 8710 // FALSE; 8711 n = Bits32(opcode, 19, 16); 8712 wback = BitIsSet(opcode, 21); 8713 increment = false; 8714 wordhigher = false; 8715 8716 // if n == 15 then UNPREDICTABLE; 8717 if (n == 15) 8718 return false; 8719 8720 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8721 if (InITBlock() && !LastInITBlock()) 8722 return false; 8723 8724 break; 8725 8726 case eEncodingT2: 8727 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8728 n = Bits32(opcode, 19, 16); 8729 wback = BitIsSet(opcode, 21); 8730 increment = true; 8731 wordhigher = false; 8732 8733 // if n == 15 then UNPREDICTABLE; 8734 if (n == 15) 8735 return false; 8736 8737 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8738 if (InITBlock() && !LastInITBlock()) 8739 return false; 8740 8741 break; 8742 8743 case eEncodingA1: 8744 // n = UInt(Rn); 8745 n = Bits32(opcode, 19, 16); 8746 8747 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8748 wback = BitIsSet(opcode, 21); 8749 increment = BitIsSet(opcode, 23); 8750 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23)); 8751 8752 // if n == 15 then UNPREDICTABLE; 8753 if (n == 15) 8754 return false; 8755 8756 break; 8757 8758 default: 8759 return false; 8760 } 8761 8762 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE 8763 // then 8764 if (!CurrentModeIsPrivileged()) 8765 // UNPREDICTABLE; 8766 return false; 8767 else { 8768 uint64_t Rn = 8769 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8770 if (!success) 8771 return false; 8772 8773 addr_t address; 8774 // address = if increment then R[n] else R[n]-8; 8775 if (increment) 8776 address = Rn; 8777 else 8778 address = Rn - 8; 8779 8780 // if wordhigher then address = address+4; 8781 if (wordhigher) 8782 address = address + 4; 8783 8784 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8785 RegisterInfo base_reg; 8786 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8787 8788 EmulateInstruction::Context context; 8789 context.type = eContextReturnFromException; 8790 context.SetRegisterPlusOffset(base_reg, address - Rn); 8791 8792 uint64_t data = MemARead(context, address + 4, 4, 0, &success); 8793 if (!success) 8794 return false; 8795 8796 CPSRWriteByInstr(data, 15, true); 8797 8798 // BranchWritePC(MemA[address,4]); 8799 uint64_t data2 = MemARead(context, address, 4, 0, &success); 8800 if (!success) 8801 return false; 8802 8803 BranchWritePC(context, data2); 8804 8805 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8806 if (wback) { 8807 context.type = eContextAdjustBaseRegister; 8808 if (increment) { 8809 context.SetOffset(8); 8810 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8811 Rn + 8)) 8812 return false; 8813 } else { 8814 context.SetOffset(-8); 8815 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8816 Rn - 8)) 8817 return false; 8818 } 8819 } // if wback 8820 } 8821 } // if ConditionPassed() 8822 return true; 8823} 8824 8825// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a 8826// register value and an immediate value, and writes the result to the 8827// destination register. It can optionally update the condition flags based on 8828// the result. 8829bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode, 8830 const ARMEncoding encoding) { 8831#if 0 8832 // ARM pseudo code... 8833 if ConditionPassed() then 8834 EncodingSpecificOperations(); 8835 result = R[n] EOR imm32; 8836 if d == 15 then // Can only occur for ARM encoding 8837 ALUWritePC(result); // setflags is always FALSE here 8838 else 8839 R[d] = result; 8840 if setflags then 8841 APSR.N = result<31>; 8842 APSR.Z = IsZeroBit(result); 8843 APSR.C = carry; 8844 // APSR.V unchanged 8845#endif 8846 8847 bool success = false; 8848 8849 if (ConditionPassed(opcode)) { 8850 uint32_t Rd, Rn; 8851 uint32_t 8852 imm32; // the immediate value to be ORed to the value obtained from Rn 8853 bool setflags; 8854 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8855 switch (encoding) { 8856 case eEncodingT1: 8857 Rd = Bits32(opcode, 11, 8); 8858 Rn = Bits32(opcode, 19, 16); 8859 setflags = BitIsSet(opcode, 20); 8860 imm32 = ThumbExpandImm_C( 8861 opcode, APSR_C, 8862 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8863 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8864 if (Rd == 15 && setflags) 8865 return EmulateTEQImm(opcode, eEncodingT1); 8866 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8867 return false; 8868 break; 8869 case eEncodingA1: 8870 Rd = Bits32(opcode, 15, 12); 8871 Rn = Bits32(opcode, 19, 16); 8872 setflags = BitIsSet(opcode, 20); 8873 imm32 = 8874 ARMExpandImm_C(opcode, APSR_C, 8875 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8876 8877 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8878 // instructions; 8879 if (Rd == 15 && setflags) 8880 return EmulateSUBSPcLrEtc(opcode, encoding); 8881 break; 8882 default: 8883 return false; 8884 } 8885 8886 // Read the first operand. 8887 uint32_t val1 = ReadCoreReg(Rn, &success); 8888 if (!success) 8889 return false; 8890 8891 uint32_t result = val1 ^ imm32; 8892 8893 EmulateInstruction::Context context; 8894 context.type = EmulateInstruction::eContextImmediate; 8895 context.SetNoArgs(); 8896 8897 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8898 return false; 8899 } 8900 return true; 8901} 8902 8903// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a 8904// register value and an optionally-shifted register value, and writes the 8905// result to the destination register. It can optionally update the condition 8906// flags based on the result. 8907bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode, 8908 const ARMEncoding encoding) { 8909#if 0 8910 // ARM pseudo code... 8911 if ConditionPassed() then 8912 EncodingSpecificOperations(); 8913 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8914 result = R[n] EOR shifted; 8915 if d == 15 then // Can only occur for ARM encoding 8916 ALUWritePC(result); // setflags is always FALSE here 8917 else 8918 R[d] = result; 8919 if setflags then 8920 APSR.N = result<31>; 8921 APSR.Z = IsZeroBit(result); 8922 APSR.C = carry; 8923 // APSR.V unchanged 8924#endif 8925 8926 bool success = false; 8927 8928 if (ConditionPassed(opcode)) { 8929 uint32_t Rd, Rn, Rm; 8930 ARM_ShifterType shift_t; 8931 uint32_t shift_n; // the shift applied to the value read from Rm 8932 bool setflags; 8933 uint32_t carry; 8934 switch (encoding) { 8935 case eEncodingT1: 8936 Rd = Rn = Bits32(opcode, 2, 0); 8937 Rm = Bits32(opcode, 5, 3); 8938 setflags = !InITBlock(); 8939 shift_t = SRType_LSL; 8940 shift_n = 0; 8941 break; 8942 case eEncodingT2: 8943 Rd = Bits32(opcode, 11, 8); 8944 Rn = Bits32(opcode, 19, 16); 8945 Rm = Bits32(opcode, 3, 0); 8946 setflags = BitIsSet(opcode, 20); 8947 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8948 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8949 if (Rd == 15 && setflags) 8950 return EmulateTEQReg(opcode, eEncodingT1); 8951 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8952 return false; 8953 break; 8954 case eEncodingA1: 8955 Rd = Bits32(opcode, 15, 12); 8956 Rn = Bits32(opcode, 19, 16); 8957 Rm = Bits32(opcode, 3, 0); 8958 setflags = BitIsSet(opcode, 20); 8959 shift_n = DecodeImmShiftARM(opcode, shift_t); 8960 8961 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8962 // instructions; 8963 if (Rd == 15 && setflags) 8964 return EmulateSUBSPcLrEtc(opcode, encoding); 8965 break; 8966 default: 8967 return false; 8968 } 8969 8970 // Read the first operand. 8971 uint32_t val1 = ReadCoreReg(Rn, &success); 8972 if (!success) 8973 return false; 8974 8975 // Read the second operand. 8976 uint32_t val2 = ReadCoreReg(Rm, &success); 8977 if (!success) 8978 return false; 8979 8980 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8981 if (!success) 8982 return false; 8983 uint32_t result = val1 ^ shifted; 8984 8985 EmulateInstruction::Context context; 8986 context.type = EmulateInstruction::eContextImmediate; 8987 context.SetNoArgs(); 8988 8989 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8990 return false; 8991 } 8992 return true; 8993} 8994 8995// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value 8996// and an immediate value, and writes the result to the destination register. 8997// It can optionally update the condition flags based on the result. 8998bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode, 8999 const ARMEncoding encoding) { 9000#if 0 9001 // ARM pseudo code... 9002 if ConditionPassed() then 9003 EncodingSpecificOperations(); 9004 result = R[n] OR imm32; 9005 if d == 15 then // Can only occur for ARM encoding 9006 ALUWritePC(result); // setflags is always FALSE here 9007 else 9008 R[d] = result; 9009 if setflags then 9010 APSR.N = result<31>; 9011 APSR.Z = IsZeroBit(result); 9012 APSR.C = carry; 9013 // APSR.V unchanged 9014#endif 9015 9016 bool success = false; 9017 9018 if (ConditionPassed(opcode)) { 9019 uint32_t Rd, Rn; 9020 uint32_t 9021 imm32; // the immediate value to be ORed to the value obtained from Rn 9022 bool setflags; 9023 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9024 switch (encoding) { 9025 case eEncodingT1: 9026 Rd = Bits32(opcode, 11, 8); 9027 Rn = Bits32(opcode, 19, 16); 9028 setflags = BitIsSet(opcode, 20); 9029 imm32 = ThumbExpandImm_C( 9030 opcode, APSR_C, 9031 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9032 // if Rn == '1111' then SEE MOV (immediate); 9033 if (Rn == 15) 9034 return EmulateMOVRdImm(opcode, eEncodingT2); 9035 if (BadReg(Rd) || Rn == 13) 9036 return false; 9037 break; 9038 case eEncodingA1: 9039 Rd = Bits32(opcode, 15, 12); 9040 Rn = Bits32(opcode, 19, 16); 9041 setflags = BitIsSet(opcode, 20); 9042 imm32 = 9043 ARMExpandImm_C(opcode, APSR_C, 9044 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9045 9046 if (Rd == 15 && setflags) 9047 return EmulateSUBSPcLrEtc(opcode, encoding); 9048 break; 9049 default: 9050 return false; 9051 } 9052 9053 // Read the first operand. 9054 uint32_t val1 = ReadCoreReg(Rn, &success); 9055 if (!success) 9056 return false; 9057 9058 uint32_t result = val1 | imm32; 9059 9060 EmulateInstruction::Context context; 9061 context.type = EmulateInstruction::eContextImmediate; 9062 context.SetNoArgs(); 9063 9064 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9065 return false; 9066 } 9067 return true; 9068} 9069 9070// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value 9071// and an optionally-shifted register value, and writes the result to the 9072// destination register. It can optionally update the condition flags based on 9073// the result. 9074bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode, 9075 const ARMEncoding encoding) { 9076#if 0 9077 // ARM pseudo code... 9078 if ConditionPassed() then 9079 EncodingSpecificOperations(); 9080 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9081 result = R[n] OR shifted; 9082 if d == 15 then // Can only occur for ARM encoding 9083 ALUWritePC(result); // setflags is always FALSE here 9084 else 9085 R[d] = result; 9086 if setflags then 9087 APSR.N = result<31>; 9088 APSR.Z = IsZeroBit(result); 9089 APSR.C = carry; 9090 // APSR.V unchanged 9091#endif 9092 9093 bool success = false; 9094 9095 if (ConditionPassed(opcode)) { 9096 uint32_t Rd, Rn, Rm; 9097 ARM_ShifterType shift_t; 9098 uint32_t shift_n; // the shift applied to the value read from Rm 9099 bool setflags; 9100 uint32_t carry; 9101 switch (encoding) { 9102 case eEncodingT1: 9103 Rd = Rn = Bits32(opcode, 2, 0); 9104 Rm = Bits32(opcode, 5, 3); 9105 setflags = !InITBlock(); 9106 shift_t = SRType_LSL; 9107 shift_n = 0; 9108 break; 9109 case eEncodingT2: 9110 Rd = Bits32(opcode, 11, 8); 9111 Rn = Bits32(opcode, 19, 16); 9112 Rm = Bits32(opcode, 3, 0); 9113 setflags = BitIsSet(opcode, 20); 9114 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9115 // if Rn == '1111' then SEE MOV (register); 9116 if (Rn == 15) 9117 return EmulateMOVRdRm(opcode, eEncodingT3); 9118 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 9119 return false; 9120 break; 9121 case eEncodingA1: 9122 Rd = Bits32(opcode, 15, 12); 9123 Rn = Bits32(opcode, 19, 16); 9124 Rm = Bits32(opcode, 3, 0); 9125 setflags = BitIsSet(opcode, 20); 9126 shift_n = DecodeImmShiftARM(opcode, shift_t); 9127 9128 if (Rd == 15 && setflags) 9129 return EmulateSUBSPcLrEtc(opcode, encoding); 9130 break; 9131 default: 9132 return false; 9133 } 9134 9135 // Read the first operand. 9136 uint32_t val1 = ReadCoreReg(Rn, &success); 9137 if (!success) 9138 return false; 9139 9140 // Read the second operand. 9141 uint32_t val2 = ReadCoreReg(Rm, &success); 9142 if (!success) 9143 return false; 9144 9145 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9146 if (!success) 9147 return false; 9148 uint32_t result = val1 | shifted; 9149 9150 EmulateInstruction::Context context; 9151 context.type = EmulateInstruction::eContextImmediate; 9152 context.SetNoArgs(); 9153 9154 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9155 return false; 9156 } 9157 return true; 9158} 9159 9160// Reverse Subtract (immediate) subtracts a register value from an immediate 9161// value, and writes the result to the destination register. It can optionally 9162// update the condition flags based on the result. 9163bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode, 9164 const ARMEncoding encoding) { 9165#if 0 9166 // ARM pseudo code... 9167 if ConditionPassed() then 9168 EncodingSpecificOperations(); 9169 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 9170 if d == 15 then // Can only occur for ARM encoding 9171 ALUWritePC(result); // setflags is always FALSE here 9172 else 9173 R[d] = result; 9174 if setflags then 9175 APSR.N = result<31>; 9176 APSR.Z = IsZeroBit(result); 9177 APSR.C = carry; 9178 APSR.V = overflow; 9179#endif 9180 9181 bool success = false; 9182 9183 uint32_t Rd; // the destination register 9184 uint32_t Rn; // the first operand 9185 bool setflags; 9186 uint32_t 9187 imm32; // the immediate value to be added to the value obtained from Rn 9188 switch (encoding) { 9189 case eEncodingT1: 9190 Rd = Bits32(opcode, 2, 0); 9191 Rn = Bits32(opcode, 5, 3); 9192 setflags = !InITBlock(); 9193 imm32 = 0; 9194 break; 9195 case eEncodingT2: 9196 Rd = Bits32(opcode, 11, 8); 9197 Rn = Bits32(opcode, 19, 16); 9198 setflags = BitIsSet(opcode, 20); 9199 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9200 if (BadReg(Rd) || BadReg(Rn)) 9201 return false; 9202 break; 9203 case eEncodingA1: 9204 Rd = Bits32(opcode, 15, 12); 9205 Rn = Bits32(opcode, 19, 16); 9206 setflags = BitIsSet(opcode, 20); 9207 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9208 9209 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9210 // instructions; 9211 if (Rd == 15 && setflags) 9212 return EmulateSUBSPcLrEtc(opcode, encoding); 9213 break; 9214 default: 9215 return false; 9216 } 9217 // Read the register value from the operand register Rn. 9218 uint32_t reg_val = ReadCoreReg(Rn, &success); 9219 if (!success) 9220 return false; 9221 9222 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 9223 9224 EmulateInstruction::Context context; 9225 context.type = EmulateInstruction::eContextImmediate; 9226 context.SetNoArgs(); 9227 9228 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9229 res.carry_out, res.overflow); 9230} 9231 9232// Reverse Subtract (register) subtracts a register value from an optionally- 9233// shifted register value, and writes the result to the destination register. 9234// It can optionally update the condition flags based on the result. 9235bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode, 9236 const ARMEncoding encoding) { 9237#if 0 9238 // ARM pseudo code... 9239 if ConditionPassed() then 9240 EncodingSpecificOperations(); 9241 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9242 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 9243 if d == 15 then // Can only occur for ARM encoding 9244 ALUWritePC(result); // setflags is always FALSE here 9245 else 9246 R[d] = result; 9247 if setflags then 9248 APSR.N = result<31>; 9249 APSR.Z = IsZeroBit(result); 9250 APSR.C = carry; 9251 APSR.V = overflow; 9252#endif 9253 9254 bool success = false; 9255 9256 uint32_t Rd; // the destination register 9257 uint32_t Rn; // the first operand 9258 uint32_t Rm; // the second operand 9259 bool setflags; 9260 ARM_ShifterType shift_t; 9261 uint32_t shift_n; // the shift applied to the value read from Rm 9262 switch (encoding) { 9263 case eEncodingT1: 9264 Rd = Bits32(opcode, 11, 8); 9265 Rn = Bits32(opcode, 19, 16); 9266 Rm = Bits32(opcode, 3, 0); 9267 setflags = BitIsSet(opcode, 20); 9268 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9269 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 9270 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9271 return false; 9272 break; 9273 case eEncodingA1: 9274 Rd = Bits32(opcode, 15, 12); 9275 Rn = Bits32(opcode, 19, 16); 9276 Rm = Bits32(opcode, 3, 0); 9277 setflags = BitIsSet(opcode, 20); 9278 shift_n = DecodeImmShiftARM(opcode, shift_t); 9279 9280 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9281 // instructions; 9282 if (Rd == 15 && setflags) 9283 return EmulateSUBSPcLrEtc(opcode, encoding); 9284 break; 9285 default: 9286 return false; 9287 } 9288 // Read the register value from register Rn. 9289 uint32_t val1 = ReadCoreReg(Rn, &success); 9290 if (!success) 9291 return false; 9292 9293 // Read the register value from register Rm. 9294 uint32_t val2 = ReadCoreReg(Rm, &success); 9295 if (!success) 9296 return false; 9297 9298 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9299 if (!success) 9300 return false; 9301 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 9302 9303 EmulateInstruction::Context context; 9304 context.type = EmulateInstruction::eContextImmediate; 9305 context.SetNoArgs(); 9306 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9307 res.carry_out, res.overflow); 9308} 9309 9310// Reverse Subtract with Carry (immediate) subtracts a register value and the 9311// value of NOT (Carry flag) from an immediate value, and writes the result to 9312// the destination register. It can optionally update the condition flags based 9313// on the result. 9314bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode, 9315 const ARMEncoding encoding) { 9316#if 0 9317 // ARM pseudo code... 9318 if ConditionPassed() then 9319 EncodingSpecificOperations(); 9320 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 9321 if d == 15 then 9322 ALUWritePC(result); // setflags is always FALSE here 9323 else 9324 R[d] = result; 9325 if setflags then 9326 APSR.N = result<31>; 9327 APSR.Z = IsZeroBit(result); 9328 APSR.C = carry; 9329 APSR.V = overflow; 9330#endif 9331 9332 bool success = false; 9333 9334 uint32_t Rd; // the destination register 9335 uint32_t Rn; // the first operand 9336 bool setflags; 9337 uint32_t 9338 imm32; // the immediate value to be added to the value obtained from Rn 9339 switch (encoding) { 9340 case eEncodingA1: 9341 Rd = Bits32(opcode, 15, 12); 9342 Rn = Bits32(opcode, 19, 16); 9343 setflags = BitIsSet(opcode, 20); 9344 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9345 9346 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9347 // instructions; 9348 if (Rd == 15 && setflags) 9349 return EmulateSUBSPcLrEtc(opcode, encoding); 9350 break; 9351 default: 9352 return false; 9353 } 9354 // Read the register value from the operand register Rn. 9355 uint32_t reg_val = ReadCoreReg(Rn, &success); 9356 if (!success) 9357 return false; 9358 9359 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 9360 9361 EmulateInstruction::Context context; 9362 context.type = EmulateInstruction::eContextImmediate; 9363 context.SetNoArgs(); 9364 9365 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9366 res.carry_out, res.overflow); 9367} 9368 9369// Reverse Subtract with Carry (register) subtracts a register value and the 9370// value of NOT (Carry flag) from an optionally-shifted register value, and 9371// writes the result to the destination register. It can optionally update the 9372// condition flags based on the result. 9373bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode, 9374 const ARMEncoding encoding) { 9375#if 0 9376 // ARM pseudo code... 9377 if ConditionPassed() then 9378 EncodingSpecificOperations(); 9379 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9380 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 9381 if d == 15 then 9382 ALUWritePC(result); // setflags is always FALSE here 9383 else 9384 R[d] = result; 9385 if setflags then 9386 APSR.N = result<31>; 9387 APSR.Z = IsZeroBit(result); 9388 APSR.C = carry; 9389 APSR.V = overflow; 9390#endif 9391 9392 bool success = false; 9393 9394 uint32_t Rd; // the destination register 9395 uint32_t Rn; // the first operand 9396 uint32_t Rm; // the second operand 9397 bool setflags; 9398 ARM_ShifterType shift_t; 9399 uint32_t shift_n; // the shift applied to the value read from Rm 9400 switch (encoding) { 9401 case eEncodingA1: 9402 Rd = Bits32(opcode, 15, 12); 9403 Rn = Bits32(opcode, 19, 16); 9404 Rm = Bits32(opcode, 3, 0); 9405 setflags = BitIsSet(opcode, 20); 9406 shift_n = DecodeImmShiftARM(opcode, shift_t); 9407 9408 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9409 // instructions; 9410 if (Rd == 15 && setflags) 9411 return EmulateSUBSPcLrEtc(opcode, encoding); 9412 break; 9413 default: 9414 return false; 9415 } 9416 // Read the register value from register Rn. 9417 uint32_t val1 = ReadCoreReg(Rn, &success); 9418 if (!success) 9419 return false; 9420 9421 // Read the register value from register Rm. 9422 uint32_t val2 = ReadCoreReg(Rm, &success); 9423 if (!success) 9424 return false; 9425 9426 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9427 if (!success) 9428 return false; 9429 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 9430 9431 EmulateInstruction::Context context; 9432 context.type = EmulateInstruction::eContextImmediate; 9433 context.SetNoArgs(); 9434 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9435 res.carry_out, res.overflow); 9436} 9437 9438// Subtract with Carry (immediate) subtracts an immediate value and the value 9439// of 9440// NOT (Carry flag) from a register value, and writes the result to the 9441// destination register. 9442// It can optionally update the condition flags based on the result. 9443bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode, 9444 const ARMEncoding encoding) { 9445#if 0 9446 // ARM pseudo code... 9447 if ConditionPassed() then 9448 EncodingSpecificOperations(); 9449 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 9450 if d == 15 then // Can only occur for ARM encoding 9451 ALUWritePC(result); // setflags is always FALSE here 9452 else 9453 R[d] = result; 9454 if setflags then 9455 APSR.N = result<31>; 9456 APSR.Z = IsZeroBit(result); 9457 APSR.C = carry; 9458 APSR.V = overflow; 9459#endif 9460 9461 bool success = false; 9462 9463 uint32_t Rd; // the destination register 9464 uint32_t Rn; // the first operand 9465 bool setflags; 9466 uint32_t 9467 imm32; // the immediate value to be added to the value obtained from Rn 9468 switch (encoding) { 9469 case eEncodingT1: 9470 Rd = Bits32(opcode, 11, 8); 9471 Rn = Bits32(opcode, 19, 16); 9472 setflags = BitIsSet(opcode, 20); 9473 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9474 if (BadReg(Rd) || BadReg(Rn)) 9475 return false; 9476 break; 9477 case eEncodingA1: 9478 Rd = Bits32(opcode, 15, 12); 9479 Rn = Bits32(opcode, 19, 16); 9480 setflags = BitIsSet(opcode, 20); 9481 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9482 9483 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9484 // instructions; 9485 if (Rd == 15 && setflags) 9486 return EmulateSUBSPcLrEtc(opcode, encoding); 9487 break; 9488 default: 9489 return false; 9490 } 9491 // Read the register value from the operand register Rn. 9492 uint32_t reg_val = ReadCoreReg(Rn, &success); 9493 if (!success) 9494 return false; 9495 9496 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9497 9498 EmulateInstruction::Context context; 9499 context.type = EmulateInstruction::eContextImmediate; 9500 context.SetNoArgs(); 9501 9502 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9503 res.carry_out, res.overflow); 9504} 9505 9506// Subtract with Carry (register) subtracts an optionally-shifted register 9507// value and the value of 9508// NOT (Carry flag) from a register value, and writes the result to the 9509// destination register. 9510// It can optionally update the condition flags based on the result. 9511bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode, 9512 const ARMEncoding encoding) { 9513#if 0 9514 // ARM pseudo code... 9515 if ConditionPassed() then 9516 EncodingSpecificOperations(); 9517 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9518 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9519 if d == 15 then // Can only occur for ARM encoding 9520 ALUWritePC(result); // setflags is always FALSE here 9521 else 9522 R[d] = result; 9523 if setflags then 9524 APSR.N = result<31>; 9525 APSR.Z = IsZeroBit(result); 9526 APSR.C = carry; 9527 APSR.V = overflow; 9528#endif 9529 9530 bool success = false; 9531 9532 uint32_t Rd; // the destination register 9533 uint32_t Rn; // the first operand 9534 uint32_t Rm; // the second operand 9535 bool setflags; 9536 ARM_ShifterType shift_t; 9537 uint32_t shift_n; // the shift applied to the value read from Rm 9538 switch (encoding) { 9539 case eEncodingT1: 9540 Rd = Rn = Bits32(opcode, 2, 0); 9541 Rm = Bits32(opcode, 5, 3); 9542 setflags = !InITBlock(); 9543 shift_t = SRType_LSL; 9544 shift_n = 0; 9545 break; 9546 case eEncodingT2: 9547 Rd = Bits32(opcode, 11, 8); 9548 Rn = Bits32(opcode, 19, 16); 9549 Rm = Bits32(opcode, 3, 0); 9550 setflags = BitIsSet(opcode, 20); 9551 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9552 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9553 return false; 9554 break; 9555 case eEncodingA1: 9556 Rd = Bits32(opcode, 15, 12); 9557 Rn = Bits32(opcode, 19, 16); 9558 Rm = Bits32(opcode, 3, 0); 9559 setflags = BitIsSet(opcode, 20); 9560 shift_n = DecodeImmShiftARM(opcode, shift_t); 9561 9562 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9563 // instructions; 9564 if (Rd == 15 && setflags) 9565 return EmulateSUBSPcLrEtc(opcode, encoding); 9566 break; 9567 default: 9568 return false; 9569 } 9570 // Read the register value from register Rn. 9571 uint32_t val1 = ReadCoreReg(Rn, &success); 9572 if (!success) 9573 return false; 9574 9575 // Read the register value from register Rm. 9576 uint32_t val2 = ReadCoreReg(Rm, &success); 9577 if (!success) 9578 return false; 9579 9580 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9581 if (!success) 9582 return false; 9583 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9584 9585 EmulateInstruction::Context context; 9586 context.type = EmulateInstruction::eContextImmediate; 9587 context.SetNoArgs(); 9588 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9589 res.carry_out, res.overflow); 9590} 9591 9592// This instruction subtracts an immediate value from a register value, and 9593// writes the result to the destination register. It can optionally update the 9594// condition flags based on the result. 9595bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode, 9596 const ARMEncoding encoding) { 9597#if 0 9598 // ARM pseudo code... 9599 if ConditionPassed() then 9600 EncodingSpecificOperations(); 9601 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9602 R[d] = result; 9603 if setflags then 9604 APSR.N = result<31>; 9605 APSR.Z = IsZeroBit(result); 9606 APSR.C = carry; 9607 APSR.V = overflow; 9608#endif 9609 9610 bool success = false; 9611 9612 uint32_t Rd; // the destination register 9613 uint32_t Rn; // the first operand 9614 bool setflags; 9615 uint32_t imm32; // the immediate value to be subtracted from the value 9616 // obtained from Rn 9617 switch (encoding) { 9618 case eEncodingT1: 9619 Rd = Bits32(opcode, 2, 0); 9620 Rn = Bits32(opcode, 5, 3); 9621 setflags = !InITBlock(); 9622 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9623 break; 9624 case eEncodingT2: 9625 Rd = Rn = Bits32(opcode, 10, 8); 9626 setflags = !InITBlock(); 9627 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9628 break; 9629 case eEncodingT3: 9630 Rd = Bits32(opcode, 11, 8); 9631 Rn = Bits32(opcode, 19, 16); 9632 setflags = BitIsSet(opcode, 20); 9633 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9634 9635 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9636 if (Rd == 15 && setflags) 9637 return EmulateCMPImm(opcode, eEncodingT2); 9638 9639 // if Rn == '1101' then SEE SUB (SP minus immediate); 9640 if (Rn == 13) 9641 return EmulateSUBSPImm(opcode, eEncodingT2); 9642 9643 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9644 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9645 return false; 9646 break; 9647 case eEncodingT4: 9648 Rd = Bits32(opcode, 11, 8); 9649 Rn = Bits32(opcode, 19, 16); 9650 setflags = BitIsSet(opcode, 20); 9651 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9652 9653 // if Rn == '1111' then SEE ADR; 9654 if (Rn == 15) 9655 return EmulateADR(opcode, eEncodingT2); 9656 9657 // if Rn == '1101' then SEE SUB (SP minus immediate); 9658 if (Rn == 13) 9659 return EmulateSUBSPImm(opcode, eEncodingT3); 9660 9661 if (BadReg(Rd)) 9662 return false; 9663 break; 9664 default: 9665 return false; 9666 } 9667 // Read the register value from the operand register Rn. 9668 uint32_t reg_val = ReadCoreReg(Rn, &success); 9669 if (!success) 9670 return false; 9671 9672 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9673 9674 EmulateInstruction::Context context; 9675 context.type = EmulateInstruction::eContextImmediate; 9676 context.SetNoArgs(); 9677 9678 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9679 res.carry_out, res.overflow); 9680} 9681 9682// This instruction subtracts an immediate value from a register value, and 9683// writes the result to the destination register. It can optionally update the 9684// condition flags based on the result. 9685bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode, 9686 const ARMEncoding encoding) { 9687#if 0 9688 // ARM pseudo code... 9689 if ConditionPassed() then 9690 EncodingSpecificOperations(); 9691 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9692 if d == 15 then 9693 ALUWritePC(result); // setflags is always FALSE here 9694 else 9695 R[d] = result; 9696 if setflags then 9697 APSR.N = result<31>; 9698 APSR.Z = IsZeroBit(result); 9699 APSR.C = carry; 9700 APSR.V = overflow; 9701#endif 9702 9703 bool success = false; 9704 9705 if (ConditionPassed(opcode)) { 9706 uint32_t Rd; // the destination register 9707 uint32_t Rn; // the first operand 9708 bool setflags; 9709 uint32_t imm32; // the immediate value to be subtracted from the value 9710 // obtained from Rn 9711 switch (encoding) { 9712 case eEncodingA1: 9713 Rd = Bits32(opcode, 15, 12); 9714 Rn = Bits32(opcode, 19, 16); 9715 setflags = BitIsSet(opcode, 20); 9716 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9717 9718 // if Rn == '1111' && S == '0' then SEE ADR; 9719 if (Rn == 15 && !setflags) 9720 return EmulateADR(opcode, eEncodingA2); 9721 9722 // if Rn == '1101' then SEE SUB (SP minus immediate); 9723 if (Rn == 13) 9724 return EmulateSUBSPImm(opcode, eEncodingA1); 9725 9726 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9727 // instructions; 9728 if (Rd == 15 && setflags) 9729 return EmulateSUBSPcLrEtc(opcode, encoding); 9730 break; 9731 default: 9732 return false; 9733 } 9734 // Read the register value from the operand register Rn. 9735 uint32_t reg_val = ReadCoreReg(Rn, &success); 9736 if (!success) 9737 return false; 9738 9739 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9740 9741 EmulateInstruction::Context context; 9742 if (Rd == 13) 9743 context.type = EmulateInstruction::eContextAdjustStackPointer; 9744 else 9745 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9746 9747 RegisterInfo dwarf_reg; 9748 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 9749 int64_t imm32_signed = imm32; 9750 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed); 9751 9752 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9753 res.carry_out, res.overflow)) 9754 return false; 9755 } 9756 return true; 9757} 9758 9759// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a 9760// register value and an immediate value. It updates the condition flags based 9761// on the result, and discards the result. 9762bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode, 9763 const ARMEncoding encoding) { 9764#if 0 9765 // ARM pseudo code... 9766 if ConditionPassed() then 9767 EncodingSpecificOperations(); 9768 result = R[n] EOR imm32; 9769 APSR.N = result<31>; 9770 APSR.Z = IsZeroBit(result); 9771 APSR.C = carry; 9772 // APSR.V unchanged 9773#endif 9774 9775 bool success = false; 9776 9777 if (ConditionPassed(opcode)) { 9778 uint32_t Rn; 9779 uint32_t 9780 imm32; // the immediate value to be ANDed to the value obtained from Rn 9781 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9782 switch (encoding) { 9783 case eEncodingT1: 9784 Rn = Bits32(opcode, 19, 16); 9785 imm32 = ThumbExpandImm_C( 9786 opcode, APSR_C, 9787 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9788 if (BadReg(Rn)) 9789 return false; 9790 break; 9791 case eEncodingA1: 9792 Rn = Bits32(opcode, 19, 16); 9793 imm32 = 9794 ARMExpandImm_C(opcode, APSR_C, 9795 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9796 break; 9797 default: 9798 return false; 9799 } 9800 9801 // Read the first operand. 9802 uint32_t val1 = ReadCoreReg(Rn, &success); 9803 if (!success) 9804 return false; 9805 9806 uint32_t result = val1 ^ imm32; 9807 9808 EmulateInstruction::Context context; 9809 context.type = EmulateInstruction::eContextImmediate; 9810 context.SetNoArgs(); 9811 9812 if (!WriteFlags(context, result, carry)) 9813 return false; 9814 } 9815 return true; 9816} 9817 9818// Test Equivalence (register) performs a bitwise exclusive OR operation on a 9819// register value and an optionally-shifted register value. It updates the 9820// condition flags based on the result, and discards the result. 9821bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode, 9822 const ARMEncoding encoding) { 9823#if 0 9824 // ARM pseudo code... 9825 if ConditionPassed() then 9826 EncodingSpecificOperations(); 9827 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9828 result = R[n] EOR shifted; 9829 APSR.N = result<31>; 9830 APSR.Z = IsZeroBit(result); 9831 APSR.C = carry; 9832 // APSR.V unchanged 9833#endif 9834 9835 bool success = false; 9836 9837 if (ConditionPassed(opcode)) { 9838 uint32_t Rn, Rm; 9839 ARM_ShifterType shift_t; 9840 uint32_t shift_n; // the shift applied to the value read from Rm 9841 uint32_t carry; 9842 switch (encoding) { 9843 case eEncodingT1: 9844 Rn = Bits32(opcode, 19, 16); 9845 Rm = Bits32(opcode, 3, 0); 9846 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9847 if (BadReg(Rn) || BadReg(Rm)) 9848 return false; 9849 break; 9850 case eEncodingA1: 9851 Rn = Bits32(opcode, 19, 16); 9852 Rm = Bits32(opcode, 3, 0); 9853 shift_n = DecodeImmShiftARM(opcode, shift_t); 9854 break; 9855 default: 9856 return false; 9857 } 9858 9859 // Read the first operand. 9860 uint32_t val1 = ReadCoreReg(Rn, &success); 9861 if (!success) 9862 return false; 9863 9864 // Read the second operand. 9865 uint32_t val2 = ReadCoreReg(Rm, &success); 9866 if (!success) 9867 return false; 9868 9869 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9870 if (!success) 9871 return false; 9872 uint32_t result = val1 ^ shifted; 9873 9874 EmulateInstruction::Context context; 9875 context.type = EmulateInstruction::eContextImmediate; 9876 context.SetNoArgs(); 9877 9878 if (!WriteFlags(context, result, carry)) 9879 return false; 9880 } 9881 return true; 9882} 9883 9884// Test (immediate) performs a bitwise AND operation on a register value and an 9885// immediate value. It updates the condition flags based on the result, and 9886// discards the result. 9887bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode, 9888 const ARMEncoding encoding) { 9889#if 0 9890 // ARM pseudo code... 9891 if ConditionPassed() then 9892 EncodingSpecificOperations(); 9893 result = R[n] AND imm32; 9894 APSR.N = result<31>; 9895 APSR.Z = IsZeroBit(result); 9896 APSR.C = carry; 9897 // APSR.V unchanged 9898#endif 9899 9900 bool success = false; 9901 9902 if (ConditionPassed(opcode)) { 9903 uint32_t Rn; 9904 uint32_t 9905 imm32; // the immediate value to be ANDed to the value obtained from Rn 9906 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9907 switch (encoding) { 9908 case eEncodingT1: 9909 Rn = Bits32(opcode, 19, 16); 9910 imm32 = ThumbExpandImm_C( 9911 opcode, APSR_C, 9912 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9913 if (BadReg(Rn)) 9914 return false; 9915 break; 9916 case eEncodingA1: 9917 Rn = Bits32(opcode, 19, 16); 9918 imm32 = 9919 ARMExpandImm_C(opcode, APSR_C, 9920 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9921 break; 9922 default: 9923 return false; 9924 } 9925 9926 // Read the first operand. 9927 uint32_t val1 = ReadCoreReg(Rn, &success); 9928 if (!success) 9929 return false; 9930 9931 uint32_t result = val1 & imm32; 9932 9933 EmulateInstruction::Context context; 9934 context.type = EmulateInstruction::eContextImmediate; 9935 context.SetNoArgs(); 9936 9937 if (!WriteFlags(context, result, carry)) 9938 return false; 9939 } 9940 return true; 9941} 9942 9943// Test (register) performs a bitwise AND operation on a register value and an 9944// optionally-shifted register value. It updates the condition flags based on 9945// the result, and discards the result. 9946bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode, 9947 const ARMEncoding encoding) { 9948#if 0 9949 // ARM pseudo code... 9950 if ConditionPassed() then 9951 EncodingSpecificOperations(); 9952 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9953 result = R[n] AND shifted; 9954 APSR.N = result<31>; 9955 APSR.Z = IsZeroBit(result); 9956 APSR.C = carry; 9957 // APSR.V unchanged 9958#endif 9959 9960 bool success = false; 9961 9962 if (ConditionPassed(opcode)) { 9963 uint32_t Rn, Rm; 9964 ARM_ShifterType shift_t; 9965 uint32_t shift_n; // the shift applied to the value read from Rm 9966 uint32_t carry; 9967 switch (encoding) { 9968 case eEncodingT1: 9969 Rn = Bits32(opcode, 2, 0); 9970 Rm = Bits32(opcode, 5, 3); 9971 shift_t = SRType_LSL; 9972 shift_n = 0; 9973 break; 9974 case eEncodingT2: 9975 Rn = Bits32(opcode, 19, 16); 9976 Rm = Bits32(opcode, 3, 0); 9977 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9978 if (BadReg(Rn) || BadReg(Rm)) 9979 return false; 9980 break; 9981 case eEncodingA1: 9982 Rn = Bits32(opcode, 19, 16); 9983 Rm = Bits32(opcode, 3, 0); 9984 shift_n = DecodeImmShiftARM(opcode, shift_t); 9985 break; 9986 default: 9987 return false; 9988 } 9989 9990 // Read the first operand. 9991 uint32_t val1 = ReadCoreReg(Rn, &success); 9992 if (!success) 9993 return false; 9994 9995 // Read the second operand. 9996 uint32_t val2 = ReadCoreReg(Rm, &success); 9997 if (!success) 9998 return false; 9999 10000 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 10001 if (!success) 10002 return false; 10003 uint32_t result = val1 & shifted; 10004 10005 EmulateInstruction::Context context; 10006 context.type = EmulateInstruction::eContextImmediate; 10007 context.SetNoArgs(); 10008 10009 if (!WriteFlags(context, result, carry)) 10010 return false; 10011 } 10012 return true; 10013} 10014 10015// A8.6.216 SUB (SP minus register) 10016bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode, 10017 const ARMEncoding encoding) { 10018#if 0 10019 if ConditionPassed() then 10020 EncodingSpecificOperations(); 10021 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10022 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10023 if d == 15 then // Can only occur for ARM encoding 10024 ALUWritePC(result); // setflags is always FALSE here 10025 else 10026 R[d] = result; 10027 if setflags then 10028 APSR.N = result<31>; 10029 APSR.Z = IsZeroBit(result); 10030 APSR.C = carry; 10031 APSR.V = overflow; 10032#endif 10033 10034 bool success = false; 10035 10036 if (ConditionPassed(opcode)) { 10037 uint32_t d; 10038 uint32_t m; 10039 bool setflags; 10040 ARM_ShifterType shift_t; 10041 uint32_t shift_n; 10042 10043 switch (encoding) { 10044 case eEncodingT1: 10045 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10046 d = Bits32(opcode, 11, 8); 10047 m = Bits32(opcode, 3, 0); 10048 setflags = BitIsSet(opcode, 20); 10049 10050 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10051 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10052 10053 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then 10054 // UNPREDICTABLE; 10055 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 10056 return false; 10057 10058 // if d == 15 || BadReg(m) then UNPREDICTABLE; 10059 if ((d == 15) || BadReg(m)) 10060 return false; 10061 break; 10062 10063 case eEncodingA1: 10064 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10065 d = Bits32(opcode, 15, 12); 10066 m = Bits32(opcode, 3, 0); 10067 setflags = BitIsSet(opcode, 20); 10068 10069 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10070 // instructions; 10071 if (d == 15 && setflags) 10072 EmulateSUBSPcLrEtc(opcode, encoding); 10073 10074 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10075 shift_n = DecodeImmShiftARM(opcode, shift_t); 10076 break; 10077 10078 default: 10079 return false; 10080 } 10081 10082 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10083 uint32_t Rm = ReadCoreReg(m, &success); 10084 if (!success) 10085 return false; 10086 10087 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10088 if (!success) 10089 return false; 10090 10091 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10092 uint32_t sp_val = ReadCoreReg(SP_REG, &success); 10093 if (!success) 10094 return false; 10095 10096 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1); 10097 10098 EmulateInstruction::Context context; 10099 context.type = eContextArithmetic; 10100 RegisterInfo sp_reg; 10101 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 10102 RegisterInfo dwarf_reg; 10103 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 10104 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg); 10105 10106 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10107 res.carry_out, res.overflow)) 10108 return false; 10109 } 10110 return true; 10111} 10112 10113// A8.6.7 ADD (register-shifted register) 10114bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode, 10115 const ARMEncoding encoding) { 10116#if 0 10117 if ConditionPassed() then 10118 EncodingSpecificOperations(); 10119 shift_n = UInt(R[s]<7:0>); 10120 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10121 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10122 R[d] = result; 10123 if setflags then 10124 APSR.N = result<31>; 10125 APSR.Z = IsZeroBit(result); 10126 APSR.C = carry; 10127 APSR.V = overflow; 10128#endif 10129 10130 bool success = false; 10131 10132 if (ConditionPassed(opcode)) { 10133 uint32_t d; 10134 uint32_t n; 10135 uint32_t m; 10136 uint32_t s; 10137 bool setflags; 10138 ARM_ShifterType shift_t; 10139 10140 switch (encoding) { 10141 case eEncodingA1: 10142 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 10143 d = Bits32(opcode, 15, 12); 10144 n = Bits32(opcode, 19, 16); 10145 m = Bits32(opcode, 3, 0); 10146 s = Bits32(opcode, 11, 8); 10147 10148 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 10149 setflags = BitIsSet(opcode, 20); 10150 shift_t = DecodeRegShift(Bits32(opcode, 6, 5)); 10151 10152 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 10153 if ((d == 15) || (n == 15) || (m == 15) || (s == 15)) 10154 return false; 10155 break; 10156 10157 default: 10158 return false; 10159 } 10160 10161 // shift_n = UInt(R[s]<7:0>); 10162 uint32_t Rs = ReadCoreReg(s, &success); 10163 if (!success) 10164 return false; 10165 10166 uint32_t shift_n = Bits32(Rs, 7, 0); 10167 10168 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10169 uint32_t Rm = ReadCoreReg(m, &success); 10170 if (!success) 10171 return false; 10172 10173 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10174 if (!success) 10175 return false; 10176 10177 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10178 uint32_t Rn = ReadCoreReg(n, &success); 10179 if (!success) 10180 return false; 10181 10182 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0); 10183 10184 // R[d] = result; 10185 EmulateInstruction::Context context; 10186 context.type = eContextArithmetic; 10187 RegisterInfo reg_n; 10188 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10189 RegisterInfo reg_m; 10190 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10191 10192 context.SetRegisterRegisterOperands(reg_n, reg_m); 10193 10194 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 10195 res.result)) 10196 return false; 10197 10198 // if setflags then 10199 // APSR.N = result<31>; 10200 // APSR.Z = IsZeroBit(result); 10201 // APSR.C = carry; 10202 // APSR.V = overflow; 10203 if (setflags) 10204 return WriteFlags(context, res.result, res.carry_out, res.overflow); 10205 } 10206 return true; 10207} 10208 10209// A8.6.213 SUB (register) 10210bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode, 10211 const ARMEncoding encoding) { 10212#if 0 10213 if ConditionPassed() then 10214 EncodingSpecificOperations(); 10215 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10216 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10217 if d == 15 then // Can only occur for ARM encoding 10218 ALUWritePC(result); // setflags is always FALSE here 10219 else 10220 R[d] = result; 10221 if setflags then 10222 APSR.N = result<31>; 10223 APSR.Z = IsZeroBit(result); 10224 APSR.C = carry; 10225 APSR.V = overflow; 10226#endif 10227 10228 bool success = false; 10229 10230 if (ConditionPassed(opcode)) { 10231 uint32_t d; 10232 uint32_t n; 10233 uint32_t m; 10234 bool setflags; 10235 ARM_ShifterType shift_t; 10236 uint32_t shift_n; 10237 10238 switch (encoding) { 10239 case eEncodingT1: 10240 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 10241 d = Bits32(opcode, 2, 0); 10242 n = Bits32(opcode, 5, 3); 10243 m = Bits32(opcode, 8, 6); 10244 setflags = !InITBlock(); 10245 10246 // (shift_t, shift_n) = (SRType_LSL, 0); 10247 shift_t = SRType_LSL; 10248 shift_n = 0; 10249 10250 break; 10251 10252 case eEncodingT2: 10253 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 10254 d = Bits32(opcode, 11, 8); 10255 n = Bits32(opcode, 19, 16); 10256 m = Bits32(opcode, 3, 0); 10257 setflags = BitIsSet(opcode, 20); 10258 10259 // if Rd == "1111" && S == "1" then SEE CMP (register); 10260 if (d == 15 && setflags == 1) 10261 return EmulateCMPImm(opcode, eEncodingT3); 10262 10263 // if Rn == "1101" then SEE SUB (SP minus register); 10264 if (n == 13) 10265 return EmulateSUBSPReg(opcode, eEncodingT1); 10266 10267 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10268 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10269 10270 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then 10271 // UNPREDICTABLE; 10272 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) || 10273 BadReg(m)) 10274 return false; 10275 10276 break; 10277 10278 case eEncodingA1: 10279 // if Rn == '1101' then SEE SUB (SP minus register); 10280 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 10281 d = Bits32(opcode, 15, 12); 10282 n = Bits32(opcode, 19, 16); 10283 m = Bits32(opcode, 3, 0); 10284 setflags = BitIsSet(opcode, 20); 10285 10286 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10287 // instructions; 10288 if ((d == 15) && setflags) 10289 EmulateSUBSPcLrEtc(opcode, encoding); 10290 10291 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10292 shift_n = DecodeImmShiftARM(opcode, shift_t); 10293 10294 break; 10295 10296 default: 10297 return false; 10298 } 10299 10300 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10301 uint32_t Rm = ReadCoreReg(m, &success); 10302 if (!success) 10303 return false; 10304 10305 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10306 if (!success) 10307 return false; 10308 10309 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10310 uint32_t Rn = ReadCoreReg(n, &success); 10311 if (!success) 10312 return false; 10313 10314 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1); 10315 10316 // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result); 10317 // // setflags is always FALSE here else 10318 // R[d] = result; 10319 // if setflags then 10320 // APSR.N = result<31>; 10321 // APSR.Z = IsZeroBit(result); 10322 // APSR.C = carry; 10323 // APSR.V = overflow; 10324 10325 EmulateInstruction::Context context; 10326 context.type = eContextArithmetic; 10327 RegisterInfo reg_n; 10328 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10329 RegisterInfo reg_m; 10330 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10331 context.SetRegisterRegisterOperands(reg_n, reg_m); 10332 10333 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10334 res.carry_out, res.overflow)) 10335 return false; 10336 } 10337 return true; 10338} 10339 10340// A8.6.202 STREX 10341// Store Register Exclusive calculates an address from a base register value 10342// and an immediate offset, and stores a word from a register to memory if the 10343// executing processor has exclusive access to the memory addressed. 10344bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode, 10345 const ARMEncoding encoding) { 10346#if 0 10347 if ConditionPassed() then 10348 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10349 address = R[n] + imm32; 10350 if ExclusiveMonitorsPass(address,4) then 10351 MemA[address,4] = R[t]; 10352 R[d] = 0; 10353 else 10354 R[d] = 1; 10355#endif 10356 10357 bool success = false; 10358 10359 if (ConditionPassed(opcode)) { 10360 uint32_t d; 10361 uint32_t t; 10362 uint32_t n; 10363 uint32_t imm32; 10364 const uint32_t addr_byte_size = GetAddressByteSize(); 10365 10366 switch (encoding) { 10367 case eEncodingT1: 10368 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = 10369 // ZeroExtend(imm8:'00', 10370 // 32); 10371 d = Bits32(opcode, 11, 8); 10372 t = Bits32(opcode, 15, 12); 10373 n = Bits32(opcode, 19, 16); 10374 imm32 = Bits32(opcode, 7, 0) << 2; 10375 10376 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 10377 if (BadReg(d) || BadReg(t) || (n == 15)) 10378 return false; 10379 10380 // if d == n || d == t then UNPREDICTABLE; 10381 if ((d == n) || (d == t)) 10382 return false; 10383 10384 break; 10385 10386 case eEncodingA1: 10387 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero 10388 // offset 10389 d = Bits32(opcode, 15, 12); 10390 t = Bits32(opcode, 3, 0); 10391 n = Bits32(opcode, 19, 16); 10392 imm32 = 0; 10393 10394 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 10395 if ((d == 15) || (t == 15) || (n == 15)) 10396 return false; 10397 10398 // if d == n || d == t then UNPREDICTABLE; 10399 if ((d == n) || (d == t)) 10400 return false; 10401 10402 break; 10403 10404 default: 10405 return false; 10406 } 10407 10408 // address = R[n] + imm32; 10409 uint32_t Rn = ReadCoreReg(n, &success); 10410 if (!success) 10411 return false; 10412 10413 addr_t address = Rn + imm32; 10414 10415 RegisterInfo base_reg; 10416 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10417 RegisterInfo data_reg; 10418 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10419 EmulateInstruction::Context context; 10420 context.type = eContextRegisterStore; 10421 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32); 10422 10423 // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass 10424 // (address, addr_byte_size)) -- For now, for the sake of emulation, we 10425 // will say this 10426 // always return 10427 // true. 10428 if (true) { 10429 // MemA[address,4] = R[t]; 10430 uint32_t Rt = 10431 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 10432 if (!success) 10433 return false; 10434 10435 if (!MemAWrite(context, address, Rt, addr_byte_size)) 10436 return false; 10437 10438 // R[d] = 0; 10439 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 10440 return false; 10441 } 10442#if 0 // unreachable because if true 10443 else 10444 { 10445 // R[d] = 1; 10446 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 10447 return false; 10448 } 10449#endif // unreachable because if true 10450 } 10451 return true; 10452} 10453 10454// A8.6.197 STRB (immediate, ARM) 10455bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode, 10456 const ARMEncoding encoding) { 10457#if 0 10458 if ConditionPassed() then 10459 EncodingSpecificOperations(); 10460 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10461 address = if index then offset_addr else R[n]; 10462 MemU[address,1] = R[t]<7:0>; 10463 if wback then R[n] = offset_addr; 10464#endif 10465 10466 bool success = false; 10467 10468 if (ConditionPassed(opcode)) { 10469 uint32_t t; 10470 uint32_t n; 10471 uint32_t imm32; 10472 bool index; 10473 bool add; 10474 bool wback; 10475 10476 switch (encoding) { 10477 case eEncodingA1: 10478 // if P == '0' && W == '1' then SEE STRBT; 10479 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10480 t = Bits32(opcode, 15, 12); 10481 n = Bits32(opcode, 19, 16); 10482 imm32 = Bits32(opcode, 11, 0); 10483 10484 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10485 index = BitIsSet(opcode, 24); 10486 add = BitIsSet(opcode, 23); 10487 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10488 10489 // if t == 15 then UNPREDICTABLE; 10490 if (t == 15) 10491 return false; 10492 10493 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10494 if (wback && ((n == 15) || (n == t))) 10495 return false; 10496 10497 break; 10498 10499 default: 10500 return false; 10501 } 10502 10503 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10504 uint32_t Rn = ReadCoreReg(n, &success); 10505 if (!success) 10506 return false; 10507 10508 addr_t offset_addr; 10509 if (add) 10510 offset_addr = Rn + imm32; 10511 else 10512 offset_addr = Rn - imm32; 10513 10514 // address = if index then offset_addr else R[n]; 10515 addr_t address; 10516 if (index) 10517 address = offset_addr; 10518 else 10519 address = Rn; 10520 10521 // MemU[address,1] = R[t]<7:0>; 10522 uint32_t Rt = ReadCoreReg(t, &success); 10523 if (!success) 10524 return false; 10525 10526 RegisterInfo base_reg; 10527 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10528 RegisterInfo data_reg; 10529 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10530 EmulateInstruction::Context context; 10531 context.type = eContextRegisterStore; 10532 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10533 10534 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1)) 10535 return false; 10536 10537 // if wback then R[n] = offset_addr; 10538 if (wback) { 10539 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10540 offset_addr)) 10541 return false; 10542 } 10543 } 10544 return true; 10545} 10546 10547// A8.6.194 STR (immediate, ARM) 10548bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode, 10549 const ARMEncoding encoding) { 10550#if 0 10551 if ConditionPassed() then 10552 EncodingSpecificOperations(); 10553 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10554 address = if index then offset_addr else R[n]; 10555 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10556 if wback then R[n] = offset_addr; 10557#endif 10558 10559 bool success = false; 10560 10561 if (ConditionPassed(opcode)) { 10562 uint32_t t; 10563 uint32_t n; 10564 uint32_t imm32; 10565 bool index; 10566 bool add; 10567 bool wback; 10568 10569 const uint32_t addr_byte_size = GetAddressByteSize(); 10570 10571 switch (encoding) { 10572 case eEncodingA1: 10573 // if P == '0' && W == '1' then SEE STRT; 10574 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == 10575 // '000000000100' then SEE PUSH; 10576 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10577 t = Bits32(opcode, 15, 12); 10578 n = Bits32(opcode, 19, 16); 10579 imm32 = Bits32(opcode, 11, 0); 10580 10581 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10582 index = BitIsSet(opcode, 24); 10583 add = BitIsSet(opcode, 23); 10584 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10585 10586 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10587 if (wback && ((n == 15) || (n == t))) 10588 return false; 10589 10590 break; 10591 10592 default: 10593 return false; 10594 } 10595 10596 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10597 uint32_t Rn = ReadCoreReg(n, &success); 10598 if (!success) 10599 return false; 10600 10601 addr_t offset_addr; 10602 if (add) 10603 offset_addr = Rn + imm32; 10604 else 10605 offset_addr = Rn - imm32; 10606 10607 // address = if index then offset_addr else R[n]; 10608 addr_t address; 10609 if (index) 10610 address = offset_addr; 10611 else 10612 address = Rn; 10613 10614 RegisterInfo base_reg; 10615 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10616 RegisterInfo data_reg; 10617 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10618 EmulateInstruction::Context context; 10619 context.type = eContextRegisterStore; 10620 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10621 10622 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10623 uint32_t Rt = ReadCoreReg(t, &success); 10624 if (!success) 10625 return false; 10626 10627 if (t == 15) { 10628 uint32_t pc_value = ReadCoreReg(PC_REG, &success); 10629 if (!success) 10630 return false; 10631 10632 if (!MemUWrite(context, address, pc_value, addr_byte_size)) 10633 return false; 10634 } else { 10635 if (!MemUWrite(context, address, Rt, addr_byte_size)) 10636 return false; 10637 } 10638 10639 // if wback then R[n] = offset_addr; 10640 if (wback) { 10641 context.type = eContextAdjustBaseRegister; 10642 context.SetImmediate(offset_addr); 10643 10644 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10645 offset_addr)) 10646 return false; 10647 } 10648 } 10649 return true; 10650} 10651 10652// A8.6.66 LDRD (immediate) 10653// Load Register Dual (immediate) calculates an address from a base register 10654// value and an immediate offset, loads two words from memory, and writes them 10655// to two registers. It can use offset, post-indexed, or pre-indexed 10656// addressing. 10657bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode, 10658 const ARMEncoding encoding) { 10659#if 0 10660 if ConditionPassed() then 10661 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10662 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10663 address = if index then offset_addr else R[n]; 10664 R[t] = MemA[address,4]; 10665 R[t2] = MemA[address+4,4]; 10666 if wback then R[n] = offset_addr; 10667#endif 10668 10669 bool success = false; 10670 10671 if (ConditionPassed(opcode)) { 10672 uint32_t t; 10673 uint32_t t2; 10674 uint32_t n; 10675 uint32_t imm32; 10676 bool index; 10677 bool add; 10678 bool wback; 10679 10680 switch (encoding) { 10681 case eEncodingT1: 10682 // if P == '0' && W == '0' then SEE 'Related encodings'; 10683 // if Rn == '1111' then SEE LDRD (literal); 10684 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10685 // ZeroExtend(imm8:'00', 32); 10686 t = Bits32(opcode, 15, 12); 10687 t2 = Bits32(opcode, 11, 8); 10688 n = Bits32(opcode, 19, 16); 10689 imm32 = Bits32(opcode, 7, 0) << 2; 10690 10691 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10692 index = BitIsSet(opcode, 24); 10693 add = BitIsSet(opcode, 23); 10694 wback = BitIsSet(opcode, 21); 10695 10696 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10697 if (wback && ((n == t) || (n == t2))) 10698 return false; 10699 10700 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10701 if (BadReg(t) || BadReg(t2) || (t == t2)) 10702 return false; 10703 10704 break; 10705 10706 case eEncodingA1: 10707 // if Rn == '1111' then SEE LDRD (literal); 10708 // if Rt<0> == '1' then UNPREDICTABLE; 10709 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10710 // 32); 10711 t = Bits32(opcode, 15, 12); 10712 if (BitIsSet(t, 0)) 10713 return false; 10714 t2 = t + 1; 10715 n = Bits32(opcode, 19, 16); 10716 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10717 10718 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10719 index = BitIsSet(opcode, 24); 10720 add = BitIsSet(opcode, 23); 10721 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10722 10723 // if P == '0' && W == '1' then UNPREDICTABLE; 10724 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10725 return false; 10726 10727 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10728 if (wback && ((n == t) || (n == t2))) 10729 return false; 10730 10731 // if t2 == 15 then UNPREDICTABLE; 10732 if (t2 == 15) 10733 return false; 10734 10735 break; 10736 10737 default: 10738 return false; 10739 } 10740 10741 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10742 uint32_t Rn = ReadCoreReg(n, &success); 10743 if (!success) 10744 return false; 10745 10746 addr_t offset_addr; 10747 if (add) 10748 offset_addr = Rn + imm32; 10749 else 10750 offset_addr = Rn - imm32; 10751 10752 // address = if index then offset_addr else R[n]; 10753 addr_t address; 10754 if (index) 10755 address = offset_addr; 10756 else 10757 address = Rn; 10758 10759 // R[t] = MemA[address,4]; 10760 RegisterInfo base_reg; 10761 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10762 10763 EmulateInstruction::Context context; 10764 if (n == 13) 10765 context.type = eContextPopRegisterOffStack; 10766 else 10767 context.type = eContextRegisterLoad; 10768 context.SetAddress(address); 10769 10770 const uint32_t addr_byte_size = GetAddressByteSize(); 10771 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10772 if (!success) 10773 return false; 10774 10775 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10776 return false; 10777 10778 // R[t2] = MemA[address+4,4]; 10779 context.SetAddress(address + 4); 10780 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10781 if (!success) 10782 return false; 10783 10784 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10785 data)) 10786 return false; 10787 10788 // if wback then R[n] = offset_addr; 10789 if (wback) { 10790 context.type = eContextAdjustBaseRegister; 10791 context.SetAddress(offset_addr); 10792 10793 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10794 offset_addr)) 10795 return false; 10796 } 10797 } 10798 return true; 10799} 10800 10801// A8.6.68 LDRD (register) 10802// Load Register Dual (register) calculates an address from a base register 10803// value and a register offset, loads two words from memory, and writes them to 10804// two registers. It can use offset, post-indexed or pre-indexed addressing. 10805bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode, 10806 const ARMEncoding encoding) { 10807#if 0 10808 if ConditionPassed() then 10809 EncodingSpecificOperations(); 10810 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10811 address = if index then offset_addr else R[n]; 10812 R[t] = MemA[address,4]; 10813 R[t2] = MemA[address+4,4]; 10814 if wback then R[n] = offset_addr; 10815#endif 10816 10817 bool success = false; 10818 10819 if (ConditionPassed(opcode)) { 10820 uint32_t t; 10821 uint32_t t2; 10822 uint32_t n; 10823 uint32_t m; 10824 bool index; 10825 bool add; 10826 bool wback; 10827 10828 switch (encoding) { 10829 case eEncodingA1: 10830 // if Rt<0> == '1' then UNPREDICTABLE; 10831 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10832 t = Bits32(opcode, 15, 12); 10833 if (BitIsSet(t, 0)) 10834 return false; 10835 t2 = t + 1; 10836 n = Bits32(opcode, 19, 16); 10837 m = Bits32(opcode, 3, 0); 10838 10839 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10840 index = BitIsSet(opcode, 24); 10841 add = BitIsSet(opcode, 23); 10842 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10843 10844 // if P == '0' && W == '1' then UNPREDICTABLE; 10845 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10846 return false; 10847 10848 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10849 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10850 return false; 10851 10852 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10853 if (wback && ((n == 15) || (n == t) || (n == t2))) 10854 return false; 10855 10856 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10857 if ((ArchVersion() < 6) && wback && (m == n)) 10858 return false; 10859 break; 10860 10861 default: 10862 return false; 10863 } 10864 10865 uint32_t Rn = ReadCoreReg(n, &success); 10866 if (!success) 10867 return false; 10868 RegisterInfo base_reg; 10869 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10870 10871 uint32_t Rm = ReadCoreReg(m, &success); 10872 if (!success) 10873 return false; 10874 RegisterInfo offset_reg; 10875 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10876 10877 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10878 addr_t offset_addr; 10879 if (add) 10880 offset_addr = Rn + Rm; 10881 else 10882 offset_addr = Rn - Rm; 10883 10884 // address = if index then offset_addr else R[n]; 10885 addr_t address; 10886 if (index) 10887 address = offset_addr; 10888 else 10889 address = Rn; 10890 10891 EmulateInstruction::Context context; 10892 if (n == 13) 10893 context.type = eContextPopRegisterOffStack; 10894 else 10895 context.type = eContextRegisterLoad; 10896 context.SetAddress(address); 10897 10898 // R[t] = MemA[address,4]; 10899 const uint32_t addr_byte_size = GetAddressByteSize(); 10900 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10901 if (!success) 10902 return false; 10903 10904 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10905 return false; 10906 10907 // R[t2] = MemA[address+4,4]; 10908 10909 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10910 if (!success) 10911 return false; 10912 10913 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10914 data)) 10915 return false; 10916 10917 // if wback then R[n] = offset_addr; 10918 if (wback) { 10919 context.type = eContextAdjustBaseRegister; 10920 context.SetAddress(offset_addr); 10921 10922 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10923 offset_addr)) 10924 return false; 10925 } 10926 } 10927 return true; 10928} 10929 10930// A8.6.200 STRD (immediate) 10931// Store Register Dual (immediate) calculates an address from a base register 10932// value and an immediate offset, and stores two words from two registers to 10933// memory. It can use offset, post-indexed, or pre-indexed addressing. 10934bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode, 10935 const ARMEncoding encoding) { 10936#if 0 10937 if ConditionPassed() then 10938 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10939 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10940 address = if index then offset_addr else R[n]; 10941 MemA[address,4] = R[t]; 10942 MemA[address+4,4] = R[t2]; 10943 if wback then R[n] = offset_addr; 10944#endif 10945 10946 bool success = false; 10947 10948 if (ConditionPassed(opcode)) { 10949 uint32_t t; 10950 uint32_t t2; 10951 uint32_t n; 10952 uint32_t imm32; 10953 bool index; 10954 bool add; 10955 bool wback; 10956 10957 switch (encoding) { 10958 case eEncodingT1: 10959 // if P == '0' && W == '0' then SEE 'Related encodings'; 10960 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10961 // ZeroExtend(imm8:'00', 32); 10962 t = Bits32(opcode, 15, 12); 10963 t2 = Bits32(opcode, 11, 8); 10964 n = Bits32(opcode, 19, 16); 10965 imm32 = Bits32(opcode, 7, 0) << 2; 10966 10967 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10968 index = BitIsSet(opcode, 24); 10969 add = BitIsSet(opcode, 23); 10970 wback = BitIsSet(opcode, 21); 10971 10972 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10973 if (wback && ((n == t) || (n == t2))) 10974 return false; 10975 10976 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10977 if ((n == 15) || BadReg(t) || BadReg(t2)) 10978 return false; 10979 10980 break; 10981 10982 case eEncodingA1: 10983 // if Rt<0> == '1' then UNPREDICTABLE; 10984 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10985 // 32); 10986 t = Bits32(opcode, 15, 12); 10987 if (BitIsSet(t, 0)) 10988 return false; 10989 10990 t2 = t + 1; 10991 n = Bits32(opcode, 19, 16); 10992 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10993 10994 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10995 index = BitIsSet(opcode, 24); 10996 add = BitIsSet(opcode, 23); 10997 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10998 10999 // if P == '0' && W == '1' then UNPREDICTABLE; 11000 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11001 return false; 11002 11003 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11004 if (wback && ((n == 15) || (n == t) || (n == t2))) 11005 return false; 11006 11007 // if t2 == 15 then UNPREDICTABLE; 11008 if (t2 == 15) 11009 return false; 11010 11011 break; 11012 11013 default: 11014 return false; 11015 } 11016 11017 RegisterInfo base_reg; 11018 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11019 11020 uint32_t Rn = ReadCoreReg(n, &success); 11021 if (!success) 11022 return false; 11023 11024 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11025 addr_t offset_addr; 11026 if (add) 11027 offset_addr = Rn + imm32; 11028 else 11029 offset_addr = Rn - imm32; 11030 11031 // address = if index then offset_addr else R[n]; 11032 addr_t address; 11033 if (index) 11034 address = offset_addr; 11035 else 11036 address = Rn; 11037 11038 // MemA[address,4] = R[t]; 11039 RegisterInfo data_reg; 11040 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11041 11042 uint32_t data = ReadCoreReg(t, &success); 11043 if (!success) 11044 return false; 11045 11046 EmulateInstruction::Context context; 11047 if (n == 13) 11048 context.type = eContextPushRegisterOnStack; 11049 else 11050 context.type = eContextRegisterStore; 11051 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11052 11053 const uint32_t addr_byte_size = GetAddressByteSize(); 11054 11055 if (!MemAWrite(context, address, data, addr_byte_size)) 11056 return false; 11057 11058 // MemA[address+4,4] = R[t2]; 11059 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11060 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11061 (address + 4) - Rn); 11062 11063 data = ReadCoreReg(t2, &success); 11064 if (!success) 11065 return false; 11066 11067 if (!MemAWrite(context, address + 4, data, addr_byte_size)) 11068 return false; 11069 11070 // if wback then R[n] = offset_addr; 11071 if (wback) { 11072 if (n == 13) 11073 context.type = eContextAdjustStackPointer; 11074 else 11075 context.type = eContextAdjustBaseRegister; 11076 context.SetAddress(offset_addr); 11077 11078 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11079 offset_addr)) 11080 return false; 11081 } 11082 } 11083 return true; 11084} 11085 11086// A8.6.201 STRD (register) 11087bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode, 11088 const ARMEncoding encoding) { 11089#if 0 11090 if ConditionPassed() then 11091 EncodingSpecificOperations(); 11092 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11093 address = if index then offset_addr else R[n]; 11094 MemA[address,4] = R[t]; 11095 MemA[address+4,4] = R[t2]; 11096 if wback then R[n] = offset_addr; 11097#endif 11098 11099 bool success = false; 11100 11101 if (ConditionPassed(opcode)) { 11102 uint32_t t; 11103 uint32_t t2; 11104 uint32_t n; 11105 uint32_t m; 11106 bool index; 11107 bool add; 11108 bool wback; 11109 11110 switch (encoding) { 11111 case eEncodingA1: 11112 // if Rt<0> == '1' then UNPREDICTABLE; 11113 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 11114 t = Bits32(opcode, 15, 12); 11115 if (BitIsSet(t, 0)) 11116 return false; 11117 11118 t2 = t + 1; 11119 n = Bits32(opcode, 19, 16); 11120 m = Bits32(opcode, 3, 0); 11121 11122 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11123 index = BitIsSet(opcode, 24); 11124 add = BitIsSet(opcode, 23); 11125 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11126 11127 // if P == '0' && W == '1' then UNPREDICTABLE; 11128 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11129 return false; 11130 11131 // if t2 == 15 || m == 15 then UNPREDICTABLE; 11132 if ((t2 == 15) || (m == 15)) 11133 return false; 11134 11135 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11136 if (wback && ((n == 15) || (n == t) || (n == t2))) 11137 return false; 11138 11139 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 11140 if ((ArchVersion() < 6) && wback && (m == n)) 11141 return false; 11142 11143 break; 11144 11145 default: 11146 return false; 11147 } 11148 11149 RegisterInfo base_reg; 11150 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11151 RegisterInfo offset_reg; 11152 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 11153 RegisterInfo data_reg; 11154 11155 uint32_t Rn = ReadCoreReg(n, &success); 11156 if (!success) 11157 return false; 11158 11159 uint32_t Rm = ReadCoreReg(m, &success); 11160 if (!success) 11161 return false; 11162 11163 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11164 addr_t offset_addr; 11165 if (add) 11166 offset_addr = Rn + Rm; 11167 else 11168 offset_addr = Rn - Rm; 11169 11170 // address = if index then offset_addr else R[n]; 11171 addr_t address; 11172 if (index) 11173 address = offset_addr; 11174 else 11175 address = Rn; 11176 // MemA[address,4] = R[t]; 11177 uint32_t Rt = ReadCoreReg(t, &success); 11178 if (!success) 11179 return false; 11180 11181 EmulateInstruction::Context context; 11182 if (t == 13) 11183 context.type = eContextPushRegisterOnStack; 11184 else 11185 context.type = eContextRegisterStore; 11186 11187 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11188 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11189 data_reg); 11190 11191 const uint32_t addr_byte_size = GetAddressByteSize(); 11192 11193 if (!MemAWrite(context, address, Rt, addr_byte_size)) 11194 return false; 11195 11196 // MemA[address+4,4] = R[t2]; 11197 uint32_t Rt2 = ReadCoreReg(t2, &success); 11198 if (!success) 11199 return false; 11200 11201 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11202 11203 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11204 data_reg); 11205 11206 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size)) 11207 return false; 11208 11209 // if wback then R[n] = offset_addr; 11210 if (wback) { 11211 context.type = eContextAdjustBaseRegister; 11212 context.SetAddress(offset_addr); 11213 11214 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11215 offset_addr)) 11216 return false; 11217 } 11218 } 11219 return true; 11220} 11221 11222// A8.6.319 VLDM 11223// Vector Load Multiple loads multiple extension registers from consecutive 11224// memory locations using an address from an ARM core register. 11225bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode, 11226 const ARMEncoding encoding) { 11227#if 0 11228 if ConditionPassed() then 11229 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11230 address = if add then R[n] else R[n]-imm32; 11231 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11232 for r = 0 to regs-1 11233 if single_regs then 11234 S[d+r] = MemA[address,4]; address = address+4; 11235 else 11236 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 11237 // Combine the word-aligned words in the correct order for 11238 // current endianness. 11239 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11240#endif 11241 11242 bool success = false; 11243 11244 if (ConditionPassed(opcode)) { 11245 bool single_regs; 11246 bool add; 11247 bool wback; 11248 uint32_t d; 11249 uint32_t n; 11250 uint32_t imm32; 11251 uint32_t regs; 11252 11253 switch (encoding) { 11254 case eEncodingT1: 11255 case eEncodingA1: 11256 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11257 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11258 // if P == '1' && W == '0' then SEE VLDR; 11259 // if P == U && W == '1' then UNDEFINED; 11260 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11261 return false; 11262 11263 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11264 // !), 101 (DB with !) 11265 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11266 single_regs = false; 11267 add = BitIsSet(opcode, 23); 11268 wback = BitIsSet(opcode, 21); 11269 11270 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11271 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11272 n = Bits32(opcode, 19, 16); 11273 imm32 = Bits32(opcode, 7, 0) << 2; 11274 11275 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 11276 regs = Bits32(opcode, 7, 0) / 2; 11277 11278 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11279 // UNPREDICTABLE; 11280 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 11281 return false; 11282 11283 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11284 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11285 return false; 11286 11287 break; 11288 11289 case eEncodingT2: 11290 case eEncodingA2: 11291 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11292 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11293 // if P == '1' && W == '0' then SEE VLDR; 11294 // if P == U && W == '1' then UNDEFINED; 11295 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11296 return false; 11297 11298 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11299 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11300 // == '1'); d = 11301 // UInt(Vd:D); n = UInt(Rn); 11302 single_regs = true; 11303 add = BitIsSet(opcode, 23); 11304 wback = BitIsSet(opcode, 21); 11305 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11306 n = Bits32(opcode, 19, 16); 11307 11308 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11309 imm32 = Bits32(opcode, 7, 0) << 2; 11310 regs = Bits32(opcode, 7, 0); 11311 11312 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11313 // UNPREDICTABLE; 11314 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11315 return false; 11316 11317 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11318 if ((regs == 0) || ((d + regs) > 32)) 11319 return false; 11320 break; 11321 11322 default: 11323 return false; 11324 } 11325 11326 RegisterInfo base_reg; 11327 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11328 11329 uint32_t Rn = ReadCoreReg(n, &success); 11330 if (!success) 11331 return false; 11332 11333 // address = if add then R[n] else R[n]-imm32; 11334 addr_t address; 11335 if (add) 11336 address = Rn; 11337 else 11338 address = Rn - imm32; 11339 11340 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11341 EmulateInstruction::Context context; 11342 11343 if (wback) { 11344 uint32_t value; 11345 if (add) 11346 value = Rn + imm32; 11347 else 11348 value = Rn - imm32; 11349 11350 context.type = eContextAdjustBaseRegister; 11351 context.SetImmediateSigned(value - Rn); 11352 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11353 value)) 11354 return false; 11355 } 11356 11357 const uint32_t addr_byte_size = GetAddressByteSize(); 11358 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11359 11360 context.type = eContextRegisterLoad; 11361 11362 // for r = 0 to regs-1 11363 for (uint32_t r = 0; r < regs; ++r) { 11364 if (single_regs) { 11365 // S[d+r] = MemA[address,4]; address = address+4; 11366 context.SetRegisterPlusOffset(base_reg, address - Rn); 11367 11368 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11369 if (!success) 11370 return false; 11371 11372 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11373 start_reg + d + r, data)) 11374 return false; 11375 11376 address = address + 4; 11377 } else { 11378 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = 11379 // address+8; 11380 context.SetRegisterPlusOffset(base_reg, address - Rn); 11381 uint32_t word1 = 11382 MemARead(context, address, addr_byte_size, 0, &success); 11383 if (!success) 11384 return false; 11385 11386 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn); 11387 uint32_t word2 = 11388 MemARead(context, address + 4, addr_byte_size, 0, &success); 11389 if (!success) 11390 return false; 11391 11392 address = address + 8; 11393 // // Combine the word-aligned words in the correct order for current 11394 // endianness. 11395 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11396 uint64_t data; 11397 if (GetByteOrder() == eByteOrderBig) { 11398 data = word1; 11399 data = (data << 32) | word2; 11400 } else { 11401 data = word2; 11402 data = (data << 32) | word1; 11403 } 11404 11405 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11406 start_reg + d + r, data)) 11407 return false; 11408 } 11409 } 11410 } 11411 return true; 11412} 11413 11414// A8.6.399 VSTM 11415// Vector Store Multiple stores multiple extension registers to consecutive 11416// memory locations using an address from an 11417// ARM core register. 11418bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode, 11419 const ARMEncoding encoding) { 11420#if 0 11421 if ConditionPassed() then 11422 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11423 address = if add then R[n] else R[n]-imm32; 11424 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11425 for r = 0 to regs-1 11426 if single_regs then 11427 MemA[address,4] = S[d+r]; address = address+4; 11428 else 11429 // Store as two word-aligned words in the correct order for 11430 // current endianness. 11431 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11432 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11433 address = address+8; 11434#endif 11435 11436 bool success = false; 11437 11438 if (ConditionPassed(opcode)) { 11439 bool single_regs; 11440 bool add; 11441 bool wback; 11442 uint32_t d; 11443 uint32_t n; 11444 uint32_t imm32; 11445 uint32_t regs; 11446 11447 switch (encoding) { 11448 case eEncodingT1: 11449 case eEncodingA1: 11450 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11451 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11452 // if P == '1' && W == '0' then SEE VSTR; 11453 // if P == U && W == '1' then UNDEFINED; 11454 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11455 return false; 11456 11457 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11458 // !), 101 (DB with !) 11459 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11460 single_regs = false; 11461 add = BitIsSet(opcode, 23); 11462 wback = BitIsSet(opcode, 21); 11463 11464 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11465 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11466 n = Bits32(opcode, 19, 16); 11467 imm32 = Bits32(opcode, 7, 0) << 2; 11468 11469 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11470 regs = Bits32(opcode, 7, 0) / 2; 11471 11472 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11473 // UNPREDICTABLE; 11474 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11475 return false; 11476 11477 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11478 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11479 return false; 11480 11481 break; 11482 11483 case eEncodingT2: 11484 case eEncodingA2: 11485 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11486 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11487 // if P == '1' && W == '0' then SEE VSTR; 11488 // if P == U && W == '1' then UNDEFINED; 11489 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11490 return false; 11491 11492 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11493 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11494 // == '1'); d = 11495 // UInt(Vd:D); n = UInt(Rn); 11496 single_regs = true; 11497 add = BitIsSet(opcode, 23); 11498 wback = BitIsSet(opcode, 21); 11499 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11500 n = Bits32(opcode, 19, 16); 11501 11502 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11503 imm32 = Bits32(opcode, 7, 0) << 2; 11504 regs = Bits32(opcode, 7, 0); 11505 11506 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11507 // UNPREDICTABLE; 11508 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11509 return false; 11510 11511 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11512 if ((regs == 0) || ((d + regs) > 32)) 11513 return false; 11514 11515 break; 11516 11517 default: 11518 return false; 11519 } 11520 11521 RegisterInfo base_reg; 11522 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11523 11524 uint32_t Rn = ReadCoreReg(n, &success); 11525 if (!success) 11526 return false; 11527 11528 // address = if add then R[n] else R[n]-imm32; 11529 addr_t address; 11530 if (add) 11531 address = Rn; 11532 else 11533 address = Rn - imm32; 11534 11535 EmulateInstruction::Context context; 11536 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11537 if (wback) { 11538 uint32_t value; 11539 if (add) 11540 value = Rn + imm32; 11541 else 11542 value = Rn - imm32; 11543 11544 context.type = eContextAdjustBaseRegister; 11545 context.SetRegisterPlusOffset(base_reg, value - Rn); 11546 11547 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11548 value)) 11549 return false; 11550 } 11551 11552 const uint32_t addr_byte_size = GetAddressByteSize(); 11553 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11554 11555 context.type = eContextRegisterStore; 11556 // for r = 0 to regs-1 11557 for (uint32_t r = 0; r < regs; ++r) { 11558 11559 if (single_regs) { 11560 // MemA[address,4] = S[d+r]; address = address+4; 11561 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11562 start_reg + d + r, 0, &success); 11563 if (!success) 11564 return false; 11565 11566 RegisterInfo data_reg; 11567 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11568 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11569 address - Rn); 11570 if (!MemAWrite(context, address, data, addr_byte_size)) 11571 return false; 11572 11573 address = address + 4; 11574 } else { 11575 // // Store as two word-aligned words in the correct order for current 11576 // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else 11577 // D[d+r]<31:0>; 11578 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else 11579 // D[d+r]<63:32>; 11580 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11581 start_reg + d + r, 0, &success); 11582 if (!success) 11583 return false; 11584 11585 RegisterInfo data_reg; 11586 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11587 11588 if (GetByteOrder() == eByteOrderBig) { 11589 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11590 address - Rn); 11591 if (!MemAWrite(context, address, Bits64(data, 63, 32), 11592 addr_byte_size)) 11593 return false; 11594 11595 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11596 (address + 4) - Rn); 11597 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11598 addr_byte_size)) 11599 return false; 11600 } else { 11601 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11602 address - Rn); 11603 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11604 return false; 11605 11606 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11607 (address + 4) - Rn); 11608 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11609 addr_byte_size)) 11610 return false; 11611 } 11612 // address = address+8; 11613 address = address + 8; 11614 } 11615 } 11616 } 11617 return true; 11618} 11619 11620// A8.6.320 11621// This instruction loads a single extension register from memory, using an 11622// address from an ARM core register, with an optional offset. 11623bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode, 11624 ARMEncoding encoding) { 11625#if 0 11626 if ConditionPassed() then 11627 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11628 base = if n == 15 then Align(PC,4) else R[n]; 11629 address = if add then (base + imm32) else (base - imm32); 11630 if single_reg then 11631 S[d] = MemA[address,4]; 11632 else 11633 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11634 // Combine the word-aligned words in the correct order for current 11635 // endianness. 11636 D[d] = if BigEndian() then word1:word2 else word2:word1; 11637#endif 11638 11639 bool success = false; 11640 11641 if (ConditionPassed(opcode)) { 11642 bool single_reg; 11643 bool add; 11644 uint32_t imm32; 11645 uint32_t d; 11646 uint32_t n; 11647 11648 switch (encoding) { 11649 case eEncodingT1: 11650 case eEncodingA1: 11651 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11652 // 32); 11653 single_reg = false; 11654 add = BitIsSet(opcode, 23); 11655 imm32 = Bits32(opcode, 7, 0) << 2; 11656 11657 // d = UInt(D:Vd); n = UInt(Rn); 11658 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11659 n = Bits32(opcode, 19, 16); 11660 11661 break; 11662 11663 case eEncodingT2: 11664 case eEncodingA2: 11665 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11666 single_reg = true; 11667 add = BitIsSet(opcode, 23); 11668 imm32 = Bits32(opcode, 7, 0) << 2; 11669 11670 // d = UInt(Vd:D); n = UInt(Rn); 11671 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11672 n = Bits32(opcode, 19, 16); 11673 11674 break; 11675 11676 default: 11677 return false; 11678 } 11679 RegisterInfo base_reg; 11680 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11681 11682 uint32_t Rn = ReadCoreReg(n, &success); 11683 if (!success) 11684 return false; 11685 11686 // base = if n == 15 then Align(PC,4) else R[n]; 11687 uint32_t base; 11688 if (n == 15) 11689 base = AlignPC(Rn); 11690 else 11691 base = Rn; 11692 11693 // address = if add then (base + imm32) else (base - imm32); 11694 addr_t address; 11695 if (add) 11696 address = base + imm32; 11697 else 11698 address = base - imm32; 11699 11700 const uint32_t addr_byte_size = GetAddressByteSize(); 11701 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11702 11703 EmulateInstruction::Context context; 11704 context.type = eContextRegisterLoad; 11705 context.SetRegisterPlusOffset(base_reg, address - base); 11706 11707 if (single_reg) { 11708 // S[d] = MemA[address,4]; 11709 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11710 if (!success) 11711 return false; 11712 11713 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11714 data)) 11715 return false; 11716 } else { 11717 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11718 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success); 11719 if (!success) 11720 return false; 11721 11722 context.SetRegisterPlusOffset(base_reg, (address + 4) - base); 11723 uint32_t word2 = 11724 MemARead(context, address + 4, addr_byte_size, 0, &success); 11725 if (!success) 11726 return false; 11727 // // Combine the word-aligned words in the correct order for current 11728 // endianness. 11729 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11730 uint64_t data64; 11731 if (GetByteOrder() == eByteOrderBig) { 11732 data64 = word1; 11733 data64 = (data64 << 32) | word2; 11734 } else { 11735 data64 = word2; 11736 data64 = (data64 << 32) | word1; 11737 } 11738 11739 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11740 data64)) 11741 return false; 11742 } 11743 } 11744 return true; 11745} 11746 11747// A8.6.400 VSTR 11748// This instruction stores a signle extension register to memory, using an 11749// address from an ARM core register, with an optional offset. 11750bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode, 11751 ARMEncoding encoding) { 11752#if 0 11753 if ConditionPassed() then 11754 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11755 address = if add then (R[n] + imm32) else (R[n] - imm32); 11756 if single_reg then 11757 MemA[address,4] = S[d]; 11758 else 11759 // Store as two word-aligned words in the correct order for current 11760 // endianness. 11761 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11762 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11763#endif 11764 11765 bool success = false; 11766 11767 if (ConditionPassed(opcode)) { 11768 bool single_reg; 11769 bool add; 11770 uint32_t imm32; 11771 uint32_t d; 11772 uint32_t n; 11773 11774 switch (encoding) { 11775 case eEncodingT1: 11776 case eEncodingA1: 11777 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11778 // 32); 11779 single_reg = false; 11780 add = BitIsSet(opcode, 23); 11781 imm32 = Bits32(opcode, 7, 0) << 2; 11782 11783 // d = UInt(D:Vd); n = UInt(Rn); 11784 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11785 n = Bits32(opcode, 19, 16); 11786 11787 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11788 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11789 return false; 11790 11791 break; 11792 11793 case eEncodingT2: 11794 case eEncodingA2: 11795 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11796 single_reg = true; 11797 add = BitIsSet(opcode, 23); 11798 imm32 = Bits32(opcode, 7, 0) << 2; 11799 11800 // d = UInt(Vd:D); n = UInt(Rn); 11801 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11802 n = Bits32(opcode, 19, 16); 11803 11804 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11805 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11806 return false; 11807 11808 break; 11809 11810 default: 11811 return false; 11812 } 11813 11814 RegisterInfo base_reg; 11815 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11816 11817 uint32_t Rn = ReadCoreReg(n, &success); 11818 if (!success) 11819 return false; 11820 11821 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11822 addr_t address; 11823 if (add) 11824 address = Rn + imm32; 11825 else 11826 address = Rn - imm32; 11827 11828 const uint32_t addr_byte_size = GetAddressByteSize(); 11829 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11830 11831 RegisterInfo data_reg; 11832 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg); 11833 EmulateInstruction::Context context; 11834 context.type = eContextRegisterStore; 11835 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11836 11837 if (single_reg) { 11838 // MemA[address,4] = S[d]; 11839 uint32_t data = 11840 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11841 if (!success) 11842 return false; 11843 11844 if (!MemAWrite(context, address, data, addr_byte_size)) 11845 return false; 11846 } else { 11847 // // Store as two word-aligned words in the correct order for current 11848 // endianness. 11849 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11850 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11851 uint64_t data = 11852 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11853 if (!success) 11854 return false; 11855 11856 if (GetByteOrder() == eByteOrderBig) { 11857 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size)) 11858 return false; 11859 11860 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11861 (address + 4) - Rn); 11862 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11863 addr_byte_size)) 11864 return false; 11865 } else { 11866 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11867 return false; 11868 11869 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11870 (address + 4) - Rn); 11871 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11872 addr_byte_size)) 11873 return false; 11874 } 11875 } 11876 } 11877 return true; 11878} 11879 11880// A8.6.307 VLDI1 (multiple single elements) This instruction loads elements 11881// from memory into one, two, three or four registers, without de-interleaving. 11882// Every element of each register is loaded. 11883bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode, 11884 ARMEncoding encoding) { 11885#if 0 11886 if ConditionPassed() then 11887 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11888 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11889 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11890 for r = 0 to regs-1 11891 for e = 0 to elements-1 11892 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11893 address = address + ebytes; 11894#endif 11895 11896 bool success = false; 11897 11898 if (ConditionPassed(opcode)) { 11899 uint32_t regs; 11900 uint32_t alignment; 11901 uint32_t ebytes; 11902 uint32_t esize; 11903 uint32_t elements; 11904 uint32_t d; 11905 uint32_t n; 11906 uint32_t m; 11907 bool wback; 11908 bool register_index; 11909 11910 switch (encoding) { 11911 case eEncodingT1: 11912 case eEncodingA1: { 11913 // case type of 11914 // when '0111' 11915 // regs = 1; if align<1> == '1' then UNDEFINED; 11916 // when '1010' 11917 // regs = 2; if align == '11' then UNDEFINED; 11918 // when '0110' 11919 // regs = 3; if align<1> == '1' then UNDEFINED; 11920 // when '0010' 11921 // regs = 4; 11922 // otherwise 11923 // SEE 'Related encodings'; 11924 uint32_t type = Bits32(opcode, 11, 8); 11925 uint32_t align = Bits32(opcode, 5, 4); 11926 if (type == 7) // '0111' 11927 { 11928 regs = 1; 11929 if (BitIsSet(align, 1)) 11930 return false; 11931 } else if (type == 10) // '1010' 11932 { 11933 regs = 2; 11934 if (align == 3) 11935 return false; 11936 11937 } else if (type == 6) // '0110' 11938 { 11939 regs = 3; 11940 if (BitIsSet(align, 1)) 11941 return false; 11942 } else if (type == 2) // '0010' 11943 { 11944 regs = 4; 11945 } else 11946 return false; 11947 11948 // alignment = if align == '00' then 1 else 4 << UInt(align); 11949 if (align == 0) 11950 alignment = 1; 11951 else 11952 alignment = 4 << align; 11953 11954 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11955 ebytes = 1 << Bits32(opcode, 7, 6); 11956 esize = 8 * ebytes; 11957 elements = 8 / ebytes; 11958 11959 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11960 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11961 n = Bits32(opcode, 19, 15); 11962 m = Bits32(opcode, 3, 0); 11963 11964 // wback = (m != 15); register_index = (m != 15 && m != 13); 11965 wback = (m != 15); 11966 register_index = ((m != 15) && (m != 13)); 11967 11968 // if d+regs > 32 then UNPREDICTABLE; 11969 if ((d + regs) > 32) 11970 return false; 11971 } break; 11972 11973 default: 11974 return false; 11975 } 11976 11977 RegisterInfo base_reg; 11978 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11979 11980 uint32_t Rn = ReadCoreReg(n, &success); 11981 if (!success) 11982 return false; 11983 11984 // address = R[n]; if (address MOD alignment) != 0 then 11985 // GenerateAlignmentException(); 11986 addr_t address = Rn; 11987 if ((address % alignment) != 0) 11988 return false; 11989 11990 EmulateInstruction::Context context; 11991 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11992 if (wback) { 11993 uint32_t Rm = ReadCoreReg(m, &success); 11994 if (!success) 11995 return false; 11996 11997 uint32_t offset; 11998 if (register_index) 11999 offset = Rm; 12000 else 12001 offset = 8 * regs; 12002 12003 uint32_t value = Rn + offset; 12004 context.type = eContextAdjustBaseRegister; 12005 context.SetRegisterPlusOffset(base_reg, offset); 12006 12007 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12008 value)) 12009 return false; 12010 } 12011 12012 // for r = 0 to regs-1 12013 for (uint32_t r = 0; r < regs; ++r) { 12014 // for e = 0 to elements-1 12015 uint64_t assembled_data = 0; 12016 for (uint32_t e = 0; e < elements; ++e) { 12017 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 12018 context.type = eContextRegisterLoad; 12019 context.SetRegisterPlusOffset(base_reg, address - Rn); 12020 uint64_t data = MemURead(context, address, ebytes, 0, &success); 12021 if (!success) 12022 return false; 12023 12024 assembled_data = 12025 (data << (e * esize)) | 12026 assembled_data; // New data goes to the left of existing data 12027 12028 // address = address + ebytes; 12029 address = address + ebytes; 12030 } 12031 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12032 assembled_data)) 12033 return false; 12034 } 12035 } 12036 return true; 12037} 12038 12039// A8.6.308 VLD1 (single element to one lane) 12040// 12041bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode, 12042 const ARMEncoding encoding) { 12043#if 0 12044 if ConditionPassed() then 12045 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12046 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12047 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12048 Elem[D[d],index,esize] = MemU[address,ebytes]; 12049#endif 12050 12051 bool success = false; 12052 12053 if (ConditionPassed(opcode)) { 12054 uint32_t ebytes; 12055 uint32_t esize; 12056 uint32_t index; 12057 uint32_t alignment; 12058 uint32_t d; 12059 uint32_t n; 12060 uint32_t m; 12061 bool wback; 12062 bool register_index; 12063 12064 switch (encoding) { 12065 case eEncodingT1: 12066 case eEncodingA1: { 12067 uint32_t size = Bits32(opcode, 11, 10); 12068 uint32_t index_align = Bits32(opcode, 7, 4); 12069 // if size == '11' then SEE VLD1 (single element to all lanes); 12070 if (size == 3) 12071 return EmulateVLD1SingleAll(opcode, encoding); 12072 // case size of 12073 if (size == 0) // when '00' 12074 { 12075 // if index_align<0> != '0' then UNDEFINED; 12076 if (BitIsClear(index_align, 0)) 12077 return false; 12078 12079 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12080 ebytes = 1; 12081 esize = 8; 12082 index = Bits32(index_align, 3, 1); 12083 alignment = 1; 12084 } else if (size == 1) // when '01' 12085 { 12086 // if index_align<1> != '0' then UNDEFINED; 12087 if (BitIsClear(index_align, 1)) 12088 return false; 12089 12090 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12091 ebytes = 2; 12092 esize = 16; 12093 index = Bits32(index_align, 3, 2); 12094 12095 // alignment = if index_align<0> == '0' then 1 else 2; 12096 if (BitIsClear(index_align, 0)) 12097 alignment = 1; 12098 else 12099 alignment = 2; 12100 } else if (size == 2) // when '10' 12101 { 12102 // if index_align<2> != '0' then UNDEFINED; 12103 if (BitIsClear(index_align, 2)) 12104 return false; 12105 12106 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12107 // UNDEFINED; 12108 if ((Bits32(index_align, 1, 0) != 0) && 12109 (Bits32(index_align, 1, 0) != 3)) 12110 return false; 12111 12112 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12113 ebytes = 4; 12114 esize = 32; 12115 index = Bit32(index_align, 3); 12116 12117 // alignment = if index_align<1:0> == '00' then 1 else 4; 12118 if (Bits32(index_align, 1, 0) == 0) 12119 alignment = 1; 12120 else 12121 alignment = 4; 12122 } else { 12123 return false; 12124 } 12125 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12126 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12127 n = Bits32(opcode, 19, 16); 12128 m = Bits32(opcode, 3, 0); 12129 12130 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12131 // then UNPREDICTABLE; 12132 wback = (m != 15); 12133 register_index = ((m != 15) && (m != 13)); 12134 12135 if (n == 15) 12136 return false; 12137 12138 } break; 12139 12140 default: 12141 return false; 12142 } 12143 12144 RegisterInfo base_reg; 12145 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12146 12147 uint32_t Rn = ReadCoreReg(n, &success); 12148 if (!success) 12149 return false; 12150 12151 // address = R[n]; if (address MOD alignment) != 0 then 12152 // GenerateAlignmentException(); 12153 addr_t address = Rn; 12154 if ((address % alignment) != 0) 12155 return false; 12156 12157 EmulateInstruction::Context context; 12158 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12159 if (wback) { 12160 uint32_t Rm = ReadCoreReg(m, &success); 12161 if (!success) 12162 return false; 12163 12164 uint32_t offset; 12165 if (register_index) 12166 offset = Rm; 12167 else 12168 offset = ebytes; 12169 12170 uint32_t value = Rn + offset; 12171 12172 context.type = eContextAdjustBaseRegister; 12173 context.SetRegisterPlusOffset(base_reg, offset); 12174 12175 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12176 value)) 12177 return false; 12178 } 12179 12180 // Elem[D[d],index,esize] = MemU[address,ebytes]; 12181 uint32_t element = MemURead(context, address, esize, 0, &success); 12182 if (!success) 12183 return false; 12184 12185 element = element << (index * esize); 12186 12187 uint64_t reg_data = 12188 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12189 if (!success) 12190 return false; 12191 12192 uint64_t all_ones = -1; 12193 uint64_t mask = all_ones 12194 << ((index + 1) * esize); // mask is all 1's to left of 12195 // where 'element' goes, & all 0's 12196 // at element & to the right of element. 12197 if (index > 0) 12198 mask = mask | Bits64(all_ones, (index * esize) - 1, 12199 0); // add 1's to the right of where 'element' goes. 12200 // now mask should be 0's where element goes & 1's everywhere else. 12201 12202 uint64_t masked_reg = 12203 reg_data & mask; // Take original reg value & zero out 'element' bits 12204 reg_data = 12205 masked_reg & element; // Put 'element' into those bits in reg_data. 12206 12207 context.type = eContextRegisterLoad; 12208 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 12209 reg_data)) 12210 return false; 12211 } 12212 return true; 12213} 12214 12215// A8.6.391 VST1 (multiple single elements) Vector Store (multiple single 12216// elements) stores elements to memory from one, two, three, or four registers, 12217// without interleaving. Every element of each register is stored. 12218bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode, 12219 ARMEncoding encoding) { 12220#if 0 12221 if ConditionPassed() then 12222 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12223 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12224 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12225 for r = 0 to regs-1 12226 for e = 0 to elements-1 12227 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12228 address = address + ebytes; 12229#endif 12230 12231 bool success = false; 12232 12233 if (ConditionPassed(opcode)) { 12234 uint32_t regs; 12235 uint32_t alignment; 12236 uint32_t ebytes; 12237 uint32_t esize; 12238 uint32_t elements; 12239 uint32_t d; 12240 uint32_t n; 12241 uint32_t m; 12242 bool wback; 12243 bool register_index; 12244 12245 switch (encoding) { 12246 case eEncodingT1: 12247 case eEncodingA1: { 12248 uint32_t type = Bits32(opcode, 11, 8); 12249 uint32_t align = Bits32(opcode, 5, 4); 12250 12251 // case type of 12252 if (type == 7) // when '0111' 12253 { 12254 // regs = 1; if align<1> == '1' then UNDEFINED; 12255 regs = 1; 12256 if (BitIsSet(align, 1)) 12257 return false; 12258 } else if (type == 10) // when '1010' 12259 { 12260 // regs = 2; if align == '11' then UNDEFINED; 12261 regs = 2; 12262 if (align == 3) 12263 return false; 12264 } else if (type == 6) // when '0110' 12265 { 12266 // regs = 3; if align<1> == '1' then UNDEFINED; 12267 regs = 3; 12268 if (BitIsSet(align, 1)) 12269 return false; 12270 } else if (type == 2) // when '0010' 12271 // regs = 4; 12272 regs = 4; 12273 else // otherwise 12274 // SEE 'Related encodings'; 12275 return false; 12276 12277 // alignment = if align == '00' then 1 else 4 << UInt(align); 12278 if (align == 0) 12279 alignment = 1; 12280 else 12281 alignment = 4 << align; 12282 12283 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 12284 ebytes = 1 << Bits32(opcode, 7, 6); 12285 esize = 8 * ebytes; 12286 elements = 8 / ebytes; 12287 12288 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12289 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12290 n = Bits32(opcode, 19, 16); 12291 m = Bits32(opcode, 3, 0); 12292 12293 // wback = (m != 15); register_index = (m != 15 && m != 13); 12294 wback = (m != 15); 12295 register_index = ((m != 15) && (m != 13)); 12296 12297 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12298 if ((d + regs) > 32) 12299 return false; 12300 12301 if (n == 15) 12302 return false; 12303 12304 } break; 12305 12306 default: 12307 return false; 12308 } 12309 12310 RegisterInfo base_reg; 12311 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12312 12313 uint32_t Rn = ReadCoreReg(n, &success); 12314 if (!success) 12315 return false; 12316 12317 // address = R[n]; if (address MOD alignment) != 0 then 12318 // GenerateAlignmentException(); 12319 addr_t address = Rn; 12320 if ((address % alignment) != 0) 12321 return false; 12322 12323 EmulateInstruction::Context context; 12324 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12325 if (wback) { 12326 uint32_t Rm = ReadCoreReg(m, &success); 12327 if (!success) 12328 return false; 12329 12330 uint32_t offset; 12331 if (register_index) 12332 offset = Rm; 12333 else 12334 offset = 8 * regs; 12335 12336 context.type = eContextAdjustBaseRegister; 12337 context.SetRegisterPlusOffset(base_reg, offset); 12338 12339 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12340 Rn + offset)) 12341 return false; 12342 } 12343 12344 RegisterInfo data_reg; 12345 context.type = eContextRegisterStore; 12346 // for r = 0 to regs-1 12347 for (uint32_t r = 0; r < regs; ++r) { 12348 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 12349 uint64_t register_data = ReadRegisterUnsigned( 12350 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 12351 if (!success) 12352 return false; 12353 12354 // for e = 0 to elements-1 12355 for (uint32_t e = 0; e < elements; ++e) { 12356 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12357 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize); 12358 12359 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12360 address - Rn); 12361 if (!MemUWrite(context, address, word, ebytes)) 12362 return false; 12363 12364 // address = address + ebytes; 12365 address = address + ebytes; 12366 } 12367 } 12368 } 12369 return true; 12370} 12371 12372// A8.6.392 VST1 (single element from one lane) This instruction stores one 12373// element to memory from one element of a register. 12374bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode, 12375 ARMEncoding encoding) { 12376#if 0 12377 if ConditionPassed() then 12378 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12379 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12380 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12381 MemU[address,ebytes] = Elem[D[d],index,esize]; 12382#endif 12383 12384 bool success = false; 12385 12386 if (ConditionPassed(opcode)) { 12387 uint32_t ebytes; 12388 uint32_t esize; 12389 uint32_t index; 12390 uint32_t alignment; 12391 uint32_t d; 12392 uint32_t n; 12393 uint32_t m; 12394 bool wback; 12395 bool register_index; 12396 12397 switch (encoding) { 12398 case eEncodingT1: 12399 case eEncodingA1: { 12400 uint32_t size = Bits32(opcode, 11, 10); 12401 uint32_t index_align = Bits32(opcode, 7, 4); 12402 12403 // if size == '11' then UNDEFINED; 12404 if (size == 3) 12405 return false; 12406 12407 // case size of 12408 if (size == 0) // when '00' 12409 { 12410 // if index_align<0> != '0' then UNDEFINED; 12411 if (BitIsClear(index_align, 0)) 12412 return false; 12413 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12414 ebytes = 1; 12415 esize = 8; 12416 index = Bits32(index_align, 3, 1); 12417 alignment = 1; 12418 } else if (size == 1) // when '01' 12419 { 12420 // if index_align<1> != '0' then UNDEFINED; 12421 if (BitIsClear(index_align, 1)) 12422 return false; 12423 12424 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12425 ebytes = 2; 12426 esize = 16; 12427 index = Bits32(index_align, 3, 2); 12428 12429 // alignment = if index_align<0> == '0' then 1 else 2; 12430 if (BitIsClear(index_align, 0)) 12431 alignment = 1; 12432 else 12433 alignment = 2; 12434 } else if (size == 2) // when '10' 12435 { 12436 // if index_align<2> != '0' then UNDEFINED; 12437 if (BitIsClear(index_align, 2)) 12438 return false; 12439 12440 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12441 // UNDEFINED; 12442 if ((Bits32(index_align, 1, 0) != 0) && 12443 (Bits32(index_align, 1, 0) != 3)) 12444 return false; 12445 12446 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12447 ebytes = 4; 12448 esize = 32; 12449 index = Bit32(index_align, 3); 12450 12451 // alignment = if index_align<1:0> == '00' then 1 else 4; 12452 if (Bits32(index_align, 1, 0) == 0) 12453 alignment = 1; 12454 else 12455 alignment = 4; 12456 } else { 12457 return false; 12458 } 12459 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12460 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12461 n = Bits32(opcode, 19, 16); 12462 m = Bits32(opcode, 3, 0); 12463 12464 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12465 // then UNPREDICTABLE; 12466 wback = (m != 15); 12467 register_index = ((m != 15) && (m != 13)); 12468 12469 if (n == 15) 12470 return false; 12471 } break; 12472 12473 default: 12474 return false; 12475 } 12476 12477 RegisterInfo base_reg; 12478 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12479 12480 uint32_t Rn = ReadCoreReg(n, &success); 12481 if (!success) 12482 return false; 12483 12484 // address = R[n]; if (address MOD alignment) != 0 then 12485 // GenerateAlignmentException(); 12486 addr_t address = Rn; 12487 if ((address % alignment) != 0) 12488 return false; 12489 12490 EmulateInstruction::Context context; 12491 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12492 if (wback) { 12493 uint32_t Rm = ReadCoreReg(m, &success); 12494 if (!success) 12495 return false; 12496 12497 uint32_t offset; 12498 if (register_index) 12499 offset = Rm; 12500 else 12501 offset = ebytes; 12502 12503 context.type = eContextAdjustBaseRegister; 12504 context.SetRegisterPlusOffset(base_reg, offset); 12505 12506 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12507 Rn + offset)) 12508 return false; 12509 } 12510 12511 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12512 uint64_t register_data = 12513 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12514 if (!success) 12515 return false; 12516 12517 uint64_t word = 12518 Bits64(register_data, ((index + 1) * esize) - 1, index * esize); 12519 12520 RegisterInfo data_reg; 12521 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12522 context.type = eContextRegisterStore; 12523 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 12524 12525 if (!MemUWrite(context, address, word, ebytes)) 12526 return false; 12527 } 12528 return true; 12529} 12530 12531// A8.6.309 VLD1 (single element to all lanes) This instruction loads one 12532// element from memory into every element of one or two vectors. 12533bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode, 12534 const ARMEncoding encoding) { 12535#if 0 12536 if ConditionPassed() then 12537 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12538 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12539 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12540 replicated_element = Replicate(MemU[address,ebytes], elements); 12541 for r = 0 to regs-1 12542 D[d+r] = replicated_element; 12543#endif 12544 12545 bool success = false; 12546 12547 if (ConditionPassed(opcode)) { 12548 uint32_t ebytes; 12549 uint32_t elements; 12550 uint32_t regs; 12551 uint32_t alignment; 12552 uint32_t d; 12553 uint32_t n; 12554 uint32_t m; 12555 bool wback; 12556 bool register_index; 12557 12558 switch (encoding) { 12559 case eEncodingT1: 12560 case eEncodingA1: { 12561 // if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12562 uint32_t size = Bits32(opcode, 7, 6); 12563 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4))) 12564 return false; 12565 12566 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' 12567 // then 1 else 2; 12568 ebytes = 1 << size; 12569 elements = 8 / ebytes; 12570 if (BitIsClear(opcode, 5)) 12571 regs = 1; 12572 else 12573 regs = 2; 12574 12575 // alignment = if a == '0' then 1 else ebytes; 12576 if (BitIsClear(opcode, 4)) 12577 alignment = 1; 12578 else 12579 alignment = ebytes; 12580 12581 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12582 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12583 n = Bits32(opcode, 19, 16); 12584 m = Bits32(opcode, 3, 0); 12585 12586 // wback = (m != 15); register_index = (m != 15 && m != 13); 12587 wback = (m != 15); 12588 register_index = ((m != 15) && (m != 13)); 12589 12590 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12591 if ((d + regs) > 32) 12592 return false; 12593 12594 if (n == 15) 12595 return false; 12596 } break; 12597 12598 default: 12599 return false; 12600 } 12601 12602 RegisterInfo base_reg; 12603 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12604 12605 uint32_t Rn = ReadCoreReg(n, &success); 12606 if (!success) 12607 return false; 12608 12609 // address = R[n]; if (address MOD alignment) != 0 then 12610 // GenerateAlignmentException(); 12611 addr_t address = Rn; 12612 if ((address % alignment) != 0) 12613 return false; 12614 12615 EmulateInstruction::Context context; 12616 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12617 if (wback) { 12618 uint32_t Rm = ReadCoreReg(m, &success); 12619 if (!success) 12620 return false; 12621 12622 uint32_t offset; 12623 if (register_index) 12624 offset = Rm; 12625 else 12626 offset = ebytes; 12627 12628 context.type = eContextAdjustBaseRegister; 12629 context.SetRegisterPlusOffset(base_reg, offset); 12630 12631 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12632 Rn + offset)) 12633 return false; 12634 } 12635 12636 // replicated_element = Replicate(MemU[address,ebytes], elements); 12637 12638 context.type = eContextRegisterLoad; 12639 uint64_t word = MemURead(context, address, ebytes, 0, &success); 12640 if (!success) 12641 return false; 12642 12643 uint64_t replicated_element = 0; 12644 uint32_t esize = ebytes * 8; 12645 for (uint32_t e = 0; e < elements; ++e) 12646 replicated_element = 12647 (replicated_element << esize) | Bits64(word, esize - 1, 0); 12648 12649 // for r = 0 to regs-1 12650 for (uint32_t r = 0; r < regs; ++r) { 12651 // D[d+r] = replicated_element; 12652 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12653 replicated_element)) 12654 return false; 12655 } 12656 } 12657 return true; 12658} 12659 12660// B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const? 12661// instruction provides an exception return without the use of the stack. It 12662// subtracts the immediate constant from the LR, branches to the resulting 12663// address, and also copies the SPSR to the CPSR. 12664bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode, 12665 const ARMEncoding encoding) { 12666#if 0 12667 if ConditionPassed() then 12668 EncodingSpecificOperations(); 12669 if CurrentInstrSet() == InstrSet_ThumbEE then 12670 UNPREDICTABLE; 12671 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12672 case opcode of 12673 when '0000' result = R[n] AND operand2; // AND 12674 when '0001' result = R[n] EOR operand2; // EOR 12675 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12676 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12677 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12678 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12679 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12680 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12681 when '1100' result = R[n] OR operand2; // ORR 12682 when '1101' result = operand2; // MOV 12683 when '1110' result = R[n] AND NOT(operand2); // BIC 12684 when '1111' result = NOT(operand2); // MVN 12685 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12686 BranchWritePC(result); 12687#endif 12688 12689 bool success = false; 12690 12691 if (ConditionPassed(opcode)) { 12692 uint32_t n; 12693 uint32_t m; 12694 uint32_t imm32; 12695 bool register_form; 12696 ARM_ShifterType shift_t; 12697 uint32_t shift_n; 12698 uint32_t code; 12699 12700 switch (encoding) { 12701 case eEncodingT1: 12702 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14; 12703 // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; 12704 // // = SUB 12705 n = 14; 12706 imm32 = Bits32(opcode, 7, 0); 12707 register_form = false; 12708 code = 2; 12709 12710 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12711 if (InITBlock() && !LastInITBlock()) 12712 return false; 12713 12714 break; 12715 12716 case eEncodingA1: 12717 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12718 n = Bits32(opcode, 19, 16); 12719 imm32 = ARMExpandImm(opcode); 12720 register_form = false; 12721 code = Bits32(opcode, 24, 21); 12722 12723 break; 12724 12725 case eEncodingA2: 12726 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12727 n = Bits32(opcode, 19, 16); 12728 m = Bits32(opcode, 3, 0); 12729 register_form = true; 12730 12731 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12732 shift_n = DecodeImmShiftARM(opcode, shift_t); 12733 12734 break; 12735 12736 default: 12737 return false; 12738 } 12739 12740 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) 12741 // else imm32; 12742 uint32_t operand2; 12743 if (register_form) { 12744 uint32_t Rm = ReadCoreReg(m, &success); 12745 if (!success) 12746 return false; 12747 12748 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success); 12749 if (!success) 12750 return false; 12751 } else { 12752 operand2 = imm32; 12753 } 12754 12755 uint32_t Rn = ReadCoreReg(n, &success); 12756 if (!success) 12757 return false; 12758 12759 AddWithCarryResult result; 12760 12761 // case opcode of 12762 switch (code) { 12763 case 0: // when '0000' 12764 // result = R[n] AND operand2; // AND 12765 result.result = Rn & operand2; 12766 break; 12767 12768 case 1: // when '0001' 12769 // result = R[n] EOR operand2; // EOR 12770 result.result = Rn ^ operand2; 12771 break; 12772 12773 case 2: // when '0010' 12774 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12775 result = AddWithCarry(Rn, ~(operand2), 1); 12776 break; 12777 12778 case 3: // when '0011' 12779 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12780 result = AddWithCarry(~(Rn), operand2, 1); 12781 break; 12782 12783 case 4: // when '0100' 12784 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12785 result = AddWithCarry(Rn, operand2, 0); 12786 break; 12787 12788 case 5: // when '0101' 12789 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12790 result = AddWithCarry(Rn, operand2, APSR_C); 12791 break; 12792 12793 case 6: // when '0110' 12794 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12795 result = AddWithCarry(Rn, ~(operand2), APSR_C); 12796 break; 12797 12798 case 7: // when '0111' 12799 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12800 result = AddWithCarry(~(Rn), operand2, APSR_C); 12801 break; 12802 12803 case 10: // when '1100' 12804 // result = R[n] OR operand2; // ORR 12805 result.result = Rn | operand2; 12806 break; 12807 12808 case 11: // when '1101' 12809 // result = operand2; // MOV 12810 result.result = operand2; 12811 break; 12812 12813 case 12: // when '1110' 12814 // result = R[n] AND NOT(operand2); // BIC 12815 result.result = Rn & ~(operand2); 12816 break; 12817 12818 case 15: // when '1111' 12819 // result = NOT(operand2); // MVN 12820 result.result = ~(operand2); 12821 break; 12822 12823 default: 12824 return false; 12825 } 12826 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12827 12828 // For now, in emulation mode, we don't have access to the SPSR, so we will 12829 // use the CPSR instead, and hope for the best. 12830 uint32_t spsr = 12831 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12832 if (!success) 12833 return false; 12834 12835 CPSRWriteByInstr(spsr, 15, true); 12836 12837 // BranchWritePC(result); 12838 EmulateInstruction::Context context; 12839 context.type = eContextAdjustPC; 12840 context.SetImmediate(result.result); 12841 12842 BranchWritePC(context, result.result); 12843 } 12844 return true; 12845} 12846 12847EmulateInstructionARM::ARMOpcode * 12848EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode, 12849 uint32_t arm_isa) { 12850 static ARMOpcode g_arm_opcodes[] = { 12851 // Prologue instructions 12852 12853 // push register(s) 12854 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12855 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 12856 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12857 &EmulateInstructionARM::EmulatePUSH, "push <register>"}, 12858 12859 // set r7 to point to a stack offset 12860 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12861 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"}, 12862 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12863 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12864 // copy the stack pointer to ip 12865 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, 12866 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"}, 12867 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12868 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"}, 12869 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12870 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12871 12872 // adjust the stack pointer 12873 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12874 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12875 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12876 &EmulateInstructionARM::EmulateSUBSPReg, 12877 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 12878 12879 // push one register 12880 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12881 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12882 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"}, 12883 12884 // vector push consecutive extension register(s) 12885 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12886 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12887 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12888 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12889 12890 // Epilogue instructions 12891 12892 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12893 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12894 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12895 &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12896 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12897 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12898 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12899 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12900 12901 // Supervisor Call (previously Software Interrupt) 12902 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12903 &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12904 12905 // Branch instructions 12906 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and 12907 // "bl <label>". 12908 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, 12909 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12910 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12911 &EmulateInstructionARM::EmulateB, "b #imm24"}, 12912 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12913 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12914 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, 12915 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12916 // for example, "bx lr" 12917 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, 12918 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12919 // bxj 12920 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, 12921 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12922 12923 // Data-processing instructions 12924 // adc (immediate) 12925 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12926 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12927 // adc (register) 12928 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12929 &EmulateInstructionARM::EmulateADCReg, 12930 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12931 // add (immediate) 12932 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12933 &EmulateInstructionARM::EmulateADDImmARM, 12934 "add{s}<c> <Rd>, <Rn>, #const"}, 12935 // add (register) 12936 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12937 &EmulateInstructionARM::EmulateADDReg, 12938 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12939 // add (register-shifted register) 12940 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, 12941 &EmulateInstructionARM::EmulateADDRegShift, 12942 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12943 // adr 12944 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12945 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12946 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, 12947 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12948 // and (immediate) 12949 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12950 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12951 // and (register) 12952 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12953 &EmulateInstructionARM::EmulateANDReg, 12954 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12955 // bic (immediate) 12956 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12957 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12958 // bic (register) 12959 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12960 &EmulateInstructionARM::EmulateBICReg, 12961 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12962 // eor (immediate) 12963 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12964 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12965 // eor (register) 12966 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12967 &EmulateInstructionARM::EmulateEORReg, 12968 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12969 // orr (immediate) 12970 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12971 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12972 // orr (register) 12973 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12974 &EmulateInstructionARM::EmulateORRReg, 12975 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12976 // rsb (immediate) 12977 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12978 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12979 // rsb (register) 12980 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12981 &EmulateInstructionARM::EmulateRSBReg, 12982 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12983 // rsc (immediate) 12984 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12985 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12986 // rsc (register) 12987 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12988 &EmulateInstructionARM::EmulateRSCReg, 12989 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12990 // sbc (immediate) 12991 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12992 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12993 // sbc (register) 12994 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12995 &EmulateInstructionARM::EmulateSBCReg, 12996 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12997 // sub (immediate, ARM) 12998 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12999 &EmulateInstructionARM::EmulateSUBImmARM, 13000 "sub{s}<c> <Rd>, <Rn>, #<const>"}, 13001 // sub (sp minus immediate) 13002 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13003 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 13004 // sub (register) 13005 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13006 &EmulateInstructionARM::EmulateSUBReg, 13007 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 13008 // teq (immediate) 13009 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13010 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 13011 // teq (register) 13012 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13013 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13014 // tst (immediate) 13015 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13016 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 13017 // tst (register) 13018 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13019 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 13020 13021 // mov (immediate) 13022 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13023 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 13024 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 13025 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"}, 13026 // mov (register) 13027 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13028 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 13029 // mvn (immediate) 13030 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13031 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 13032 // mvn (register) 13033 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13034 &EmulateInstructionARM::EmulateMVNReg, 13035 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 13036 // cmn (immediate) 13037 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13038 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13039 // cmn (register) 13040 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13041 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13042 // cmp (immediate) 13043 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13044 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 13045 // cmp (register) 13046 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13047 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 13048 // asr (immediate) 13049 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, 13050 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 13051 // asr (register) 13052 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13053 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 13054 // lsl (immediate) 13055 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13056 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 13057 // lsl (register) 13058 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, 13059 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 13060 // lsr (immediate) 13061 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, 13062 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 13063 // lsr (register) 13064 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13065 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 13066 // rrx is a special case encoding of ror (immediate) 13067 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13068 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 13069 // ror (immediate) 13070 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13071 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 13072 // ror (register) 13073 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, 13074 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 13075 // mul 13076 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, 13077 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"}, 13078 13079 // subs pc, lr and related instructions 13080 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13081 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13082 "<opc>S<c> PC,#<const> | <Rn>,#<const>"}, 13083 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, 13084 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13085 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"}, 13086 13087 // Load instructions 13088 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13089 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13090 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13091 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"}, 13092 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13093 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13094 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13095 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"}, 13096 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13097 &EmulateInstructionARM::EmulateLDRImmediateARM, 13098 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"}, 13099 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13100 &EmulateInstructionARM::EmulateLDRRegister, 13101 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"}, 13102 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13103 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 13104 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13105 &EmulateInstructionARM::EmulateLDRBRegister, 13106 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"}, 13107 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13108 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13109 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13110 &EmulateInstructionARM::EmulateLDRHRegister, 13111 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13112 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13113 &EmulateInstructionARM::EmulateLDRSBImmediate, 13114 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"}, 13115 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13116 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"}, 13117 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13118 &EmulateInstructionARM::EmulateLDRSBRegister, 13119 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13120 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13121 &EmulateInstructionARM::EmulateLDRSHImmediate, 13122 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 13123 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13124 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13125 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13126 &EmulateInstructionARM::EmulateLDRSHRegister, 13127 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13128 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13129 &EmulateInstructionARM::EmulateLDRDImmediate, 13130 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 13131 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13132 &EmulateInstructionARM::EmulateLDRDRegister, 13133 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13134 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13135 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13136 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13137 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13138 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13139 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13140 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13141 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13142 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13143 &EmulateInstructionARM::EmulateVLD1Multiple, 13144 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13145 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13146 &EmulateInstructionARM::EmulateVLD1Single, 13147 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13148 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13149 &EmulateInstructionARM::EmulateVLD1SingleAll, 13150 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13151 13152 // Store instructions 13153 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13154 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13155 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13156 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"}, 13157 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13158 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13159 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13160 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"}, 13161 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13162 &EmulateInstructionARM::EmulateSTRRegister, 13163 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"}, 13164 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13165 &EmulateInstructionARM::EmulateSTRHRegister, 13166 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"}, 13167 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13168 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 13169 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13170 &EmulateInstructionARM::EmulateSTRBImmARM, 13171 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13172 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13173 &EmulateInstructionARM::EmulateSTRImmARM, 13174 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13175 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13176 &EmulateInstructionARM::EmulateSTRDImm, 13177 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 13178 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13179 &EmulateInstructionARM::EmulateSTRDReg, 13180 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13181 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13182 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13183 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13184 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13185 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13186 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 13187 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13188 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 13189 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13190 &EmulateInstructionARM::EmulateVST1Multiple, 13191 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13192 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13193 &EmulateInstructionARM::EmulateVST1Single, 13194 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13195 13196 // Other instructions 13197 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13198 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13199 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13200 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"}, 13201 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13202 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13203 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13204 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"}, 13205 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13206 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"} 13207 13208 }; 13209 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 13210 13211 for (size_t i = 0; i < k_num_arm_opcodes; ++i) { 13212 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 13213 (g_arm_opcodes[i].variants & arm_isa) != 0) 13214 return &g_arm_opcodes[i]; 13215 } 13216 return nullptr; 13217} 13218 13219EmulateInstructionARM::ARMOpcode * 13220EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode, 13221 uint32_t arm_isa) { 13222 13223 static ARMOpcode g_thumb_opcodes[] = { 13224 // Prologue instructions 13225 13226 // push register(s) 13227 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, 13228 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 13229 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13230 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"}, 13231 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13232 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"}, 13233 13234 // set r7 to point to a stack offset 13235 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13236 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"}, 13237 // copy the stack pointer to r7 13238 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, 13239 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"}, 13240 // move from high register to low register (comes after "mov r7, sp" to 13241 // resolve ambiguity) 13242 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, 13243 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"}, 13244 13245 // PC-relative load into register (see also EmulateADDSPRm) 13246 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13247 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 13248 13249 // adjust the stack pointer 13250 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, 13251 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 13252 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13253 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 13254 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13255 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 13256 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13257 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 13258 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13259 &EmulateInstructionARM::EmulateSUBSPReg, 13260 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 13261 13262 // vector push consecutive extension register(s) 13263 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13264 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 13265 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13266 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 13267 13268 // Epilogue instructions 13269 13270 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13271 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 13272 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13273 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 13274 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13275 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 13276 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13277 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"}, 13278 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13279 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"}, 13280 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13281 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 13282 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13283 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 13284 13285 // Supervisor Call (previously Software Interrupt) 13286 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13287 &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 13288 13289 // If Then makes up to four following instructions conditional. 13290 // The next 5 opcode _must_ come before the if then instruction 13291 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13292 &EmulateInstructionARM::EmulateNop, "nop"}, 13293 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13294 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 13295 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13296 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 13297 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13298 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 13299 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13300 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 13301 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13302 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 13303 13304 // Branch instructions 13305 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 13306 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13307 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 13308 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13309 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 13310 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13311 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 13312 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13313 &EmulateInstructionARM::EmulateB, 13314 "b<c>.w #imm8 (outside or last in IT)"}, 13315 // J1 == J2 == 1 13316 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, 13317 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 13318 // J1 == J2 == 1 13319 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, 13320 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 13321 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, 13322 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 13323 // for example, "bx lr" 13324 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, 13325 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 13326 // bxj 13327 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, 13328 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 13329 // compare and branch 13330 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13331 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 13332 // table branch byte 13333 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13334 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 13335 // table branch halfword 13336 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13337 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 13338 13339 // Data-processing instructions 13340 // adc (immediate) 13341 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13342 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 13343 // adc (register) 13344 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, 13345 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 13346 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13347 &EmulateInstructionARM::EmulateADCReg, 13348 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13349 // add (register) 13350 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13351 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 13352 // Make sure "add sp, <Rm>" comes before this instruction, so there's no 13353 // ambiguity decoding the two. 13354 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, 13355 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 13356 // adr 13357 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13358 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13359 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13360 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 13361 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13362 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13363 // and (immediate) 13364 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13365 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 13366 // and (register) 13367 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13368 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 13369 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13370 &EmulateInstructionARM::EmulateANDReg, 13371 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13372 // bic (immediate) 13373 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13374 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 13375 // bic (register) 13376 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, 13377 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 13378 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13379 &EmulateInstructionARM::EmulateBICReg, 13380 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13381 // eor (immediate) 13382 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13383 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 13384 // eor (register) 13385 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, 13386 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 13387 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13388 &EmulateInstructionARM::EmulateEORReg, 13389 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13390 // orr (immediate) 13391 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13392 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 13393 // orr (register) 13394 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, 13395 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 13396 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13397 &EmulateInstructionARM::EmulateORRReg, 13398 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13399 // rsb (immediate) 13400 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, 13401 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 13402 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13403 &EmulateInstructionARM::EmulateRSBImm, 13404 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 13405 // rsb (register) 13406 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13407 &EmulateInstructionARM::EmulateRSBReg, 13408 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13409 // sbc (immediate) 13410 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13411 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13412 // sbc (register) 13413 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, 13414 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 13415 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13416 &EmulateInstructionARM::EmulateSBCReg, 13417 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13418 // add (immediate, Thumb) 13419 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13420 &EmulateInstructionARM::EmulateADDImmThumb, 13421 "adds|add<c> <Rd>,<Rn>,#<imm3>"}, 13422 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13423 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"}, 13424 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13425 &EmulateInstructionARM::EmulateADDImmThumb, 13426 "add{s}<c>.w <Rd>,<Rn>,#<const>"}, 13427 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13428 &EmulateInstructionARM::EmulateADDImmThumb, 13429 "addw<c> <Rd>,<Rn>,#<imm12>"}, 13430 // sub (immediate, Thumb) 13431 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13432 &EmulateInstructionARM::EmulateSUBImmThumb, 13433 "subs|sub<c> <Rd>, <Rn> #imm3"}, 13434 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, 13435 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 13436 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13437 &EmulateInstructionARM::EmulateSUBImmThumb, 13438 "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 13439 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13440 &EmulateInstructionARM::EmulateSUBImmThumb, 13441 "subw<c> <Rd>, <Rn>, #imm12"}, 13442 // sub (sp minus immediate) 13443 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13444 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 13445 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13446 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 13447 // sub (register) 13448 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13449 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 13450 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13451 &EmulateInstructionARM::EmulateSUBReg, 13452 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 13453 // teq (immediate) 13454 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13455 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 13456 // teq (register) 13457 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13458 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13459 // tst (immediate) 13460 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13461 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 13462 // tst (register) 13463 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, 13464 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 13465 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13466 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 13467 13468 // move from high register to high register 13469 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, 13470 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 13471 // move from low register to low register 13472 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13473 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 13474 // mov{s}<c>.w <Rd>, <Rm> 13475 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13476 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 13477 // move immediate 13478 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13479 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 13480 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13481 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 13482 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13483 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 13484 // mvn (immediate) 13485 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13486 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 13487 // mvn (register) 13488 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13489 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 13490 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13491 &EmulateInstructionARM::EmulateMVNReg, 13492 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 13493 // cmn (immediate) 13494 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13495 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13496 // cmn (register) 13497 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13498 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 13499 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13500 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13501 // cmp (immediate) 13502 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13503 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 13504 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13505 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 13506 // cmp (register) (Rn and Rm both from r0-r7) 13507 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, 13508 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13509 // cmp (register) (Rn and Rm not both from r0-r7) 13510 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, 13511 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13512 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, 13513 &EmulateInstructionARM::EmulateCMPReg, 13514 "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 13515 // asr (immediate) 13516 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13517 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 13518 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13519 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 13520 // asr (register) 13521 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, 13522 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 13523 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13524 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13525 // lsl (immediate) 13526 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13527 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 13528 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13529 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 13530 // lsl (register) 13531 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13532 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 13533 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13534 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13535 // lsr (immediate) 13536 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13537 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 13538 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13539 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 13540 // lsr (register) 13541 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13542 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 13543 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13544 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13545 // rrx is a special case encoding of ror (immediate) 13546 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13547 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 13548 // ror (immediate) 13549 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13550 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 13551 // ror (register) 13552 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13553 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 13554 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13555 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13556 // mul 13557 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13558 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"}, 13559 // mul 13560 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13561 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"}, 13562 13563 // subs pc, lr and related instructions 13564 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13565 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"}, 13566 13567 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE 13568 // LDM.. Instructions in this table; 13569 // otherwise the wrong instructions will be selected. 13570 13571 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13572 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"}, 13573 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13574 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"}, 13575 13576 // Load instructions 13577 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13578 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13579 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13580 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"}, 13581 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13582 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13583 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13584 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 13585 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13586 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 13587 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13588 &EmulateInstructionARM::EmulateLDRRtRnImm, 13589 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 13590 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13591 &EmulateInstructionARM::EmulateLDRRtRnImm, 13592 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 13593 // Thumb2 PC-relative load into register 13594 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13595 &EmulateInstructionARM::EmulateLDRRtPCRelative, 13596 "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 13597 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13598 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"}, 13599 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13600 &EmulateInstructionARM::EmulateLDRRegister, 13601 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"}, 13602 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13603 &EmulateInstructionARM::EmulateLDRBImmediate, 13604 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"}, 13605 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13606 &EmulateInstructionARM::EmulateLDRBImmediate, 13607 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13608 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13609 &EmulateInstructionARM::EmulateLDRBImmediate, 13610 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"}, 13611 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13612 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"}, 13613 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13614 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"}, 13615 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13616 &EmulateInstructionARM::EmulateLDRBRegister, 13617 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13618 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13619 &EmulateInstructionARM::EmulateLDRHImmediate, 13620 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"}, 13621 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13622 &EmulateInstructionARM::EmulateLDRHImmediate, 13623 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13624 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13625 &EmulateInstructionARM::EmulateLDRHImmediate, 13626 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"}, 13627 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13628 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13629 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13630 &EmulateInstructionARM::EmulateLDRHRegister, 13631 "ldrh<c> <Rt>, [<Rn>,<Rm>]"}, 13632 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13633 &EmulateInstructionARM::EmulateLDRHRegister, 13634 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13635 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13636 &EmulateInstructionARM::EmulateLDRSBImmediate, 13637 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"}, 13638 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13639 &EmulateInstructionARM::EmulateLDRSBImmediate, 13640 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13641 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13642 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"}, 13643 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13644 &EmulateInstructionARM::EmulateLDRSBRegister, 13645 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"}, 13646 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13647 &EmulateInstructionARM::EmulateLDRSBRegister, 13648 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13649 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13650 &EmulateInstructionARM::EmulateLDRSHImmediate, 13651 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"}, 13652 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13653 &EmulateInstructionARM::EmulateLDRSHImmediate, 13654 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13655 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13656 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13657 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13658 &EmulateInstructionARM::EmulateLDRSHRegister, 13659 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"}, 13660 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13661 &EmulateInstructionARM::EmulateLDRSHRegister, 13662 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13663 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13664 &EmulateInstructionARM::EmulateLDRDImmediate, 13665 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 13666 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13667 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13668 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13669 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13670 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13671 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13672 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13673 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 13674 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13675 &EmulateInstructionARM::EmulateVLD1Multiple, 13676 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13677 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13678 &EmulateInstructionARM::EmulateVLD1Single, 13679 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13680 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13681 &EmulateInstructionARM::EmulateVLD1SingleAll, 13682 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13683 13684 // Store instructions 13685 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13686 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13687 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13688 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"}, 13689 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13690 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13691 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13692 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"}, 13693 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13694 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"}, 13695 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13696 &EmulateInstructionARM::EmulateSTRThumb, 13697 "str<c>.w <Rt>, [<Rn>,#<imm12>]"}, 13698 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13699 &EmulateInstructionARM::EmulateSTRThumb, 13700 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"}, 13701 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13702 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"}, 13703 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13704 &EmulateInstructionARM::EmulateSTRRegister, 13705 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"}, 13706 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13707 &EmulateInstructionARM::EmulateSTRBThumb, 13708 "strb<c> <Rt>, [<Rn>, #<imm5>]"}, 13709 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13710 &EmulateInstructionARM::EmulateSTRBThumb, 13711 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"}, 13712 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13713 &EmulateInstructionARM::EmulateSTRBThumb, 13714 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"}, 13715 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13716 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"}, 13717 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13718 &EmulateInstructionARM::EmulateSTRHRegister, 13719 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13720 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13721 &EmulateInstructionARM::EmulateSTREX, 13722 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"}, 13723 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13724 &EmulateInstructionARM::EmulateSTRDImm, 13725 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 13726 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13727 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13728 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13729 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13730 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13731 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13732 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13733 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13734 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13735 &EmulateInstructionARM::EmulateVST1Multiple, 13736 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13737 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13738 &EmulateInstructionARM::EmulateVST1Single, 13739 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13740 13741 // Other instructions 13742 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13743 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"}, 13744 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, 13745 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13746 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13747 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"}, 13748 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13749 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13750 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13751 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"}, 13752 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13753 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13754 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13755 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"}, 13756 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13757 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13758 }; 13759 13760 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 13761 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) { 13762 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 13763 (g_thumb_opcodes[i].variants & arm_isa) != 0) 13764 return &g_thumb_opcodes[i]; 13765 } 13766 return nullptr; 13767} 13768 13769bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) { 13770 m_arch = arch; 13771 m_arm_isa = 0; 13772 const char *arch_cstr = arch.GetArchitectureName(); 13773 if (arch_cstr) { 13774 if (0 == ::strcasecmp(arch_cstr, "armv4t")) 13775 m_arm_isa = ARMv4T; 13776 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) 13777 m_arm_isa = ARMv5TEJ; 13778 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) 13779 m_arm_isa = ARMv5TE; 13780 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) 13781 m_arm_isa = ARMv5T; 13782 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) 13783 m_arm_isa = ARMv6K; 13784 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) 13785 m_arm_isa = ARMv6T2; 13786 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) 13787 m_arm_isa = ARMv7S; 13788 else if (0 == ::strcasecmp(arch_cstr, "arm")) 13789 m_arm_isa = ARMvAll; 13790 else if (0 == ::strcasecmp(arch_cstr, "thumb")) 13791 m_arm_isa = ARMvAll; 13792 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5)) 13793 m_arm_isa = ARMv4; 13794 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5)) 13795 m_arm_isa = ARMv6; 13796 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5)) 13797 m_arm_isa = ARMv7; 13798 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5)) 13799 m_arm_isa = ARMv8; 13800 } 13801 return m_arm_isa != 0; 13802} 13803 13804bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode, 13805 const Address &inst_addr, 13806 Target *target) { 13807 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { 13808 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || 13809 m_arch.IsAlwaysThumbInstructions()) 13810 m_opcode_mode = eModeThumb; 13811 else { 13812 AddressClass addr_class = inst_addr.GetAddressClass(); 13813 13814 if ((addr_class == AddressClass::eCode) || 13815 (addr_class == AddressClass::eUnknown)) 13816 m_opcode_mode = eModeARM; 13817 else if (addr_class == AddressClass::eCodeAlternateISA) 13818 m_opcode_mode = eModeThumb; 13819 else 13820 return false; 13821 } 13822 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions()) 13823 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13824 else 13825 m_opcode_cpsr = CPSR_MODE_USR; 13826 return true; 13827 } 13828 return false; 13829} 13830 13831bool EmulateInstructionARM::ReadInstruction() { 13832 bool success = false; 13833 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric, 13834 LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13835 if (success) { 13836 addr_t pc = 13837 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 13838 LLDB_INVALID_ADDRESS, &success); 13839 if (success) { 13840 Context read_inst_context; 13841 read_inst_context.type = eContextReadOpcode; 13842 read_inst_context.SetNoArgs(); 13843 13844 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) { 13845 m_opcode_mode = eModeThumb; 13846 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13847 13848 if (success) { 13849 if ((thumb_opcode & 0xe000) != 0xe000 || 13850 ((thumb_opcode & 0x1800u) == 0)) { 13851 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder()); 13852 } else { 13853 m_opcode.SetOpcode32( 13854 (thumb_opcode << 16) | 13855 MemARead(read_inst_context, pc + 2, 2, 0, &success), 13856 GetByteOrder()); 13857 } 13858 } 13859 } else { 13860 m_opcode_mode = eModeARM; 13861 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success), 13862 GetByteOrder()); 13863 } 13864 13865 if (!m_ignore_conditions) { 13866 // If we are not ignoreing the conditions then init the it session from 13867 // the current value of cpsr. 13868 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | 13869 Bits32(m_opcode_cpsr, 26, 25); 13870 if (it != 0) 13871 m_it_session.InitIT(it); 13872 } 13873 } 13874 } 13875 if (!success) { 13876 m_opcode_mode = eModeInvalid; 13877 m_addr = LLDB_INVALID_ADDRESS; 13878 } 13879 return success; 13880} 13881 13882uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; } 13883 13884bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) { 13885 // If we are ignoring conditions, then always return true. this allows us to 13886 // iterate over disassembly code and still emulate an instruction even if we 13887 // don't have all the right bits set in the CPSR register... 13888 if (m_ignore_conditions) 13889 return true; 13890 13891 const uint32_t cond = CurrentCond(opcode); 13892 if (cond == UINT32_MAX) 13893 return false; 13894 13895 bool result = false; 13896 switch (UnsignedBits(cond, 3, 1)) { 13897 case 0: 13898 if (m_opcode_cpsr == 0) 13899 result = true; 13900 else 13901 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13902 break; 13903 case 1: 13904 if (m_opcode_cpsr == 0) 13905 result = true; 13906 else 13907 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13908 break; 13909 case 2: 13910 if (m_opcode_cpsr == 0) 13911 result = true; 13912 else 13913 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13914 break; 13915 case 3: 13916 if (m_opcode_cpsr == 0) 13917 result = true; 13918 else 13919 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13920 break; 13921 case 4: 13922 if (m_opcode_cpsr == 0) 13923 result = true; 13924 else 13925 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && 13926 ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13927 break; 13928 case 5: 13929 if (m_opcode_cpsr == 0) 13930 result = true; 13931 else { 13932 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13933 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13934 result = n == v; 13935 } 13936 break; 13937 case 6: 13938 if (m_opcode_cpsr == 0) 13939 result = true; 13940 else { 13941 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13942 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13943 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13944 } 13945 break; 13946 case 7: 13947 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13948 // opcodes different meanings, but always means execution happens. 13949 return true; 13950 } 13951 13952 if (cond & 1) 13953 result = !result; 13954 return result; 13955} 13956 13957uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) { 13958 switch (m_opcode_mode) { 13959 case eModeInvalid: 13960 break; 13961 13962 case eModeARM: 13963 return UnsignedBits(opcode, 31, 28); 13964 13965 case eModeThumb: 13966 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13967 // 'cond' field of the encoding. 13968 { 13969 const uint32_t byte_size = m_opcode.GetByteSize(); 13970 if (byte_size == 2) { 13971 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 13972 return Bits32(opcode, 11, 8); 13973 } else if (byte_size == 4) { 13974 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 && 13975 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) { 13976 return Bits32(opcode, 25, 22); 13977 } 13978 } else 13979 // We have an invalid thumb instruction, let's bail out. 13980 break; 13981 13982 return m_it_session.GetCond(); 13983 } 13984 } 13985 return UINT32_MAX; // Return invalid value 13986} 13987 13988bool EmulateInstructionARM::InITBlock() { 13989 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13990} 13991 13992bool EmulateInstructionARM::LastInITBlock() { 13993 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13994} 13995 13996bool EmulateInstructionARM::BadMode(uint32_t mode) { 13997 13998 switch (mode) { 13999 case 16: 14000 return false; // '10000' 14001 case 17: 14002 return false; // '10001' 14003 case 18: 14004 return false; // '10010' 14005 case 19: 14006 return false; // '10011' 14007 case 22: 14008 return false; // '10110' 14009 case 23: 14010 return false; // '10111' 14011 case 27: 14012 return false; // '11011' 14013 case 31: 14014 return false; // '11111' 14015 default: 14016 return true; 14017 } 14018 return true; 14019} 14020 14021bool EmulateInstructionARM::CurrentModeIsPrivileged() { 14022 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0); 14023 14024 if (BadMode(mode)) 14025 return false; 14026 14027 if (mode == 16) 14028 return false; 14029 14030 return true; 14031} 14032 14033void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask, 14034 bool affect_execstate) { 14035 bool privileged = CurrentModeIsPrivileged(); 14036 14037 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20; 14038 14039 if (BitIsSet(bytemask, 3)) { 14040 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27); 14041 if (affect_execstate) 14042 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24); 14043 } 14044 14045 if (BitIsSet(bytemask, 2)) { 14046 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16); 14047 } 14048 14049 if (BitIsSet(bytemask, 1)) { 14050 if (affect_execstate) 14051 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10); 14052 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9); 14053 if (privileged) 14054 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8); 14055 } 14056 14057 if (BitIsSet(bytemask, 0)) { 14058 if (privileged) 14059 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6); 14060 if (affect_execstate) 14061 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5); 14062 if (privileged) 14063 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0); 14064 } 14065 14066 m_opcode_cpsr = tmp_cpsr; 14067} 14068 14069bool EmulateInstructionARM::BranchWritePC(const Context &context, 14070 uint32_t addr) { 14071 addr_t target; 14072 14073 // Check the current instruction set. 14074 if (CurrentInstrSet() == eModeARM) 14075 target = addr & 0xfffffffc; 14076 else 14077 target = addr & 0xfffffffe; 14078 14079 return WriteRegisterUnsigned(context, eRegisterKindGeneric, 14080 LLDB_REGNUM_GENERIC_PC, target); 14081} 14082 14083// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by 14084// inspecting addr. 14085bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) { 14086 addr_t target; 14087 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 14088 // we want to record it and issue a WriteRegister callback so the clients can 14089 // track the mode changes accordingly. 14090 bool cpsr_changed = false; 14091 14092 if (BitIsSet(addr, 0)) { 14093 if (CurrentInstrSet() != eModeThumb) { 14094 SelectInstrSet(eModeThumb); 14095 cpsr_changed = true; 14096 } 14097 target = addr & 0xfffffffe; 14098 context.SetISA(eModeThumb); 14099 } else if (BitIsClear(addr, 1)) { 14100 if (CurrentInstrSet() != eModeARM) { 14101 SelectInstrSet(eModeARM); 14102 cpsr_changed = true; 14103 } 14104 target = addr & 0xfffffffc; 14105 context.SetISA(eModeARM); 14106 } else 14107 return false; // address<1:0> == '10' => UNPREDICTABLE 14108 14109 if (cpsr_changed) { 14110 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14111 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14112 return false; 14113 } 14114 return WriteRegisterUnsigned(context, eRegisterKindGeneric, 14115 LLDB_REGNUM_GENERIC_PC, target); 14116} 14117 14118// Dispatches to either BXWritePC or BranchWritePC based on architecture 14119// versions. 14120bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) { 14121 if (ArchVersion() >= ARMv5T) 14122 return BXWritePC(context, addr); 14123 else 14124 return BranchWritePC((const Context)context, addr); 14125} 14126 14127// Dispatches to either BXWritePC or BranchWritePC based on architecture 14128// versions and current instruction set. 14129bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) { 14130 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 14131 return BXWritePC(context, addr); 14132 else 14133 return BranchWritePC((const Context)context, addr); 14134} 14135 14136EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() { 14137 return m_opcode_mode; 14138} 14139 14140// Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 14141// ReadInstruction() is performed. This function has a side effect of updating 14142// the m_new_inst_cpsr member variable if necessary. 14143bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) { 14144 m_new_inst_cpsr = m_opcode_cpsr; 14145 switch (arm_or_thumb) { 14146 default: 14147 return false; 14148 case eModeARM: 14149 // Clear the T bit. 14150 m_new_inst_cpsr &= ~MASK_CPSR_T; 14151 break; 14152 case eModeThumb: 14153 // Set the T bit. 14154 m_new_inst_cpsr |= MASK_CPSR_T; 14155 break; 14156 } 14157 return true; 14158} 14159 14160// This function returns TRUE if the processor currently provides support for 14161// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 14162// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 14163bool EmulateInstructionARM::UnalignedSupport() { 14164 return (ArchVersion() >= ARMv7); 14165} 14166 14167// The main addition and subtraction instructions can produce status 14168// information about both unsigned carry and signed overflow conditions. This 14169// status information can be used to synthesize multi-word additions and 14170// subtractions. 14171EmulateInstructionARM::AddWithCarryResult 14172EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) { 14173 uint32_t result; 14174 uint8_t carry_out; 14175 uint8_t overflow; 14176 14177 uint64_t unsigned_sum = x + y + carry_in; 14178 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 14179 14180 result = UnsignedBits(unsigned_sum, 31, 0); 14181 // carry_out = (result == unsigned_sum ? 0 : 1); 14182 overflow = ((int32_t)result == signed_sum ? 0 : 1); 14183 14184 if (carry_in) 14185 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0; 14186 else 14187 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0; 14188 14189 AddWithCarryResult res = {result, carry_out, overflow}; 14190 return res; 14191} 14192 14193uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) { 14194 lldb::RegisterKind reg_kind; 14195 uint32_t reg_num; 14196 switch (num) { 14197 case SP_REG: 14198 reg_kind = eRegisterKindGeneric; 14199 reg_num = LLDB_REGNUM_GENERIC_SP; 14200 break; 14201 case LR_REG: 14202 reg_kind = eRegisterKindGeneric; 14203 reg_num = LLDB_REGNUM_GENERIC_RA; 14204 break; 14205 case PC_REG: 14206 reg_kind = eRegisterKindGeneric; 14207 reg_num = LLDB_REGNUM_GENERIC_PC; 14208 break; 14209 default: 14210 if (num < SP_REG) { 14211 reg_kind = eRegisterKindDWARF; 14212 reg_num = dwarf_r0 + num; 14213 } else { 14214 // assert(0 && "Invalid register number"); 14215 *success = false; 14216 return UINT32_MAX; 14217 } 14218 break; 14219 } 14220 14221 // Read our register. 14222 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success); 14223 14224 // When executing an ARM instruction , PC reads as the address of the current 14225 // instruction plus 8. When executing a Thumb instruction , PC reads as the 14226 // address of the current instruction plus 4. 14227 if (num == 15) { 14228 if (CurrentInstrSet() == eModeARM) 14229 val += 8; 14230 else 14231 val += 4; 14232 } 14233 14234 return val; 14235} 14236 14237// Write the result to the ARM core register Rd, and optionally update the 14238// condition flags based on the result. 14239// 14240// This helper method tries to encapsulate the following pseudocode from the 14241// ARM Architecture Reference Manual: 14242// 14243// if d == 15 then // Can only occur for encoding A1 14244// ALUWritePC(result); // setflags is always FALSE here 14245// else 14246// R[d] = result; 14247// if setflags then 14248// APSR.N = result<31>; 14249// APSR.Z = IsZeroBit(result); 14250// APSR.C = carry; 14251// // APSR.V unchanged 14252// 14253// In the above case, the API client does not pass in the overflow arg, which 14254// defaults to ~0u. 14255bool EmulateInstructionARM::WriteCoreRegOptionalFlags( 14256 Context &context, const uint32_t result, const uint32_t Rd, bool setflags, 14257 const uint32_t carry, const uint32_t overflow) { 14258 if (Rd == 15) { 14259 if (!ALUWritePC(context, result)) 14260 return false; 14261 } else { 14262 lldb::RegisterKind reg_kind; 14263 uint32_t reg_num; 14264 switch (Rd) { 14265 case SP_REG: 14266 reg_kind = eRegisterKindGeneric; 14267 reg_num = LLDB_REGNUM_GENERIC_SP; 14268 break; 14269 case LR_REG: 14270 reg_kind = eRegisterKindGeneric; 14271 reg_num = LLDB_REGNUM_GENERIC_RA; 14272 break; 14273 default: 14274 reg_kind = eRegisterKindDWARF; 14275 reg_num = dwarf_r0 + Rd; 14276 } 14277 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result)) 14278 return false; 14279 if (setflags) 14280 return WriteFlags(context, result, carry, overflow); 14281 } 14282 return true; 14283} 14284 14285// This helper method tries to encapsulate the following pseudocode from the 14286// ARM Architecture Reference Manual: 14287// 14288// APSR.N = result<31>; 14289// APSR.Z = IsZeroBit(result); 14290// APSR.C = carry; 14291// APSR.V = overflow 14292// 14293// Default arguments can be specified for carry and overflow parameters, which 14294// means not to update the respective flags. 14295bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result, 14296 const uint32_t carry, 14297 const uint32_t overflow) { 14298 m_new_inst_cpsr = m_opcode_cpsr; 14299 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 14300 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 14301 if (carry != ~0u) 14302 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 14303 if (overflow != ~0u) 14304 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 14305 if (m_new_inst_cpsr != m_opcode_cpsr) { 14306 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14307 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14308 return false; 14309 } 14310 return true; 14311} 14312 14313bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) { 14314 ARMOpcode *opcode_data = nullptr; 14315 14316 if (m_opcode_mode == eModeThumb) 14317 opcode_data = 14318 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14319 else if (m_opcode_mode == eModeARM) 14320 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14321 14322 const bool auto_advance_pc = 14323 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 14324 m_ignore_conditions = 14325 evaluate_options & eEmulateInstructionOptionIgnoreConditions; 14326 14327 bool success = false; 14328 if (m_opcode_cpsr == 0 || !m_ignore_conditions) { 14329 m_opcode_cpsr = 14330 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 14331 } 14332 14333 // Only return false if we are unable to read the CPSR if we care about 14334 // conditions 14335 if (!success && !m_ignore_conditions) 14336 return false; 14337 14338 uint32_t orig_pc_value = 0; 14339 if (auto_advance_pc) { 14340 orig_pc_value = 14341 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14342 if (!success) 14343 return false; 14344 } 14345 14346 // Call the Emulate... function if we managed to decode the opcode. 14347 if (opcode_data) { 14348 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(), 14349 opcode_data->encoding); 14350 if (!success) 14351 return false; 14352 } 14353 14354 // Advance the ITSTATE bits to their values for the next instruction if we 14355 // haven't just executed an IT instruction what initialized it. 14356 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() && 14357 (opcode_data == nullptr || 14358 opcode_data->callback != &EmulateInstructionARM::EmulateIT)) 14359 m_it_session.ITAdvance(); 14360 14361 if (auto_advance_pc) { 14362 uint32_t after_pc_value = 14363 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14364 if (!success) 14365 return false; 14366 14367 if (auto_advance_pc && (after_pc_value == orig_pc_value)) { 14368 after_pc_value += m_opcode.GetByteSize(); 14369 14370 EmulateInstruction::Context context; 14371 context.type = eContextAdvancePC; 14372 context.SetNoArgs(); 14373 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc, 14374 after_pc_value)) 14375 return false; 14376 } 14377 } 14378 return true; 14379} 14380 14381EmulateInstruction::InstructionCondition 14382EmulateInstructionARM::GetInstructionCondition() { 14383 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32()); 14384 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX) 14385 return EmulateInstruction::UnconditionalCondition; 14386 return cond; 14387} 14388 14389bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, 14390 OptionValueDictionary *test_data) { 14391 if (!test_data) { 14392 out_stream->Printf("TestEmulation: Missing test data.\n"); 14393 return false; 14394 } 14395 14396 static ConstString opcode_key("opcode"); 14397 static ConstString before_key("before_state"); 14398 static ConstString after_key("after_state"); 14399 14400 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key); 14401 14402 uint32_t test_opcode; 14403 if ((value_sp.get() == nullptr) || 14404 (value_sp->GetType() != OptionValue::eTypeUInt64)) { 14405 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n"); 14406 return false; 14407 } 14408 test_opcode = value_sp->GetUInt64Value(); 14409 14410 if (arch.GetTriple().getArch() == llvm::Triple::thumb || 14411 arch.IsAlwaysThumbInstructions()) { 14412 m_opcode_mode = eModeThumb; 14413 if (test_opcode < 0x10000) 14414 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder()); 14415 else 14416 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14417 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) { 14418 m_opcode_mode = eModeARM; 14419 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14420 } else { 14421 out_stream->Printf("TestEmulation: Invalid arch.\n"); 14422 return false; 14423 } 14424 14425 EmulationStateARM before_state; 14426 EmulationStateARM after_state; 14427 14428 value_sp = test_data->GetValueForKey(before_key); 14429 if ((value_sp.get() == nullptr) || 14430 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14431 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n"); 14432 return false; 14433 } 14434 14435 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary(); 14436 if (!before_state.LoadStateFromDictionary(state_dictionary)) { 14437 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n"); 14438 return false; 14439 } 14440 14441 value_sp = test_data->GetValueForKey(after_key); 14442 if ((value_sp.get() == nullptr) || 14443 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14444 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n"); 14445 return false; 14446 } 14447 14448 state_dictionary = value_sp->GetAsDictionary(); 14449 if (!after_state.LoadStateFromDictionary(state_dictionary)) { 14450 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n"); 14451 return false; 14452 } 14453 14454 SetBaton((void *)&before_state); 14455 SetCallbacks(&EmulationStateARM::ReadPseudoMemory, 14456 &EmulationStateARM::WritePseudoMemory, 14457 &EmulationStateARM::ReadPseudoRegister, 14458 &EmulationStateARM::WritePseudoRegister); 14459 14460 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 14461 if (!success) { 14462 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n"); 14463 return false; 14464 } 14465 14466 success = before_state.CompareState(after_state); 14467 if (!success) 14468 out_stream->Printf( 14469 "TestEmulation: 'before' and 'after' states do not match.\n"); 14470 14471 return success; 14472} 14473// 14474// 14475// const char * 14476// EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 14477//{ 14478// if (reg_kind == eRegisterKindGeneric) 14479// { 14480// switch (reg_num) 14481// { 14482// case LLDB_REGNUM_GENERIC_PC: return "pc"; 14483// case LLDB_REGNUM_GENERIC_SP: return "sp"; 14484// case LLDB_REGNUM_GENERIC_FP: return "fp"; 14485// case LLDB_REGNUM_GENERIC_RA: return "lr"; 14486// case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 14487// default: return NULL; 14488// } 14489// } 14490// else if (reg_kind == eRegisterKindDWARF) 14491// { 14492// return GetARMDWARFRegisterName (reg_num); 14493// } 14494// return NULL; 14495//} 14496// 14497bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { 14498 unwind_plan.Clear(); 14499 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 14500 14501 UnwindPlan::RowSP row(new UnwindPlan::Row); 14502 14503 // Our previous Call Frame Address is the stack pointer 14504 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0); 14505 14506 unwind_plan.AppendRow(row); 14507 unwind_plan.SetSourceName("EmulateInstructionARM"); 14508 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 14509 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 14510 unwind_plan.SetReturnAddressRegister(dwarf_lr); 14511 return true; 14512} 14513