1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include <stdlib.h> 11 12 #include "EmulateInstructionARM.h" 13 #include "EmulationStateARM.h" 14 #include "lldb/Core/ArchSpec.h" 15 #include "lldb/Core/Address.h" 16 #include "lldb/Core/ConstString.h" 17 #include "lldb/Core/PluginManager.h" 18 #include "lldb/Core/Stream.h" 19 #include "lldb/Interpreter/OptionValueArray.h" 20 #include "lldb/Interpreter/OptionValueDictionary.h" 21 #include "lldb/Symbol/UnwindPlan.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" // for SignExtend32 template function 29 // and countTrailingZeros function 30 31 using namespace lldb; 32 using namespace lldb_private; 33 34 // Convenient macro definitions. 35 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 36 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 37 38 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 39 40 //---------------------------------------------------------------------- 41 // 42 // ITSession implementation 43 // 44 //---------------------------------------------------------------------- 45 46 // A8.6.50 47 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 48 static uint32_t 49 CountITSize (uint32_t ITMask) { 50 // First count the trailing zeros of the IT mask. 51 uint32_t TZ = llvm::countTrailingZeros(ITMask); 52 if (TZ > 3) 53 { 54 #ifdef LLDB_CONFIGURATION_DEBUG 55 printf("Encoding error: IT Mask '0000'\n"); 56 #endif 57 return 0; 58 } 59 return (4 - TZ); 60 } 61 62 // Init ITState. Note that at least one bit is always 1 in mask. 63 bool ITSession::InitIT(uint32_t bits7_0) 64 { 65 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 66 if (ITCounter == 0) 67 return false; 68 69 // A8.6.50 IT 70 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 71 if (FirstCond == 0xF) 72 { 73 #ifdef LLDB_CONFIGURATION_DEBUG 74 printf("Encoding error: IT FirstCond '1111'\n"); 75 #endif 76 return false; 77 } 78 if (FirstCond == 0xE && ITCounter != 1) 79 { 80 #ifdef LLDB_CONFIGURATION_DEBUG 81 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 82 #endif 83 return false; 84 } 85 86 ITState = bits7_0; 87 return true; 88 } 89 90 // Update ITState if necessary. 91 void ITSession::ITAdvance() 92 { 93 //assert(ITCounter); 94 --ITCounter; 95 if (ITCounter == 0) 96 ITState = 0; 97 else 98 { 99 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 100 SetBits32(ITState, 4, 0, NewITState4_0); 101 } 102 } 103 104 // Return true if we're inside an IT Block. 105 bool ITSession::InITBlock() 106 { 107 return ITCounter != 0; 108 } 109 110 // Return true if we're the last instruction inside an IT Block. 111 bool ITSession::LastInITBlock() 112 { 113 return ITCounter == 1; 114 } 115 116 // Get condition bits for the current thumb instruction. 117 uint32_t ITSession::GetCond() 118 { 119 if (InITBlock()) 120 return Bits32(ITState, 7, 4); 121 else 122 return COND_AL; 123 } 124 125 // ARM constants used during decoding 126 #define REG_RD 0 127 #define LDM_REGLIST 1 128 #define SP_REG 13 129 #define LR_REG 14 130 #define PC_REG 15 131 #define PC_REGLIST_BIT 0x8000 132 133 #define ARMv4 (1u << 0) 134 #define ARMv4T (1u << 1) 135 #define ARMv5T (1u << 2) 136 #define ARMv5TE (1u << 3) 137 #define ARMv5TEJ (1u << 4) 138 #define ARMv6 (1u << 5) 139 #define ARMv6K (1u << 6) 140 #define ARMv6T2 (1u << 7) 141 #define ARMv7 (1u << 8) 142 #define ARMv7S (1u << 9) 143 #define ARMv8 (1u << 10) 144 #define ARMvAll (0xffffffffu) 145 146 #define ARMV4T_ABOVE (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 147 #define ARMV5_ABOVE (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 148 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 149 #define ARMV5J_ABOVE (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 150 #define ARMV6_ABOVE (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8) 151 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8) 152 #define ARMV7_ABOVE (ARMv7|ARMv7S|ARMv8) 153 154 #define No_VFP 0 155 #define VFPv1 (1u << 1) 156 #define VFPv2 (1u << 2) 157 #define VFPv3 (1u << 3) 158 #define AdvancedSIMD (1u << 4) 159 160 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 161 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 162 #define VFPv2v3 (VFPv2 | VFPv3) 163 164 //---------------------------------------------------------------------- 165 // 166 // EmulateInstructionARM implementation 167 // 168 //---------------------------------------------------------------------- 169 170 void 171 EmulateInstructionARM::Initialize () 172 { 173 PluginManager::RegisterPlugin (GetPluginNameStatic (), 174 GetPluginDescriptionStatic (), 175 CreateInstance); 176 } 177 178 void 179 EmulateInstructionARM::Terminate () 180 { 181 PluginManager::UnregisterPlugin (CreateInstance); 182 } 183 184 ConstString 185 EmulateInstructionARM::GetPluginNameStatic () 186 { 187 static ConstString g_name("arm"); 188 return g_name; 189 } 190 191 const char * 192 EmulateInstructionARM::GetPluginDescriptionStatic () 193 { 194 return "Emulate instructions for the ARM architecture."; 195 } 196 197 EmulateInstruction * 198 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type) 199 { 200 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(inst_type)) 201 { 202 if (arch.GetTriple().getArch() == llvm::Triple::arm) 203 { 204 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 205 206 if (emulate_insn_ap.get()) 207 return emulate_insn_ap.release(); 208 } 209 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 210 { 211 std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch)); 212 213 if (emulate_insn_ap.get()) 214 return emulate_insn_ap.release(); 215 } 216 } 217 218 return NULL; 219 } 220 221 bool 222 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch) 223 { 224 if (arch.GetTriple().getArch () == llvm::Triple::arm) 225 return true; 226 else if (arch.GetTriple().getArch () == llvm::Triple::thumb) 227 return true; 228 229 return false; 230 } 231 232 // Write "bits (32) UNKNOWN" to memory address "address". Helper function for many ARM instructions. 233 bool 234 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address) 235 { 236 EmulateInstruction::Context context; 237 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 238 context.SetNoArgs (); 239 240 uint32_t random_data = rand (); 241 const uint32_t addr_byte_size = GetAddressByteSize(); 242 243 if (!MemAWrite (context, address, random_data, addr_byte_size)) 244 return false; 245 246 return true; 247 } 248 249 // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM instructions. 250 bool 251 EmulateInstructionARM::WriteBits32Unknown (int n) 252 { 253 EmulateInstruction::Context context; 254 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 255 context.SetNoArgs (); 256 257 bool success; 258 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 259 260 if (!success) 261 return false; 262 263 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 264 return false; 265 266 return true; 267 } 268 269 bool 270 EmulateInstructionARM::GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterInfo ®_info) 271 { 272 if (reg_kind == eRegisterKindGeneric) 273 { 274 switch (reg_num) 275 { 276 case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break; 277 case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break; 278 case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break; 279 case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break; 280 case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break; 281 default: return false; 282 } 283 } 284 285 if (reg_kind == eRegisterKindDWARF) 286 return GetARMDWARFRegisterInfo(reg_num, reg_info); 287 return false; 288 } 289 290 uint32_t 291 EmulateInstructionARM::GetFramePointerRegisterNumber () const 292 { 293 if (m_arch.GetTriple().getEnvironment() == llvm::Triple::Android) 294 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android 295 296 bool is_apple = false; 297 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 298 is_apple = true; 299 switch (m_arch.GetTriple().getOS()) 300 { 301 case llvm::Triple::Darwin: 302 case llvm::Triple::MacOSX: 303 case llvm::Triple::IOS: 304 is_apple = true; 305 break; 306 default: 307 break; 308 } 309 310 /* On Apple iOS et al, the frame pointer register is always r7. 311 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 312 */ 313 314 uint32_t fp_regnum = 11; 315 316 if (is_apple) 317 fp_regnum = 7; 318 319 if (m_opcode_mode == eModeThumb) 320 fp_regnum = 7; 321 322 return fp_regnum; 323 } 324 325 uint32_t 326 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 327 { 328 bool is_apple = false; 329 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 330 is_apple = true; 331 switch (m_arch.GetTriple().getOS()) 332 { 333 case llvm::Triple::Darwin: 334 case llvm::Triple::MacOSX: 335 case llvm::Triple::IOS: 336 is_apple = true; 337 break; 338 default: 339 break; 340 } 341 342 /* On Apple iOS et al, the frame pointer register is always r7. 343 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 344 */ 345 346 uint32_t fp_regnum = dwarf_r11; 347 348 if (is_apple) 349 fp_regnum = dwarf_r7; 350 351 if (m_opcode_mode == eModeThumb) 352 fp_regnum = dwarf_r7; 353 354 return fp_regnum; 355 } 356 357 // Push Multiple Registers stores multiple registers to the stack, storing to 358 // consecutive memory locations ending just below the address in SP, and updates 359 // SP to point to the start of the stored data. 360 bool 361 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 362 { 363 #if 0 364 // ARM pseudo code... 365 if (ConditionPassed()) 366 { 367 EncodingSpecificOperations(); 368 NullCheckIfThumbEE(13); 369 address = SP - 4*BitCount(registers); 370 371 for (i = 0 to 14) 372 { 373 if (registers<i> == '1') 374 { 375 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 376 MemA[address,4] = bits(32) UNKNOWN; 377 else 378 MemA[address,4] = R[i]; 379 address = address + 4; 380 } 381 } 382 383 if (registers<15> == '1') // Only possible for encoding A1 or A2 384 MemA[address,4] = PCStoreValue(); 385 386 SP = SP - 4*BitCount(registers); 387 } 388 #endif 389 390 bool success = false; 391 if (ConditionPassed(opcode)) 392 { 393 const uint32_t addr_byte_size = GetAddressByteSize(); 394 const addr_t sp = ReadCoreReg (SP_REG, &success); 395 if (!success) 396 return false; 397 uint32_t registers = 0; 398 uint32_t Rt; // the source register 399 switch (encoding) { 400 case eEncodingT1: 401 registers = Bits32(opcode, 7, 0); 402 // The M bit represents LR. 403 if (Bit32(opcode, 8)) 404 registers |= (1u << 14); 405 // if BitCount(registers) < 1 then UNPREDICTABLE; 406 if (BitCount(registers) < 1) 407 return false; 408 break; 409 case eEncodingT2: 410 // Ignore bits 15 & 13. 411 registers = Bits32(opcode, 15, 0) & ~0xa000; 412 // if BitCount(registers) < 2 then UNPREDICTABLE; 413 if (BitCount(registers) < 2) 414 return false; 415 break; 416 case eEncodingT3: 417 Rt = Bits32(opcode, 15, 12); 418 // if BadReg(t) then UNPREDICTABLE; 419 if (BadReg(Rt)) 420 return false; 421 registers = (1u << Rt); 422 break; 423 case eEncodingA1: 424 registers = Bits32(opcode, 15, 0); 425 // Instead of return false, let's handle the following case as well, 426 // which amounts to pushing one reg onto the full descending stacks. 427 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 428 break; 429 case eEncodingA2: 430 Rt = Bits32(opcode, 15, 12); 431 // if t == 13 then UNPREDICTABLE; 432 if (Rt == dwarf_sp) 433 return false; 434 registers = (1u << Rt); 435 break; 436 default: 437 return false; 438 } 439 addr_t sp_offset = addr_byte_size * BitCount (registers); 440 addr_t addr = sp - sp_offset; 441 uint32_t i; 442 443 EmulateInstruction::Context context; 444 context.type = EmulateInstruction::eContextPushRegisterOnStack; 445 RegisterInfo reg_info; 446 RegisterInfo sp_reg; 447 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 448 for (i=0; i<15; ++i) 449 { 450 if (BitIsSet (registers, i)) 451 { 452 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 453 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 454 uint32_t reg_value = ReadCoreReg(i, &success); 455 if (!success) 456 return false; 457 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 458 return false; 459 addr += addr_byte_size; 460 } 461 } 462 463 if (BitIsSet (registers, 15)) 464 { 465 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 466 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 467 const uint32_t pc = ReadCoreReg(PC_REG, &success); 468 if (!success) 469 return false; 470 if (!MemAWrite (context, addr, pc, addr_byte_size)) 471 return false; 472 } 473 474 context.type = EmulateInstruction::eContextAdjustStackPointer; 475 context.SetImmediateSigned (-sp_offset); 476 477 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 478 return false; 479 } 480 return true; 481 } 482 483 // Pop Multiple Registers loads multiple registers from the stack, loading from 484 // consecutive memory locations staring at the address in SP, and updates 485 // SP to point just above the loaded data. 486 bool 487 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 488 { 489 #if 0 490 // ARM pseudo code... 491 if (ConditionPassed()) 492 { 493 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 494 address = SP; 495 for i = 0 to 14 496 if registers<i> == '1' then 497 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 498 if registers<15> == '1' then 499 if UnalignedAllowed then 500 LoadWritePC(MemU[address,4]); 501 else 502 LoadWritePC(MemA[address,4]); 503 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 504 if registers<13> == '1' then SP = bits(32) UNKNOWN; 505 } 506 #endif 507 508 bool success = false; 509 510 if (ConditionPassed(opcode)) 511 { 512 const uint32_t addr_byte_size = GetAddressByteSize(); 513 const addr_t sp = ReadCoreReg (SP_REG, &success); 514 if (!success) 515 return false; 516 uint32_t registers = 0; 517 uint32_t Rt; // the destination register 518 switch (encoding) { 519 case eEncodingT1: 520 registers = Bits32(opcode, 7, 0); 521 // The P bit represents PC. 522 if (Bit32(opcode, 8)) 523 registers |= (1u << 15); 524 // if BitCount(registers) < 1 then UNPREDICTABLE; 525 if (BitCount(registers) < 1) 526 return false; 527 break; 528 case eEncodingT2: 529 // Ignore bit 13. 530 registers = Bits32(opcode, 15, 0) & ~0x2000; 531 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 532 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 533 return false; 534 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 535 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 536 return false; 537 break; 538 case eEncodingT3: 539 Rt = Bits32(opcode, 15, 12); 540 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 541 if (Rt == 13) 542 return false; 543 if (Rt == 15 && InITBlock() && !LastInITBlock()) 544 return false; 545 registers = (1u << Rt); 546 break; 547 case eEncodingA1: 548 registers = Bits32(opcode, 15, 0); 549 // Instead of return false, let's handle the following case as well, 550 // which amounts to popping one reg from the full descending stacks. 551 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 552 553 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 554 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 555 return false; 556 break; 557 case eEncodingA2: 558 Rt = Bits32(opcode, 15, 12); 559 // if t == 13 then UNPREDICTABLE; 560 if (Rt == dwarf_sp) 561 return false; 562 registers = (1u << Rt); 563 break; 564 default: 565 return false; 566 } 567 addr_t sp_offset = addr_byte_size * BitCount (registers); 568 addr_t addr = sp; 569 uint32_t i, data; 570 571 EmulateInstruction::Context context; 572 context.type = EmulateInstruction::eContextPopRegisterOffStack; 573 574 RegisterInfo sp_reg; 575 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 576 577 for (i=0; i<15; ++i) 578 { 579 if (BitIsSet (registers, i)) 580 { 581 context.SetRegisterPlusOffset (sp_reg, addr - sp); 582 data = MemARead(context, addr, 4, 0, &success); 583 if (!success) 584 return false; 585 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 586 return false; 587 addr += addr_byte_size; 588 } 589 } 590 591 if (BitIsSet (registers, 15)) 592 { 593 context.SetRegisterPlusOffset (sp_reg, addr - sp); 594 data = MemARead(context, addr, 4, 0, &success); 595 if (!success) 596 return false; 597 // In ARMv5T and above, this is an interworking branch. 598 if (!LoadWritePC(context, data)) 599 return false; 600 //addr += addr_byte_size; 601 } 602 603 context.type = EmulateInstruction::eContextAdjustStackPointer; 604 context.SetImmediateSigned (sp_offset); 605 606 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 607 return false; 608 } 609 return true; 610 } 611 612 // Set r7 or ip to point to saved value residing within the stack. 613 // ADD (SP plus immediate) 614 bool 615 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 616 { 617 #if 0 618 // ARM pseudo code... 619 if (ConditionPassed()) 620 { 621 EncodingSpecificOperations(); 622 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 623 if d == 15 then 624 ALUWritePC(result); // setflags is always FALSE here 625 else 626 R[d] = result; 627 if setflags then 628 APSR.N = result<31>; 629 APSR.Z = IsZeroBit(result); 630 APSR.C = carry; 631 APSR.V = overflow; 632 } 633 #endif 634 635 bool success = false; 636 637 if (ConditionPassed(opcode)) 638 { 639 const addr_t sp = ReadCoreReg (SP_REG, &success); 640 if (!success) 641 return false; 642 uint32_t Rd; // the destination register 643 uint32_t imm32; 644 switch (encoding) { 645 case eEncodingT1: 646 Rd = 7; 647 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 648 break; 649 case eEncodingA1: 650 Rd = Bits32(opcode, 15, 12); 651 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 652 break; 653 default: 654 return false; 655 } 656 addr_t sp_offset = imm32; 657 addr_t addr = sp + sp_offset; // a pointer to the stack area 658 659 EmulateInstruction::Context context; 660 if (Rd == GetFramePointerRegisterNumber()) 661 context.type = eContextSetFramePointer; 662 else 663 context.type = EmulateInstruction::eContextRegisterPlusOffset; 664 RegisterInfo sp_reg; 665 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 666 context.SetRegisterPlusOffset (sp_reg, sp_offset); 667 668 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 669 return false; 670 } 671 return true; 672 } 673 674 // Set r7 or ip to the current stack pointer. 675 // MOV (register) 676 bool 677 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 678 { 679 #if 0 680 // ARM pseudo code... 681 if (ConditionPassed()) 682 { 683 EncodingSpecificOperations(); 684 result = R[m]; 685 if d == 15 then 686 ALUWritePC(result); // setflags is always FALSE here 687 else 688 R[d] = result; 689 if setflags then 690 APSR.N = result<31>; 691 APSR.Z = IsZeroBit(result); 692 // APSR.C unchanged 693 // APSR.V unchanged 694 } 695 #endif 696 697 bool success = false; 698 699 if (ConditionPassed(opcode)) 700 { 701 const addr_t sp = ReadCoreReg (SP_REG, &success); 702 if (!success) 703 return false; 704 uint32_t Rd; // the destination register 705 switch (encoding) { 706 case eEncodingT1: 707 Rd = 7; 708 break; 709 case eEncodingA1: 710 Rd = 12; 711 break; 712 default: 713 return false; 714 } 715 716 EmulateInstruction::Context context; 717 if (Rd == GetFramePointerRegisterNumber()) 718 context.type = EmulateInstruction::eContextSetFramePointer; 719 else 720 context.type = EmulateInstruction::eContextRegisterPlusOffset; 721 RegisterInfo sp_reg; 722 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 723 context.SetRegisterPlusOffset (sp_reg, 0); 724 725 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 726 return false; 727 } 728 return true; 729 } 730 731 // Move from high register (r8-r15) to low register (r0-r7). 732 // MOV (register) 733 bool 734 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 735 { 736 return EmulateMOVRdRm (opcode, encoding); 737 } 738 739 // Move from register to register. 740 // MOV (register) 741 bool 742 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 743 { 744 #if 0 745 // ARM pseudo code... 746 if (ConditionPassed()) 747 { 748 EncodingSpecificOperations(); 749 result = R[m]; 750 if d == 15 then 751 ALUWritePC(result); // setflags is always FALSE here 752 else 753 R[d] = result; 754 if setflags then 755 APSR.N = result<31>; 756 APSR.Z = IsZeroBit(result); 757 // APSR.C unchanged 758 // APSR.V unchanged 759 } 760 #endif 761 762 bool success = false; 763 764 if (ConditionPassed(opcode)) 765 { 766 uint32_t Rm; // the source register 767 uint32_t Rd; // the destination register 768 bool setflags; 769 switch (encoding) { 770 case eEncodingT1: 771 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 772 Rm = Bits32(opcode, 6, 3); 773 setflags = false; 774 if (Rd == 15 && InITBlock() && !LastInITBlock()) 775 return false; 776 break; 777 case eEncodingT2: 778 Rd = Bits32(opcode, 2, 0); 779 Rm = Bits32(opcode, 5, 3); 780 setflags = true; 781 if (InITBlock()) 782 return false; 783 break; 784 case eEncodingT3: 785 Rd = Bits32(opcode, 11, 8); 786 Rm = Bits32(opcode, 3, 0); 787 setflags = BitIsSet(opcode, 20); 788 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 789 if (setflags && (BadReg(Rd) || BadReg(Rm))) 790 return false; 791 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 792 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 793 return false; 794 break; 795 case eEncodingA1: 796 Rd = Bits32(opcode, 15, 12); 797 Rm = Bits32(opcode, 3, 0); 798 setflags = BitIsSet(opcode, 20); 799 800 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 801 if (Rd == 15 && setflags) 802 return EmulateSUBSPcLrEtc (opcode, encoding); 803 break; 804 default: 805 return false; 806 } 807 uint32_t result = ReadCoreReg(Rm, &success); 808 if (!success) 809 return false; 810 811 // The context specifies that Rm is to be moved into Rd. 812 EmulateInstruction::Context context; 813 if (Rd == 13) 814 context.type = EmulateInstruction::eContextAdjustStackPointer; 815 else 816 context.type = EmulateInstruction::eContextRegisterPlusOffset; 817 RegisterInfo dwarf_reg; 818 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 819 context.SetRegisterPlusOffset (dwarf_reg, 0); 820 821 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 822 return false; 823 } 824 return true; 825 } 826 827 // Move (immediate) writes an immediate value to the destination register. It 828 // can optionally update the condition flags based on the value. 829 // MOV (immediate) 830 bool 831 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 832 { 833 #if 0 834 // ARM pseudo code... 835 if (ConditionPassed()) 836 { 837 EncodingSpecificOperations(); 838 result = imm32; 839 if d == 15 then // Can only occur for ARM encoding 840 ALUWritePC(result); // setflags is always FALSE here 841 else 842 R[d] = result; 843 if setflags then 844 APSR.N = result<31>; 845 APSR.Z = IsZeroBit(result); 846 APSR.C = carry; 847 // APSR.V unchanged 848 } 849 #endif 850 851 if (ConditionPassed(opcode)) 852 { 853 uint32_t Rd; // the destination register 854 uint32_t imm32; // the immediate value to be written to Rd 855 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 856 // for setflags == false, this value is a don't care 857 // initialized to 0 to silence the static analyzer 858 bool setflags; 859 switch (encoding) { 860 case eEncodingT1: 861 Rd = Bits32(opcode, 10, 8); 862 setflags = !InITBlock(); 863 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 864 carry = APSR_C; 865 866 break; 867 868 case eEncodingT2: 869 Rd = Bits32(opcode, 11, 8); 870 setflags = BitIsSet(opcode, 20); 871 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 872 if (BadReg(Rd)) 873 return false; 874 875 break; 876 877 case eEncodingT3: 878 { 879 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 880 Rd = Bits32 (opcode, 11, 8); 881 setflags = false; 882 uint32_t imm4 = Bits32 (opcode, 19, 16); 883 uint32_t imm3 = Bits32 (opcode, 14, 12); 884 uint32_t i = Bit32 (opcode, 26); 885 uint32_t imm8 = Bits32 (opcode, 7, 0); 886 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 887 888 // if BadReg(d) then UNPREDICTABLE; 889 if (BadReg (Rd)) 890 return false; 891 } 892 break; 893 894 case eEncodingA1: 895 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 896 Rd = Bits32 (opcode, 15, 12); 897 setflags = BitIsSet (opcode, 20); 898 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 899 900 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 901 if ((Rd == 15) && setflags) 902 return EmulateSUBSPcLrEtc (opcode, encoding); 903 904 break; 905 906 case eEncodingA2: 907 { 908 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 909 Rd = Bits32 (opcode, 15, 12); 910 setflags = false; 911 uint32_t imm4 = Bits32 (opcode, 19, 16); 912 uint32_t imm12 = Bits32 (opcode, 11, 0); 913 imm32 = (imm4 << 12) | imm12; 914 915 // if d == 15 then UNPREDICTABLE; 916 if (Rd == 15) 917 return false; 918 } 919 break; 920 921 default: 922 return false; 923 } 924 uint32_t result = imm32; 925 926 // The context specifies that an immediate is to be moved into Rd. 927 EmulateInstruction::Context context; 928 context.type = EmulateInstruction::eContextImmediate; 929 context.SetNoArgs (); 930 931 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 932 return false; 933 } 934 return true; 935 } 936 937 // MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 938 // register. These 32 bits do not depend on whether the source register values are considered to be signed values or 939 // unsigned values. 940 // 941 // Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 942 // limited to only a few forms of the instruction. 943 bool 944 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 945 { 946 #if 0 947 if ConditionPassed() then 948 EncodingSpecificOperations(); 949 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 950 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 951 result = operand1 * operand2; 952 R[d] = result<31:0>; 953 if setflags then 954 APSR.N = result<31>; 955 APSR.Z = IsZeroBit(result); 956 if ArchVersion() == 4 then 957 APSR.C = bit UNKNOWN; 958 // else APSR.C unchanged 959 // APSR.V always unchanged 960 #endif 961 962 if (ConditionPassed(opcode)) 963 { 964 uint32_t d; 965 uint32_t n; 966 uint32_t m; 967 bool setflags; 968 969 // EncodingSpecificOperations(); 970 switch (encoding) 971 { 972 case eEncodingT1: 973 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 974 d = Bits32 (opcode, 2, 0); 975 n = Bits32 (opcode, 5, 3); 976 m = Bits32 (opcode, 2, 0); 977 setflags = !InITBlock(); 978 979 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 980 if ((ArchVersion() < ARMv6) && (d == n)) 981 return false; 982 983 break; 984 985 case eEncodingT2: 986 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 987 d = Bits32 (opcode, 11, 8); 988 n = Bits32 (opcode, 19, 16); 989 m = Bits32 (opcode, 3, 0); 990 setflags = false; 991 992 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 993 if (BadReg (d) || BadReg (n) || BadReg (m)) 994 return false; 995 996 break; 997 998 case eEncodingA1: 999 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 1000 d = Bits32 (opcode, 19, 16); 1001 n = Bits32 (opcode, 3, 0); 1002 m = Bits32 (opcode, 11, 8); 1003 setflags = BitIsSet (opcode, 20); 1004 1005 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1006 if ((d == 15) || (n == 15) || (m == 15)) 1007 return false; 1008 1009 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1010 if ((ArchVersion() < ARMv6) && (d == n)) 1011 return false; 1012 1013 break; 1014 1015 default: 1016 return false; 1017 } 1018 1019 bool success = false; 1020 1021 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1022 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1023 if (!success) 1024 return false; 1025 1026 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1027 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1028 if (!success) 1029 return false; 1030 1031 // result = operand1 * operand2; 1032 uint64_t result = operand1 * operand2; 1033 1034 // R[d] = result<31:0>; 1035 RegisterInfo op1_reg; 1036 RegisterInfo op2_reg; 1037 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1038 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1039 1040 EmulateInstruction::Context context; 1041 context.type = eContextArithmetic; 1042 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 1043 1044 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 1045 return false; 1046 1047 // if setflags then 1048 if (setflags) 1049 { 1050 // APSR.N = result<31>; 1051 // APSR.Z = IsZeroBit(result); 1052 m_new_inst_cpsr = m_opcode_cpsr; 1053 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 1054 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1055 if (m_new_inst_cpsr != m_opcode_cpsr) 1056 { 1057 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1058 return false; 1059 } 1060 1061 // if ArchVersion() == 4 then 1062 // APSR.C = bit UNKNOWN; 1063 } 1064 } 1065 return true; 1066 } 1067 1068 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1069 // It can optionally update the condition flags based on the value. 1070 bool 1071 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1072 { 1073 #if 0 1074 // ARM pseudo code... 1075 if (ConditionPassed()) 1076 { 1077 EncodingSpecificOperations(); 1078 result = NOT(imm32); 1079 if d == 15 then // Can only occur for ARM encoding 1080 ALUWritePC(result); // setflags is always FALSE here 1081 else 1082 R[d] = result; 1083 if setflags then 1084 APSR.N = result<31>; 1085 APSR.Z = IsZeroBit(result); 1086 APSR.C = carry; 1087 // APSR.V unchanged 1088 } 1089 #endif 1090 1091 if (ConditionPassed(opcode)) 1092 { 1093 uint32_t Rd; // the destination register 1094 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1095 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1096 bool setflags; 1097 switch (encoding) { 1098 case eEncodingT1: 1099 Rd = Bits32(opcode, 11, 8); 1100 setflags = BitIsSet(opcode, 20); 1101 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1102 break; 1103 case eEncodingA1: 1104 Rd = Bits32(opcode, 15, 12); 1105 setflags = BitIsSet(opcode, 20); 1106 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1107 1108 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1109 if (Rd == 15 && setflags) 1110 return EmulateSUBSPcLrEtc (opcode, encoding); 1111 break; 1112 default: 1113 return false; 1114 } 1115 uint32_t result = ~imm32; 1116 1117 // The context specifies that an immediate is to be moved into Rd. 1118 EmulateInstruction::Context context; 1119 context.type = EmulateInstruction::eContextImmediate; 1120 context.SetNoArgs (); 1121 1122 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1123 return false; 1124 } 1125 return true; 1126 } 1127 1128 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1129 // It can optionally update the condition flags based on the result. 1130 bool 1131 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1132 { 1133 #if 0 1134 // ARM pseudo code... 1135 if (ConditionPassed()) 1136 { 1137 EncodingSpecificOperations(); 1138 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1139 result = NOT(shifted); 1140 if d == 15 then // Can only occur for ARM encoding 1141 ALUWritePC(result); // setflags is always FALSE here 1142 else 1143 R[d] = result; 1144 if setflags then 1145 APSR.N = result<31>; 1146 APSR.Z = IsZeroBit(result); 1147 APSR.C = carry; 1148 // APSR.V unchanged 1149 } 1150 #endif 1151 1152 if (ConditionPassed(opcode)) 1153 { 1154 uint32_t Rm; // the source register 1155 uint32_t Rd; // the destination register 1156 ARM_ShifterType shift_t; 1157 uint32_t shift_n; // the shift applied to the value read from Rm 1158 bool setflags; 1159 uint32_t carry; // the carry bit after the shift operation 1160 switch (encoding) { 1161 case eEncodingT1: 1162 Rd = Bits32(opcode, 2, 0); 1163 Rm = Bits32(opcode, 5, 3); 1164 setflags = !InITBlock(); 1165 shift_t = SRType_LSL; 1166 shift_n = 0; 1167 if (InITBlock()) 1168 return false; 1169 break; 1170 case eEncodingT2: 1171 Rd = Bits32(opcode, 11, 8); 1172 Rm = Bits32(opcode, 3, 0); 1173 setflags = BitIsSet(opcode, 20); 1174 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1175 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1176 if (BadReg(Rd) || BadReg(Rm)) 1177 return false; 1178 break; 1179 case eEncodingA1: 1180 Rd = Bits32(opcode, 15, 12); 1181 Rm = Bits32(opcode, 3, 0); 1182 setflags = BitIsSet(opcode, 20); 1183 shift_n = DecodeImmShiftARM(opcode, shift_t); 1184 break; 1185 default: 1186 return false; 1187 } 1188 bool success = false; 1189 uint32_t value = ReadCoreReg(Rm, &success); 1190 if (!success) 1191 return false; 1192 1193 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1194 if (!success) 1195 return false; 1196 uint32_t result = ~shifted; 1197 1198 // The context specifies that an immediate is to be moved into Rd. 1199 EmulateInstruction::Context context; 1200 context.type = EmulateInstruction::eContextImmediate; 1201 context.SetNoArgs (); 1202 1203 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1204 return false; 1205 } 1206 return true; 1207 } 1208 1209 // PC relative immediate load into register, possibly followed by ADD (SP plus register). 1210 // LDR (literal) 1211 bool 1212 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1213 { 1214 #if 0 1215 // ARM pseudo code... 1216 if (ConditionPassed()) 1217 { 1218 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1219 base = Align(PC,4); 1220 address = if add then (base + imm32) else (base - imm32); 1221 data = MemU[address,4]; 1222 if t == 15 then 1223 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1224 elsif UnalignedSupport() || address<1:0> = '00' then 1225 R[t] = data; 1226 else // Can only apply before ARMv7 1227 if CurrentInstrSet() == InstrSet_ARM then 1228 R[t] = ROR(data, 8*UInt(address<1:0>)); 1229 else 1230 R[t] = bits(32) UNKNOWN; 1231 } 1232 #endif 1233 1234 if (ConditionPassed(opcode)) 1235 { 1236 bool success = false; 1237 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1238 if (!success) 1239 return false; 1240 1241 // PC relative immediate load context 1242 EmulateInstruction::Context context; 1243 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1244 RegisterInfo pc_reg; 1245 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1246 context.SetRegisterPlusOffset (pc_reg, 0); 1247 1248 uint32_t Rt; // the destination register 1249 uint32_t imm32; // immediate offset from the PC 1250 bool add; // +imm32 or -imm32? 1251 addr_t base; // the base address 1252 addr_t address; // the PC relative address 1253 uint32_t data; // the literal data value from the PC relative load 1254 switch (encoding) { 1255 case eEncodingT1: 1256 Rt = Bits32(opcode, 10, 8); 1257 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1258 add = true; 1259 break; 1260 case eEncodingT2: 1261 Rt = Bits32(opcode, 15, 12); 1262 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1263 add = BitIsSet(opcode, 23); 1264 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1265 return false; 1266 break; 1267 default: 1268 return false; 1269 } 1270 1271 base = Align(pc, 4); 1272 if (add) 1273 address = base + imm32; 1274 else 1275 address = base - imm32; 1276 1277 context.SetRegisterPlusOffset(pc_reg, address - base); 1278 data = MemURead(context, address, 4, 0, &success); 1279 if (!success) 1280 return false; 1281 1282 if (Rt == 15) 1283 { 1284 if (Bits32(address, 1, 0) == 0) 1285 { 1286 // In ARMv5T and above, this is an interworking branch. 1287 if (!LoadWritePC(context, data)) 1288 return false; 1289 } 1290 else 1291 return false; 1292 } 1293 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1294 { 1295 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1296 return false; 1297 } 1298 else // We don't handle ARM for now. 1299 return false; 1300 1301 } 1302 return true; 1303 } 1304 1305 // An add operation to adjust the SP. 1306 // ADD (SP plus immediate) 1307 bool 1308 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1309 { 1310 #if 0 1311 // ARM pseudo code... 1312 if (ConditionPassed()) 1313 { 1314 EncodingSpecificOperations(); 1315 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1316 if d == 15 then // Can only occur for ARM encoding 1317 ALUWritePC(result); // setflags is always FALSE here 1318 else 1319 R[d] = result; 1320 if setflags then 1321 APSR.N = result<31>; 1322 APSR.Z = IsZeroBit(result); 1323 APSR.C = carry; 1324 APSR.V = overflow; 1325 } 1326 #endif 1327 1328 bool success = false; 1329 1330 if (ConditionPassed(opcode)) 1331 { 1332 const addr_t sp = ReadCoreReg (SP_REG, &success); 1333 if (!success) 1334 return false; 1335 uint32_t imm32; // the immediate operand 1336 uint32_t d; 1337 bool setflags; 1338 switch (encoding) 1339 { 1340 case eEncodingT1: 1341 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1342 d = Bits32 (opcode, 10, 8); 1343 imm32 = (Bits32 (opcode, 7, 0) << 2); 1344 setflags = false; 1345 break; 1346 1347 case eEncodingT2: 1348 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1349 d = 13; 1350 imm32 = ThumbImm7Scaled (opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1351 setflags = false; 1352 break; 1353 1354 case eEncodingT3: 1355 // d = UInt(Rd); setflags = (S == "1"); imm32 = ThumbExpandImm(i:imm3:imm8); 1356 d = Bits32 (opcode, 11, 8); 1357 imm32 = ThumbExpandImm (opcode); 1358 setflags = Bit32 (opcode, 20); 1359 1360 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 1361 if (d == 15 && setflags == 1) 1362 return false; // CMN (immediate) not yet supported 1363 1364 // if d == 15 && S == "0" then UNPREDICTABLE; 1365 if (d == 15 && setflags == 0) 1366 return false; 1367 break; 1368 1369 case eEncodingT4: 1370 { 1371 // if Rn == '1111' then SEE ADR; 1372 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 1373 d = Bits32 (opcode, 11, 8); 1374 setflags = false; 1375 uint32_t i = Bit32 (opcode, 26); 1376 uint32_t imm3 = Bits32 (opcode, 14, 12); 1377 uint32_t imm8 = Bits32 (opcode, 7, 0); 1378 imm32 = (i << 11) | (imm3 << 8) | imm8; 1379 1380 // if d == 15 then UNPREDICTABLE; 1381 if (d == 15) 1382 return false; 1383 } 1384 break; 1385 1386 default: 1387 return false; 1388 } 1389 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 1390 AddWithCarryResult res = AddWithCarry (sp, imm32, 0); 1391 1392 EmulateInstruction::Context context; 1393 if (d == 13) 1394 context.type = EmulateInstruction::eContextAdjustStackPointer; 1395 else 1396 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1397 1398 RegisterInfo sp_reg; 1399 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1400 context.SetRegisterPlusOffset (sp_reg, res.result - sp); 1401 1402 if (d == 15) 1403 { 1404 if (!ALUWritePC (context, res.result)) 1405 return false; 1406 } 1407 else 1408 { 1409 // R[d] = result; 1410 // if setflags then 1411 // APSR.N = result<31>; 1412 // APSR.Z = IsZeroBit(result); 1413 // APSR.C = carry; 1414 // APSR.V = overflow; 1415 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 1416 return false; 1417 } 1418 } 1419 return true; 1420 } 1421 1422 // An add operation to adjust the SP. 1423 // ADD (SP plus register) 1424 bool 1425 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1426 { 1427 #if 0 1428 // ARM pseudo code... 1429 if (ConditionPassed()) 1430 { 1431 EncodingSpecificOperations(); 1432 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1433 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1434 if d == 15 then 1435 ALUWritePC(result); // setflags is always FALSE here 1436 else 1437 R[d] = result; 1438 if setflags then 1439 APSR.N = result<31>; 1440 APSR.Z = IsZeroBit(result); 1441 APSR.C = carry; 1442 APSR.V = overflow; 1443 } 1444 #endif 1445 1446 bool success = false; 1447 1448 if (ConditionPassed(opcode)) 1449 { 1450 const addr_t sp = ReadCoreReg (SP_REG, &success); 1451 if (!success) 1452 return false; 1453 uint32_t Rm; // the second operand 1454 switch (encoding) { 1455 case eEncodingT2: 1456 Rm = Bits32(opcode, 6, 3); 1457 break; 1458 default: 1459 return false; 1460 } 1461 int32_t reg_value = ReadCoreReg(Rm, &success); 1462 if (!success) 1463 return false; 1464 1465 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1466 1467 EmulateInstruction::Context context; 1468 context.type = eContextArithmetic; 1469 RegisterInfo sp_reg; 1470 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1471 1472 RegisterInfo other_reg; 1473 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1474 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1475 1476 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1477 return false; 1478 } 1479 return true; 1480 } 1481 1482 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1483 // at a PC-relative address, and changes instruction set from ARM to Thumb, or 1484 // from Thumb to ARM. 1485 // BLX (immediate) 1486 bool 1487 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1488 { 1489 #if 0 1490 // ARM pseudo code... 1491 if (ConditionPassed()) 1492 { 1493 EncodingSpecificOperations(); 1494 if CurrentInstrSet() == InstrSet_ARM then 1495 LR = PC - 4; 1496 else 1497 LR = PC<31:1> : '1'; 1498 if targetInstrSet == InstrSet_ARM then 1499 targetAddress = Align(PC,4) + imm32; 1500 else 1501 targetAddress = PC + imm32; 1502 SelectInstrSet(targetInstrSet); 1503 BranchWritePC(targetAddress); 1504 } 1505 #endif 1506 1507 bool success = true; 1508 1509 if (ConditionPassed(opcode)) 1510 { 1511 EmulateInstruction::Context context; 1512 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1513 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1514 if (!success) 1515 return false; 1516 addr_t lr; // next instruction address 1517 addr_t target; // target address 1518 int32_t imm32; // PC-relative offset 1519 switch (encoding) { 1520 case eEncodingT1: 1521 { 1522 lr = pc | 1u; // return address 1523 uint32_t S = Bit32(opcode, 26); 1524 uint32_t imm10 = Bits32(opcode, 25, 16); 1525 uint32_t J1 = Bit32(opcode, 13); 1526 uint32_t J2 = Bit32(opcode, 11); 1527 uint32_t imm11 = Bits32(opcode, 10, 0); 1528 uint32_t I1 = !(J1 ^ S); 1529 uint32_t I2 = !(J2 ^ S); 1530 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1531 imm32 = llvm::SignExtend32<25>(imm25); 1532 target = pc + imm32; 1533 SelectInstrSet (eModeThumb); 1534 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1535 if (InITBlock() && !LastInITBlock()) 1536 return false; 1537 break; 1538 } 1539 case eEncodingT2: 1540 { 1541 lr = pc | 1u; // return address 1542 uint32_t S = Bit32(opcode, 26); 1543 uint32_t imm10H = Bits32(opcode, 25, 16); 1544 uint32_t J1 = Bit32(opcode, 13); 1545 uint32_t J2 = Bit32(opcode, 11); 1546 uint32_t imm10L = Bits32(opcode, 10, 1); 1547 uint32_t I1 = !(J1 ^ S); 1548 uint32_t I2 = !(J2 ^ S); 1549 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1550 imm32 = llvm::SignExtend32<25>(imm25); 1551 target = Align(pc, 4) + imm32; 1552 SelectInstrSet (eModeARM); 1553 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1554 if (InITBlock() && !LastInITBlock()) 1555 return false; 1556 break; 1557 } 1558 case eEncodingA1: 1559 lr = pc - 4; // return address 1560 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1561 target = Align(pc, 4) + imm32; 1562 SelectInstrSet (eModeARM); 1563 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1564 break; 1565 case eEncodingA2: 1566 lr = pc - 4; // return address 1567 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1568 target = pc + imm32; 1569 SelectInstrSet (eModeThumb); 1570 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1571 break; 1572 default: 1573 return false; 1574 } 1575 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1576 return false; 1577 if (!BranchWritePC(context, target)) 1578 return false; 1579 if (m_opcode_cpsr != m_new_inst_cpsr) 1580 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1581 return false; 1582 } 1583 return true; 1584 } 1585 1586 // Branch with Link and Exchange (register) calls a subroutine at an address and 1587 // instruction set specified by a register. 1588 // BLX (register) 1589 bool 1590 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1591 { 1592 #if 0 1593 // ARM pseudo code... 1594 if (ConditionPassed()) 1595 { 1596 EncodingSpecificOperations(); 1597 target = R[m]; 1598 if CurrentInstrSet() == InstrSet_ARM then 1599 next_instr_addr = PC - 4; 1600 LR = next_instr_addr; 1601 else 1602 next_instr_addr = PC - 2; 1603 LR = next_instr_addr<31:1> : '1'; 1604 BXWritePC(target); 1605 } 1606 #endif 1607 1608 bool success = false; 1609 1610 if (ConditionPassed(opcode)) 1611 { 1612 EmulateInstruction::Context context; 1613 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1614 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1615 addr_t lr; // next instruction address 1616 if (!success) 1617 return false; 1618 uint32_t Rm; // the register with the target address 1619 switch (encoding) { 1620 case eEncodingT1: 1621 lr = (pc - 2) | 1u; // return address 1622 Rm = Bits32(opcode, 6, 3); 1623 // if m == 15 then UNPREDICTABLE; 1624 if (Rm == 15) 1625 return false; 1626 if (InITBlock() && !LastInITBlock()) 1627 return false; 1628 break; 1629 case eEncodingA1: 1630 lr = pc - 4; // return address 1631 Rm = Bits32(opcode, 3, 0); 1632 // if m == 15 then UNPREDICTABLE; 1633 if (Rm == 15) 1634 return false; 1635 break; 1636 default: 1637 return false; 1638 } 1639 addr_t target = ReadCoreReg (Rm, &success); 1640 if (!success) 1641 return false; 1642 RegisterInfo dwarf_reg; 1643 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1644 context.SetRegister (dwarf_reg); 1645 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1646 return false; 1647 if (!BXWritePC(context, target)) 1648 return false; 1649 } 1650 return true; 1651 } 1652 1653 // Branch and Exchange causes a branch to an address and instruction set specified by a register. 1654 bool 1655 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1656 { 1657 #if 0 1658 // ARM pseudo code... 1659 if (ConditionPassed()) 1660 { 1661 EncodingSpecificOperations(); 1662 BXWritePC(R[m]); 1663 } 1664 #endif 1665 1666 if (ConditionPassed(opcode)) 1667 { 1668 EmulateInstruction::Context context; 1669 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1670 uint32_t Rm; // the register with the target address 1671 switch (encoding) { 1672 case eEncodingT1: 1673 Rm = Bits32(opcode, 6, 3); 1674 if (InITBlock() && !LastInITBlock()) 1675 return false; 1676 break; 1677 case eEncodingA1: 1678 Rm = Bits32(opcode, 3, 0); 1679 break; 1680 default: 1681 return false; 1682 } 1683 bool success = false; 1684 addr_t target = ReadCoreReg (Rm, &success); 1685 if (!success) 1686 return false; 1687 1688 RegisterInfo dwarf_reg; 1689 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1690 context.SetRegister (dwarf_reg); 1691 if (!BXWritePC(context, target)) 1692 return false; 1693 } 1694 return true; 1695 } 1696 1697 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1698 // address and instruction set specified by a register as though it were a BX instruction. 1699 // 1700 // TODO: Emulate Jazelle architecture? 1701 // We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1702 bool 1703 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1704 { 1705 #if 0 1706 // ARM pseudo code... 1707 if (ConditionPassed()) 1708 { 1709 EncodingSpecificOperations(); 1710 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1711 BXWritePC(R[m]); 1712 else 1713 if JazelleAcceptsExecution() then 1714 SwitchToJazelleExecution(); 1715 else 1716 SUBARCHITECTURE_DEFINED handler call; 1717 } 1718 #endif 1719 1720 if (ConditionPassed(opcode)) 1721 { 1722 EmulateInstruction::Context context; 1723 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1724 uint32_t Rm; // the register with the target address 1725 switch (encoding) { 1726 case eEncodingT1: 1727 Rm = Bits32(opcode, 19, 16); 1728 if (BadReg(Rm)) 1729 return false; 1730 if (InITBlock() && !LastInITBlock()) 1731 return false; 1732 break; 1733 case eEncodingA1: 1734 Rm = Bits32(opcode, 3, 0); 1735 if (Rm == 15) 1736 return false; 1737 break; 1738 default: 1739 return false; 1740 } 1741 bool success = false; 1742 addr_t target = ReadCoreReg (Rm, &success); 1743 if (!success) 1744 return false; 1745 1746 RegisterInfo dwarf_reg; 1747 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1748 context.SetRegister (dwarf_reg); 1749 if (!BXWritePC(context, target)) 1750 return false; 1751 } 1752 return true; 1753 } 1754 1755 // Set r7 to point to some ip offset. 1756 // SUB (immediate) 1757 bool 1758 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1759 { 1760 #if 0 1761 // ARM pseudo code... 1762 if (ConditionPassed()) 1763 { 1764 EncodingSpecificOperations(); 1765 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1766 if d == 15 then // Can only occur for ARM encoding 1767 ALUWritePC(result); // setflags is always FALSE here 1768 else 1769 R[d] = result; 1770 if setflags then 1771 APSR.N = result<31>; 1772 APSR.Z = IsZeroBit(result); 1773 APSR.C = carry; 1774 APSR.V = overflow; 1775 } 1776 #endif 1777 1778 if (ConditionPassed(opcode)) 1779 { 1780 bool success = false; 1781 const addr_t ip = ReadCoreReg (12, &success); 1782 if (!success) 1783 return false; 1784 uint32_t imm32; 1785 switch (encoding) { 1786 case eEncodingA1: 1787 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1788 break; 1789 default: 1790 return false; 1791 } 1792 addr_t ip_offset = imm32; 1793 addr_t addr = ip - ip_offset; // the adjusted ip value 1794 1795 EmulateInstruction::Context context; 1796 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1797 RegisterInfo dwarf_reg; 1798 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1799 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1800 1801 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1802 return false; 1803 } 1804 return true; 1805 } 1806 1807 // Set ip to point to some stack offset. 1808 // SUB (SP minus immediate) 1809 bool 1810 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1811 { 1812 #if 0 1813 // ARM pseudo code... 1814 if (ConditionPassed()) 1815 { 1816 EncodingSpecificOperations(); 1817 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1818 if d == 15 then // Can only occur for ARM encoding 1819 ALUWritePC(result); // setflags is always FALSE here 1820 else 1821 R[d] = result; 1822 if setflags then 1823 APSR.N = result<31>; 1824 APSR.Z = IsZeroBit(result); 1825 APSR.C = carry; 1826 APSR.V = overflow; 1827 } 1828 #endif 1829 1830 if (ConditionPassed(opcode)) 1831 { 1832 bool success = false; 1833 const addr_t sp = ReadCoreReg (SP_REG, &success); 1834 if (!success) 1835 return false; 1836 uint32_t imm32; 1837 switch (encoding) { 1838 case eEncodingA1: 1839 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1840 break; 1841 default: 1842 return false; 1843 } 1844 addr_t sp_offset = imm32; 1845 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1846 1847 EmulateInstruction::Context context; 1848 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1849 RegisterInfo dwarf_reg; 1850 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1851 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1852 1853 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1854 return false; 1855 } 1856 return true; 1857 } 1858 1859 // This instruction subtracts an immediate value from the SP value, and writes 1860 // the result to the destination register. 1861 // 1862 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1863 bool 1864 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1865 { 1866 #if 0 1867 // ARM pseudo code... 1868 if (ConditionPassed()) 1869 { 1870 EncodingSpecificOperations(); 1871 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1872 if d == 15 then // Can only occur for ARM encoding 1873 ALUWritePC(result); // setflags is always FALSE here 1874 else 1875 R[d] = result; 1876 if setflags then 1877 APSR.N = result<31>; 1878 APSR.Z = IsZeroBit(result); 1879 APSR.C = carry; 1880 APSR.V = overflow; 1881 } 1882 #endif 1883 1884 bool success = false; 1885 if (ConditionPassed(opcode)) 1886 { 1887 const addr_t sp = ReadCoreReg (SP_REG, &success); 1888 if (!success) 1889 return false; 1890 1891 uint32_t Rd; 1892 bool setflags; 1893 uint32_t imm32; 1894 switch (encoding) { 1895 case eEncodingT1: 1896 Rd = 13; 1897 setflags = false; 1898 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1899 break; 1900 case eEncodingT2: 1901 Rd = Bits32(opcode, 11, 8); 1902 setflags = BitIsSet(opcode, 20); 1903 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1904 if (Rd == 15 && setflags) 1905 return EmulateCMPImm(opcode, eEncodingT2); 1906 if (Rd == 15 && !setflags) 1907 return false; 1908 break; 1909 case eEncodingT3: 1910 Rd = Bits32(opcode, 11, 8); 1911 setflags = false; 1912 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1913 if (Rd == 15) 1914 return false; 1915 break; 1916 case eEncodingA1: 1917 Rd = Bits32(opcode, 15, 12); 1918 setflags = BitIsSet(opcode, 20); 1919 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1920 1921 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1922 if (Rd == 15 && setflags) 1923 return EmulateSUBSPcLrEtc (opcode, encoding); 1924 break; 1925 default: 1926 return false; 1927 } 1928 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1929 1930 EmulateInstruction::Context context; 1931 if (Rd == 13) 1932 { 1933 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1934 // value gets passed down to context.SetImmediateSigned. 1935 context.type = EmulateInstruction::eContextAdjustStackPointer; 1936 context.SetImmediateSigned (-imm64); // the stack pointer offset 1937 } 1938 else 1939 { 1940 context.type = EmulateInstruction::eContextImmediate; 1941 context.SetNoArgs (); 1942 } 1943 1944 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1945 return false; 1946 } 1947 return true; 1948 } 1949 1950 // A store operation to the stack that also updates the SP. 1951 bool 1952 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1953 { 1954 #if 0 1955 // ARM pseudo code... 1956 if (ConditionPassed()) 1957 { 1958 EncodingSpecificOperations(); 1959 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1960 address = if index then offset_addr else R[n]; 1961 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1962 if wback then R[n] = offset_addr; 1963 } 1964 #endif 1965 1966 bool success = false; 1967 if (ConditionPassed(opcode)) 1968 { 1969 const uint32_t addr_byte_size = GetAddressByteSize(); 1970 const addr_t sp = ReadCoreReg (SP_REG, &success); 1971 if (!success) 1972 return false; 1973 uint32_t Rt; // the source register 1974 uint32_t imm12; 1975 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1976 1977 bool index; 1978 bool add; 1979 bool wback; 1980 switch (encoding) { 1981 case eEncodingA1: 1982 Rt = Bits32(opcode, 15, 12); 1983 imm12 = Bits32(opcode, 11, 0); 1984 Rn = Bits32 (opcode, 19, 16); 1985 1986 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1987 return false; 1988 1989 index = BitIsSet (opcode, 24); 1990 add = BitIsSet (opcode, 23); 1991 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 1992 1993 if (wback && ((Rn == 15) || (Rn == Rt))) 1994 return false; 1995 break; 1996 default: 1997 return false; 1998 } 1999 addr_t offset_addr; 2000 if (add) 2001 offset_addr = sp + imm12; 2002 else 2003 offset_addr = sp - imm12; 2004 2005 addr_t addr; 2006 if (index) 2007 addr = offset_addr; 2008 else 2009 addr = sp; 2010 2011 EmulateInstruction::Context context; 2012 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2013 RegisterInfo sp_reg; 2014 RegisterInfo dwarf_reg; 2015 2016 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2017 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2018 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2019 if (Rt != 15) 2020 { 2021 uint32_t reg_value = ReadCoreReg(Rt, &success); 2022 if (!success) 2023 return false; 2024 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 2025 return false; 2026 } 2027 else 2028 { 2029 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2030 if (!success) 2031 return false; 2032 if (!MemUWrite (context, addr, pc, addr_byte_size)) 2033 return false; 2034 } 2035 2036 2037 if (wback) 2038 { 2039 context.type = EmulateInstruction::eContextAdjustStackPointer; 2040 context.SetImmediateSigned (addr - sp); 2041 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 2042 return false; 2043 } 2044 } 2045 return true; 2046 } 2047 2048 // Vector Push stores multiple extension registers to the stack. 2049 // It also updates SP to point to the start of the stored data. 2050 bool 2051 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 2052 { 2053 #if 0 2054 // ARM pseudo code... 2055 if (ConditionPassed()) 2056 { 2057 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2058 address = SP - imm32; 2059 SP = SP - imm32; 2060 if single_regs then 2061 for r = 0 to regs-1 2062 MemA[address,4] = S[d+r]; address = address+4; 2063 else 2064 for r = 0 to regs-1 2065 // Store as two word-aligned words in the correct order for current endianness. 2066 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2067 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2068 address = address+8; 2069 } 2070 #endif 2071 2072 bool success = false; 2073 if (ConditionPassed(opcode)) 2074 { 2075 const uint32_t addr_byte_size = GetAddressByteSize(); 2076 const addr_t sp = ReadCoreReg (SP_REG, &success); 2077 if (!success) 2078 return false; 2079 bool single_regs; 2080 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2081 uint32_t imm32; // stack offset 2082 uint32_t regs; // number of registers 2083 switch (encoding) { 2084 case eEncodingT1: 2085 case eEncodingA1: 2086 single_regs = false; 2087 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2088 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2089 // If UInt(imm8) is odd, see "FSTMX". 2090 regs = Bits32(opcode, 7, 0) / 2; 2091 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2092 if (regs == 0 || regs > 16 || (d + regs) > 32) 2093 return false; 2094 break; 2095 case eEncodingT2: 2096 case eEncodingA2: 2097 single_regs = true; 2098 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2099 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2100 regs = Bits32(opcode, 7, 0); 2101 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2102 if (regs == 0 || regs > 16 || (d + regs) > 32) 2103 return false; 2104 break; 2105 default: 2106 return false; 2107 } 2108 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2109 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2110 addr_t sp_offset = imm32; 2111 addr_t addr = sp - sp_offset; 2112 uint32_t i; 2113 2114 EmulateInstruction::Context context; 2115 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2116 2117 RegisterInfo dwarf_reg; 2118 RegisterInfo sp_reg; 2119 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2120 for (i=0; i<regs; ++i) 2121 { 2122 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2123 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2124 // uint64_t to accommodate 64-bit registers. 2125 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2126 if (!success) 2127 return false; 2128 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2129 return false; 2130 addr += reg_byte_size; 2131 } 2132 2133 context.type = EmulateInstruction::eContextAdjustStackPointer; 2134 context.SetImmediateSigned (-sp_offset); 2135 2136 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2137 return false; 2138 } 2139 return true; 2140 } 2141 2142 // Vector Pop loads multiple extension registers from the stack. 2143 // It also updates SP to point just above the loaded data. 2144 bool 2145 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2146 { 2147 #if 0 2148 // ARM pseudo code... 2149 if (ConditionPassed()) 2150 { 2151 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2152 address = SP; 2153 SP = SP + imm32; 2154 if single_regs then 2155 for r = 0 to regs-1 2156 S[d+r] = MemA[address,4]; address = address+4; 2157 else 2158 for r = 0 to regs-1 2159 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2160 // Combine the word-aligned words in the correct order for current endianness. 2161 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2162 } 2163 #endif 2164 2165 bool success = false; 2166 if (ConditionPassed(opcode)) 2167 { 2168 const uint32_t addr_byte_size = GetAddressByteSize(); 2169 const addr_t sp = ReadCoreReg (SP_REG, &success); 2170 if (!success) 2171 return false; 2172 bool single_regs; 2173 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2174 uint32_t imm32; // stack offset 2175 uint32_t regs; // number of registers 2176 switch (encoding) { 2177 case eEncodingT1: 2178 case eEncodingA1: 2179 single_regs = false; 2180 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2181 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2182 // If UInt(imm8) is odd, see "FLDMX". 2183 regs = Bits32(opcode, 7, 0) / 2; 2184 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2185 if (regs == 0 || regs > 16 || (d + regs) > 32) 2186 return false; 2187 break; 2188 case eEncodingT2: 2189 case eEncodingA2: 2190 single_regs = true; 2191 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2192 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2193 regs = Bits32(opcode, 7, 0); 2194 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2195 if (regs == 0 || regs > 16 || (d + regs) > 32) 2196 return false; 2197 break; 2198 default: 2199 return false; 2200 } 2201 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2202 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2203 addr_t sp_offset = imm32; 2204 addr_t addr = sp; 2205 uint32_t i; 2206 uint64_t data; // uint64_t to accommodate 64-bit registers. 2207 2208 EmulateInstruction::Context context; 2209 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2210 2211 RegisterInfo dwarf_reg; 2212 RegisterInfo sp_reg; 2213 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2214 for (i=0; i<regs; ++i) 2215 { 2216 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2217 context.SetRegisterPlusOffset (sp_reg, addr - sp); 2218 data = MemARead(context, addr, reg_byte_size, 0, &success); 2219 if (!success) 2220 return false; 2221 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2222 return false; 2223 addr += reg_byte_size; 2224 } 2225 2226 context.type = EmulateInstruction::eContextAdjustStackPointer; 2227 context.SetImmediateSigned (sp_offset); 2228 2229 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2230 return false; 2231 } 2232 return true; 2233 } 2234 2235 // SVC (previously SWI) 2236 bool 2237 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2238 { 2239 #if 0 2240 // ARM pseudo code... 2241 if (ConditionPassed()) 2242 { 2243 EncodingSpecificOperations(); 2244 CallSupervisor(); 2245 } 2246 #endif 2247 2248 bool success = false; 2249 2250 if (ConditionPassed(opcode)) 2251 { 2252 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2253 addr_t lr; // next instruction address 2254 if (!success) 2255 return false; 2256 uint32_t imm32; // the immediate constant 2257 uint32_t mode; // ARM or Thumb mode 2258 switch (encoding) { 2259 case eEncodingT1: 2260 lr = (pc + 2) | 1u; // return address 2261 imm32 = Bits32(opcode, 7, 0); 2262 mode = eModeThumb; 2263 break; 2264 case eEncodingA1: 2265 lr = pc + 4; // return address 2266 imm32 = Bits32(opcode, 23, 0); 2267 mode = eModeARM; 2268 break; 2269 default: 2270 return false; 2271 } 2272 2273 EmulateInstruction::Context context; 2274 context.type = EmulateInstruction::eContextSupervisorCall; 2275 context.SetISAAndImmediate (mode, imm32); 2276 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2277 return false; 2278 } 2279 return true; 2280 } 2281 2282 // If Then makes up to four following instructions (the IT block) conditional. 2283 bool 2284 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2285 { 2286 #if 0 2287 // ARM pseudo code... 2288 EncodingSpecificOperations(); 2289 ITSTATE.IT<7:0> = firstcond:mask; 2290 #endif 2291 2292 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2293 return true; 2294 } 2295 2296 bool 2297 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2298 { 2299 // NOP, nothing to do... 2300 return true; 2301 } 2302 2303 // Branch causes a branch to a target address. 2304 bool 2305 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2306 { 2307 #if 0 2308 // ARM pseudo code... 2309 if (ConditionPassed()) 2310 { 2311 EncodingSpecificOperations(); 2312 BranchWritePC(PC + imm32); 2313 } 2314 #endif 2315 2316 bool success = false; 2317 2318 if (ConditionPassed(opcode)) 2319 { 2320 EmulateInstruction::Context context; 2321 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2322 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2323 if (!success) 2324 return false; 2325 addr_t target; // target address 2326 int32_t imm32; // PC-relative offset 2327 switch (encoding) { 2328 case eEncodingT1: 2329 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2330 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2331 target = pc + imm32; 2332 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2333 break; 2334 case eEncodingT2: 2335 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2336 target = pc + imm32; 2337 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2338 break; 2339 case eEncodingT3: 2340 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2341 { 2342 if (Bits32(opcode, 25, 23) == 7) 2343 return false; // See Branches and miscellaneous control on page A6-235. 2344 2345 uint32_t S = Bit32(opcode, 26); 2346 uint32_t imm6 = Bits32(opcode, 21, 16); 2347 uint32_t J1 = Bit32(opcode, 13); 2348 uint32_t J2 = Bit32(opcode, 11); 2349 uint32_t imm11 = Bits32(opcode, 10, 0); 2350 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2351 imm32 = llvm::SignExtend32<21>(imm21); 2352 target = pc + imm32; 2353 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2354 break; 2355 } 2356 case eEncodingT4: 2357 { 2358 uint32_t S = Bit32(opcode, 26); 2359 uint32_t imm10 = Bits32(opcode, 25, 16); 2360 uint32_t J1 = Bit32(opcode, 13); 2361 uint32_t J2 = Bit32(opcode, 11); 2362 uint32_t imm11 = Bits32(opcode, 10, 0); 2363 uint32_t I1 = !(J1 ^ S); 2364 uint32_t I2 = !(J2 ^ S); 2365 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2366 imm32 = llvm::SignExtend32<25>(imm25); 2367 target = pc + imm32; 2368 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2369 break; 2370 } 2371 case eEncodingA1: 2372 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2373 target = pc + imm32; 2374 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2375 break; 2376 default: 2377 return false; 2378 } 2379 if (!BranchWritePC(context, target)) 2380 return false; 2381 } 2382 return true; 2383 } 2384 2385 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2386 // zero and conditionally branch forward a constant value. They do not affect the condition flags. 2387 // CBNZ, CBZ 2388 bool 2389 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2390 { 2391 #if 0 2392 // ARM pseudo code... 2393 EncodingSpecificOperations(); 2394 if nonzero ^ IsZero(R[n]) then 2395 BranchWritePC(PC + imm32); 2396 #endif 2397 2398 bool success = false; 2399 2400 // Read the register value from the operand register Rn. 2401 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2402 if (!success) 2403 return false; 2404 2405 EmulateInstruction::Context context; 2406 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2407 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2408 if (!success) 2409 return false; 2410 2411 addr_t target; // target address 2412 uint32_t imm32; // PC-relative offset to branch forward 2413 bool nonzero; 2414 switch (encoding) { 2415 case eEncodingT1: 2416 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2417 nonzero = BitIsSet(opcode, 11); 2418 target = pc + imm32; 2419 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2420 break; 2421 default: 2422 return false; 2423 } 2424 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2425 if (!BranchWritePC(context, target)) 2426 return false; 2427 2428 return true; 2429 } 2430 2431 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2432 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2433 // The branch length is twice the value of the byte returned from the table. 2434 // 2435 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2436 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2437 // The branch length is twice the value of the halfword returned from the table. 2438 // TBB, TBH 2439 bool 2440 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2441 { 2442 #if 0 2443 // ARM pseudo code... 2444 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2445 if is_tbh then 2446 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2447 else 2448 halfwords = UInt(MemU[R[n]+R[m], 1]); 2449 BranchWritePC(PC + 2*halfwords); 2450 #endif 2451 2452 bool success = false; 2453 2454 if (ConditionPassed(opcode)) 2455 { 2456 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2457 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2458 bool is_tbh; // true if table branch halfword 2459 switch (encoding) { 2460 case eEncodingT1: 2461 Rn = Bits32(opcode, 19, 16); 2462 Rm = Bits32(opcode, 3, 0); 2463 is_tbh = BitIsSet(opcode, 4); 2464 if (Rn == 13 || BadReg(Rm)) 2465 return false; 2466 if (InITBlock() && !LastInITBlock()) 2467 return false; 2468 break; 2469 default: 2470 return false; 2471 } 2472 2473 // Read the address of the table from the operand register Rn. 2474 // The PC can be used, in which case the table immediately follows this instruction. 2475 uint32_t base = ReadCoreReg(Rn, &success); 2476 if (!success) 2477 return false; 2478 2479 // the table index 2480 uint32_t index = ReadCoreReg(Rm, &success); 2481 if (!success) 2482 return false; 2483 2484 // the offsetted table address 2485 addr_t addr = base + (is_tbh ? index*2 : index); 2486 2487 // PC-relative offset to branch forward 2488 EmulateInstruction::Context context; 2489 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2490 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2491 if (!success) 2492 return false; 2493 2494 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2495 if (!success) 2496 return false; 2497 2498 // target address 2499 addr_t target = pc + offset; 2500 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2501 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2502 2503 if (!BranchWritePC(context, target)) 2504 return false; 2505 } 2506 2507 return true; 2508 } 2509 2510 // This instruction adds an immediate value to a register value, and writes the result to the destination register. 2511 // It can optionally update the condition flags based on the result. 2512 bool 2513 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2514 { 2515 #if 0 2516 if ConditionPassed() then 2517 EncodingSpecificOperations(); 2518 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2519 R[d] = result; 2520 if setflags then 2521 APSR.N = result<31>; 2522 APSR.Z = IsZeroBit(result); 2523 APSR.C = carry; 2524 APSR.V = overflow; 2525 #endif 2526 2527 bool success = false; 2528 2529 if (ConditionPassed(opcode)) 2530 { 2531 uint32_t d; 2532 uint32_t n; 2533 bool setflags; 2534 uint32_t imm32; 2535 uint32_t carry_out; 2536 2537 //EncodingSpecificOperations(); 2538 switch (encoding) 2539 { 2540 case eEncodingT1: 2541 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2542 d = Bits32 (opcode, 2, 0); 2543 n = Bits32 (opcode, 5, 3); 2544 setflags = !InITBlock(); 2545 imm32 = Bits32 (opcode, 8,6); 2546 2547 break; 2548 2549 case eEncodingT2: 2550 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2551 d = Bits32 (opcode, 10, 8); 2552 n = Bits32 (opcode, 10, 8); 2553 setflags = !InITBlock(); 2554 imm32 = Bits32 (opcode, 7, 0); 2555 2556 break; 2557 2558 case eEncodingT3: 2559 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2560 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2561 d = Bits32 (opcode, 11, 8); 2562 n = Bits32 (opcode, 19, 16); 2563 setflags = BitIsSet (opcode, 20); 2564 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2565 2566 // if Rn == '1101' then SEE ADD (SP plus immediate); 2567 if (n == 13) 2568 return EmulateADDSPImm(opcode, eEncodingT3); 2569 2570 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2571 if (BadReg (d) || (n == 15)) 2572 return false; 2573 2574 break; 2575 2576 case eEncodingT4: 2577 { 2578 // if Rn == '1111' then SEE ADR; 2579 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2580 d = Bits32 (opcode, 11, 8); 2581 n = Bits32 (opcode, 19, 16); 2582 setflags = false; 2583 uint32_t i = Bit32 (opcode, 26); 2584 uint32_t imm3 = Bits32 (opcode, 14, 12); 2585 uint32_t imm8 = Bits32 (opcode, 7, 0); 2586 imm32 = (i << 11) | (imm3 << 8) | imm8; 2587 2588 // if Rn == '1101' then SEE ADD (SP plus immediate); 2589 if (n == 13) 2590 return EmulateADDSPImm(opcode, eEncodingT4); 2591 2592 // if BadReg(d) then UNPREDICTABLE; 2593 if (BadReg (d)) 2594 return false; 2595 2596 break; 2597 } 2598 2599 default: 2600 return false; 2601 } 2602 2603 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2604 if (!success) 2605 return false; 2606 2607 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2608 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2609 2610 RegisterInfo reg_n; 2611 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2612 2613 EmulateInstruction::Context context; 2614 context.type = eContextArithmetic; 2615 context.SetRegisterPlusOffset (reg_n, imm32); 2616 2617 //R[d] = result; 2618 //if setflags then 2619 //APSR.N = result<31>; 2620 //APSR.Z = IsZeroBit(result); 2621 //APSR.C = carry; 2622 //APSR.V = overflow; 2623 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2624 return false; 2625 2626 } 2627 return true; 2628 } 2629 2630 // This instruction adds an immediate value to a register value, and writes the result to the destination 2631 // register. It can optionally update the condition flags based on the result. 2632 bool 2633 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2634 { 2635 #if 0 2636 // ARM pseudo code... 2637 if ConditionPassed() then 2638 EncodingSpecificOperations(); 2639 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2640 if d == 15 then 2641 ALUWritePC(result); // setflags is always FALSE here 2642 else 2643 R[d] = result; 2644 if setflags then 2645 APSR.N = result<31>; 2646 APSR.Z = IsZeroBit(result); 2647 APSR.C = carry; 2648 APSR.V = overflow; 2649 #endif 2650 2651 bool success = false; 2652 2653 if (ConditionPassed(opcode)) 2654 { 2655 uint32_t Rd, Rn; 2656 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2657 bool setflags; 2658 switch (encoding) 2659 { 2660 case eEncodingA1: 2661 Rd = Bits32(opcode, 15, 12); 2662 Rn = Bits32(opcode, 19, 16); 2663 setflags = BitIsSet(opcode, 20); 2664 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2665 break; 2666 default: 2667 return false; 2668 } 2669 2670 // Read the first operand. 2671 uint32_t val1 = ReadCoreReg(Rn, &success); 2672 if (!success) 2673 return false; 2674 2675 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2676 2677 EmulateInstruction::Context context; 2678 if (Rd == 13) 2679 context.type = EmulateInstruction::eContextAdjustStackPointer; 2680 else if (Rd == GetFramePointerRegisterNumber()) 2681 context.type = EmulateInstruction::eContextSetFramePointer; 2682 else 2683 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2684 2685 RegisterInfo dwarf_reg; 2686 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2687 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2688 2689 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2690 return false; 2691 } 2692 return true; 2693 } 2694 2695 // This instruction adds a register value and an optionally-shifted register value, and writes the result 2696 // to the destination register. It can optionally update the condition flags based on the result. 2697 bool 2698 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2699 { 2700 #if 0 2701 // ARM pseudo code... 2702 if ConditionPassed() then 2703 EncodingSpecificOperations(); 2704 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2705 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2706 if d == 15 then 2707 ALUWritePC(result); // setflags is always FALSE here 2708 else 2709 R[d] = result; 2710 if setflags then 2711 APSR.N = result<31>; 2712 APSR.Z = IsZeroBit(result); 2713 APSR.C = carry; 2714 APSR.V = overflow; 2715 #endif 2716 2717 bool success = false; 2718 2719 if (ConditionPassed(opcode)) 2720 { 2721 uint32_t Rd, Rn, Rm; 2722 ARM_ShifterType shift_t; 2723 uint32_t shift_n; // the shift applied to the value read from Rm 2724 bool setflags; 2725 switch (encoding) 2726 { 2727 case eEncodingT1: 2728 Rd = Bits32(opcode, 2, 0); 2729 Rn = Bits32(opcode, 5, 3); 2730 Rm = Bits32(opcode, 8, 6); 2731 setflags = !InITBlock(); 2732 shift_t = SRType_LSL; 2733 shift_n = 0; 2734 break; 2735 case eEncodingT2: 2736 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2737 Rm = Bits32(opcode, 6, 3); 2738 setflags = false; 2739 shift_t = SRType_LSL; 2740 shift_n = 0; 2741 if (Rn == 15 && Rm == 15) 2742 return false; 2743 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2744 return false; 2745 break; 2746 case eEncodingA1: 2747 Rd = Bits32(opcode, 15, 12); 2748 Rn = Bits32(opcode, 19, 16); 2749 Rm = Bits32(opcode, 3, 0); 2750 setflags = BitIsSet(opcode, 20); 2751 shift_n = DecodeImmShiftARM(opcode, shift_t); 2752 break; 2753 default: 2754 return false; 2755 } 2756 2757 // Read the first operand. 2758 uint32_t val1 = ReadCoreReg(Rn, &success); 2759 if (!success) 2760 return false; 2761 2762 // Read the second operand. 2763 uint32_t val2 = ReadCoreReg(Rm, &success); 2764 if (!success) 2765 return false; 2766 2767 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2768 if (!success) 2769 return false; 2770 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2771 2772 EmulateInstruction::Context context; 2773 context.type = eContextArithmetic; 2774 RegisterInfo op1_reg; 2775 RegisterInfo op2_reg; 2776 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2777 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2778 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2779 2780 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2781 return false; 2782 } 2783 return true; 2784 } 2785 2786 // Compare Negative (immediate) adds a register value and an immediate value. 2787 // It updates the condition flags based on the result, and discards the result. 2788 bool 2789 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2790 { 2791 #if 0 2792 // ARM pseudo code... 2793 if ConditionPassed() then 2794 EncodingSpecificOperations(); 2795 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2796 APSR.N = result<31>; 2797 APSR.Z = IsZeroBit(result); 2798 APSR.C = carry; 2799 APSR.V = overflow; 2800 #endif 2801 2802 bool success = false; 2803 2804 uint32_t Rn; // the first operand 2805 uint32_t imm32; // the immediate value to be compared with 2806 switch (encoding) { 2807 case eEncodingT1: 2808 Rn = Bits32(opcode, 19, 16); 2809 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2810 if (Rn == 15) 2811 return false; 2812 break; 2813 case eEncodingA1: 2814 Rn = Bits32(opcode, 19, 16); 2815 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2816 break; 2817 default: 2818 return false; 2819 } 2820 // Read the register value from the operand register Rn. 2821 uint32_t reg_val = ReadCoreReg(Rn, &success); 2822 if (!success) 2823 return false; 2824 2825 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2826 2827 EmulateInstruction::Context context; 2828 context.type = EmulateInstruction::eContextImmediate; 2829 context.SetNoArgs (); 2830 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2831 return false; 2832 2833 return true; 2834 } 2835 2836 // Compare Negative (register) adds a register value and an optionally-shifted register value. 2837 // It updates the condition flags based on the result, and discards the result. 2838 bool 2839 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2840 { 2841 #if 0 2842 // ARM pseudo code... 2843 if ConditionPassed() then 2844 EncodingSpecificOperations(); 2845 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2846 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2847 APSR.N = result<31>; 2848 APSR.Z = IsZeroBit(result); 2849 APSR.C = carry; 2850 APSR.V = overflow; 2851 #endif 2852 2853 bool success = false; 2854 2855 uint32_t Rn; // the first operand 2856 uint32_t Rm; // the second operand 2857 ARM_ShifterType shift_t; 2858 uint32_t shift_n; // the shift applied to the value read from Rm 2859 switch (encoding) { 2860 case eEncodingT1: 2861 Rn = Bits32(opcode, 2, 0); 2862 Rm = Bits32(opcode, 5, 3); 2863 shift_t = SRType_LSL; 2864 shift_n = 0; 2865 break; 2866 case eEncodingT2: 2867 Rn = Bits32(opcode, 19, 16); 2868 Rm = Bits32(opcode, 3, 0); 2869 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2870 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2871 if (Rn == 15 || BadReg(Rm)) 2872 return false; 2873 break; 2874 case eEncodingA1: 2875 Rn = Bits32(opcode, 19, 16); 2876 Rm = Bits32(opcode, 3, 0); 2877 shift_n = DecodeImmShiftARM(opcode, shift_t); 2878 break; 2879 default: 2880 return false; 2881 } 2882 // Read the register value from register Rn. 2883 uint32_t val1 = ReadCoreReg(Rn, &success); 2884 if (!success) 2885 return false; 2886 2887 // Read the register value from register Rm. 2888 uint32_t val2 = ReadCoreReg(Rm, &success); 2889 if (!success) 2890 return false; 2891 2892 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2893 if (!success) 2894 return false; 2895 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2896 2897 EmulateInstruction::Context context; 2898 context.type = EmulateInstruction::eContextImmediate; 2899 context.SetNoArgs(); 2900 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2901 return false; 2902 2903 return true; 2904 } 2905 2906 // Compare (immediate) subtracts an immediate value from a register value. 2907 // It updates the condition flags based on the result, and discards the result. 2908 bool 2909 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2910 { 2911 #if 0 2912 // ARM pseudo code... 2913 if ConditionPassed() then 2914 EncodingSpecificOperations(); 2915 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2916 APSR.N = result<31>; 2917 APSR.Z = IsZeroBit(result); 2918 APSR.C = carry; 2919 APSR.V = overflow; 2920 #endif 2921 2922 bool success = false; 2923 2924 uint32_t Rn; // the first operand 2925 uint32_t imm32; // the immediate value to be compared with 2926 switch (encoding) { 2927 case eEncodingT1: 2928 Rn = Bits32(opcode, 10, 8); 2929 imm32 = Bits32(opcode, 7, 0); 2930 break; 2931 case eEncodingT2: 2932 Rn = Bits32(opcode, 19, 16); 2933 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2934 if (Rn == 15) 2935 return false; 2936 break; 2937 case eEncodingA1: 2938 Rn = Bits32(opcode, 19, 16); 2939 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2940 break; 2941 default: 2942 return false; 2943 } 2944 // Read the register value from the operand register Rn. 2945 uint32_t reg_val = ReadCoreReg(Rn, &success); 2946 if (!success) 2947 return false; 2948 2949 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2950 2951 EmulateInstruction::Context context; 2952 context.type = EmulateInstruction::eContextImmediate; 2953 context.SetNoArgs (); 2954 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2955 return false; 2956 2957 return true; 2958 } 2959 2960 // Compare (register) subtracts an optionally-shifted register value from a register value. 2961 // It updates the condition flags based on the result, and discards the result. 2962 bool 2963 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2964 { 2965 #if 0 2966 // ARM pseudo code... 2967 if ConditionPassed() then 2968 EncodingSpecificOperations(); 2969 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2970 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2971 APSR.N = result<31>; 2972 APSR.Z = IsZeroBit(result); 2973 APSR.C = carry; 2974 APSR.V = overflow; 2975 #endif 2976 2977 bool success = false; 2978 2979 uint32_t Rn; // the first operand 2980 uint32_t Rm; // the second operand 2981 ARM_ShifterType shift_t; 2982 uint32_t shift_n; // the shift applied to the value read from Rm 2983 switch (encoding) { 2984 case eEncodingT1: 2985 Rn = Bits32(opcode, 2, 0); 2986 Rm = Bits32(opcode, 5, 3); 2987 shift_t = SRType_LSL; 2988 shift_n = 0; 2989 break; 2990 case eEncodingT2: 2991 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2992 Rm = Bits32(opcode, 6, 3); 2993 shift_t = SRType_LSL; 2994 shift_n = 0; 2995 if (Rn < 8 && Rm < 8) 2996 return false; 2997 if (Rn == 15 || Rm == 15) 2998 return false; 2999 break; 3000 case eEncodingT3: 3001 Rn = Bits32(opcode, 19, 16); 3002 Rm = Bits32(opcode, 3, 0); 3003 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3004 if (Rn == 15 || BadReg(Rm)) 3005 return false; 3006 break; 3007 case eEncodingA1: 3008 Rn = Bits32(opcode, 19, 16); 3009 Rm = Bits32(opcode, 3, 0); 3010 shift_n = DecodeImmShiftARM(opcode, shift_t); 3011 break; 3012 default: 3013 return false; 3014 } 3015 // Read the register value from register Rn. 3016 uint32_t val1 = ReadCoreReg(Rn, &success); 3017 if (!success) 3018 return false; 3019 3020 // Read the register value from register Rm. 3021 uint32_t val2 = ReadCoreReg(Rm, &success); 3022 if (!success) 3023 return false; 3024 3025 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3026 if (!success) 3027 return false; 3028 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3029 3030 EmulateInstruction::Context context; 3031 context.type = EmulateInstruction::eContextImmediate; 3032 context.SetNoArgs(); 3033 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3034 return false; 3035 3036 return true; 3037 } 3038 3039 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 3040 // shifting in copies of its sign bit, and writes the result to the destination register. It can 3041 // optionally update the condition flags based on the result. 3042 bool 3043 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 3044 { 3045 #if 0 3046 // ARM pseudo code... 3047 if ConditionPassed() then 3048 EncodingSpecificOperations(); 3049 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3050 if d == 15 then // Can only occur for ARM encoding 3051 ALUWritePC(result); // setflags is always FALSE here 3052 else 3053 R[d] = result; 3054 if setflags then 3055 APSR.N = result<31>; 3056 APSR.Z = IsZeroBit(result); 3057 APSR.C = carry; 3058 // APSR.V unchanged 3059 #endif 3060 3061 return EmulateShiftImm (opcode, encoding, SRType_ASR); 3062 } 3063 3064 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 3065 // shifting in copies of its sign bit, and writes the result to the destination register. 3066 // The variable number of bits is read from the bottom byte of a register. It can optionally update 3067 // the condition flags based on the result. 3068 bool 3069 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 3070 { 3071 #if 0 3072 // ARM pseudo code... 3073 if ConditionPassed() then 3074 EncodingSpecificOperations(); 3075 shift_n = UInt(R[m]<7:0>); 3076 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3077 R[d] = result; 3078 if setflags then 3079 APSR.N = result<31>; 3080 APSR.Z = IsZeroBit(result); 3081 APSR.C = carry; 3082 // APSR.V unchanged 3083 #endif 3084 3085 return EmulateShiftReg (opcode, encoding, SRType_ASR); 3086 } 3087 3088 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 3089 // shifting in zeros, and writes the result to the destination register. It can optionally 3090 // update the condition flags based on the result. 3091 bool 3092 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 3093 { 3094 #if 0 3095 // ARM pseudo code... 3096 if ConditionPassed() then 3097 EncodingSpecificOperations(); 3098 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3099 if d == 15 then // Can only occur for ARM encoding 3100 ALUWritePC(result); // setflags is always FALSE here 3101 else 3102 R[d] = result; 3103 if setflags then 3104 APSR.N = result<31>; 3105 APSR.Z = IsZeroBit(result); 3106 APSR.C = carry; 3107 // APSR.V unchanged 3108 #endif 3109 3110 return EmulateShiftImm (opcode, encoding, SRType_LSL); 3111 } 3112 3113 // Logical Shift Left (register) shifts a register value left by a variable number of bits, 3114 // shifting in zeros, and writes the result to the destination register. The variable number 3115 // of bits is read from the bottom byte of a register. It can optionally update the condition 3116 // flags based on the result. 3117 bool 3118 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 3119 { 3120 #if 0 3121 // ARM pseudo code... 3122 if ConditionPassed() then 3123 EncodingSpecificOperations(); 3124 shift_n = UInt(R[m]<7:0>); 3125 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3126 R[d] = result; 3127 if setflags then 3128 APSR.N = result<31>; 3129 APSR.Z = IsZeroBit(result); 3130 APSR.C = carry; 3131 // APSR.V unchanged 3132 #endif 3133 3134 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3135 } 3136 3137 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3138 // shifting in zeros, and writes the result to the destination register. It can optionally 3139 // update the condition flags based on the result. 3140 bool 3141 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3142 { 3143 #if 0 3144 // ARM pseudo code... 3145 if ConditionPassed() then 3146 EncodingSpecificOperations(); 3147 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3148 if d == 15 then // Can only occur for ARM encoding 3149 ALUWritePC(result); // setflags is always FALSE here 3150 else 3151 R[d] = result; 3152 if setflags then 3153 APSR.N = result<31>; 3154 APSR.Z = IsZeroBit(result); 3155 APSR.C = carry; 3156 // APSR.V unchanged 3157 #endif 3158 3159 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3160 } 3161 3162 // Logical Shift Right (register) shifts a register value right by a variable number of bits, 3163 // shifting in zeros, and writes the result to the destination register. The variable number 3164 // of bits is read from the bottom byte of a register. It can optionally update the condition 3165 // flags based on the result. 3166 bool 3167 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3168 { 3169 #if 0 3170 // ARM pseudo code... 3171 if ConditionPassed() then 3172 EncodingSpecificOperations(); 3173 shift_n = UInt(R[m]<7:0>); 3174 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3175 R[d] = result; 3176 if setflags then 3177 APSR.N = result<31>; 3178 APSR.Z = IsZeroBit(result); 3179 APSR.C = carry; 3180 // APSR.V unchanged 3181 #endif 3182 3183 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3184 } 3185 3186 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3187 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3188 // It can optionally update the condition flags based on the result. 3189 bool 3190 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3191 { 3192 #if 0 3193 // ARM pseudo code... 3194 if ConditionPassed() then 3195 EncodingSpecificOperations(); 3196 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3197 if d == 15 then // Can only occur for ARM encoding 3198 ALUWritePC(result); // setflags is always FALSE here 3199 else 3200 R[d] = result; 3201 if setflags then 3202 APSR.N = result<31>; 3203 APSR.Z = IsZeroBit(result); 3204 APSR.C = carry; 3205 // APSR.V unchanged 3206 #endif 3207 3208 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3209 } 3210 3211 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3212 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3213 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3214 // flags based on the result. 3215 bool 3216 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3217 { 3218 #if 0 3219 // ARM pseudo code... 3220 if ConditionPassed() then 3221 EncodingSpecificOperations(); 3222 shift_n = UInt(R[m]<7:0>); 3223 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3224 R[d] = result; 3225 if setflags then 3226 APSR.N = result<31>; 3227 APSR.Z = IsZeroBit(result); 3228 APSR.C = carry; 3229 // APSR.V unchanged 3230 #endif 3231 3232 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3233 } 3234 3235 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3236 // with the carry flag shifted into bit [31]. 3237 // 3238 // RRX can optionally update the condition flags based on the result. 3239 // In that case, bit [0] is shifted into the carry flag. 3240 bool 3241 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3242 { 3243 #if 0 3244 // ARM pseudo code... 3245 if ConditionPassed() then 3246 EncodingSpecificOperations(); 3247 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3248 if d == 15 then // Can only occur for ARM encoding 3249 ALUWritePC(result); // setflags is always FALSE here 3250 else 3251 R[d] = result; 3252 if setflags then 3253 APSR.N = result<31>; 3254 APSR.Z = IsZeroBit(result); 3255 APSR.C = carry; 3256 // APSR.V unchanged 3257 #endif 3258 3259 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3260 } 3261 3262 bool 3263 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3264 { 3265 // assert(shift_type == SRType_ASR 3266 // || shift_type == SRType_LSL 3267 // || shift_type == SRType_LSR 3268 // || shift_type == SRType_ROR 3269 // || shift_type == SRType_RRX); 3270 3271 bool success = false; 3272 3273 if (ConditionPassed(opcode)) 3274 { 3275 uint32_t Rd; // the destination register 3276 uint32_t Rm; // the first operand register 3277 uint32_t imm5; // encoding for the shift amount 3278 uint32_t carry; // the carry bit after the shift operation 3279 bool setflags; 3280 3281 // Special case handling! 3282 // A8.6.139 ROR (immediate) -- Encoding T1 3283 ARMEncoding use_encoding = encoding; 3284 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3285 { 3286 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3287 // have the same decoding of bit fields as the other Thumb2 shift operations. 3288 use_encoding = eEncodingT2; 3289 } 3290 3291 switch (use_encoding) { 3292 case eEncodingT1: 3293 // Due to the above special case handling! 3294 if (shift_type == SRType_ROR) 3295 return false; 3296 3297 Rd = Bits32(opcode, 2, 0); 3298 Rm = Bits32(opcode, 5, 3); 3299 setflags = !InITBlock(); 3300 imm5 = Bits32(opcode, 10, 6); 3301 break; 3302 case eEncodingT2: 3303 // A8.6.141 RRX 3304 // There's no imm form of RRX instructions. 3305 if (shift_type == SRType_RRX) 3306 return false; 3307 3308 Rd = Bits32(opcode, 11, 8); 3309 Rm = Bits32(opcode, 3, 0); 3310 setflags = BitIsSet(opcode, 20); 3311 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3312 if (BadReg(Rd) || BadReg(Rm)) 3313 return false; 3314 break; 3315 case eEncodingA1: 3316 Rd = Bits32(opcode, 15, 12); 3317 Rm = Bits32(opcode, 3, 0); 3318 setflags = BitIsSet(opcode, 20); 3319 imm5 = Bits32(opcode, 11, 7); 3320 break; 3321 default: 3322 return false; 3323 } 3324 3325 // A8.6.139 ROR (immediate) 3326 if (shift_type == SRType_ROR && imm5 == 0) 3327 shift_type = SRType_RRX; 3328 3329 // Get the first operand. 3330 uint32_t value = ReadCoreReg (Rm, &success); 3331 if (!success) 3332 return false; 3333 3334 // Decode the shift amount if not RRX. 3335 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3336 3337 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3338 if (!success) 3339 return false; 3340 3341 // The context specifies that an immediate is to be moved into Rd. 3342 EmulateInstruction::Context context; 3343 context.type = EmulateInstruction::eContextImmediate; 3344 context.SetNoArgs (); 3345 3346 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3347 return false; 3348 } 3349 return true; 3350 } 3351 3352 bool 3353 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3354 { 3355 // assert(shift_type == SRType_ASR 3356 // || shift_type == SRType_LSL 3357 // || shift_type == SRType_LSR 3358 // || shift_type == SRType_ROR); 3359 3360 bool success = false; 3361 3362 if (ConditionPassed(opcode)) 3363 { 3364 uint32_t Rd; // the destination register 3365 uint32_t Rn; // the first operand register 3366 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3367 uint32_t carry; // the carry bit after the shift operation 3368 bool setflags; 3369 switch (encoding) { 3370 case eEncodingT1: 3371 Rd = Bits32(opcode, 2, 0); 3372 Rn = Rd; 3373 Rm = Bits32(opcode, 5, 3); 3374 setflags = !InITBlock(); 3375 break; 3376 case eEncodingT2: 3377 Rd = Bits32(opcode, 11, 8); 3378 Rn = Bits32(opcode, 19, 16); 3379 Rm = Bits32(opcode, 3, 0); 3380 setflags = BitIsSet(opcode, 20); 3381 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3382 return false; 3383 break; 3384 case eEncodingA1: 3385 Rd = Bits32(opcode, 15, 12); 3386 Rn = Bits32(opcode, 3, 0); 3387 Rm = Bits32(opcode, 11, 8); 3388 setflags = BitIsSet(opcode, 20); 3389 if (Rd == 15 || Rn == 15 || Rm == 15) 3390 return false; 3391 break; 3392 default: 3393 return false; 3394 } 3395 3396 // Get the first operand. 3397 uint32_t value = ReadCoreReg (Rn, &success); 3398 if (!success) 3399 return false; 3400 // Get the Rm register content. 3401 uint32_t val = ReadCoreReg (Rm, &success); 3402 if (!success) 3403 return false; 3404 3405 // Get the shift amount. 3406 uint32_t amt = Bits32(val, 7, 0); 3407 3408 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3409 if (!success) 3410 return false; 3411 3412 // The context specifies that an immediate is to be moved into Rd. 3413 EmulateInstruction::Context context; 3414 context.type = EmulateInstruction::eContextImmediate; 3415 context.SetNoArgs (); 3416 3417 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3418 return false; 3419 } 3420 return true; 3421 } 3422 3423 // LDM loads multiple registers from consecutive memory locations, using an 3424 // address from a base register. Optionally the address just above the highest of those locations 3425 // can be written back to the base register. 3426 bool 3427 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3428 { 3429 #if 0 3430 // ARM pseudo code... 3431 if ConditionPassed() 3432 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3433 address = R[n]; 3434 3435 for i = 0 to 14 3436 if registers<i> == '1' then 3437 R[i] = MemA[address, 4]; address = address + 4; 3438 if registers<15> == '1' then 3439 LoadWritePC (MemA[address, 4]); 3440 3441 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3442 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3443 3444 #endif 3445 3446 bool success = false; 3447 if (ConditionPassed(opcode)) 3448 { 3449 uint32_t n; 3450 uint32_t registers = 0; 3451 bool wback; 3452 const uint32_t addr_byte_size = GetAddressByteSize(); 3453 switch (encoding) 3454 { 3455 case eEncodingT1: 3456 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3457 n = Bits32 (opcode, 10, 8); 3458 registers = Bits32 (opcode, 7, 0); 3459 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3460 wback = BitIsClear (registers, n); 3461 // if BitCount(registers) < 1 then UNPREDICTABLE; 3462 if (BitCount(registers) < 1) 3463 return false; 3464 break; 3465 case eEncodingT2: 3466 // if W == '1' && Rn == '1101' then SEE POP; 3467 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3468 n = Bits32 (opcode, 19, 16); 3469 registers = Bits32 (opcode, 15, 0); 3470 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3471 wback = BitIsSet (opcode, 21); 3472 3473 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3474 if ((n == 15) 3475 || (BitCount (registers) < 2) 3476 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3477 return false; 3478 3479 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3480 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3481 return false; 3482 3483 // if wback && registers<n> == '1' then UNPREDICTABLE; 3484 if (wback 3485 && BitIsSet (registers, n)) 3486 return false; 3487 break; 3488 3489 case eEncodingA1: 3490 n = Bits32 (opcode, 19, 16); 3491 registers = Bits32 (opcode, 15, 0); 3492 wback = BitIsSet (opcode, 21); 3493 if ((n == 15) 3494 || (BitCount (registers) < 1)) 3495 return false; 3496 break; 3497 default: 3498 return false; 3499 } 3500 3501 int32_t offset = 0; 3502 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3503 if (!success) 3504 return false; 3505 3506 EmulateInstruction::Context context; 3507 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3508 RegisterInfo dwarf_reg; 3509 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3510 context.SetRegisterPlusOffset (dwarf_reg, offset); 3511 3512 for (int i = 0; i < 14; ++i) 3513 { 3514 if (BitIsSet (registers, i)) 3515 { 3516 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3517 context.SetRegisterPlusOffset (dwarf_reg, offset); 3518 if (wback && (n == 13)) // Pop Instruction 3519 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3520 3521 // R[i] = MemA [address, 4]; address = address + 4; 3522 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3523 if (!success) 3524 return false; 3525 3526 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3527 return false; 3528 3529 offset += addr_byte_size; 3530 } 3531 } 3532 3533 if (BitIsSet (registers, 15)) 3534 { 3535 //LoadWritePC (MemA [address, 4]); 3536 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3537 context.SetRegisterPlusOffset (dwarf_reg, offset); 3538 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3539 if (!success) 3540 return false; 3541 // In ARMv5T and above, this is an interworking branch. 3542 if (!LoadWritePC(context, data)) 3543 return false; 3544 } 3545 3546 if (wback && BitIsClear (registers, n)) 3547 { 3548 // R[n] = R[n] + 4 * BitCount (registers) 3549 int32_t offset = addr_byte_size * BitCount (registers); 3550 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3551 context.SetRegisterPlusOffset (dwarf_reg, offset); 3552 3553 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3554 return false; 3555 } 3556 if (wback && BitIsSet (registers, n)) 3557 // R[n] bits(32) UNKNOWN; 3558 return WriteBits32Unknown (n); 3559 } 3560 return true; 3561 } 3562 3563 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3564 // The consecutive memory locations end at this address and the address just below the lowest of those locations 3565 // can optionally be written back to the base register. 3566 bool 3567 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3568 { 3569 #if 0 3570 // ARM pseudo code... 3571 if ConditionPassed() then 3572 EncodingSpecificOperations(); 3573 address = R[n] - 4*BitCount(registers) + 4; 3574 3575 for i = 0 to 14 3576 if registers<i> == '1' then 3577 R[i] = MemA[address,4]; address = address + 4; 3578 3579 if registers<15> == '1' then 3580 LoadWritePC(MemA[address,4]); 3581 3582 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3583 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3584 #endif 3585 3586 bool success = false; 3587 3588 if (ConditionPassed(opcode)) 3589 { 3590 uint32_t n; 3591 uint32_t registers = 0; 3592 bool wback; 3593 const uint32_t addr_byte_size = GetAddressByteSize(); 3594 3595 // EncodingSpecificOperations(); 3596 switch (encoding) 3597 { 3598 case eEncodingA1: 3599 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3600 n = Bits32 (opcode, 19, 16); 3601 registers = Bits32 (opcode, 15, 0); 3602 wback = BitIsSet (opcode, 21); 3603 3604 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3605 if ((n == 15) || (BitCount (registers) < 1)) 3606 return false; 3607 3608 break; 3609 3610 default: 3611 return false; 3612 } 3613 // address = R[n] - 4*BitCount(registers) + 4; 3614 3615 int32_t offset = 0; 3616 addr_t Rn = ReadCoreReg (n, &success); 3617 3618 if (!success) 3619 return false; 3620 3621 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3622 3623 EmulateInstruction::Context context; 3624 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3625 RegisterInfo dwarf_reg; 3626 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3627 context.SetRegisterPlusOffset (dwarf_reg, offset); 3628 3629 // for i = 0 to 14 3630 for (int i = 0; i < 14; ++i) 3631 { 3632 // if registers<i> == '1' then 3633 if (BitIsSet (registers, i)) 3634 { 3635 // R[i] = MemA[address,4]; address = address + 4; 3636 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3637 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3638 if (!success) 3639 return false; 3640 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3641 return false; 3642 offset += addr_byte_size; 3643 } 3644 } 3645 3646 // if registers<15> == '1' then 3647 // LoadWritePC(MemA[address,4]); 3648 if (BitIsSet (registers, 15)) 3649 { 3650 context.SetRegisterPlusOffset (dwarf_reg, offset); 3651 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3652 if (!success) 3653 return false; 3654 // In ARMv5T and above, this is an interworking branch. 3655 if (!LoadWritePC(context, data)) 3656 return false; 3657 } 3658 3659 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3660 if (wback && BitIsClear (registers, n)) 3661 { 3662 if (!success) 3663 return false; 3664 3665 offset = (addr_byte_size * BitCount (registers)) * -1; 3666 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3667 context.SetImmediateSigned (offset); 3668 addr_t addr = Rn + offset; 3669 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3670 return false; 3671 } 3672 3673 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3674 if (wback && BitIsSet (registers, n)) 3675 return WriteBits32Unknown (n); 3676 } 3677 return true; 3678 } 3679 3680 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3681 // consecutive memory locations end just below this address, and the address of the lowest of those locations can 3682 // be optionally written back to the base register. 3683 bool 3684 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3685 { 3686 #if 0 3687 // ARM pseudo code... 3688 if ConditionPassed() then 3689 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3690 address = R[n] - 4*BitCount(registers); 3691 3692 for i = 0 to 14 3693 if registers<i> == '1' then 3694 R[i] = MemA[address,4]; address = address + 4; 3695 if registers<15> == '1' then 3696 LoadWritePC(MemA[address,4]); 3697 3698 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3699 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3700 #endif 3701 3702 bool success = false; 3703 3704 if (ConditionPassed(opcode)) 3705 { 3706 uint32_t n; 3707 uint32_t registers = 0; 3708 bool wback; 3709 const uint32_t addr_byte_size = GetAddressByteSize(); 3710 switch (encoding) 3711 { 3712 case eEncodingT1: 3713 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3714 n = Bits32 (opcode, 19, 16); 3715 registers = Bits32 (opcode, 15, 0); 3716 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3717 wback = BitIsSet (opcode, 21); 3718 3719 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3720 if ((n == 15) 3721 || (BitCount (registers) < 2) 3722 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3723 return false; 3724 3725 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3726 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3727 return false; 3728 3729 // if wback && registers<n> == '1' then UNPREDICTABLE; 3730 if (wback && BitIsSet (registers, n)) 3731 return false; 3732 3733 break; 3734 3735 case eEncodingA1: 3736 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3737 n = Bits32 (opcode, 19, 16); 3738 registers = Bits32 (opcode, 15, 0); 3739 wback = BitIsSet (opcode, 21); 3740 3741 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3742 if ((n == 15) || (BitCount (registers) < 1)) 3743 return false; 3744 3745 break; 3746 3747 default: 3748 return false; 3749 } 3750 3751 // address = R[n] - 4*BitCount(registers); 3752 3753 int32_t offset = 0; 3754 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3755 3756 if (!success) 3757 return false; 3758 3759 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3760 EmulateInstruction::Context context; 3761 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3762 RegisterInfo dwarf_reg; 3763 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3764 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3765 3766 for (int i = 0; i < 14; ++i) 3767 { 3768 if (BitIsSet (registers, i)) 3769 { 3770 // R[i] = MemA[address,4]; address = address + 4; 3771 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3772 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3773 if (!success) 3774 return false; 3775 3776 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3777 return false; 3778 3779 offset += addr_byte_size; 3780 } 3781 } 3782 3783 // if registers<15> == '1' then 3784 // LoadWritePC(MemA[address,4]); 3785 if (BitIsSet (registers, 15)) 3786 { 3787 context.SetRegisterPlusOffset (dwarf_reg, offset); 3788 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3789 if (!success) 3790 return false; 3791 // In ARMv5T and above, this is an interworking branch. 3792 if (!LoadWritePC(context, data)) 3793 return false; 3794 } 3795 3796 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3797 if (wback && BitIsClear (registers, n)) 3798 { 3799 if (!success) 3800 return false; 3801 3802 offset = (addr_byte_size * BitCount (registers)) * -1; 3803 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3804 context.SetImmediateSigned (offset); 3805 addr_t addr = Rn + offset; 3806 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3807 return false; 3808 } 3809 3810 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3811 if (wback && BitIsSet (registers, n)) 3812 return WriteBits32Unknown (n); 3813 } 3814 return true; 3815 } 3816 3817 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3818 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3819 // optinoally be written back to the base register. 3820 bool 3821 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3822 { 3823 #if 0 3824 if ConditionPassed() then 3825 EncodingSpecificOperations(); 3826 address = R[n] + 4; 3827 3828 for i = 0 to 14 3829 if registers<i> == '1' then 3830 R[i] = MemA[address,4]; address = address + 4; 3831 if registers<15> == '1' then 3832 LoadWritePC(MemA[address,4]); 3833 3834 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3835 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3836 #endif 3837 3838 bool success = false; 3839 3840 if (ConditionPassed(opcode)) 3841 { 3842 uint32_t n; 3843 uint32_t registers = 0; 3844 bool wback; 3845 const uint32_t addr_byte_size = GetAddressByteSize(); 3846 switch (encoding) 3847 { 3848 case eEncodingA1: 3849 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3850 n = Bits32 (opcode, 19, 16); 3851 registers = Bits32 (opcode, 15, 0); 3852 wback = BitIsSet (opcode, 21); 3853 3854 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3855 if ((n == 15) || (BitCount (registers) < 1)) 3856 return false; 3857 3858 break; 3859 default: 3860 return false; 3861 } 3862 // address = R[n] + 4; 3863 3864 int32_t offset = 0; 3865 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3866 3867 if (!success) 3868 return false; 3869 3870 addr_t address = Rn + addr_byte_size; 3871 3872 EmulateInstruction::Context context; 3873 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3874 RegisterInfo dwarf_reg; 3875 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3876 context.SetRegisterPlusOffset (dwarf_reg, offset); 3877 3878 for (int i = 0; i < 14; ++i) 3879 { 3880 if (BitIsSet (registers, i)) 3881 { 3882 // R[i] = MemA[address,4]; address = address + 4; 3883 3884 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3885 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3886 if (!success) 3887 return false; 3888 3889 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3890 return false; 3891 3892 offset += addr_byte_size; 3893 } 3894 } 3895 3896 // if registers<15> == '1' then 3897 // LoadWritePC(MemA[address,4]); 3898 if (BitIsSet (registers, 15)) 3899 { 3900 context.SetRegisterPlusOffset (dwarf_reg, offset); 3901 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3902 if (!success) 3903 return false; 3904 // In ARMv5T and above, this is an interworking branch. 3905 if (!LoadWritePC(context, data)) 3906 return false; 3907 } 3908 3909 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3910 if (wback && BitIsClear (registers, n)) 3911 { 3912 if (!success) 3913 return false; 3914 3915 offset = addr_byte_size * BitCount (registers); 3916 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3917 context.SetImmediateSigned (offset); 3918 addr_t addr = Rn + offset; 3919 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3920 return false; 3921 } 3922 3923 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3924 if (wback && BitIsSet (registers, n)) 3925 return WriteBits32Unknown (n); 3926 } 3927 return true; 3928 } 3929 3930 // Load Register (immediate) calculates an address from a base register value and 3931 // an immediate offset, loads a word from memory, and writes to a register. 3932 // LDR (immediate, Thumb) 3933 bool 3934 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3935 { 3936 #if 0 3937 // ARM pseudo code... 3938 if (ConditionPassed()) 3939 { 3940 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3941 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3942 address = if index then offset_addr else R[n]; 3943 data = MemU[address,4]; 3944 if wback then R[n] = offset_addr; 3945 if t == 15 then 3946 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3947 elsif UnalignedSupport() || address<1:0> = '00' then 3948 R[t] = data; 3949 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3950 } 3951 #endif 3952 3953 bool success = false; 3954 3955 if (ConditionPassed(opcode)) 3956 { 3957 uint32_t Rt; // the destination register 3958 uint32_t Rn; // the base register 3959 uint32_t imm32; // the immediate offset used to form the address 3960 addr_t offset_addr; // the offset address 3961 addr_t address; // the calculated address 3962 uint32_t data; // the literal data value from memory load 3963 bool add, index, wback; 3964 switch (encoding) { 3965 case eEncodingT1: 3966 Rt = Bits32(opcode, 2, 0); 3967 Rn = Bits32(opcode, 5, 3); 3968 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3969 // index = TRUE; add = TRUE; wback = FALSE 3970 add = true; 3971 index = true; 3972 wback = false; 3973 3974 break; 3975 3976 case eEncodingT2: 3977 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3978 Rt = Bits32 (opcode, 10, 8); 3979 Rn = 13; 3980 imm32 = Bits32 (opcode, 7, 0) << 2; 3981 3982 // index = TRUE; add = TRUE; wback = FALSE; 3983 index = true; 3984 add = true; 3985 wback = false; 3986 3987 break; 3988 3989 case eEncodingT3: 3990 // if Rn == '1111' then SEE LDR (literal); 3991 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3992 Rt = Bits32 (opcode, 15, 12); 3993 Rn = Bits32 (opcode, 19, 16); 3994 imm32 = Bits32 (opcode, 11, 0); 3995 3996 // index = TRUE; add = TRUE; wback = FALSE; 3997 index = true; 3998 add = true; 3999 wback = false; 4000 4001 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4002 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4003 return false; 4004 4005 break; 4006 4007 case eEncodingT4: 4008 // if Rn == '1111' then SEE LDR (literal); 4009 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4010 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 4011 // if P == '0' && W == '0' then UNDEFINED; 4012 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 4013 return false; 4014 4015 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4016 Rt = Bits32 (opcode, 15, 12); 4017 Rn = Bits32 (opcode, 19, 16); 4018 imm32 = Bits32 (opcode, 7, 0); 4019 4020 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4021 index = BitIsSet (opcode, 10); 4022 add = BitIsSet (opcode, 9); 4023 wback = BitIsSet (opcode, 8); 4024 4025 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 4026 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 4027 return false; 4028 4029 break; 4030 4031 default: 4032 return false; 4033 } 4034 uint32_t base = ReadCoreReg (Rn, &success); 4035 if (!success) 4036 return false; 4037 if (add) 4038 offset_addr = base + imm32; 4039 else 4040 offset_addr = base - imm32; 4041 4042 address = (index ? offset_addr : base); 4043 4044 RegisterInfo base_reg; 4045 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4046 if (wback) 4047 { 4048 EmulateInstruction::Context ctx; 4049 if (Rn == 13) 4050 { 4051 ctx.type = eContextAdjustStackPointer; 4052 ctx.SetImmediateSigned((int32_t) (offset_addr - base)); 4053 } 4054 else if (Rn == GetFramePointerRegisterNumber()) 4055 { 4056 ctx.type = eContextSetFramePointer; 4057 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4058 } 4059 else 4060 { 4061 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4062 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4063 } 4064 4065 4066 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 4067 return false; 4068 } 4069 4070 // Prepare to write to the Rt register. 4071 EmulateInstruction::Context context; 4072 context.type = EmulateInstruction::eContextRegisterLoad; 4073 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4074 4075 // Read memory from the address. 4076 data = MemURead(context, address, 4, 0, &success); 4077 if (!success) 4078 return false; 4079 4080 if (Rt == 15) 4081 { 4082 if (Bits32(address, 1, 0) == 0) 4083 { 4084 if (!LoadWritePC(context, data)) 4085 return false; 4086 } 4087 else 4088 return false; 4089 } 4090 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 4091 { 4092 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 4093 return false; 4094 } 4095 else 4096 WriteBits32Unknown (Rt); 4097 } 4098 return true; 4099 } 4100 4101 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 4102 // from a base register. The consecutive memory locations start at this address, and the address just above the last 4103 // of those locations can optionally be written back to the base register. 4104 bool 4105 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 4106 { 4107 #if 0 4108 if ConditionPassed() then 4109 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4110 address = R[n]; 4111 4112 for i = 0 to 14 4113 if registers<i> == '1' then 4114 if i == n && wback && i != LowestSetBit(registers) then 4115 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4116 else 4117 MemA[address,4] = R[i]; 4118 address = address + 4; 4119 4120 if registers<15> == '1' then // Only possible for encoding A1 4121 MemA[address,4] = PCStoreValue(); 4122 if wback then R[n] = R[n] + 4*BitCount(registers); 4123 #endif 4124 4125 bool success = false; 4126 4127 if (ConditionPassed(opcode)) 4128 { 4129 uint32_t n; 4130 uint32_t registers = 0; 4131 bool wback; 4132 const uint32_t addr_byte_size = GetAddressByteSize(); 4133 4134 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4135 switch (encoding) 4136 { 4137 case eEncodingT1: 4138 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4139 n = Bits32 (opcode, 10, 8); 4140 registers = Bits32 (opcode, 7, 0); 4141 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4142 wback = true; 4143 4144 // if BitCount(registers) < 1 then UNPREDICTABLE; 4145 if (BitCount (registers) < 1) 4146 return false; 4147 4148 break; 4149 4150 case eEncodingT2: 4151 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4152 n = Bits32 (opcode, 19, 16); 4153 registers = Bits32 (opcode, 15, 0); 4154 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4155 wback = BitIsSet (opcode, 21); 4156 4157 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4158 if ((n == 15) || (BitCount (registers) < 2)) 4159 return false; 4160 4161 // if wback && registers<n> == '1' then UNPREDICTABLE; 4162 if (wback && BitIsSet (registers, n)) 4163 return false; 4164 4165 break; 4166 4167 case eEncodingA1: 4168 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4169 n = Bits32 (opcode, 19, 16); 4170 registers = Bits32 (opcode, 15, 0); 4171 wback = BitIsSet (opcode, 21); 4172 4173 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4174 if ((n == 15) || (BitCount (registers) < 1)) 4175 return false; 4176 4177 break; 4178 4179 default: 4180 return false; 4181 } 4182 4183 // address = R[n]; 4184 int32_t offset = 0; 4185 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4186 if (!success) 4187 return false; 4188 4189 EmulateInstruction::Context context; 4190 context.type = EmulateInstruction::eContextRegisterStore; 4191 RegisterInfo base_reg; 4192 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4193 4194 // for i = 0 to 14 4195 uint32_t lowest_set_bit = 14; 4196 for (uint32_t i = 0; i < 14; ++i) 4197 { 4198 // if registers<i> == '1' then 4199 if (BitIsSet (registers, i)) 4200 { 4201 if (i < lowest_set_bit) 4202 lowest_set_bit = i; 4203 // if i == n && wback && i != LowestSetBit(registers) then 4204 if ((i == n) && wback && (i != lowest_set_bit)) 4205 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4206 WriteBits32UnknownToMemory (address + offset); 4207 else 4208 { 4209 // MemA[address,4] = R[i]; 4210 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4211 if (!success) 4212 return false; 4213 4214 RegisterInfo data_reg; 4215 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4216 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4217 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4218 return false; 4219 } 4220 4221 // address = address + 4; 4222 offset += addr_byte_size; 4223 } 4224 } 4225 4226 // if registers<15> == '1' then // Only possible for encoding A1 4227 // MemA[address,4] = PCStoreValue(); 4228 if (BitIsSet (registers, 15)) 4229 { 4230 RegisterInfo pc_reg; 4231 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4232 context.SetRegisterPlusOffset (pc_reg, 8); 4233 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4234 if (!success) 4235 return false; 4236 4237 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4238 return false; 4239 } 4240 4241 // if wback then R[n] = R[n] + 4*BitCount(registers); 4242 if (wback) 4243 { 4244 offset = addr_byte_size * BitCount (registers); 4245 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4246 context.SetImmediateSigned (offset); 4247 addr_t data = address + offset; 4248 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4249 return false; 4250 } 4251 } 4252 return true; 4253 } 4254 4255 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4256 // from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4257 // of those locations can optionally be written back to the base register. 4258 bool 4259 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4260 { 4261 #if 0 4262 if ConditionPassed() then 4263 EncodingSpecificOperations(); 4264 address = R[n] - 4*BitCount(registers) + 4; 4265 4266 for i = 0 to 14 4267 if registers<i> == '1' then 4268 if i == n && wback && i != LowestSetBit(registers) then 4269 MemA[address,4] = bits(32) UNKNOWN; 4270 else 4271 MemA[address,4] = R[i]; 4272 address = address + 4; 4273 4274 if registers<15> == '1' then 4275 MemA[address,4] = PCStoreValue(); 4276 4277 if wback then R[n] = R[n] - 4*BitCount(registers); 4278 #endif 4279 4280 bool success = false; 4281 4282 if (ConditionPassed(opcode)) 4283 { 4284 uint32_t n; 4285 uint32_t registers = 0; 4286 bool wback; 4287 const uint32_t addr_byte_size = GetAddressByteSize(); 4288 4289 // EncodingSpecificOperations(); 4290 switch (encoding) 4291 { 4292 case eEncodingA1: 4293 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4294 n = Bits32 (opcode, 19, 16); 4295 registers = Bits32 (opcode, 15, 0); 4296 wback = BitIsSet (opcode, 21); 4297 4298 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4299 if ((n == 15) || (BitCount (registers) < 1)) 4300 return false; 4301 break; 4302 default: 4303 return false; 4304 } 4305 4306 // address = R[n] - 4*BitCount(registers) + 4; 4307 int32_t offset = 0; 4308 addr_t Rn = ReadCoreReg (n, &success); 4309 if (!success) 4310 return false; 4311 4312 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4313 4314 EmulateInstruction::Context context; 4315 context.type = EmulateInstruction::eContextRegisterStore; 4316 RegisterInfo base_reg; 4317 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4318 4319 // for i = 0 to 14 4320 uint32_t lowest_bit_set = 14; 4321 for (uint32_t i = 0; i < 14; ++i) 4322 { 4323 // if registers<i> == '1' then 4324 if (BitIsSet (registers, i)) 4325 { 4326 if (i < lowest_bit_set) 4327 lowest_bit_set = i; 4328 //if i == n && wback && i != LowestSetBit(registers) then 4329 if ((i == n) && wback && (i != lowest_bit_set)) 4330 // MemA[address,4] = bits(32) UNKNOWN; 4331 WriteBits32UnknownToMemory (address + offset); 4332 else 4333 { 4334 // MemA[address,4] = R[i]; 4335 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4336 if (!success) 4337 return false; 4338 4339 RegisterInfo data_reg; 4340 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4341 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4342 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4343 return false; 4344 } 4345 4346 // address = address + 4; 4347 offset += addr_byte_size; 4348 } 4349 } 4350 4351 // if registers<15> == '1' then 4352 // MemA[address,4] = PCStoreValue(); 4353 if (BitIsSet (registers, 15)) 4354 { 4355 RegisterInfo pc_reg; 4356 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4357 context.SetRegisterPlusOffset (pc_reg, 8); 4358 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4359 if (!success) 4360 return false; 4361 4362 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4363 return false; 4364 } 4365 4366 // if wback then R[n] = R[n] - 4*BitCount(registers); 4367 if (wback) 4368 { 4369 offset = (addr_byte_size * BitCount (registers)) * -1; 4370 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4371 context.SetImmediateSigned (offset); 4372 addr_t data = Rn + offset; 4373 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4374 return false; 4375 } 4376 } 4377 return true; 4378 } 4379 4380 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4381 // from a base register. The consecutive memory locations end just below this address, and the address of the first of 4382 // those locations can optionally be written back to the base register. 4383 bool 4384 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4385 { 4386 #if 0 4387 if ConditionPassed() then 4388 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4389 address = R[n] - 4*BitCount(registers); 4390 4391 for i = 0 to 14 4392 if registers<i> == '1' then 4393 if i == n && wback && i != LowestSetBit(registers) then 4394 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4395 else 4396 MemA[address,4] = R[i]; 4397 address = address + 4; 4398 4399 if registers<15> == '1' then // Only possible for encoding A1 4400 MemA[address,4] = PCStoreValue(); 4401 4402 if wback then R[n] = R[n] - 4*BitCount(registers); 4403 #endif 4404 4405 4406 bool success = false; 4407 4408 if (ConditionPassed(opcode)) 4409 { 4410 uint32_t n; 4411 uint32_t registers = 0; 4412 bool wback; 4413 const uint32_t addr_byte_size = GetAddressByteSize(); 4414 4415 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4416 switch (encoding) 4417 { 4418 case eEncodingT1: 4419 // if W == '1' && Rn == '1101' then SEE PUSH; 4420 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4421 { 4422 // See PUSH 4423 } 4424 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4425 n = Bits32 (opcode, 19, 16); 4426 registers = Bits32 (opcode, 15, 0); 4427 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4428 wback = BitIsSet (opcode, 21); 4429 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4430 if ((n == 15) || BitCount (registers) < 2) 4431 return false; 4432 // if wback && registers<n> == '1' then UNPREDICTABLE; 4433 if (wback && BitIsSet (registers, n)) 4434 return false; 4435 break; 4436 4437 case eEncodingA1: 4438 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE PUSH; 4439 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4440 { 4441 // See Push 4442 } 4443 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4444 n = Bits32 (opcode, 19, 16); 4445 registers = Bits32 (opcode, 15, 0); 4446 wback = BitIsSet (opcode, 21); 4447 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4448 if ((n == 15) || BitCount (registers) < 1) 4449 return false; 4450 break; 4451 4452 default: 4453 return false; 4454 } 4455 4456 // address = R[n] - 4*BitCount(registers); 4457 4458 int32_t offset = 0; 4459 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4460 if (!success) 4461 return false; 4462 4463 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4464 4465 EmulateInstruction::Context context; 4466 context.type = EmulateInstruction::eContextRegisterStore; 4467 RegisterInfo base_reg; 4468 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4469 4470 // for i = 0 to 14 4471 uint32_t lowest_set_bit = 14; 4472 for (uint32_t i = 0; i < 14; ++i) 4473 { 4474 // if registers<i> == '1' then 4475 if (BitIsSet (registers, i)) 4476 { 4477 if (i < lowest_set_bit) 4478 lowest_set_bit = i; 4479 // if i == n && wback && i != LowestSetBit(registers) then 4480 if ((i == n) && wback && (i != lowest_set_bit)) 4481 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4482 WriteBits32UnknownToMemory (address + offset); 4483 else 4484 { 4485 // MemA[address,4] = R[i]; 4486 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4487 if (!success) 4488 return false; 4489 4490 RegisterInfo data_reg; 4491 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4492 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4493 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4494 return false; 4495 } 4496 4497 // address = address + 4; 4498 offset += addr_byte_size; 4499 } 4500 } 4501 4502 // if registers<15> == '1' then // Only possible for encoding A1 4503 // MemA[address,4] = PCStoreValue(); 4504 if (BitIsSet (registers, 15)) 4505 { 4506 RegisterInfo pc_reg; 4507 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4508 context.SetRegisterPlusOffset (pc_reg, 8); 4509 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4510 if (!success) 4511 return false; 4512 4513 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4514 return false; 4515 } 4516 4517 // if wback then R[n] = R[n] - 4*BitCount(registers); 4518 if (wback) 4519 { 4520 offset = (addr_byte_size * BitCount (registers)) * -1; 4521 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4522 context.SetImmediateSigned (offset); 4523 addr_t data = Rn + offset; 4524 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4525 return false; 4526 } 4527 } 4528 return true; 4529 } 4530 4531 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4532 // from a base register. The consecutive memory locations start just above this address, and the address of the last 4533 // of those locations can optionally be written back to the base register. 4534 bool 4535 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4536 { 4537 #if 0 4538 if ConditionPassed() then 4539 EncodingSpecificOperations(); 4540 address = R[n] + 4; 4541 4542 for i = 0 to 14 4543 if registers<i> == '1' then 4544 if i == n && wback && i != LowestSetBit(registers) then 4545 MemA[address,4] = bits(32) UNKNOWN; 4546 else 4547 MemA[address,4] = R[i]; 4548 address = address + 4; 4549 4550 if registers<15> == '1' then 4551 MemA[address,4] = PCStoreValue(); 4552 4553 if wback then R[n] = R[n] + 4*BitCount(registers); 4554 #endif 4555 4556 bool success = false; 4557 4558 if (ConditionPassed(opcode)) 4559 { 4560 uint32_t n; 4561 uint32_t registers = 0; 4562 bool wback; 4563 const uint32_t addr_byte_size = GetAddressByteSize(); 4564 4565 // EncodingSpecificOperations(); 4566 switch (encoding) 4567 { 4568 case eEncodingA1: 4569 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4570 n = Bits32 (opcode, 19, 16); 4571 registers = Bits32 (opcode, 15, 0); 4572 wback = BitIsSet (opcode, 21); 4573 4574 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4575 if ((n == 15) && (BitCount (registers) < 1)) 4576 return false; 4577 break; 4578 default: 4579 return false; 4580 } 4581 // address = R[n] + 4; 4582 4583 int32_t offset = 0; 4584 addr_t Rn = ReadCoreReg (n, &success); 4585 if (!success) 4586 return false; 4587 4588 addr_t address = Rn + addr_byte_size; 4589 4590 EmulateInstruction::Context context; 4591 context.type = EmulateInstruction::eContextRegisterStore; 4592 RegisterInfo base_reg; 4593 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4594 4595 uint32_t lowest_set_bit = 14; 4596 // for i = 0 to 14 4597 for (uint32_t i = 0; i < 14; ++i) 4598 { 4599 // if registers<i> == '1' then 4600 if (BitIsSet (registers, i)) 4601 { 4602 if (i < lowest_set_bit) 4603 lowest_set_bit = i; 4604 // if i == n && wback && i != LowestSetBit(registers) then 4605 if ((i == n) && wback && (i != lowest_set_bit)) 4606 // MemA[address,4] = bits(32) UNKNOWN; 4607 WriteBits32UnknownToMemory (address + offset); 4608 // else 4609 else 4610 { 4611 // MemA[address,4] = R[i]; 4612 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4613 if (!success) 4614 return false; 4615 4616 RegisterInfo data_reg; 4617 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4618 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4619 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4620 return false; 4621 } 4622 4623 // address = address + 4; 4624 offset += addr_byte_size; 4625 } 4626 } 4627 4628 // if registers<15> == '1' then 4629 // MemA[address,4] = PCStoreValue(); 4630 if (BitIsSet (registers, 15)) 4631 { 4632 RegisterInfo pc_reg; 4633 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4634 context.SetRegisterPlusOffset (pc_reg, 8); 4635 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4636 if (!success) 4637 return false; 4638 4639 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4640 return false; 4641 } 4642 4643 // if wback then R[n] = R[n] + 4*BitCount(registers); 4644 if (wback) 4645 { 4646 offset = addr_byte_size * BitCount (registers); 4647 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4648 context.SetImmediateSigned (offset); 4649 addr_t data = Rn + offset; 4650 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4651 return false; 4652 } 4653 } 4654 return true; 4655 } 4656 4657 // STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word 4658 // from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4659 bool 4660 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4661 { 4662 #if 0 4663 if ConditionPassed() then 4664 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4665 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4666 address = if index then offset_addr else R[n]; 4667 if UnalignedSupport() || address<1:0> == '00' then 4668 MemU[address,4] = R[t]; 4669 else // Can only occur before ARMv7 4670 MemU[address,4] = bits(32) UNKNOWN; 4671 if wback then R[n] = offset_addr; 4672 #endif 4673 4674 bool success = false; 4675 4676 if (ConditionPassed(opcode)) 4677 { 4678 const uint32_t addr_byte_size = GetAddressByteSize(); 4679 4680 uint32_t t; 4681 uint32_t n; 4682 uint32_t imm32; 4683 bool index; 4684 bool add; 4685 bool wback; 4686 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4687 switch (encoding) 4688 { 4689 case eEncodingT1: 4690 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4691 t = Bits32 (opcode, 2, 0); 4692 n = Bits32 (opcode, 5, 3); 4693 imm32 = Bits32 (opcode, 10, 6) << 2; 4694 4695 // index = TRUE; add = TRUE; wback = FALSE; 4696 index = true; 4697 add = false; 4698 wback = false; 4699 break; 4700 4701 case eEncodingT2: 4702 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4703 t = Bits32 (opcode, 10, 8); 4704 n = 13; 4705 imm32 = Bits32 (opcode, 7, 0) << 2; 4706 4707 // index = TRUE; add = TRUE; wback = FALSE; 4708 index = true; 4709 add = true; 4710 wback = false; 4711 break; 4712 4713 case eEncodingT3: 4714 // if Rn == '1111' then UNDEFINED; 4715 if (Bits32 (opcode, 19, 16) == 15) 4716 return false; 4717 4718 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4719 t = Bits32 (opcode, 15, 12); 4720 n = Bits32 (opcode, 19, 16); 4721 imm32 = Bits32 (opcode, 11, 0); 4722 4723 // index = TRUE; add = TRUE; wback = FALSE; 4724 index = true; 4725 add = true; 4726 wback = false; 4727 4728 // if t == 15 then UNPREDICTABLE; 4729 if (t == 15) 4730 return false; 4731 break; 4732 4733 case eEncodingT4: 4734 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4735 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4736 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4737 if ((Bits32 (opcode, 19, 16) == 15) 4738 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4739 return false; 4740 4741 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4742 t = Bits32 (opcode, 15, 12); 4743 n = Bits32 (opcode, 19, 16); 4744 imm32 = Bits32 (opcode, 7, 0); 4745 4746 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4747 index = BitIsSet (opcode, 10); 4748 add = BitIsSet (opcode, 9); 4749 wback = BitIsSet (opcode, 8); 4750 4751 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4752 if ((t == 15) || (wback && (n == t))) 4753 return false; 4754 break; 4755 4756 default: 4757 return false; 4758 } 4759 4760 addr_t offset_addr; 4761 addr_t address; 4762 4763 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4764 uint32_t base_address = ReadCoreReg (n, &success); 4765 if (!success) 4766 return false; 4767 4768 if (add) 4769 offset_addr = base_address + imm32; 4770 else 4771 offset_addr = base_address - imm32; 4772 4773 // address = if index then offset_addr else R[n]; 4774 if (index) 4775 address = offset_addr; 4776 else 4777 address = base_address; 4778 4779 EmulateInstruction::Context context; 4780 context.type = eContextRegisterStore; 4781 RegisterInfo base_reg; 4782 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4783 4784 // if UnalignedSupport() || address<1:0> == '00' then 4785 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4786 { 4787 // MemU[address,4] = R[t]; 4788 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4789 if (!success) 4790 return false; 4791 4792 RegisterInfo data_reg; 4793 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4794 int32_t offset = address - base_address; 4795 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4796 if (!MemUWrite (context, address, data, addr_byte_size)) 4797 return false; 4798 } 4799 else 4800 { 4801 // MemU[address,4] = bits(32) UNKNOWN; 4802 WriteBits32UnknownToMemory (address); 4803 } 4804 4805 // if wback then R[n] = offset_addr; 4806 if (wback) 4807 { 4808 context.type = eContextRegisterLoad; 4809 context.SetAddress (offset_addr); 4810 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4811 return false; 4812 } 4813 } 4814 return true; 4815 } 4816 4817 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4818 // word from a register to memory. The offset register value can optionally be shifted. 4819 bool 4820 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4821 { 4822 #if 0 4823 if ConditionPassed() then 4824 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4825 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4826 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4827 address = if index then offset_addr else R[n]; 4828 if t == 15 then // Only possible for encoding A1 4829 data = PCStoreValue(); 4830 else 4831 data = R[t]; 4832 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4833 MemU[address,4] = data; 4834 else // Can only occur before ARMv7 4835 MemU[address,4] = bits(32) UNKNOWN; 4836 if wback then R[n] = offset_addr; 4837 #endif 4838 4839 bool success = false; 4840 4841 if (ConditionPassed(opcode)) 4842 { 4843 const uint32_t addr_byte_size = GetAddressByteSize(); 4844 4845 uint32_t t; 4846 uint32_t n; 4847 uint32_t m; 4848 ARM_ShifterType shift_t; 4849 uint32_t shift_n; 4850 bool index; 4851 bool add; 4852 bool wback; 4853 4854 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4855 switch (encoding) 4856 { 4857 case eEncodingT1: 4858 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4859 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4860 t = Bits32 (opcode, 2, 0); 4861 n = Bits32 (opcode, 5, 3); 4862 m = Bits32 (opcode, 8, 6); 4863 4864 // index = TRUE; add = TRUE; wback = FALSE; 4865 index = true; 4866 add = true; 4867 wback = false; 4868 4869 // (shift_t, shift_n) = (SRType_LSL, 0); 4870 shift_t = SRType_LSL; 4871 shift_n = 0; 4872 break; 4873 4874 case eEncodingT2: 4875 // if Rn == '1111' then UNDEFINED; 4876 if (Bits32 (opcode, 19, 16) == 15) 4877 return false; 4878 4879 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4880 t = Bits32 (opcode, 15, 12); 4881 n = Bits32 (opcode, 19, 16); 4882 m = Bits32 (opcode, 3, 0); 4883 4884 // index = TRUE; add = TRUE; wback = FALSE; 4885 index = true; 4886 add = true; 4887 wback = false; 4888 4889 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4890 shift_t = SRType_LSL; 4891 shift_n = Bits32 (opcode, 5, 4); 4892 4893 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4894 if ((t == 15) || (BadReg (m))) 4895 return false; 4896 break; 4897 4898 case eEncodingA1: 4899 { 4900 // if P == '0' && W == '1' then SEE STRT; 4901 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4902 t = Bits32 (opcode, 15, 12); 4903 n = Bits32 (opcode, 19, 16); 4904 m = Bits32 (opcode, 3, 0); 4905 4906 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4907 index = BitIsSet (opcode, 24); 4908 add = BitIsSet (opcode, 23); 4909 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4910 4911 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4912 uint32_t typ = Bits32 (opcode, 6, 5); 4913 uint32_t imm5 = Bits32 (opcode, 11, 7); 4914 shift_n = DecodeImmShift(typ, imm5, shift_t); 4915 4916 // if m == 15 then UNPREDICTABLE; 4917 if (m == 15) 4918 return false; 4919 4920 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4921 if (wback && ((n == 15) || (n == t))) 4922 return false; 4923 4924 break; 4925 } 4926 default: 4927 return false; 4928 } 4929 4930 addr_t offset_addr; 4931 addr_t address; 4932 int32_t offset = 0; 4933 4934 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4935 if (!success) 4936 return false; 4937 4938 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4939 if (!success) 4940 return false; 4941 4942 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4943 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4944 if (!success) 4945 return false; 4946 4947 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4948 if (add) 4949 offset_addr = base_address + offset; 4950 else 4951 offset_addr = base_address - offset; 4952 4953 // address = if index then offset_addr else R[n]; 4954 if (index) 4955 address = offset_addr; 4956 else 4957 address = base_address; 4958 4959 uint32_t data; 4960 // if t == 15 then // Only possible for encoding A1 4961 if (t == 15) 4962 // data = PCStoreValue(); 4963 data = ReadCoreReg (PC_REG, &success); 4964 else 4965 // data = R[t]; 4966 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4967 4968 if (!success) 4969 return false; 4970 4971 EmulateInstruction::Context context; 4972 context.type = eContextRegisterStore; 4973 4974 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4975 if (UnalignedSupport () 4976 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4977 || CurrentInstrSet() == eModeARM) 4978 { 4979 // MemU[address,4] = data; 4980 4981 RegisterInfo base_reg; 4982 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4983 4984 RegisterInfo data_reg; 4985 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4986 4987 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4988 if (!MemUWrite (context, address, data, addr_byte_size)) 4989 return false; 4990 4991 } 4992 else 4993 // MemU[address,4] = bits(32) UNKNOWN; 4994 WriteBits32UnknownToMemory (address); 4995 4996 // if wback then R[n] = offset_addr; 4997 if (wback) 4998 { 4999 context.type = eContextRegisterLoad; 5000 context.SetAddress (offset_addr); 5001 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5002 return false; 5003 } 5004 5005 } 5006 return true; 5007 } 5008 5009 bool 5010 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 5011 { 5012 #if 0 5013 if ConditionPassed() then 5014 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5015 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5016 address = if index then offset_addr else R[n]; 5017 MemU[address,1] = R[t]<7:0>; 5018 if wback then R[n] = offset_addr; 5019 #endif 5020 5021 5022 bool success = false; 5023 5024 if (ConditionPassed(opcode)) 5025 { 5026 uint32_t t; 5027 uint32_t n; 5028 uint32_t imm32; 5029 bool index; 5030 bool add; 5031 bool wback; 5032 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5033 switch (encoding) 5034 { 5035 case eEncodingT1: 5036 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5037 t = Bits32 (opcode, 2, 0); 5038 n = Bits32 (opcode, 5, 3); 5039 imm32 = Bits32 (opcode, 10, 6); 5040 5041 // index = TRUE; add = TRUE; wback = FALSE; 5042 index = true; 5043 add = true; 5044 wback = false; 5045 break; 5046 5047 case eEncodingT2: 5048 // if Rn == '1111' then UNDEFINED; 5049 if (Bits32 (opcode, 19, 16) == 15) 5050 return false; 5051 5052 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5053 t = Bits32 (opcode, 15, 12); 5054 n = Bits32 (opcode, 19, 16); 5055 imm32 = Bits32 (opcode, 11, 0); 5056 5057 // index = TRUE; add = TRUE; wback = FALSE; 5058 index = true; 5059 add = true; 5060 wback = false; 5061 5062 // if BadReg(t) then UNPREDICTABLE; 5063 if (BadReg (t)) 5064 return false; 5065 break; 5066 5067 case eEncodingT3: 5068 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5069 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5070 if (Bits32 (opcode, 19, 16) == 15) 5071 return false; 5072 5073 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5074 t = Bits32 (opcode, 15, 12); 5075 n = Bits32 (opcode, 19, 16); 5076 imm32 = Bits32 (opcode, 7, 0); 5077 5078 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5079 index = BitIsSet (opcode, 10); 5080 add = BitIsSet (opcode, 9); 5081 wback = BitIsSet (opcode, 8); 5082 5083 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5084 if ((BadReg (t)) || (wback && (n == t))) 5085 return false; 5086 break; 5087 5088 default: 5089 return false; 5090 } 5091 5092 addr_t offset_addr; 5093 addr_t address; 5094 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5095 if (!success) 5096 return false; 5097 5098 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5099 if (add) 5100 offset_addr = base_address + imm32; 5101 else 5102 offset_addr = base_address - imm32; 5103 5104 // address = if index then offset_addr else R[n]; 5105 if (index) 5106 address = offset_addr; 5107 else 5108 address = base_address; 5109 5110 // MemU[address,1] = R[t]<7:0> 5111 RegisterInfo base_reg; 5112 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5113 5114 RegisterInfo data_reg; 5115 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5116 5117 EmulateInstruction::Context context; 5118 context.type = eContextRegisterStore; 5119 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5120 5121 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5122 if (!success) 5123 return false; 5124 5125 data = Bits32 (data, 7, 0); 5126 5127 if (!MemUWrite (context, address, data, 1)) 5128 return false; 5129 5130 // if wback then R[n] = offset_addr; 5131 if (wback) 5132 { 5133 context.type = eContextRegisterLoad; 5134 context.SetAddress (offset_addr); 5135 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5136 return false; 5137 } 5138 5139 } 5140 5141 return true; 5142 } 5143 5144 // STRH (register) calculates an address from a base register value and an offset register value, and stores a 5145 // halfword from a register to memory. The offset register value can be shifted left by 0, 1, 2, or 3 bits. 5146 bool 5147 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5148 { 5149 #if 0 5150 if ConditionPassed() then 5151 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5152 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5153 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5154 address = if index then offset_addr else R[n]; 5155 if UnalignedSupport() || address<0> == '0' then 5156 MemU[address,2] = R[t]<15:0>; 5157 else // Can only occur before ARMv7 5158 MemU[address,2] = bits(16) UNKNOWN; 5159 if wback then R[n] = offset_addr; 5160 #endif 5161 5162 bool success = false; 5163 5164 if (ConditionPassed(opcode)) 5165 { 5166 uint32_t t; 5167 uint32_t n; 5168 uint32_t m; 5169 bool index; 5170 bool add; 5171 bool wback; 5172 ARM_ShifterType shift_t; 5173 uint32_t shift_n; 5174 5175 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5176 switch (encoding) 5177 { 5178 case eEncodingT1: 5179 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5180 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5181 t = Bits32 (opcode, 2, 0); 5182 n = Bits32 (opcode, 5, 3); 5183 m = Bits32 (opcode, 8, 6); 5184 5185 // index = TRUE; add = TRUE; wback = FALSE; 5186 index = true; 5187 add = true; 5188 wback = false; 5189 5190 // (shift_t, shift_n) = (SRType_LSL, 0); 5191 shift_t = SRType_LSL; 5192 shift_n = 0; 5193 5194 break; 5195 5196 case eEncodingT2: 5197 // if Rn == '1111' then UNDEFINED; 5198 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5199 t = Bits32 (opcode, 15, 12); 5200 n = Bits32 (opcode, 19, 16); 5201 m = Bits32 (opcode, 3, 0); 5202 if (n == 15) 5203 return false; 5204 5205 // index = TRUE; add = TRUE; wback = FALSE; 5206 index = true; 5207 add = true; 5208 wback = false; 5209 5210 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5211 shift_t = SRType_LSL; 5212 shift_n = Bits32 (opcode, 5, 4); 5213 5214 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5215 if (BadReg (t) || BadReg (m)) 5216 return false; 5217 5218 break; 5219 5220 case eEncodingA1: 5221 // if P == '0' && W == '1' then SEE STRHT; 5222 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5223 t = Bits32 (opcode, 15, 12); 5224 n = Bits32 (opcode, 19, 16); 5225 m = Bits32 (opcode, 3, 0); 5226 5227 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5228 index = BitIsSet (opcode, 24); 5229 add = BitIsSet (opcode, 23); 5230 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5231 5232 // (shift_t, shift_n) = (SRType_LSL, 0); 5233 shift_t = SRType_LSL; 5234 shift_n = 0; 5235 5236 // if t == 15 || m == 15 then UNPREDICTABLE; 5237 if ((t == 15) || (m == 15)) 5238 return false; 5239 5240 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5241 if (wback && ((n == 15) || (n == t))) 5242 return false; 5243 5244 break; 5245 5246 default: 5247 return false; 5248 } 5249 5250 uint32_t Rm = ReadCoreReg (m, &success); 5251 if (!success) 5252 return false; 5253 5254 uint32_t Rn = ReadCoreReg (n, &success); 5255 if (!success) 5256 return false; 5257 5258 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5259 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5260 if (!success) 5261 return false; 5262 5263 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5264 addr_t offset_addr; 5265 if (add) 5266 offset_addr = Rn + offset; 5267 else 5268 offset_addr = Rn - offset; 5269 5270 // address = if index then offset_addr else R[n]; 5271 addr_t address; 5272 if (index) 5273 address = offset_addr; 5274 else 5275 address = Rn; 5276 5277 EmulateInstruction::Context context; 5278 context.type = eContextRegisterStore; 5279 RegisterInfo base_reg; 5280 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5281 RegisterInfo offset_reg; 5282 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5283 5284 // if UnalignedSupport() || address<0> == '0' then 5285 if (UnalignedSupport() || BitIsClear (address, 0)) 5286 { 5287 // MemU[address,2] = R[t]<15:0>; 5288 uint32_t Rt = ReadCoreReg (t, &success); 5289 if (!success) 5290 return false; 5291 5292 EmulateInstruction::Context context; 5293 context.type = eContextRegisterStore; 5294 RegisterInfo base_reg; 5295 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5296 RegisterInfo offset_reg; 5297 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5298 RegisterInfo data_reg; 5299 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5300 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5301 5302 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5303 return false; 5304 } 5305 else // Can only occur before ARMv7 5306 { 5307 // MemU[address,2] = bits(16) UNKNOWN; 5308 } 5309 5310 // if wback then R[n] = offset_addr; 5311 if (wback) 5312 { 5313 context.type = eContextAdjustBaseRegister; 5314 context.SetAddress (offset_addr); 5315 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5316 return false; 5317 } 5318 } 5319 5320 return true; 5321 } 5322 5323 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5324 // and writes the result to the destination register. It can optionally update the condition flags 5325 // based on the result. 5326 bool 5327 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5328 { 5329 #if 0 5330 // ARM pseudo code... 5331 if ConditionPassed() then 5332 EncodingSpecificOperations(); 5333 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5334 if d == 15 then // Can only occur for ARM encoding 5335 ALUWritePC(result); // setflags is always FALSE here 5336 else 5337 R[d] = result; 5338 if setflags then 5339 APSR.N = result<31>; 5340 APSR.Z = IsZeroBit(result); 5341 APSR.C = carry; 5342 APSR.V = overflow; 5343 #endif 5344 5345 bool success = false; 5346 5347 if (ConditionPassed(opcode)) 5348 { 5349 uint32_t Rd, Rn; 5350 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5351 bool setflags; 5352 switch (encoding) 5353 { 5354 case eEncodingT1: 5355 Rd = Bits32(opcode, 11, 8); 5356 Rn = Bits32(opcode, 19, 16); 5357 setflags = BitIsSet(opcode, 20); 5358 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5359 if (BadReg(Rd) || BadReg(Rn)) 5360 return false; 5361 break; 5362 case eEncodingA1: 5363 Rd = Bits32(opcode, 15, 12); 5364 Rn = Bits32(opcode, 19, 16); 5365 setflags = BitIsSet(opcode, 20); 5366 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5367 5368 if (Rd == 15 && setflags) 5369 return EmulateSUBSPcLrEtc (opcode, encoding); 5370 break; 5371 default: 5372 return false; 5373 } 5374 5375 // Read the first operand. 5376 int32_t val1 = ReadCoreReg(Rn, &success); 5377 if (!success) 5378 return false; 5379 5380 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5381 5382 EmulateInstruction::Context context; 5383 context.type = EmulateInstruction::eContextImmediate; 5384 context.SetNoArgs (); 5385 5386 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5387 return false; 5388 } 5389 return true; 5390 } 5391 5392 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5393 // register value, and writes the result to the destination register. It can optionally update the 5394 // condition flags based on the result. 5395 bool 5396 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5397 { 5398 #if 0 5399 // ARM pseudo code... 5400 if ConditionPassed() then 5401 EncodingSpecificOperations(); 5402 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5403 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5404 if d == 15 then // Can only occur for ARM encoding 5405 ALUWritePC(result); // setflags is always FALSE here 5406 else 5407 R[d] = result; 5408 if setflags then 5409 APSR.N = result<31>; 5410 APSR.Z = IsZeroBit(result); 5411 APSR.C = carry; 5412 APSR.V = overflow; 5413 #endif 5414 5415 bool success = false; 5416 5417 if (ConditionPassed(opcode)) 5418 { 5419 uint32_t Rd, Rn, Rm; 5420 ARM_ShifterType shift_t; 5421 uint32_t shift_n; // the shift applied to the value read from Rm 5422 bool setflags; 5423 switch (encoding) 5424 { 5425 case eEncodingT1: 5426 Rd = Rn = Bits32(opcode, 2, 0); 5427 Rm = Bits32(opcode, 5, 3); 5428 setflags = !InITBlock(); 5429 shift_t = SRType_LSL; 5430 shift_n = 0; 5431 break; 5432 case eEncodingT2: 5433 Rd = Bits32(opcode, 11, 8); 5434 Rn = Bits32(opcode, 19, 16); 5435 Rm = Bits32(opcode, 3, 0); 5436 setflags = BitIsSet(opcode, 20); 5437 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5438 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5439 return false; 5440 break; 5441 case eEncodingA1: 5442 Rd = Bits32(opcode, 15, 12); 5443 Rn = Bits32(opcode, 19, 16); 5444 Rm = Bits32(opcode, 3, 0); 5445 setflags = BitIsSet(opcode, 20); 5446 shift_n = DecodeImmShiftARM(opcode, shift_t); 5447 5448 if (Rd == 15 && setflags) 5449 return EmulateSUBSPcLrEtc (opcode, encoding); 5450 break; 5451 default: 5452 return false; 5453 } 5454 5455 // Read the first operand. 5456 int32_t val1 = ReadCoreReg(Rn, &success); 5457 if (!success) 5458 return false; 5459 5460 // Read the second operand. 5461 int32_t val2 = ReadCoreReg(Rm, &success); 5462 if (!success) 5463 return false; 5464 5465 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5466 if (!success) 5467 return false; 5468 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5469 5470 EmulateInstruction::Context context; 5471 context.type = EmulateInstruction::eContextImmediate; 5472 context.SetNoArgs (); 5473 5474 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5475 return false; 5476 } 5477 return true; 5478 } 5479 5480 // This instruction adds an immediate value to the PC value to form a PC-relative address, 5481 // and writes the result to the destination register. 5482 bool 5483 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5484 { 5485 #if 0 5486 // ARM pseudo code... 5487 if ConditionPassed() then 5488 EncodingSpecificOperations(); 5489 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5490 if d == 15 then // Can only occur for ARM encodings 5491 ALUWritePC(result); 5492 else 5493 R[d] = result; 5494 #endif 5495 5496 bool success = false; 5497 5498 if (ConditionPassed(opcode)) 5499 { 5500 uint32_t Rd; 5501 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5502 bool add; 5503 switch (encoding) 5504 { 5505 case eEncodingT1: 5506 Rd = Bits32(opcode, 10, 8); 5507 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5508 add = true; 5509 break; 5510 case eEncodingT2: 5511 case eEncodingT3: 5512 Rd = Bits32(opcode, 11, 8); 5513 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5514 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5515 if (BadReg(Rd)) 5516 return false; 5517 break; 5518 case eEncodingA1: 5519 case eEncodingA2: 5520 Rd = Bits32(opcode, 15, 12); 5521 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5522 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5523 break; 5524 default: 5525 return false; 5526 } 5527 5528 // Read the PC value. 5529 uint32_t pc = ReadCoreReg(PC_REG, &success); 5530 if (!success) 5531 return false; 5532 5533 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5534 5535 EmulateInstruction::Context context; 5536 context.type = EmulateInstruction::eContextImmediate; 5537 context.SetNoArgs (); 5538 5539 if (!WriteCoreReg(context, result, Rd)) 5540 return false; 5541 } 5542 return true; 5543 } 5544 5545 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5546 // to the destination register. It can optionally update the condition flags based on the result. 5547 bool 5548 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5549 { 5550 #if 0 5551 // ARM pseudo code... 5552 if ConditionPassed() then 5553 EncodingSpecificOperations(); 5554 result = R[n] AND imm32; 5555 if d == 15 then // Can only occur for ARM encoding 5556 ALUWritePC(result); // setflags is always FALSE here 5557 else 5558 R[d] = result; 5559 if setflags then 5560 APSR.N = result<31>; 5561 APSR.Z = IsZeroBit(result); 5562 APSR.C = carry; 5563 // APSR.V unchanged 5564 #endif 5565 5566 bool success = false; 5567 5568 if (ConditionPassed(opcode)) 5569 { 5570 uint32_t Rd, Rn; 5571 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5572 bool setflags; 5573 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5574 switch (encoding) 5575 { 5576 case eEncodingT1: 5577 Rd = Bits32(opcode, 11, 8); 5578 Rn = Bits32(opcode, 19, 16); 5579 setflags = BitIsSet(opcode, 20); 5580 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5581 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5582 if (Rd == 15 && setflags) 5583 return EmulateTSTImm(opcode, eEncodingT1); 5584 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5585 return false; 5586 break; 5587 case eEncodingA1: 5588 Rd = Bits32(opcode, 15, 12); 5589 Rn = Bits32(opcode, 19, 16); 5590 setflags = BitIsSet(opcode, 20); 5591 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5592 5593 if (Rd == 15 && setflags) 5594 return EmulateSUBSPcLrEtc (opcode, encoding); 5595 break; 5596 default: 5597 return false; 5598 } 5599 5600 // Read the first operand. 5601 uint32_t val1 = ReadCoreReg(Rn, &success); 5602 if (!success) 5603 return false; 5604 5605 uint32_t result = val1 & imm32; 5606 5607 EmulateInstruction::Context context; 5608 context.type = EmulateInstruction::eContextImmediate; 5609 context.SetNoArgs (); 5610 5611 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5612 return false; 5613 } 5614 return true; 5615 } 5616 5617 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5618 // and writes the result to the destination register. It can optionally update the condition flags 5619 // based on the result. 5620 bool 5621 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5622 { 5623 #if 0 5624 // ARM pseudo code... 5625 if ConditionPassed() then 5626 EncodingSpecificOperations(); 5627 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5628 result = R[n] AND shifted; 5629 if d == 15 then // Can only occur for ARM encoding 5630 ALUWritePC(result); // setflags is always FALSE here 5631 else 5632 R[d] = result; 5633 if setflags then 5634 APSR.N = result<31>; 5635 APSR.Z = IsZeroBit(result); 5636 APSR.C = carry; 5637 // APSR.V unchanged 5638 #endif 5639 5640 bool success = false; 5641 5642 if (ConditionPassed(opcode)) 5643 { 5644 uint32_t Rd, Rn, Rm; 5645 ARM_ShifterType shift_t; 5646 uint32_t shift_n; // the shift applied to the value read from Rm 5647 bool setflags; 5648 uint32_t carry; 5649 switch (encoding) 5650 { 5651 case eEncodingT1: 5652 Rd = Rn = Bits32(opcode, 2, 0); 5653 Rm = Bits32(opcode, 5, 3); 5654 setflags = !InITBlock(); 5655 shift_t = SRType_LSL; 5656 shift_n = 0; 5657 break; 5658 case eEncodingT2: 5659 Rd = Bits32(opcode, 11, 8); 5660 Rn = Bits32(opcode, 19, 16); 5661 Rm = Bits32(opcode, 3, 0); 5662 setflags = BitIsSet(opcode, 20); 5663 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5664 // if Rd == '1111' && S == '1' then SEE TST (register); 5665 if (Rd == 15 && setflags) 5666 return EmulateTSTReg(opcode, eEncodingT2); 5667 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5668 return false; 5669 break; 5670 case eEncodingA1: 5671 Rd = Bits32(opcode, 15, 12); 5672 Rn = Bits32(opcode, 19, 16); 5673 Rm = Bits32(opcode, 3, 0); 5674 setflags = BitIsSet(opcode, 20); 5675 shift_n = DecodeImmShiftARM(opcode, shift_t); 5676 5677 if (Rd == 15 && setflags) 5678 return EmulateSUBSPcLrEtc (opcode, encoding); 5679 break; 5680 default: 5681 return false; 5682 } 5683 5684 // Read the first operand. 5685 uint32_t val1 = ReadCoreReg(Rn, &success); 5686 if (!success) 5687 return false; 5688 5689 // Read the second operand. 5690 uint32_t val2 = ReadCoreReg(Rm, &success); 5691 if (!success) 5692 return false; 5693 5694 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5695 if (!success) 5696 return false; 5697 uint32_t result = val1 & shifted; 5698 5699 EmulateInstruction::Context context; 5700 context.type = EmulateInstruction::eContextImmediate; 5701 context.SetNoArgs (); 5702 5703 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5704 return false; 5705 } 5706 return true; 5707 } 5708 5709 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5710 // immediate value, and writes the result to the destination register. It can optionally update the 5711 // condition flags based on the result. 5712 bool 5713 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5714 { 5715 #if 0 5716 // ARM pseudo code... 5717 if ConditionPassed() then 5718 EncodingSpecificOperations(); 5719 result = R[n] AND NOT(imm32); 5720 if d == 15 then // Can only occur for ARM encoding 5721 ALUWritePC(result); // setflags is always FALSE here 5722 else 5723 R[d] = result; 5724 if setflags then 5725 APSR.N = result<31>; 5726 APSR.Z = IsZeroBit(result); 5727 APSR.C = carry; 5728 // APSR.V unchanged 5729 #endif 5730 5731 bool success = false; 5732 5733 if (ConditionPassed(opcode)) 5734 { 5735 uint32_t Rd, Rn; 5736 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5737 bool setflags; 5738 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5739 switch (encoding) 5740 { 5741 case eEncodingT1: 5742 Rd = Bits32(opcode, 11, 8); 5743 Rn = Bits32(opcode, 19, 16); 5744 setflags = BitIsSet(opcode, 20); 5745 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5746 if (BadReg(Rd) || BadReg(Rn)) 5747 return false; 5748 break; 5749 case eEncodingA1: 5750 Rd = Bits32(opcode, 15, 12); 5751 Rn = Bits32(opcode, 19, 16); 5752 setflags = BitIsSet(opcode, 20); 5753 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5754 5755 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5756 if (Rd == 15 && setflags) 5757 return EmulateSUBSPcLrEtc (opcode, encoding); 5758 break; 5759 default: 5760 return false; 5761 } 5762 5763 // Read the first operand. 5764 uint32_t val1 = ReadCoreReg(Rn, &success); 5765 if (!success) 5766 return false; 5767 5768 uint32_t result = val1 & ~imm32; 5769 5770 EmulateInstruction::Context context; 5771 context.type = EmulateInstruction::eContextImmediate; 5772 context.SetNoArgs (); 5773 5774 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5775 return false; 5776 } 5777 return true; 5778 } 5779 5780 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5781 // optionally-shifted register value, and writes the result to the destination register. 5782 // It can optionally update the condition flags based on the result. 5783 bool 5784 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5785 { 5786 #if 0 5787 // ARM pseudo code... 5788 if ConditionPassed() then 5789 EncodingSpecificOperations(); 5790 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5791 result = R[n] AND NOT(shifted); 5792 if d == 15 then // Can only occur for ARM encoding 5793 ALUWritePC(result); // setflags is always FALSE here 5794 else 5795 R[d] = result; 5796 if setflags then 5797 APSR.N = result<31>; 5798 APSR.Z = IsZeroBit(result); 5799 APSR.C = carry; 5800 // APSR.V unchanged 5801 #endif 5802 5803 bool success = false; 5804 5805 if (ConditionPassed(opcode)) 5806 { 5807 uint32_t Rd, Rn, Rm; 5808 ARM_ShifterType shift_t; 5809 uint32_t shift_n; // the shift applied to the value read from Rm 5810 bool setflags; 5811 uint32_t carry; 5812 switch (encoding) 5813 { 5814 case eEncodingT1: 5815 Rd = Rn = Bits32(opcode, 2, 0); 5816 Rm = Bits32(opcode, 5, 3); 5817 setflags = !InITBlock(); 5818 shift_t = SRType_LSL; 5819 shift_n = 0; 5820 break; 5821 case eEncodingT2: 5822 Rd = Bits32(opcode, 11, 8); 5823 Rn = Bits32(opcode, 19, 16); 5824 Rm = Bits32(opcode, 3, 0); 5825 setflags = BitIsSet(opcode, 20); 5826 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5827 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5828 return false; 5829 break; 5830 case eEncodingA1: 5831 Rd = Bits32(opcode, 15, 12); 5832 Rn = Bits32(opcode, 19, 16); 5833 Rm = Bits32(opcode, 3, 0); 5834 setflags = BitIsSet(opcode, 20); 5835 shift_n = DecodeImmShiftARM(opcode, shift_t); 5836 5837 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5838 if (Rd == 15 && setflags) 5839 return EmulateSUBSPcLrEtc (opcode, encoding); 5840 break; 5841 default: 5842 return false; 5843 } 5844 5845 // Read the first operand. 5846 uint32_t val1 = ReadCoreReg(Rn, &success); 5847 if (!success) 5848 return false; 5849 5850 // Read the second operand. 5851 uint32_t val2 = ReadCoreReg(Rm, &success); 5852 if (!success) 5853 return false; 5854 5855 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5856 if (!success) 5857 return false; 5858 uint32_t result = val1 & ~shifted; 5859 5860 EmulateInstruction::Context context; 5861 context.type = EmulateInstruction::eContextImmediate; 5862 context.SetNoArgs (); 5863 5864 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5865 return false; 5866 } 5867 return true; 5868 } 5869 5870 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5871 // from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5872 bool 5873 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5874 { 5875 #if 0 5876 if ConditionPassed() then 5877 EncodingSpecificOperations(); 5878 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5879 address = if index then offset_addr else R[n]; 5880 data = MemU[address,4]; 5881 if wback then R[n] = offset_addr; 5882 if t == 15 then 5883 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5884 elsif UnalignedSupport() || address<1:0> = '00' then 5885 R[t] = data; 5886 else // Can only apply before ARMv7 5887 R[t] = ROR(data, 8*UInt(address<1:0>)); 5888 #endif 5889 5890 bool success = false; 5891 5892 if (ConditionPassed(opcode)) 5893 { 5894 const uint32_t addr_byte_size = GetAddressByteSize(); 5895 5896 uint32_t t; 5897 uint32_t n; 5898 uint32_t imm32; 5899 bool index; 5900 bool add; 5901 bool wback; 5902 5903 switch (encoding) 5904 { 5905 case eEncodingA1: 5906 // if Rn == '1111' then SEE LDR (literal); 5907 // if P == '0' && W == '1' then SEE LDRT; 5908 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5909 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5910 t = Bits32 (opcode, 15, 12); 5911 n = Bits32 (opcode, 19, 16); 5912 imm32 = Bits32 (opcode, 11, 0); 5913 5914 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5915 index = BitIsSet (opcode, 24); 5916 add = BitIsSet (opcode, 23); 5917 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5918 5919 // if wback && n == t then UNPREDICTABLE; 5920 if (wback && (n == t)) 5921 return false; 5922 5923 break; 5924 5925 default: 5926 return false; 5927 } 5928 5929 addr_t address; 5930 addr_t offset_addr; 5931 addr_t base_address = ReadCoreReg (n, &success); 5932 if (!success) 5933 return false; 5934 5935 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5936 if (add) 5937 offset_addr = base_address + imm32; 5938 else 5939 offset_addr = base_address - imm32; 5940 5941 // address = if index then offset_addr else R[n]; 5942 if (index) 5943 address = offset_addr; 5944 else 5945 address = base_address; 5946 5947 // data = MemU[address,4]; 5948 5949 RegisterInfo base_reg; 5950 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5951 5952 EmulateInstruction::Context context; 5953 context.type = eContextRegisterLoad; 5954 context.SetRegisterPlusOffset (base_reg, address - base_address); 5955 5956 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5957 if (!success) 5958 return false; 5959 5960 // if wback then R[n] = offset_addr; 5961 if (wback) 5962 { 5963 context.type = eContextAdjustBaseRegister; 5964 context.SetAddress (offset_addr); 5965 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5966 return false; 5967 } 5968 5969 // if t == 15 then 5970 if (t == 15) 5971 { 5972 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5973 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5974 { 5975 // LoadWritePC (data); 5976 context.type = eContextRegisterLoad; 5977 context.SetRegisterPlusOffset (base_reg, address - base_address); 5978 LoadWritePC (context, data); 5979 } 5980 else 5981 return false; 5982 } 5983 // elsif UnalignedSupport() || address<1:0> = '00' then 5984 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5985 { 5986 // R[t] = data; 5987 context.type = eContextRegisterLoad; 5988 context.SetRegisterPlusOffset (base_reg, address - base_address); 5989 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5990 return false; 5991 } 5992 // else // Can only apply before ARMv7 5993 else 5994 { 5995 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5996 data = ROR (data, Bits32 (address, 1, 0), &success); 5997 if (!success) 5998 return false; 5999 context.type = eContextRegisterLoad; 6000 context.SetImmediate (data); 6001 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6002 return false; 6003 } 6004 6005 } 6006 return true; 6007 } 6008 6009 // LDR (register) calculates an address from a base register value and an offset register value, loads a word 6010 // from memory, and writes it to a register. The offset register value can optionally be shifted. 6011 bool 6012 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 6013 { 6014 #if 0 6015 if ConditionPassed() then 6016 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6017 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6018 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6019 address = if index then offset_addr else R[n]; 6020 data = MemU[address,4]; 6021 if wback then R[n] = offset_addr; 6022 if t == 15 then 6023 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6024 elsif UnalignedSupport() || address<1:0> = '00' then 6025 R[t] = data; 6026 else // Can only apply before ARMv7 6027 if CurrentInstrSet() == InstrSet_ARM then 6028 R[t] = ROR(data, 8*UInt(address<1:0>)); 6029 else 6030 R[t] = bits(32) UNKNOWN; 6031 #endif 6032 6033 bool success = false; 6034 6035 if (ConditionPassed(opcode)) 6036 { 6037 const uint32_t addr_byte_size = GetAddressByteSize(); 6038 6039 uint32_t t; 6040 uint32_t n; 6041 uint32_t m; 6042 bool index; 6043 bool add; 6044 bool wback; 6045 ARM_ShifterType shift_t; 6046 uint32_t shift_n; 6047 6048 switch (encoding) 6049 { 6050 case eEncodingT1: 6051 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6052 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6053 t = Bits32 (opcode, 2, 0); 6054 n = Bits32 (opcode, 5, 3); 6055 m = Bits32 (opcode, 8, 6); 6056 6057 // index = TRUE; add = TRUE; wback = FALSE; 6058 index = true; 6059 add = true; 6060 wback = false; 6061 6062 // (shift_t, shift_n) = (SRType_LSL, 0); 6063 shift_t = SRType_LSL; 6064 shift_n = 0; 6065 6066 break; 6067 6068 case eEncodingT2: 6069 // if Rn == '1111' then SEE LDR (literal); 6070 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6071 t = Bits32 (opcode, 15, 12); 6072 n = Bits32 (opcode, 19, 16); 6073 m = Bits32 (opcode, 3, 0); 6074 6075 // index = TRUE; add = TRUE; wback = FALSE; 6076 index = true; 6077 add = true; 6078 wback = false; 6079 6080 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6081 shift_t = SRType_LSL; 6082 shift_n = Bits32 (opcode, 5, 4); 6083 6084 // if BadReg(m) then UNPREDICTABLE; 6085 if (BadReg (m)) 6086 return false; 6087 6088 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6089 if ((t == 15) && InITBlock() && !LastInITBlock()) 6090 return false; 6091 6092 break; 6093 6094 case eEncodingA1: 6095 { 6096 // if P == '0' && W == '1' then SEE LDRT; 6097 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6098 t = Bits32 (opcode, 15, 12); 6099 n = Bits32 (opcode, 19, 16); 6100 m = Bits32 (opcode, 3, 0); 6101 6102 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6103 index = BitIsSet (opcode, 24); 6104 add = BitIsSet (opcode, 23); 6105 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6106 6107 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6108 uint32_t type = Bits32 (opcode, 6, 5); 6109 uint32_t imm5 = Bits32 (opcode, 11, 7); 6110 shift_n = DecodeImmShift (type, imm5, shift_t); 6111 6112 // if m == 15 then UNPREDICTABLE; 6113 if (m == 15) 6114 return false; 6115 6116 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6117 if (wback && ((n == 15) || (n == t))) 6118 return false; 6119 } 6120 break; 6121 6122 6123 default: 6124 return false; 6125 } 6126 6127 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6128 if (!success) 6129 return false; 6130 6131 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6132 if (!success) 6133 return false; 6134 6135 addr_t offset_addr; 6136 addr_t address; 6137 6138 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6139 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6140 if (!success) 6141 return false; 6142 6143 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6144 if (add) 6145 offset_addr = Rn + offset; 6146 else 6147 offset_addr = Rn - offset; 6148 6149 // address = if index then offset_addr else R[n]; 6150 if (index) 6151 address = offset_addr; 6152 else 6153 address = Rn; 6154 6155 // data = MemU[address,4]; 6156 RegisterInfo base_reg; 6157 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6158 6159 EmulateInstruction::Context context; 6160 context.type = eContextRegisterLoad; 6161 context.SetRegisterPlusOffset (base_reg, address - Rn); 6162 6163 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6164 if (!success) 6165 return false; 6166 6167 // if wback then R[n] = offset_addr; 6168 if (wback) 6169 { 6170 context.type = eContextAdjustBaseRegister; 6171 context.SetAddress (offset_addr); 6172 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6173 return false; 6174 } 6175 6176 // if t == 15 then 6177 if (t == 15) 6178 { 6179 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6180 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6181 { 6182 context.type = eContextRegisterLoad; 6183 context.SetRegisterPlusOffset (base_reg, address - Rn); 6184 LoadWritePC (context, data); 6185 } 6186 else 6187 return false; 6188 } 6189 // elsif UnalignedSupport() || address<1:0> = '00' then 6190 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6191 { 6192 // R[t] = data; 6193 context.type = eContextRegisterLoad; 6194 context.SetRegisterPlusOffset (base_reg, address - Rn); 6195 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6196 return false; 6197 } 6198 else // Can only apply before ARMv7 6199 { 6200 // if CurrentInstrSet() == InstrSet_ARM then 6201 if (CurrentInstrSet () == eModeARM) 6202 { 6203 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6204 data = ROR (data, Bits32 (address, 1, 0), &success); 6205 if (!success) 6206 return false; 6207 context.type = eContextRegisterLoad; 6208 context.SetImmediate (data); 6209 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6210 return false; 6211 } 6212 else 6213 { 6214 // R[t] = bits(32) UNKNOWN; 6215 WriteBits32Unknown (t); 6216 } 6217 } 6218 } 6219 return true; 6220 } 6221 6222 // LDRB (immediate, Thumb) 6223 bool 6224 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6225 { 6226 #if 0 6227 if ConditionPassed() then 6228 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6229 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6230 address = if index then offset_addr else R[n]; 6231 R[t] = ZeroExtend(MemU[address,1], 32); 6232 if wback then R[n] = offset_addr; 6233 #endif 6234 6235 bool success = false; 6236 6237 if (ConditionPassed(opcode)) 6238 { 6239 uint32_t t; 6240 uint32_t n; 6241 uint32_t imm32; 6242 bool index; 6243 bool add; 6244 bool wback; 6245 6246 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6247 switch (encoding) 6248 { 6249 case eEncodingT1: 6250 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6251 t = Bits32 (opcode, 2, 0); 6252 n = Bits32 (opcode, 5, 3); 6253 imm32 = Bits32 (opcode, 10, 6); 6254 6255 // index = TRUE; add = TRUE; wback = FALSE; 6256 index = true; 6257 add = true; 6258 wback= false; 6259 6260 break; 6261 6262 case eEncodingT2: 6263 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6264 t = Bits32 (opcode, 15, 12); 6265 n = Bits32 (opcode, 19, 16); 6266 imm32 = Bits32 (opcode, 11, 0); 6267 6268 // index = TRUE; add = TRUE; wback = FALSE; 6269 index = true; 6270 add = true; 6271 wback = false; 6272 6273 // if Rt == '1111' then SEE PLD; 6274 if (t == 15) 6275 return false; // PLD is not implemented yet 6276 6277 // if Rn == '1111' then SEE LDRB (literal); 6278 if (n == 15) 6279 return EmulateLDRBLiteral(opcode, eEncodingT1); 6280 6281 // if t == 13 then UNPREDICTABLE; 6282 if (t == 13) 6283 return false; 6284 6285 break; 6286 6287 case eEncodingT3: 6288 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6289 // if P == '0' && W == '0' then UNDEFINED; 6290 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6291 return false; 6292 6293 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6294 t = Bits32 (opcode, 15, 12); 6295 n = Bits32 (opcode, 19, 16); 6296 imm32 = Bits32 (opcode, 7, 0); 6297 6298 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6299 index = BitIsSet (opcode, 10); 6300 add = BitIsSet (opcode, 9); 6301 wback = BitIsSet (opcode, 8); 6302 6303 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6304 if (t == 15) 6305 return false; // PLD is not implemented yet 6306 6307 // if Rn == '1111' then SEE LDRB (literal); 6308 if (n == 15) 6309 return EmulateLDRBLiteral(opcode, eEncodingT1); 6310 6311 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6312 if (BadReg (t) || (wback && (n == t))) 6313 return false; 6314 6315 break; 6316 6317 default: 6318 return false; 6319 } 6320 6321 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6322 if (!success) 6323 return false; 6324 6325 addr_t address; 6326 addr_t offset_addr; 6327 6328 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6329 if (add) 6330 offset_addr = Rn + imm32; 6331 else 6332 offset_addr = Rn - imm32; 6333 6334 // address = if index then offset_addr else R[n]; 6335 if (index) 6336 address = offset_addr; 6337 else 6338 address = Rn; 6339 6340 // R[t] = ZeroExtend(MemU[address,1], 32); 6341 RegisterInfo base_reg; 6342 RegisterInfo data_reg; 6343 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6344 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6345 6346 EmulateInstruction::Context context; 6347 context.type = eContextRegisterLoad; 6348 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6349 6350 uint64_t data = MemURead (context, address, 1, 0, &success); 6351 if (!success) 6352 return false; 6353 6354 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6355 return false; 6356 6357 // if wback then R[n] = offset_addr; 6358 if (wback) 6359 { 6360 context.type = eContextAdjustBaseRegister; 6361 context.SetAddress (offset_addr); 6362 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6363 return false; 6364 } 6365 } 6366 return true; 6367 } 6368 6369 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6370 // zero-extends it to form a 32-bit word and writes it to a register. 6371 bool 6372 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6373 { 6374 #if 0 6375 if ConditionPassed() then 6376 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6377 base = Align(PC,4); 6378 address = if add then (base + imm32) else (base - imm32); 6379 R[t] = ZeroExtend(MemU[address,1], 32); 6380 #endif 6381 6382 bool success = false; 6383 6384 if (ConditionPassed(opcode)) 6385 { 6386 uint32_t t; 6387 uint32_t imm32; 6388 bool add; 6389 switch (encoding) 6390 { 6391 case eEncodingT1: 6392 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6393 t = Bits32 (opcode, 15, 12); 6394 imm32 = Bits32 (opcode, 11, 0); 6395 add = BitIsSet (opcode, 23); 6396 6397 // if Rt == '1111' then SEE PLD; 6398 if (t == 15) 6399 return false; // PLD is not implemented yet 6400 6401 // if t == 13 then UNPREDICTABLE; 6402 if (t == 13) 6403 return false; 6404 6405 break; 6406 6407 case eEncodingA1: 6408 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6409 t = Bits32 (opcode, 15, 12); 6410 imm32 = Bits32 (opcode, 11, 0); 6411 add = BitIsSet (opcode, 23); 6412 6413 // if t == 15 then UNPREDICTABLE; 6414 if (t == 15) 6415 return false; 6416 break; 6417 6418 default: 6419 return false; 6420 } 6421 6422 // base = Align(PC,4); 6423 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6424 if (!success) 6425 return false; 6426 6427 uint32_t base = AlignPC (pc_val); 6428 6429 addr_t address; 6430 // address = if add then (base + imm32) else (base - imm32); 6431 if (add) 6432 address = base + imm32; 6433 else 6434 address = base - imm32; 6435 6436 // R[t] = ZeroExtend(MemU[address,1], 32); 6437 EmulateInstruction::Context context; 6438 context.type = eContextRelativeBranchImmediate; 6439 context.SetImmediate (address - base); 6440 6441 uint64_t data = MemURead (context, address, 1, 0, &success); 6442 if (!success) 6443 return false; 6444 6445 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6446 return false; 6447 } 6448 return true; 6449 } 6450 6451 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6452 // memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6453 // optionally be shifted. 6454 bool 6455 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6456 { 6457 #if 0 6458 if ConditionPassed() then 6459 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6460 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6461 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6462 address = if index then offset_addr else R[n]; 6463 R[t] = ZeroExtend(MemU[address,1],32); 6464 if wback then R[n] = offset_addr; 6465 #endif 6466 6467 bool success = false; 6468 6469 if (ConditionPassed(opcode)) 6470 { 6471 uint32_t t; 6472 uint32_t n; 6473 uint32_t m; 6474 bool index; 6475 bool add; 6476 bool wback; 6477 ARM_ShifterType shift_t; 6478 uint32_t shift_n; 6479 6480 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6481 switch (encoding) 6482 { 6483 case eEncodingT1: 6484 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6485 t = Bits32 (opcode, 2, 0); 6486 n = Bits32 (opcode, 5, 3); 6487 m = Bits32 (opcode, 8, 6); 6488 6489 // index = TRUE; add = TRUE; wback = FALSE; 6490 index = true; 6491 add = true; 6492 wback = false; 6493 6494 // (shift_t, shift_n) = (SRType_LSL, 0); 6495 shift_t = SRType_LSL; 6496 shift_n = 0; 6497 break; 6498 6499 case eEncodingT2: 6500 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6501 t = Bits32 (opcode, 15, 12); 6502 n = Bits32 (opcode, 19, 16); 6503 m = Bits32 (opcode, 3, 0); 6504 6505 // index = TRUE; add = TRUE; wback = FALSE; 6506 index = true; 6507 add = true; 6508 wback = false; 6509 6510 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6511 shift_t = SRType_LSL; 6512 shift_n = Bits32 (opcode, 5, 4); 6513 6514 // if Rt == '1111' then SEE PLD; 6515 if (t == 15) 6516 return false; // PLD is not implemented yet 6517 6518 // if Rn == '1111' then SEE LDRB (literal); 6519 if (n == 15) 6520 return EmulateLDRBLiteral(opcode, eEncodingT1); 6521 6522 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6523 if ((t == 13) || BadReg (m)) 6524 return false; 6525 break; 6526 6527 case eEncodingA1: 6528 { 6529 // if P == '0' && W == '1' then SEE LDRBT; 6530 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6531 t = Bits32 (opcode, 15, 12); 6532 n = Bits32 (opcode, 19, 16); 6533 m = Bits32 (opcode, 3, 0); 6534 6535 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6536 index = BitIsSet (opcode, 24); 6537 add = BitIsSet (opcode, 23); 6538 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6539 6540 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6541 uint32_t type = Bits32 (opcode, 6, 5); 6542 uint32_t imm5 = Bits32 (opcode, 11, 7); 6543 shift_n = DecodeImmShift (type, imm5, shift_t); 6544 6545 // if t == 15 || m == 15 then UNPREDICTABLE; 6546 if ((t == 15) || (m == 15)) 6547 return false; 6548 6549 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6550 if (wback && ((n == 15) || (n == t))) 6551 return false; 6552 } 6553 break; 6554 6555 default: 6556 return false; 6557 } 6558 6559 addr_t offset_addr; 6560 addr_t address; 6561 6562 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6563 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6564 if (!success) 6565 return false; 6566 6567 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6568 if (!success) 6569 return false; 6570 6571 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6572 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6573 if (!success) 6574 return false; 6575 6576 if (add) 6577 offset_addr = Rn + offset; 6578 else 6579 offset_addr = Rn - offset; 6580 6581 // address = if index then offset_addr else R[n]; 6582 if (index) 6583 address = offset_addr; 6584 else 6585 address = Rn; 6586 6587 // R[t] = ZeroExtend(MemU[address,1],32); 6588 RegisterInfo base_reg; 6589 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6590 6591 EmulateInstruction::Context context; 6592 context.type = eContextRegisterLoad; 6593 context.SetRegisterPlusOffset (base_reg, address - Rn); 6594 6595 uint64_t data = MemURead (context, address, 1, 0, &success); 6596 if (!success) 6597 return false; 6598 6599 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6600 return false; 6601 6602 // if wback then R[n] = offset_addr; 6603 if (wback) 6604 { 6605 context.type = eContextAdjustBaseRegister; 6606 context.SetAddress (offset_addr); 6607 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6608 return false; 6609 } 6610 } 6611 return true; 6612 } 6613 6614 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6615 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6616 // post-indexed, or pre-indexed addressing. 6617 bool 6618 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6619 { 6620 #if 0 6621 if ConditionPassed() then 6622 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6623 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6624 address = if index then offset_addr else R[n]; 6625 data = MemU[address,2]; 6626 if wback then R[n] = offset_addr; 6627 if UnalignedSupport() || address<0> = '0' then 6628 R[t] = ZeroExtend(data, 32); 6629 else // Can only apply before ARMv7 6630 R[t] = bits(32) UNKNOWN; 6631 #endif 6632 6633 6634 bool success = false; 6635 6636 if (ConditionPassed(opcode)) 6637 { 6638 uint32_t t; 6639 uint32_t n; 6640 uint32_t imm32; 6641 bool index; 6642 bool add; 6643 bool wback; 6644 6645 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6646 switch (encoding) 6647 { 6648 case eEncodingT1: 6649 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6650 t = Bits32 (opcode, 2, 0); 6651 n = Bits32 (opcode, 5, 3); 6652 imm32 = Bits32 (opcode, 10, 6) << 1; 6653 6654 // index = TRUE; add = TRUE; wback = FALSE; 6655 index = true; 6656 add = true; 6657 wback = false; 6658 6659 break; 6660 6661 case eEncodingT2: 6662 // if Rt == '1111' then SEE "Unallocated memory hints"; 6663 // if Rn == '1111' then SEE LDRH (literal); 6664 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6665 t = Bits32 (opcode, 15, 12); 6666 n = Bits32 (opcode, 19, 16); 6667 imm32 = Bits32 (opcode, 11, 0); 6668 6669 // index = TRUE; add = TRUE; wback = FALSE; 6670 index = true; 6671 add = true; 6672 wback = false; 6673 6674 // if t == 13 then UNPREDICTABLE; 6675 if (t == 13) 6676 return false; 6677 break; 6678 6679 case eEncodingT3: 6680 // if Rn == '1111' then SEE LDRH (literal); 6681 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6682 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6683 // if P == '0' && W == '0' then UNDEFINED; 6684 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6685 return false; 6686 6687 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6688 t = Bits32 (opcode, 15, 12); 6689 n = Bits32 (opcode, 19, 16); 6690 imm32 = Bits32 (opcode, 7, 0); 6691 6692 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6693 index = BitIsSet (opcode, 10); 6694 add = BitIsSet (opcode, 9); 6695 wback = BitIsSet (opcode, 8); 6696 6697 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6698 if (BadReg (t) || (wback && (n == t))) 6699 return false; 6700 break; 6701 6702 default: 6703 return false; 6704 } 6705 6706 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6707 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6708 if (!success) 6709 return false; 6710 6711 addr_t offset_addr; 6712 addr_t address; 6713 6714 if (add) 6715 offset_addr = Rn + imm32; 6716 else 6717 offset_addr = Rn - imm32; 6718 6719 // address = if index then offset_addr else R[n]; 6720 if (index) 6721 address = offset_addr; 6722 else 6723 address = Rn; 6724 6725 // data = MemU[address,2]; 6726 RegisterInfo base_reg; 6727 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6728 6729 EmulateInstruction::Context context; 6730 context.type = eContextRegisterLoad; 6731 context.SetRegisterPlusOffset (base_reg, address - Rn); 6732 6733 uint64_t data = MemURead (context, address, 2, 0, &success); 6734 if (!success) 6735 return false; 6736 6737 // if wback then R[n] = offset_addr; 6738 if (wback) 6739 { 6740 context.type = eContextAdjustBaseRegister; 6741 context.SetAddress (offset_addr); 6742 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6743 return false; 6744 } 6745 6746 // if UnalignedSupport() || address<0> = '0' then 6747 if (UnalignedSupport () || BitIsClear (address, 0)) 6748 { 6749 // R[t] = ZeroExtend(data, 32); 6750 context.type = eContextRegisterLoad; 6751 context.SetRegisterPlusOffset (base_reg, address - Rn); 6752 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6753 return false; 6754 } 6755 else // Can only apply before ARMv7 6756 { 6757 // R[t] = bits(32) UNKNOWN; 6758 WriteBits32Unknown (t); 6759 } 6760 } 6761 return true; 6762 } 6763 6764 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6765 // zero-extends it to form a 32-bit word, and writes it to a register. 6766 bool 6767 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6768 { 6769 #if 0 6770 if ConditionPassed() then 6771 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6772 base = Align(PC,4); 6773 address = if add then (base + imm32) else (base - imm32); 6774 data = MemU[address,2]; 6775 if UnalignedSupport() || address<0> = '0' then 6776 R[t] = ZeroExtend(data, 32); 6777 else // Can only apply before ARMv7 6778 R[t] = bits(32) UNKNOWN; 6779 #endif 6780 6781 bool success = false; 6782 6783 if (ConditionPassed(opcode)) 6784 { 6785 uint32_t t; 6786 uint32_t imm32; 6787 bool add; 6788 6789 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6790 switch (encoding) 6791 { 6792 case eEncodingT1: 6793 // if Rt == '1111' then SEE "Unallocated memory hints"; 6794 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6795 t = Bits32 (opcode, 15, 12); 6796 imm32 = Bits32 (opcode, 11, 0); 6797 add = BitIsSet (opcode, 23); 6798 6799 // if t == 13 then UNPREDICTABLE; 6800 if (t == 13) 6801 return false; 6802 6803 break; 6804 6805 case eEncodingA1: 6806 { 6807 uint32_t imm4H = Bits32 (opcode, 11, 8); 6808 uint32_t imm4L = Bits32 (opcode, 3, 0); 6809 6810 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6811 t = Bits32 (opcode, 15, 12); 6812 imm32 = (imm4H << 4) | imm4L; 6813 add = BitIsSet (opcode, 23); 6814 6815 // if t == 15 then UNPREDICTABLE; 6816 if (t == 15) 6817 return false; 6818 break; 6819 } 6820 6821 default: 6822 return false; 6823 } 6824 6825 // base = Align(PC,4); 6826 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6827 if (!success) 6828 return false; 6829 6830 addr_t base = AlignPC (pc_value); 6831 addr_t address; 6832 6833 // address = if add then (base + imm32) else (base - imm32); 6834 if (add) 6835 address = base + imm32; 6836 else 6837 address = base - imm32; 6838 6839 // data = MemU[address,2]; 6840 RegisterInfo base_reg; 6841 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6842 6843 EmulateInstruction::Context context; 6844 context.type = eContextRegisterLoad; 6845 context.SetRegisterPlusOffset (base_reg, address - base); 6846 6847 uint64_t data = MemURead (context, address, 2, 0, &success); 6848 if (!success) 6849 return false; 6850 6851 6852 // if UnalignedSupport() || address<0> = '0' then 6853 if (UnalignedSupport () || BitIsClear (address, 0)) 6854 { 6855 // R[t] = ZeroExtend(data, 32); 6856 context.type = eContextRegisterLoad; 6857 context.SetRegisterPlusOffset (base_reg, address - base); 6858 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6859 return false; 6860 6861 } 6862 else // Can only apply before ARMv7 6863 { 6864 // R[t] = bits(32) UNKNOWN; 6865 WriteBits32Unknown (t); 6866 } 6867 } 6868 return true; 6869 } 6870 6871 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6872 // from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6873 // be shifted left by 0, 1, 2, or 3 bits. 6874 bool 6875 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6876 { 6877 #if 0 6878 if ConditionPassed() then 6879 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6880 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6881 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6882 address = if index then offset_addr else R[n]; 6883 data = MemU[address,2]; 6884 if wback then R[n] = offset_addr; 6885 if UnalignedSupport() || address<0> = '0' then 6886 R[t] = ZeroExtend(data, 32); 6887 else // Can only apply before ARMv7 6888 R[t] = bits(32) UNKNOWN; 6889 #endif 6890 6891 bool success = false; 6892 6893 if (ConditionPassed(opcode)) 6894 { 6895 uint32_t t; 6896 uint32_t n; 6897 uint32_t m; 6898 bool index; 6899 bool add; 6900 bool wback; 6901 ARM_ShifterType shift_t; 6902 uint32_t shift_n; 6903 6904 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6905 switch (encoding) 6906 { 6907 case eEncodingT1: 6908 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6909 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6910 t = Bits32 (opcode, 2, 0); 6911 n = Bits32 (opcode, 5, 3); 6912 m = Bits32 (opcode, 8, 6); 6913 6914 // index = TRUE; add = TRUE; wback = FALSE; 6915 index = true; 6916 add = true; 6917 wback = false; 6918 6919 // (shift_t, shift_n) = (SRType_LSL, 0); 6920 shift_t = SRType_LSL; 6921 shift_n = 0; 6922 6923 break; 6924 6925 case eEncodingT2: 6926 // if Rn == '1111' then SEE LDRH (literal); 6927 // if Rt == '1111' then SEE "Unallocated memory hints"; 6928 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6929 t = Bits32 (opcode, 15, 12); 6930 n = Bits32 (opcode, 19, 16); 6931 m = Bits32 (opcode, 3, 0); 6932 6933 // index = TRUE; add = TRUE; wback = FALSE; 6934 index = true; 6935 add = true; 6936 wback = false; 6937 6938 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6939 shift_t = SRType_LSL; 6940 shift_n = Bits32 (opcode, 5, 4); 6941 6942 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6943 if ((t == 13) || BadReg (m)) 6944 return false; 6945 break; 6946 6947 case eEncodingA1: 6948 // if P == '0' && W == '1' then SEE LDRHT; 6949 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6950 t = Bits32 (opcode, 15, 12); 6951 n = Bits32 (opcode, 19, 16); 6952 m = Bits32 (opcode, 3, 0); 6953 6954 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6955 index = BitIsSet (opcode, 24); 6956 add = BitIsSet (opcode, 23); 6957 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6958 6959 // (shift_t, shift_n) = (SRType_LSL, 0); 6960 shift_t = SRType_LSL; 6961 shift_n = 0; 6962 6963 // if t == 15 || m == 15 then UNPREDICTABLE; 6964 if ((t == 15) || (m == 15)) 6965 return false; 6966 6967 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6968 if (wback && ((n == 15) || (n == t))) 6969 return false; 6970 6971 break; 6972 6973 default: 6974 return false; 6975 } 6976 6977 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6978 6979 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6980 if (!success) 6981 return false; 6982 6983 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6984 if (!success) 6985 return false; 6986 6987 addr_t offset_addr; 6988 addr_t address; 6989 6990 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6991 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6992 if (!success) 6993 return false; 6994 6995 if (add) 6996 offset_addr = Rn + offset; 6997 else 6998 offset_addr = Rn - offset; 6999 7000 // address = if index then offset_addr else R[n]; 7001 if (index) 7002 address = offset_addr; 7003 else 7004 address = Rn; 7005 7006 // data = MemU[address,2]; 7007 RegisterInfo base_reg; 7008 RegisterInfo offset_reg; 7009 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7010 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7011 7012 EmulateInstruction::Context context; 7013 context.type = eContextRegisterLoad; 7014 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7015 uint64_t data = MemURead (context, address, 2, 0, &success); 7016 if (!success) 7017 return false; 7018 7019 // if wback then R[n] = offset_addr; 7020 if (wback) 7021 { 7022 context.type = eContextAdjustBaseRegister; 7023 context.SetAddress (offset_addr); 7024 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7025 return false; 7026 } 7027 7028 // if UnalignedSupport() || address<0> = '0' then 7029 if (UnalignedSupport() || BitIsClear (address, 0)) 7030 { 7031 // R[t] = ZeroExtend(data, 32); 7032 context.type = eContextRegisterLoad; 7033 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7034 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7035 return false; 7036 } 7037 else // Can only apply before ARMv7 7038 { 7039 // R[t] = bits(32) UNKNOWN; 7040 WriteBits32Unknown (t); 7041 } 7042 } 7043 return true; 7044 } 7045 7046 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 7047 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 7048 // or pre-indexed addressing. 7049 bool 7050 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 7051 { 7052 #if 0 7053 if ConditionPassed() then 7054 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7055 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7056 address = if index then offset_addr else R[n]; 7057 R[t] = SignExtend(MemU[address,1], 32); 7058 if wback then R[n] = offset_addr; 7059 #endif 7060 7061 bool success = false; 7062 7063 if (ConditionPassed(opcode)) 7064 { 7065 uint32_t t; 7066 uint32_t n; 7067 uint32_t imm32; 7068 bool index; 7069 bool add; 7070 bool wback; 7071 7072 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7073 switch (encoding) 7074 { 7075 case eEncodingT1: 7076 // if Rt == '1111' then SEE PLI; 7077 // if Rn == '1111' then SEE LDRSB (literal); 7078 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7079 t = Bits32 (opcode, 15, 12); 7080 n = Bits32 (opcode, 19, 16); 7081 imm32 = Bits32 (opcode, 11, 0); 7082 7083 // index = TRUE; add = TRUE; wback = FALSE; 7084 index = true; 7085 add = true; 7086 wback = false; 7087 7088 // if t == 13 then UNPREDICTABLE; 7089 if (t == 13) 7090 return false; 7091 7092 break; 7093 7094 case eEncodingT2: 7095 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7096 // if Rn == '1111' then SEE LDRSB (literal); 7097 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7098 // if P == '0' && W == '0' then UNDEFINED; 7099 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7100 return false; 7101 7102 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7103 t = Bits32 (opcode, 15, 12); 7104 n = Bits32 (opcode, 19, 16); 7105 imm32 = Bits32 (opcode, 7, 0); 7106 7107 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7108 index = BitIsSet (opcode, 10); 7109 add = BitIsSet (opcode, 9); 7110 wback = BitIsSet (opcode, 8); 7111 7112 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7113 if (((t == 13) || ((t == 15) 7114 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 7115 || (wback && (n == t))) 7116 return false; 7117 7118 break; 7119 7120 case eEncodingA1: 7121 { 7122 // if Rn == '1111' then SEE LDRSB (literal); 7123 // if P == '0' && W == '1' then SEE LDRSBT; 7124 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7125 t = Bits32 (opcode, 15, 12); 7126 n = Bits32 (opcode, 19, 16); 7127 7128 uint32_t imm4H = Bits32 (opcode, 11, 8); 7129 uint32_t imm4L = Bits32 (opcode, 3, 0); 7130 imm32 = (imm4H << 4) | imm4L; 7131 7132 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7133 index = BitIsSet (opcode, 24); 7134 add = BitIsSet (opcode, 23); 7135 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 7136 7137 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7138 if ((t == 15) || (wback && (n == t))) 7139 return false; 7140 7141 break; 7142 } 7143 7144 default: 7145 return false; 7146 } 7147 7148 uint64_t Rn = ReadCoreReg (n, &success); 7149 if (!success) 7150 return false; 7151 7152 addr_t offset_addr; 7153 addr_t address; 7154 7155 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7156 if (add) 7157 offset_addr = Rn + imm32; 7158 else 7159 offset_addr = Rn - imm32; 7160 7161 // address = if index then offset_addr else R[n]; 7162 if (index) 7163 address = offset_addr; 7164 else 7165 address = Rn; 7166 7167 // R[t] = SignExtend(MemU[address,1], 32); 7168 RegisterInfo base_reg; 7169 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7170 7171 EmulateInstruction::Context context; 7172 context.type = eContextRegisterLoad; 7173 context.SetRegisterPlusOffset (base_reg, address - Rn); 7174 7175 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7176 if (!success) 7177 return false; 7178 7179 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7180 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7181 return false; 7182 7183 // if wback then R[n] = offset_addr; 7184 if (wback) 7185 { 7186 context.type = eContextAdjustBaseRegister; 7187 context.SetAddress (offset_addr); 7188 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7189 return false; 7190 } 7191 } 7192 7193 return true; 7194 } 7195 7196 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7197 // sign-extends it to form a 32-bit word, and writes tit to a register. 7198 bool 7199 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7200 { 7201 #if 0 7202 if ConditionPassed() then 7203 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7204 base = Align(PC,4); 7205 address = if add then (base + imm32) else (base - imm32); 7206 R[t] = SignExtend(MemU[address,1], 32); 7207 #endif 7208 7209 bool success = false; 7210 7211 if (ConditionPassed(opcode)) 7212 { 7213 uint32_t t; 7214 uint32_t imm32; 7215 bool add; 7216 7217 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7218 switch (encoding) 7219 { 7220 case eEncodingT1: 7221 // if Rt == '1111' then SEE PLI; 7222 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7223 t = Bits32 (opcode, 15, 12); 7224 imm32 = Bits32 (opcode, 11, 0); 7225 add = BitIsSet (opcode, 23); 7226 7227 // if t == 13 then UNPREDICTABLE; 7228 if (t == 13) 7229 return false; 7230 7231 break; 7232 7233 case eEncodingA1: 7234 { 7235 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7236 t = Bits32 (opcode, 15, 12); 7237 uint32_t imm4H = Bits32 (opcode, 11, 8); 7238 uint32_t imm4L = Bits32 (opcode, 3, 0); 7239 imm32 = (imm4H << 4) | imm4L; 7240 add = BitIsSet (opcode, 23); 7241 7242 // if t == 15 then UNPREDICTABLE; 7243 if (t == 15) 7244 return false; 7245 7246 break; 7247 } 7248 7249 default: 7250 return false; 7251 } 7252 7253 // base = Align(PC,4); 7254 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7255 if (!success) 7256 return false; 7257 uint64_t base = AlignPC (pc_value); 7258 7259 // address = if add then (base + imm32) else (base - imm32); 7260 addr_t address; 7261 if (add) 7262 address = base + imm32; 7263 else 7264 address = base - imm32; 7265 7266 // R[t] = SignExtend(MemU[address,1], 32); 7267 RegisterInfo base_reg; 7268 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7269 7270 EmulateInstruction::Context context; 7271 context.type = eContextRegisterLoad; 7272 context.SetRegisterPlusOffset (base_reg, address - base); 7273 7274 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7275 if (!success) 7276 return false; 7277 7278 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7279 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7280 return false; 7281 } 7282 return true; 7283 } 7284 7285 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7286 // memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7287 // shifted left by 0, 1, 2, or 3 bits. 7288 bool 7289 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7290 { 7291 #if 0 7292 if ConditionPassed() then 7293 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7294 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7295 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7296 address = if index then offset_addr else R[n]; 7297 R[t] = SignExtend(MemU[address,1], 32); 7298 if wback then R[n] = offset_addr; 7299 #endif 7300 7301 bool success = false; 7302 7303 if (ConditionPassed(opcode)) 7304 { 7305 uint32_t t; 7306 uint32_t n; 7307 uint32_t m; 7308 bool index; 7309 bool add; 7310 bool wback; 7311 ARM_ShifterType shift_t; 7312 uint32_t shift_n; 7313 7314 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7315 switch (encoding) 7316 { 7317 case eEncodingT1: 7318 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7319 t = Bits32 (opcode, 2, 0); 7320 n = Bits32 (opcode, 5, 3); 7321 m = Bits32 (opcode, 8, 6); 7322 7323 // index = TRUE; add = TRUE; wback = FALSE; 7324 index = true; 7325 add = true; 7326 wback = false; 7327 7328 // (shift_t, shift_n) = (SRType_LSL, 0); 7329 shift_t = SRType_LSL; 7330 shift_n = 0; 7331 7332 break; 7333 7334 case eEncodingT2: 7335 // if Rt == '1111' then SEE PLI; 7336 // if Rn == '1111' then SEE LDRSB (literal); 7337 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7338 t = Bits32 (opcode, 15, 12); 7339 n = Bits32 (opcode, 19, 16); 7340 m = Bits32 (opcode, 3, 0); 7341 7342 // index = TRUE; add = TRUE; wback = FALSE; 7343 index = true; 7344 add = true; 7345 wback = false; 7346 7347 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7348 shift_t = SRType_LSL; 7349 shift_n = Bits32 (opcode, 5, 4); 7350 7351 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7352 if ((t == 13) || BadReg (m)) 7353 return false; 7354 break; 7355 7356 case eEncodingA1: 7357 // if P == '0' && W == '1' then SEE LDRSBT; 7358 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7359 t = Bits32 (opcode, 15, 12); 7360 n = Bits32 (opcode, 19, 16); 7361 m = Bits32 (opcode, 3, 0); 7362 7363 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7364 index = BitIsSet (opcode, 24); 7365 add = BitIsSet (opcode, 23); 7366 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7367 7368 // (shift_t, shift_n) = (SRType_LSL, 0); 7369 shift_t = SRType_LSL; 7370 shift_n = 0; 7371 7372 // if t == 15 || m == 15 then UNPREDICTABLE; 7373 if ((t == 15) || (m == 15)) 7374 return false; 7375 7376 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7377 if (wback && ((n == 15) || (n == t))) 7378 return false; 7379 break; 7380 7381 default: 7382 return false; 7383 } 7384 7385 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7386 if (!success) 7387 return false; 7388 7389 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7390 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7391 if (!success) 7392 return false; 7393 7394 addr_t offset_addr; 7395 addr_t address; 7396 7397 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7398 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7399 if (!success) 7400 return false; 7401 7402 if (add) 7403 offset_addr = Rn + offset; 7404 else 7405 offset_addr = Rn - offset; 7406 7407 // address = if index then offset_addr else R[n]; 7408 if (index) 7409 address = offset_addr; 7410 else 7411 address = Rn; 7412 7413 // R[t] = SignExtend(MemU[address,1], 32); 7414 RegisterInfo base_reg; 7415 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7416 RegisterInfo offset_reg; 7417 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7418 7419 EmulateInstruction::Context context; 7420 context.type = eContextRegisterLoad; 7421 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7422 7423 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7424 if (!success) 7425 return false; 7426 7427 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7428 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7429 return false; 7430 7431 // if wback then R[n] = offset_addr; 7432 if (wback) 7433 { 7434 context.type = eContextAdjustBaseRegister; 7435 context.SetAddress (offset_addr); 7436 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7437 return false; 7438 } 7439 } 7440 return true; 7441 } 7442 7443 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7444 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7445 // pre-indexed addressing. 7446 bool 7447 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7448 { 7449 #if 0 7450 if ConditionPassed() then 7451 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7452 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7453 address = if index then offset_addr else R[n]; 7454 data = MemU[address,2]; 7455 if wback then R[n] = offset_addr; 7456 if UnalignedSupport() || address<0> = '0' then 7457 R[t] = SignExtend(data, 32); 7458 else // Can only apply before ARMv7 7459 R[t] = bits(32) UNKNOWN; 7460 #endif 7461 7462 bool success = false; 7463 7464 if (ConditionPassed(opcode)) 7465 { 7466 uint32_t t; 7467 uint32_t n; 7468 uint32_t imm32; 7469 bool index; 7470 bool add; 7471 bool wback; 7472 7473 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7474 switch (encoding) 7475 { 7476 case eEncodingT1: 7477 // if Rn == '1111' then SEE LDRSH (literal); 7478 // if Rt == '1111' then SEE "Unallocated memory hints"; 7479 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7480 t = Bits32 (opcode, 15, 12); 7481 n = Bits32 (opcode, 19, 16); 7482 imm32 = Bits32 (opcode, 11, 0); 7483 7484 // index = TRUE; add = TRUE; wback = FALSE; 7485 index = true; 7486 add = true; 7487 wback = false; 7488 7489 // if t == 13 then UNPREDICTABLE; 7490 if (t == 13) 7491 return false; 7492 7493 break; 7494 7495 case eEncodingT2: 7496 // if Rn == '1111' then SEE LDRSH (literal); 7497 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7498 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7499 // if P == '0' && W == '0' then UNDEFINED; 7500 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7501 return false; 7502 7503 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7504 t = Bits32 (opcode, 15, 12); 7505 n = Bits32 (opcode, 19, 16); 7506 imm32 = Bits32 (opcode, 7, 0); 7507 7508 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7509 index = BitIsSet (opcode, 10); 7510 add = BitIsSet (opcode, 9); 7511 wback = BitIsSet (opcode, 8); 7512 7513 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7514 if (BadReg (t) || (wback && (n == t))) 7515 return false; 7516 7517 break; 7518 7519 case eEncodingA1: 7520 { 7521 // if Rn == '1111' then SEE LDRSH (literal); 7522 // if P == '0' && W == '1' then SEE LDRSHT; 7523 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7524 t = Bits32 (opcode, 15, 12); 7525 n = Bits32 (opcode, 19, 16); 7526 uint32_t imm4H = Bits32 (opcode, 11,8); 7527 uint32_t imm4L = Bits32 (opcode, 3, 0); 7528 imm32 = (imm4H << 4) | imm4L; 7529 7530 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7531 index = BitIsSet (opcode, 24); 7532 add = BitIsSet (opcode, 23); 7533 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7534 7535 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7536 if ((t == 15) || (wback && (n == t))) 7537 return false; 7538 7539 break; 7540 } 7541 7542 default: 7543 return false; 7544 } 7545 7546 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7547 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7548 if (!success) 7549 return false; 7550 7551 addr_t offset_addr; 7552 if (add) 7553 offset_addr = Rn + imm32; 7554 else 7555 offset_addr = Rn - imm32; 7556 7557 // address = if index then offset_addr else R[n]; 7558 addr_t address; 7559 if (index) 7560 address = offset_addr; 7561 else 7562 address = Rn; 7563 7564 // data = MemU[address,2]; 7565 RegisterInfo base_reg; 7566 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7567 7568 EmulateInstruction::Context context; 7569 context.type = eContextRegisterLoad; 7570 context.SetRegisterPlusOffset (base_reg, address - Rn); 7571 7572 uint64_t data = MemURead (context, address, 2, 0, &success); 7573 if (!success) 7574 return false; 7575 7576 // if wback then R[n] = offset_addr; 7577 if (wback) 7578 { 7579 context.type = eContextAdjustBaseRegister; 7580 context.SetAddress (offset_addr); 7581 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7582 return false; 7583 } 7584 7585 // if UnalignedSupport() || address<0> = '0' then 7586 if (UnalignedSupport() || BitIsClear (address, 0)) 7587 { 7588 // R[t] = SignExtend(data, 32); 7589 int64_t signed_data = llvm::SignExtend64<16>(data); 7590 context.type = eContextRegisterLoad; 7591 context.SetRegisterPlusOffset (base_reg, address - Rn); 7592 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7593 return false; 7594 } 7595 else // Can only apply before ARMv7 7596 { 7597 // R[t] = bits(32) UNKNOWN; 7598 WriteBits32Unknown (t); 7599 } 7600 } 7601 return true; 7602 } 7603 7604 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7605 // sign-extends it to from a 32-bit word, and writes it to a register. 7606 bool 7607 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7608 { 7609 #if 0 7610 if ConditionPassed() then 7611 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7612 base = Align(PC,4); 7613 address = if add then (base + imm32) else (base - imm32); 7614 data = MemU[address,2]; 7615 if UnalignedSupport() || address<0> = '0' then 7616 R[t] = SignExtend(data, 32); 7617 else // Can only apply before ARMv7 7618 R[t] = bits(32) UNKNOWN; 7619 #endif 7620 7621 bool success = false; 7622 7623 if (ConditionPassed(opcode)) 7624 { 7625 uint32_t t; 7626 uint32_t imm32; 7627 bool add; 7628 7629 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7630 switch (encoding) 7631 { 7632 case eEncodingT1: 7633 // if Rt == '1111' then SEE "Unallocated memory hints"; 7634 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7635 t = Bits32 (opcode, 15, 12); 7636 imm32 = Bits32 (opcode, 11, 0); 7637 add = BitIsSet (opcode, 23); 7638 7639 // if t == 13 then UNPREDICTABLE; 7640 if (t == 13) 7641 return false; 7642 7643 break; 7644 7645 case eEncodingA1: 7646 { 7647 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7648 t = Bits32 (opcode, 15, 12); 7649 uint32_t imm4H = Bits32 (opcode, 11, 8); 7650 uint32_t imm4L = Bits32 (opcode, 3, 0); 7651 imm32 = (imm4H << 4) | imm4L; 7652 add = BitIsSet (opcode, 23); 7653 7654 // if t == 15 then UNPREDICTABLE; 7655 if (t == 15) 7656 return false; 7657 7658 break; 7659 } 7660 default: 7661 return false; 7662 } 7663 7664 // base = Align(PC,4); 7665 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7666 if (!success) 7667 return false; 7668 7669 uint64_t base = AlignPC (pc_value); 7670 7671 addr_t address; 7672 // address = if add then (base + imm32) else (base - imm32); 7673 if (add) 7674 address = base + imm32; 7675 else 7676 address = base - imm32; 7677 7678 // data = MemU[address,2]; 7679 RegisterInfo base_reg; 7680 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7681 7682 EmulateInstruction::Context context; 7683 context.type = eContextRegisterLoad; 7684 context.SetRegisterPlusOffset (base_reg, imm32); 7685 7686 uint64_t data = MemURead (context, address, 2, 0, &success); 7687 if (!success) 7688 return false; 7689 7690 // if UnalignedSupport() || address<0> = '0' then 7691 if (UnalignedSupport() || BitIsClear (address, 0)) 7692 { 7693 // R[t] = SignExtend(data, 32); 7694 int64_t signed_data = llvm::SignExtend64<16>(data); 7695 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7696 return false; 7697 } 7698 else // Can only apply before ARMv7 7699 { 7700 // R[t] = bits(32) UNKNOWN; 7701 WriteBits32Unknown (t); 7702 } 7703 } 7704 return true; 7705 } 7706 7707 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7708 // from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7709 // shifted left by 0, 1, 2, or 3 bits. 7710 bool 7711 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7712 { 7713 #if 0 7714 if ConditionPassed() then 7715 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7716 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7717 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7718 address = if index then offset_addr else R[n]; 7719 data = MemU[address,2]; 7720 if wback then R[n] = offset_addr; 7721 if UnalignedSupport() || address<0> = '0' then 7722 R[t] = SignExtend(data, 32); 7723 else // Can only apply before ARMv7 7724 R[t] = bits(32) UNKNOWN; 7725 #endif 7726 7727 bool success = false; 7728 7729 if (ConditionPassed(opcode)) 7730 { 7731 uint32_t t; 7732 uint32_t n; 7733 uint32_t m; 7734 bool index; 7735 bool add; 7736 bool wback; 7737 ARM_ShifterType shift_t; 7738 uint32_t shift_n; 7739 7740 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7741 switch (encoding) 7742 { 7743 case eEncodingT1: 7744 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7745 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7746 t = Bits32 (opcode, 2, 0); 7747 n = Bits32 (opcode, 5, 3); 7748 m = Bits32 (opcode, 8, 6); 7749 7750 // index = TRUE; add = TRUE; wback = FALSE; 7751 index = true; 7752 add = true; 7753 wback = false; 7754 7755 // (shift_t, shift_n) = (SRType_LSL, 0); 7756 shift_t = SRType_LSL; 7757 shift_n = 0; 7758 7759 break; 7760 7761 case eEncodingT2: 7762 // if Rn == '1111' then SEE LDRSH (literal); 7763 // if Rt == '1111' then SEE "Unallocated memory hints"; 7764 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7765 t = Bits32 (opcode, 15, 12); 7766 n = Bits32 (opcode, 19, 16); 7767 m = Bits32 (opcode, 3, 0); 7768 7769 // index = TRUE; add = TRUE; wback = FALSE; 7770 index = true; 7771 add = true; 7772 wback = false; 7773 7774 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7775 shift_t = SRType_LSL; 7776 shift_n = Bits32 (opcode, 5, 4); 7777 7778 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7779 if ((t == 13) || BadReg (m)) 7780 return false; 7781 7782 break; 7783 7784 case eEncodingA1: 7785 // if P == '0' && W == '1' then SEE LDRSHT; 7786 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7787 t = Bits32 (opcode, 15, 12); 7788 n = Bits32 (opcode, 19, 16); 7789 m = Bits32 (opcode, 3, 0); 7790 7791 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7792 index = BitIsSet (opcode, 24); 7793 add = BitIsSet (opcode, 23); 7794 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7795 7796 // (shift_t, shift_n) = (SRType_LSL, 0); 7797 shift_t = SRType_LSL; 7798 shift_n = 0; 7799 7800 // if t == 15 || m == 15 then UNPREDICTABLE; 7801 if ((t == 15) || (m == 15)) 7802 return false; 7803 7804 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7805 if (wback && ((n == 15) || (n == t))) 7806 return false; 7807 7808 break; 7809 7810 default: 7811 return false; 7812 } 7813 7814 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7815 if (!success) 7816 return false; 7817 7818 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7819 if (!success) 7820 return false; 7821 7822 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7823 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7824 if (!success) 7825 return false; 7826 7827 addr_t offset_addr; 7828 addr_t address; 7829 7830 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7831 if (add) 7832 offset_addr = Rn + offset; 7833 else 7834 offset_addr = Rn - offset; 7835 7836 // address = if index then offset_addr else R[n]; 7837 if (index) 7838 address = offset_addr; 7839 else 7840 address = Rn; 7841 7842 // data = MemU[address,2]; 7843 RegisterInfo base_reg; 7844 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7845 7846 RegisterInfo offset_reg; 7847 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7848 7849 EmulateInstruction::Context context; 7850 context.type = eContextRegisterLoad; 7851 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7852 7853 uint64_t data = MemURead (context, address, 2, 0, &success); 7854 if (!success) 7855 return false; 7856 7857 // if wback then R[n] = offset_addr; 7858 if (wback) 7859 { 7860 context.type = eContextAdjustBaseRegister; 7861 context.SetAddress (offset_addr); 7862 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7863 return false; 7864 } 7865 7866 // if UnalignedSupport() || address<0> = '0' then 7867 if (UnalignedSupport() || BitIsClear (address, 0)) 7868 { 7869 // R[t] = SignExtend(data, 32); 7870 context.type = eContextRegisterLoad; 7871 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7872 7873 int64_t signed_data = llvm::SignExtend64<16>(data); 7874 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7875 return false; 7876 } 7877 else // Can only apply before ARMv7 7878 { 7879 // R[t] = bits(32) UNKNOWN; 7880 WriteBits32Unknown (t); 7881 } 7882 } 7883 return true; 7884 } 7885 7886 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7887 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7888 bool 7889 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7890 { 7891 #if 0 7892 if ConditionPassed() then 7893 EncodingSpecificOperations(); 7894 rotated = ROR(R[m], rotation); 7895 R[d] = SignExtend(rotated<7:0>, 32); 7896 #endif 7897 7898 bool success = false; 7899 7900 if (ConditionPassed(opcode)) 7901 { 7902 uint32_t d; 7903 uint32_t m; 7904 uint32_t rotation; 7905 7906 // EncodingSpecificOperations(); 7907 switch (encoding) 7908 { 7909 case eEncodingT1: 7910 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7911 d = Bits32 (opcode, 2, 0); 7912 m = Bits32 (opcode, 5, 3); 7913 rotation = 0; 7914 7915 break; 7916 7917 case eEncodingT2: 7918 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7919 d = Bits32 (opcode, 11, 8); 7920 m = Bits32 (opcode, 3, 0); 7921 rotation = Bits32 (opcode, 5, 4) << 3; 7922 7923 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7924 if (BadReg (d) || BadReg (m)) 7925 return false; 7926 7927 break; 7928 7929 case eEncodingA1: 7930 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7931 d = Bits32 (opcode, 15, 12); 7932 m = Bits32 (opcode, 3, 0); 7933 rotation = Bits32 (opcode, 11, 10) << 3; 7934 7935 // if d == 15 || m == 15 then UNPREDICTABLE; 7936 if ((d == 15) || (m == 15)) 7937 return false; 7938 7939 break; 7940 7941 default: 7942 return false; 7943 } 7944 7945 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7946 if (!success) 7947 return false; 7948 7949 // rotated = ROR(R[m], rotation); 7950 uint64_t rotated = ROR (Rm, rotation, &success); 7951 if (!success) 7952 return false; 7953 7954 // R[d] = SignExtend(rotated<7:0>, 32); 7955 int64_t data = llvm::SignExtend64<8>(rotated); 7956 7957 RegisterInfo source_reg; 7958 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7959 7960 EmulateInstruction::Context context; 7961 context.type = eContextRegisterLoad; 7962 context.SetRegister (source_reg); 7963 7964 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7965 return false; 7966 } 7967 return true; 7968 } 7969 7970 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7971 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7972 bool 7973 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7974 { 7975 #if 0 7976 if ConditionPassed() then 7977 EncodingSpecificOperations(); 7978 rotated = ROR(R[m], rotation); 7979 R[d] = SignExtend(rotated<15:0>, 32); 7980 #endif 7981 7982 bool success = false; 7983 7984 if (ConditionPassed(opcode)) 7985 { 7986 uint32_t d; 7987 uint32_t m; 7988 uint32_t rotation; 7989 7990 // EncodingSpecificOperations(); 7991 switch (encoding) 7992 { 7993 case eEncodingT1: 7994 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7995 d = Bits32 (opcode, 2, 0); 7996 m = Bits32 (opcode, 5, 3); 7997 rotation = 0; 7998 7999 break; 8000 8001 case eEncodingT2: 8002 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8003 d = Bits32 (opcode, 11, 8); 8004 m = Bits32 (opcode, 3, 0); 8005 rotation = Bits32 (opcode, 5, 4) << 3; 8006 8007 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8008 if (BadReg (d) || BadReg (m)) 8009 return false; 8010 8011 break; 8012 8013 case eEncodingA1: 8014 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8015 d = Bits32 (opcode, 15, 12); 8016 m = Bits32 (opcode, 3, 0); 8017 rotation = Bits32 (opcode, 11, 10) << 3; 8018 8019 // if d == 15 || m == 15 then UNPREDICTABLE; 8020 if ((d == 15) || (m == 15)) 8021 return false; 8022 8023 break; 8024 8025 default: 8026 return false; 8027 } 8028 8029 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8030 if (!success) 8031 return false; 8032 8033 // rotated = ROR(R[m], rotation); 8034 uint64_t rotated = ROR (Rm, rotation, &success); 8035 if (!success) 8036 return false; 8037 8038 // R[d] = SignExtend(rotated<15:0>, 32); 8039 RegisterInfo source_reg; 8040 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8041 8042 EmulateInstruction::Context context; 8043 context.type = eContextRegisterLoad; 8044 context.SetRegister (source_reg); 8045 8046 int64_t data = llvm::SignExtend64<16> (rotated); 8047 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 8048 return false; 8049 } 8050 8051 return true; 8052 } 8053 8054 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 8055 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 8056 bool 8057 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 8058 { 8059 #if 0 8060 if ConditionPassed() then 8061 EncodingSpecificOperations(); 8062 rotated = ROR(R[m], rotation); 8063 R[d] = ZeroExtend(rotated<7:0>, 32); 8064 #endif 8065 8066 bool success = false; 8067 8068 if (ConditionPassed(opcode)) 8069 { 8070 uint32_t d; 8071 uint32_t m; 8072 uint32_t rotation; 8073 8074 // EncodingSpecificOperations(); 8075 switch (encoding) 8076 { 8077 case eEncodingT1: 8078 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8079 d = Bits32 (opcode, 2, 0); 8080 m = Bits32 (opcode, 5, 3); 8081 rotation = 0; 8082 8083 break; 8084 8085 case eEncodingT2: 8086 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8087 d = Bits32 (opcode, 11, 8); 8088 m = Bits32 (opcode, 3, 0); 8089 rotation = Bits32 (opcode, 5, 4) << 3; 8090 8091 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8092 if (BadReg (d) || BadReg (m)) 8093 return false; 8094 8095 break; 8096 8097 case eEncodingA1: 8098 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8099 d = Bits32 (opcode, 15, 12); 8100 m = Bits32 (opcode, 3, 0); 8101 rotation = Bits32 (opcode, 11, 10) << 3; 8102 8103 // if d == 15 || m == 15 then UNPREDICTABLE; 8104 if ((d == 15) || (m == 15)) 8105 return false; 8106 8107 break; 8108 8109 default: 8110 return false; 8111 } 8112 8113 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8114 if (!success) 8115 return false; 8116 8117 // rotated = ROR(R[m], rotation); 8118 uint64_t rotated = ROR (Rm, rotation, &success); 8119 if (!success) 8120 return false; 8121 8122 // R[d] = ZeroExtend(rotated<7:0>, 32); 8123 RegisterInfo source_reg; 8124 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8125 8126 EmulateInstruction::Context context; 8127 context.type = eContextRegisterLoad; 8128 context.SetRegister (source_reg); 8129 8130 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 8131 return false; 8132 } 8133 return true; 8134 } 8135 8136 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 8137 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 8138 bool 8139 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 8140 { 8141 #if 0 8142 if ConditionPassed() then 8143 EncodingSpecificOperations(); 8144 rotated = ROR(R[m], rotation); 8145 R[d] = ZeroExtend(rotated<15:0>, 32); 8146 #endif 8147 8148 bool success = false; 8149 8150 if (ConditionPassed(opcode)) 8151 { 8152 uint32_t d; 8153 uint32_t m; 8154 uint32_t rotation; 8155 8156 switch (encoding) 8157 { 8158 case eEncodingT1: 8159 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8160 d = Bits32 (opcode, 2, 0); 8161 m = Bits32 (opcode, 5, 3); 8162 rotation = 0; 8163 8164 break; 8165 8166 case eEncodingT2: 8167 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8168 d = Bits32 (opcode, 11, 8); 8169 m = Bits32 (opcode, 3, 0); 8170 rotation = Bits32 (opcode, 5, 4) << 3; 8171 8172 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8173 if (BadReg (d) || BadReg (m)) 8174 return false; 8175 8176 break; 8177 8178 case eEncodingA1: 8179 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8180 d = Bits32 (opcode, 15, 12); 8181 m = Bits32 (opcode, 3, 0); 8182 rotation = Bits32 (opcode, 11, 10) << 3; 8183 8184 // if d == 15 || m == 15 then UNPREDICTABLE; 8185 if ((d == 15) || (m == 15)) 8186 return false; 8187 8188 break; 8189 8190 default: 8191 return false; 8192 } 8193 8194 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8195 if (!success) 8196 return false; 8197 8198 // rotated = ROR(R[m], rotation); 8199 uint64_t rotated = ROR (Rm, rotation, &success); 8200 if (!success) 8201 return false; 8202 8203 // R[d] = ZeroExtend(rotated<15:0>, 32); 8204 RegisterInfo source_reg; 8205 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8206 8207 EmulateInstruction::Context context; 8208 context.type = eContextRegisterLoad; 8209 context.SetRegister (source_reg); 8210 8211 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8212 return false; 8213 } 8214 return true; 8215 } 8216 8217 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8218 // word respectively. 8219 bool 8220 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8221 { 8222 #if 0 8223 if ConditionPassed() then 8224 EncodingSpecificOperations(); 8225 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8226 UNPREDICTABLE; 8227 else 8228 address = if increment then R[n] else R[n]-8; 8229 if wordhigher then address = address+4; 8230 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8231 BranchWritePC(MemA[address,4]); 8232 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8233 #endif 8234 8235 bool success = false; 8236 8237 if (ConditionPassed(opcode)) 8238 { 8239 uint32_t n; 8240 bool wback; 8241 bool increment; 8242 bool wordhigher; 8243 8244 // EncodingSpecificOperations(); 8245 switch (encoding) 8246 { 8247 case eEncodingT1: 8248 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8249 n = Bits32 (opcode, 19, 16); 8250 wback = BitIsSet (opcode, 21); 8251 increment = false; 8252 wordhigher = false; 8253 8254 // if n == 15 then UNPREDICTABLE; 8255 if (n == 15) 8256 return false; 8257 8258 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8259 if (InITBlock() && !LastInITBlock()) 8260 return false; 8261 8262 break; 8263 8264 case eEncodingT2: 8265 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8266 n = Bits32 (opcode, 19, 16); 8267 wback = BitIsSet (opcode, 21); 8268 increment = true; 8269 wordhigher = false; 8270 8271 // if n == 15 then UNPREDICTABLE; 8272 if (n == 15) 8273 return false; 8274 8275 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8276 if (InITBlock() && !LastInITBlock()) 8277 return false; 8278 8279 break; 8280 8281 case eEncodingA1: 8282 // n = UInt(Rn); 8283 n = Bits32 (opcode, 19, 16); 8284 8285 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8286 wback = BitIsSet (opcode, 21); 8287 increment = BitIsSet (opcode, 23); 8288 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8289 8290 // if n == 15 then UNPREDICTABLE; 8291 if (n == 15) 8292 return false; 8293 8294 break; 8295 8296 default: 8297 return false; 8298 } 8299 8300 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8301 if (!CurrentModeIsPrivileged ()) 8302 // UNPREDICTABLE; 8303 return false; 8304 else 8305 { 8306 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8307 if (!success) 8308 return false; 8309 8310 addr_t address; 8311 // address = if increment then R[n] else R[n]-8; 8312 if (increment) 8313 address = Rn; 8314 else 8315 address = Rn - 8; 8316 8317 // if wordhigher then address = address+4; 8318 if (wordhigher) 8319 address = address + 4; 8320 8321 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8322 RegisterInfo base_reg; 8323 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8324 8325 EmulateInstruction::Context context; 8326 context.type = eContextReturnFromException; 8327 context.SetRegisterPlusOffset (base_reg, address - Rn); 8328 8329 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8330 if (!success) 8331 return false; 8332 8333 CPSRWriteByInstr (data, 15, true); 8334 8335 // BranchWritePC(MemA[address,4]); 8336 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8337 if (!success) 8338 return false; 8339 8340 BranchWritePC (context, data2); 8341 8342 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8343 if (wback) 8344 { 8345 context.type = eContextAdjustBaseRegister; 8346 if (increment) 8347 { 8348 context.SetOffset (8); 8349 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8350 return false; 8351 } 8352 else 8353 { 8354 context.SetOffset (-8); 8355 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8356 return false; 8357 } 8358 } // if wback 8359 } 8360 } // if ConditionPassed() 8361 return true; 8362 } 8363 8364 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8365 // and writes the result to the destination register. It can optionally update the condition flags based on 8366 // the result. 8367 bool 8368 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8369 { 8370 #if 0 8371 // ARM pseudo code... 8372 if ConditionPassed() then 8373 EncodingSpecificOperations(); 8374 result = R[n] EOR imm32; 8375 if d == 15 then // Can only occur for ARM encoding 8376 ALUWritePC(result); // setflags is always FALSE here 8377 else 8378 R[d] = result; 8379 if setflags then 8380 APSR.N = result<31>; 8381 APSR.Z = IsZeroBit(result); 8382 APSR.C = carry; 8383 // APSR.V unchanged 8384 #endif 8385 8386 bool success = false; 8387 8388 if (ConditionPassed(opcode)) 8389 { 8390 uint32_t Rd, Rn; 8391 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8392 bool setflags; 8393 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8394 switch (encoding) 8395 { 8396 case eEncodingT1: 8397 Rd = Bits32(opcode, 11, 8); 8398 Rn = Bits32(opcode, 19, 16); 8399 setflags = BitIsSet(opcode, 20); 8400 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8401 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8402 if (Rd == 15 && setflags) 8403 return EmulateTEQImm (opcode, eEncodingT1); 8404 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8405 return false; 8406 break; 8407 case eEncodingA1: 8408 Rd = Bits32(opcode, 15, 12); 8409 Rn = Bits32(opcode, 19, 16); 8410 setflags = BitIsSet(opcode, 20); 8411 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8412 8413 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8414 if (Rd == 15 && setflags) 8415 return EmulateSUBSPcLrEtc (opcode, encoding); 8416 break; 8417 default: 8418 return false; 8419 } 8420 8421 // Read the first operand. 8422 uint32_t val1 = ReadCoreReg(Rn, &success); 8423 if (!success) 8424 return false; 8425 8426 uint32_t result = val1 ^ imm32; 8427 8428 EmulateInstruction::Context context; 8429 context.type = EmulateInstruction::eContextImmediate; 8430 context.SetNoArgs (); 8431 8432 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8433 return false; 8434 } 8435 return true; 8436 } 8437 8438 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8439 // optionally-shifted register value, and writes the result to the destination register. 8440 // It can optionally update the condition flags based on the result. 8441 bool 8442 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8443 { 8444 #if 0 8445 // ARM pseudo code... 8446 if ConditionPassed() then 8447 EncodingSpecificOperations(); 8448 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8449 result = R[n] EOR shifted; 8450 if d == 15 then // Can only occur for ARM encoding 8451 ALUWritePC(result); // setflags is always FALSE here 8452 else 8453 R[d] = result; 8454 if setflags then 8455 APSR.N = result<31>; 8456 APSR.Z = IsZeroBit(result); 8457 APSR.C = carry; 8458 // APSR.V unchanged 8459 #endif 8460 8461 bool success = false; 8462 8463 if (ConditionPassed(opcode)) 8464 { 8465 uint32_t Rd, Rn, Rm; 8466 ARM_ShifterType shift_t; 8467 uint32_t shift_n; // the shift applied to the value read from Rm 8468 bool setflags; 8469 uint32_t carry; 8470 switch (encoding) 8471 { 8472 case eEncodingT1: 8473 Rd = Rn = Bits32(opcode, 2, 0); 8474 Rm = Bits32(opcode, 5, 3); 8475 setflags = !InITBlock(); 8476 shift_t = SRType_LSL; 8477 shift_n = 0; 8478 break; 8479 case eEncodingT2: 8480 Rd = Bits32(opcode, 11, 8); 8481 Rn = Bits32(opcode, 19, 16); 8482 Rm = Bits32(opcode, 3, 0); 8483 setflags = BitIsSet(opcode, 20); 8484 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8485 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8486 if (Rd == 15 && setflags) 8487 return EmulateTEQReg (opcode, eEncodingT1); 8488 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8489 return false; 8490 break; 8491 case eEncodingA1: 8492 Rd = Bits32(opcode, 15, 12); 8493 Rn = Bits32(opcode, 19, 16); 8494 Rm = Bits32(opcode, 3, 0); 8495 setflags = BitIsSet(opcode, 20); 8496 shift_n = DecodeImmShiftARM(opcode, shift_t); 8497 8498 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8499 if (Rd == 15 && setflags) 8500 return EmulateSUBSPcLrEtc (opcode, encoding); 8501 break; 8502 default: 8503 return false; 8504 } 8505 8506 // Read the first operand. 8507 uint32_t val1 = ReadCoreReg(Rn, &success); 8508 if (!success) 8509 return false; 8510 8511 // Read the second operand. 8512 uint32_t val2 = ReadCoreReg(Rm, &success); 8513 if (!success) 8514 return false; 8515 8516 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8517 if (!success) 8518 return false; 8519 uint32_t result = val1 ^ shifted; 8520 8521 EmulateInstruction::Context context; 8522 context.type = EmulateInstruction::eContextImmediate; 8523 context.SetNoArgs (); 8524 8525 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8526 return false; 8527 } 8528 return true; 8529 } 8530 8531 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8532 // writes the result to the destination register. It can optionally update the condition flags based 8533 // on the result. 8534 bool 8535 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8536 { 8537 #if 0 8538 // ARM pseudo code... 8539 if ConditionPassed() then 8540 EncodingSpecificOperations(); 8541 result = R[n] OR imm32; 8542 if d == 15 then // Can only occur for ARM encoding 8543 ALUWritePC(result); // setflags is always FALSE here 8544 else 8545 R[d] = result; 8546 if setflags then 8547 APSR.N = result<31>; 8548 APSR.Z = IsZeroBit(result); 8549 APSR.C = carry; 8550 // APSR.V unchanged 8551 #endif 8552 8553 bool success = false; 8554 8555 if (ConditionPassed(opcode)) 8556 { 8557 uint32_t Rd, Rn; 8558 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8559 bool setflags; 8560 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8561 switch (encoding) 8562 { 8563 case eEncodingT1: 8564 Rd = Bits32(opcode, 11, 8); 8565 Rn = Bits32(opcode, 19, 16); 8566 setflags = BitIsSet(opcode, 20); 8567 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8568 // if Rn == '1111' then SEE MOV (immediate); 8569 if (Rn == 15) 8570 return EmulateMOVRdImm (opcode, eEncodingT2); 8571 if (BadReg(Rd) || Rn == 13) 8572 return false; 8573 break; 8574 case eEncodingA1: 8575 Rd = Bits32(opcode, 15, 12); 8576 Rn = Bits32(opcode, 19, 16); 8577 setflags = BitIsSet(opcode, 20); 8578 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8579 8580 if (Rd == 15 && setflags) 8581 return EmulateSUBSPcLrEtc (opcode, encoding); 8582 break; 8583 default: 8584 return false; 8585 } 8586 8587 // Read the first operand. 8588 uint32_t val1 = ReadCoreReg(Rn, &success); 8589 if (!success) 8590 return false; 8591 8592 uint32_t result = val1 | imm32; 8593 8594 EmulateInstruction::Context context; 8595 context.type = EmulateInstruction::eContextImmediate; 8596 context.SetNoArgs (); 8597 8598 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8599 return false; 8600 } 8601 return true; 8602 } 8603 8604 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8605 // value, and writes the result to the destination register. It can optionally update the condition flags based 8606 // on the result. 8607 bool 8608 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8609 { 8610 #if 0 8611 // ARM pseudo code... 8612 if ConditionPassed() then 8613 EncodingSpecificOperations(); 8614 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8615 result = R[n] OR shifted; 8616 if d == 15 then // Can only occur for ARM encoding 8617 ALUWritePC(result); // setflags is always FALSE here 8618 else 8619 R[d] = result; 8620 if setflags then 8621 APSR.N = result<31>; 8622 APSR.Z = IsZeroBit(result); 8623 APSR.C = carry; 8624 // APSR.V unchanged 8625 #endif 8626 8627 bool success = false; 8628 8629 if (ConditionPassed(opcode)) 8630 { 8631 uint32_t Rd, Rn, Rm; 8632 ARM_ShifterType shift_t; 8633 uint32_t shift_n; // the shift applied to the value read from Rm 8634 bool setflags; 8635 uint32_t carry; 8636 switch (encoding) 8637 { 8638 case eEncodingT1: 8639 Rd = Rn = Bits32(opcode, 2, 0); 8640 Rm = Bits32(opcode, 5, 3); 8641 setflags = !InITBlock(); 8642 shift_t = SRType_LSL; 8643 shift_n = 0; 8644 break; 8645 case eEncodingT2: 8646 Rd = Bits32(opcode, 11, 8); 8647 Rn = Bits32(opcode, 19, 16); 8648 Rm = Bits32(opcode, 3, 0); 8649 setflags = BitIsSet(opcode, 20); 8650 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8651 // if Rn == '1111' then SEE MOV (register); 8652 if (Rn == 15) 8653 return EmulateMOVRdRm (opcode, eEncodingT3); 8654 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8655 return false; 8656 break; 8657 case eEncodingA1: 8658 Rd = Bits32(opcode, 15, 12); 8659 Rn = Bits32(opcode, 19, 16); 8660 Rm = Bits32(opcode, 3, 0); 8661 setflags = BitIsSet(opcode, 20); 8662 shift_n = DecodeImmShiftARM(opcode, shift_t); 8663 8664 if (Rd == 15 && setflags) 8665 return EmulateSUBSPcLrEtc (opcode, encoding); 8666 break; 8667 default: 8668 return false; 8669 } 8670 8671 // Read the first operand. 8672 uint32_t val1 = ReadCoreReg(Rn, &success); 8673 if (!success) 8674 return false; 8675 8676 // Read the second operand. 8677 uint32_t val2 = ReadCoreReg(Rm, &success); 8678 if (!success) 8679 return false; 8680 8681 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8682 if (!success) 8683 return false; 8684 uint32_t result = val1 | shifted; 8685 8686 EmulateInstruction::Context context; 8687 context.type = EmulateInstruction::eContextImmediate; 8688 context.SetNoArgs (); 8689 8690 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8691 return false; 8692 } 8693 return true; 8694 } 8695 8696 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8697 // the destination register. It can optionally update the condition flags based on the result. 8698 bool 8699 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8700 { 8701 #if 0 8702 // ARM pseudo code... 8703 if ConditionPassed() then 8704 EncodingSpecificOperations(); 8705 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8706 if d == 15 then // Can only occur for ARM encoding 8707 ALUWritePC(result); // setflags is always FALSE here 8708 else 8709 R[d] = result; 8710 if setflags then 8711 APSR.N = result<31>; 8712 APSR.Z = IsZeroBit(result); 8713 APSR.C = carry; 8714 APSR.V = overflow; 8715 #endif 8716 8717 bool success = false; 8718 8719 uint32_t Rd; // the destination register 8720 uint32_t Rn; // the first operand 8721 bool setflags; 8722 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8723 switch (encoding) { 8724 case eEncodingT1: 8725 Rd = Bits32(opcode, 2, 0); 8726 Rn = Bits32(opcode, 5, 3); 8727 setflags = !InITBlock(); 8728 imm32 = 0; 8729 break; 8730 case eEncodingT2: 8731 Rd = Bits32(opcode, 11, 8); 8732 Rn = Bits32(opcode, 19, 16); 8733 setflags = BitIsSet(opcode, 20); 8734 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8735 if (BadReg(Rd) || BadReg(Rn)) 8736 return false; 8737 break; 8738 case eEncodingA1: 8739 Rd = Bits32(opcode, 15, 12); 8740 Rn = Bits32(opcode, 19, 16); 8741 setflags = BitIsSet(opcode, 20); 8742 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8743 8744 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8745 if (Rd == 15 && setflags) 8746 return EmulateSUBSPcLrEtc (opcode, encoding); 8747 break; 8748 default: 8749 return false; 8750 } 8751 // Read the register value from the operand register Rn. 8752 uint32_t reg_val = ReadCoreReg(Rn, &success); 8753 if (!success) 8754 return false; 8755 8756 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8757 8758 EmulateInstruction::Context context; 8759 context.type = EmulateInstruction::eContextImmediate; 8760 context.SetNoArgs (); 8761 8762 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8763 return false; 8764 8765 return true; 8766 } 8767 8768 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8769 // result to the destination register. It can optionally update the condition flags based on the result. 8770 bool 8771 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8772 { 8773 #if 0 8774 // ARM pseudo code... 8775 if ConditionPassed() then 8776 EncodingSpecificOperations(); 8777 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8778 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8779 if d == 15 then // Can only occur for ARM encoding 8780 ALUWritePC(result); // setflags is always FALSE here 8781 else 8782 R[d] = result; 8783 if setflags then 8784 APSR.N = result<31>; 8785 APSR.Z = IsZeroBit(result); 8786 APSR.C = carry; 8787 APSR.V = overflow; 8788 #endif 8789 8790 bool success = false; 8791 8792 uint32_t Rd; // the destination register 8793 uint32_t Rn; // the first operand 8794 uint32_t Rm; // the second operand 8795 bool setflags; 8796 ARM_ShifterType shift_t; 8797 uint32_t shift_n; // the shift applied to the value read from Rm 8798 switch (encoding) { 8799 case eEncodingT1: 8800 Rd = Bits32(opcode, 11, 8); 8801 Rn = Bits32(opcode, 19, 16); 8802 Rm = Bits32(opcode, 3, 0); 8803 setflags = BitIsSet(opcode, 20); 8804 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8805 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8806 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8807 return false; 8808 break; 8809 case eEncodingA1: 8810 Rd = Bits32(opcode, 15, 12); 8811 Rn = Bits32(opcode, 19, 16); 8812 Rm = Bits32(opcode, 3, 0); 8813 setflags = BitIsSet(opcode, 20); 8814 shift_n = DecodeImmShiftARM(opcode, shift_t); 8815 8816 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8817 if (Rd == 15 && setflags) 8818 return EmulateSUBSPcLrEtc (opcode, encoding); 8819 break; 8820 default: 8821 return false; 8822 } 8823 // Read the register value from register Rn. 8824 uint32_t val1 = ReadCoreReg(Rn, &success); 8825 if (!success) 8826 return false; 8827 8828 // Read the register value from register Rm. 8829 uint32_t val2 = ReadCoreReg(Rm, &success); 8830 if (!success) 8831 return false; 8832 8833 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8834 if (!success) 8835 return false; 8836 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8837 8838 EmulateInstruction::Context context; 8839 context.type = EmulateInstruction::eContextImmediate; 8840 context.SetNoArgs(); 8841 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8842 return false; 8843 8844 return true; 8845 } 8846 8847 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8848 // an immediate value, and writes the result to the destination register. It can optionally update the condition 8849 // flags based on the result. 8850 bool 8851 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8852 { 8853 #if 0 8854 // ARM pseudo code... 8855 if ConditionPassed() then 8856 EncodingSpecificOperations(); 8857 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8858 if d == 15 then 8859 ALUWritePC(result); // setflags is always FALSE here 8860 else 8861 R[d] = result; 8862 if setflags then 8863 APSR.N = result<31>; 8864 APSR.Z = IsZeroBit(result); 8865 APSR.C = carry; 8866 APSR.V = overflow; 8867 #endif 8868 8869 bool success = false; 8870 8871 uint32_t Rd; // the destination register 8872 uint32_t Rn; // the first operand 8873 bool setflags; 8874 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8875 switch (encoding) { 8876 case eEncodingA1: 8877 Rd = Bits32(opcode, 15, 12); 8878 Rn = Bits32(opcode, 19, 16); 8879 setflags = BitIsSet(opcode, 20); 8880 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8881 8882 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8883 if (Rd == 15 && setflags) 8884 return EmulateSUBSPcLrEtc (opcode, encoding); 8885 break; 8886 default: 8887 return false; 8888 } 8889 // Read the register value from the operand register Rn. 8890 uint32_t reg_val = ReadCoreReg(Rn, &success); 8891 if (!success) 8892 return false; 8893 8894 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8895 8896 EmulateInstruction::Context context; 8897 context.type = EmulateInstruction::eContextImmediate; 8898 context.SetNoArgs (); 8899 8900 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8901 return false; 8902 8903 return true; 8904 } 8905 8906 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8907 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8908 // condition flags based on the result. 8909 bool 8910 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8911 { 8912 #if 0 8913 // ARM pseudo code... 8914 if ConditionPassed() then 8915 EncodingSpecificOperations(); 8916 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8917 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8918 if d == 15 then 8919 ALUWritePC(result); // setflags is always FALSE here 8920 else 8921 R[d] = result; 8922 if setflags then 8923 APSR.N = result<31>; 8924 APSR.Z = IsZeroBit(result); 8925 APSR.C = carry; 8926 APSR.V = overflow; 8927 #endif 8928 8929 bool success = false; 8930 8931 uint32_t Rd; // the destination register 8932 uint32_t Rn; // the first operand 8933 uint32_t Rm; // the second operand 8934 bool setflags; 8935 ARM_ShifterType shift_t; 8936 uint32_t shift_n; // the shift applied to the value read from Rm 8937 switch (encoding) { 8938 case eEncodingA1: 8939 Rd = Bits32(opcode, 15, 12); 8940 Rn = Bits32(opcode, 19, 16); 8941 Rm = Bits32(opcode, 3, 0); 8942 setflags = BitIsSet(opcode, 20); 8943 shift_n = DecodeImmShiftARM(opcode, shift_t); 8944 8945 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8946 if (Rd == 15 && setflags) 8947 return EmulateSUBSPcLrEtc (opcode, encoding); 8948 break; 8949 default: 8950 return false; 8951 } 8952 // Read the register value from register Rn. 8953 uint32_t val1 = ReadCoreReg(Rn, &success); 8954 if (!success) 8955 return false; 8956 8957 // Read the register value from register Rm. 8958 uint32_t val2 = ReadCoreReg(Rm, &success); 8959 if (!success) 8960 return false; 8961 8962 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8963 if (!success) 8964 return false; 8965 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8966 8967 EmulateInstruction::Context context; 8968 context.type = EmulateInstruction::eContextImmediate; 8969 context.SetNoArgs(); 8970 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8971 return false; 8972 8973 return true; 8974 } 8975 8976 // Subtract with Carry (immediate) subtracts an immediate value and the value of 8977 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8978 // It can optionally update the condition flags based on the result. 8979 bool 8980 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 8981 { 8982 #if 0 8983 // ARM pseudo code... 8984 if ConditionPassed() then 8985 EncodingSpecificOperations(); 8986 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8987 if d == 15 then // Can only occur for ARM encoding 8988 ALUWritePC(result); // setflags is always FALSE here 8989 else 8990 R[d] = result; 8991 if setflags then 8992 APSR.N = result<31>; 8993 APSR.Z = IsZeroBit(result); 8994 APSR.C = carry; 8995 APSR.V = overflow; 8996 #endif 8997 8998 bool success = false; 8999 9000 uint32_t Rd; // the destination register 9001 uint32_t Rn; // the first operand 9002 bool setflags; 9003 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 9004 switch (encoding) { 9005 case eEncodingT1: 9006 Rd = Bits32(opcode, 11, 8); 9007 Rn = Bits32(opcode, 19, 16); 9008 setflags = BitIsSet(opcode, 20); 9009 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9010 if (BadReg(Rd) || BadReg(Rn)) 9011 return false; 9012 break; 9013 case eEncodingA1: 9014 Rd = Bits32(opcode, 15, 12); 9015 Rn = Bits32(opcode, 19, 16); 9016 setflags = BitIsSet(opcode, 20); 9017 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9018 9019 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9020 if (Rd == 15 && setflags) 9021 return EmulateSUBSPcLrEtc (opcode, encoding); 9022 break; 9023 default: 9024 return false; 9025 } 9026 // Read the register value from the operand register Rn. 9027 uint32_t reg_val = ReadCoreReg(Rn, &success); 9028 if (!success) 9029 return false; 9030 9031 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9032 9033 EmulateInstruction::Context context; 9034 context.type = EmulateInstruction::eContextImmediate; 9035 context.SetNoArgs (); 9036 9037 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9038 return false; 9039 9040 return true; 9041 } 9042 9043 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 9044 // NOT (Carry flag) from a register value, and writes the result to the destination register. 9045 // It can optionally update the condition flags based on the result. 9046 bool 9047 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 9048 { 9049 #if 0 9050 // ARM pseudo code... 9051 if ConditionPassed() then 9052 EncodingSpecificOperations(); 9053 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9054 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9055 if d == 15 then // Can only occur for ARM encoding 9056 ALUWritePC(result); // setflags is always FALSE here 9057 else 9058 R[d] = result; 9059 if setflags then 9060 APSR.N = result<31>; 9061 APSR.Z = IsZeroBit(result); 9062 APSR.C = carry; 9063 APSR.V = overflow; 9064 #endif 9065 9066 bool success = false; 9067 9068 uint32_t Rd; // the destination register 9069 uint32_t Rn; // the first operand 9070 uint32_t Rm; // the second operand 9071 bool setflags; 9072 ARM_ShifterType shift_t; 9073 uint32_t shift_n; // the shift applied to the value read from Rm 9074 switch (encoding) { 9075 case eEncodingT1: 9076 Rd = Rn = Bits32(opcode, 2, 0); 9077 Rm = Bits32(opcode, 5, 3); 9078 setflags = !InITBlock(); 9079 shift_t = SRType_LSL; 9080 shift_n = 0; 9081 break; 9082 case eEncodingT2: 9083 Rd = Bits32(opcode, 11, 8); 9084 Rn = Bits32(opcode, 19, 16); 9085 Rm = Bits32(opcode, 3, 0); 9086 setflags = BitIsSet(opcode, 20); 9087 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9088 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9089 return false; 9090 break; 9091 case eEncodingA1: 9092 Rd = Bits32(opcode, 15, 12); 9093 Rn = Bits32(opcode, 19, 16); 9094 Rm = Bits32(opcode, 3, 0); 9095 setflags = BitIsSet(opcode, 20); 9096 shift_n = DecodeImmShiftARM(opcode, shift_t); 9097 9098 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9099 if (Rd == 15 && setflags) 9100 return EmulateSUBSPcLrEtc (opcode, encoding); 9101 break; 9102 default: 9103 return false; 9104 } 9105 // Read the register value from register Rn. 9106 uint32_t val1 = ReadCoreReg(Rn, &success); 9107 if (!success) 9108 return false; 9109 9110 // Read the register value from register Rm. 9111 uint32_t val2 = ReadCoreReg(Rm, &success); 9112 if (!success) 9113 return false; 9114 9115 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9116 if (!success) 9117 return false; 9118 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9119 9120 EmulateInstruction::Context context; 9121 context.type = EmulateInstruction::eContextImmediate; 9122 context.SetNoArgs(); 9123 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9124 return false; 9125 9126 return true; 9127 } 9128 9129 // This instruction subtracts an immediate value from a register value, and writes the result 9130 // to the destination register. It can optionally update the condition flags based on the result. 9131 bool 9132 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 9133 { 9134 #if 0 9135 // ARM pseudo code... 9136 if ConditionPassed() then 9137 EncodingSpecificOperations(); 9138 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9139 R[d] = result; 9140 if setflags then 9141 APSR.N = result<31>; 9142 APSR.Z = IsZeroBit(result); 9143 APSR.C = carry; 9144 APSR.V = overflow; 9145 #endif 9146 9147 bool success = false; 9148 9149 uint32_t Rd; // the destination register 9150 uint32_t Rn; // the first operand 9151 bool setflags; 9152 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9153 switch (encoding) { 9154 case eEncodingT1: 9155 Rd = Bits32(opcode, 2, 0); 9156 Rn = Bits32(opcode, 5, 3); 9157 setflags = !InITBlock(); 9158 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9159 break; 9160 case eEncodingT2: 9161 Rd = Rn = Bits32(opcode, 10, 8); 9162 setflags = !InITBlock(); 9163 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9164 break; 9165 case eEncodingT3: 9166 Rd = Bits32(opcode, 11, 8); 9167 Rn = Bits32(opcode, 19, 16); 9168 setflags = BitIsSet(opcode, 20); 9169 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9170 9171 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9172 if (Rd == 15 && setflags) 9173 return EmulateCMPImm (opcode, eEncodingT2); 9174 9175 // if Rn == '1101' then SEE SUB (SP minus immediate); 9176 if (Rn == 13) 9177 return EmulateSUBSPImm (opcode, eEncodingT2); 9178 9179 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9180 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9181 return false; 9182 break; 9183 case eEncodingT4: 9184 Rd = Bits32(opcode, 11, 8); 9185 Rn = Bits32(opcode, 19, 16); 9186 setflags = BitIsSet(opcode, 20); 9187 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9188 9189 // if Rn == '1111' then SEE ADR; 9190 if (Rn == 15) 9191 return EmulateADR (opcode, eEncodingT2); 9192 9193 // if Rn == '1101' then SEE SUB (SP minus immediate); 9194 if (Rn == 13) 9195 return EmulateSUBSPImm (opcode, eEncodingT3); 9196 9197 if (BadReg(Rd)) 9198 return false; 9199 break; 9200 default: 9201 return false; 9202 } 9203 // Read the register value from the operand register Rn. 9204 uint32_t reg_val = ReadCoreReg(Rn, &success); 9205 if (!success) 9206 return false; 9207 9208 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9209 9210 EmulateInstruction::Context context; 9211 context.type = EmulateInstruction::eContextImmediate; 9212 context.SetNoArgs (); 9213 9214 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9215 return false; 9216 9217 return true; 9218 } 9219 9220 // This instruction subtracts an immediate value from a register value, and writes the result 9221 // to the destination register. It can optionally update the condition flags based on the result. 9222 bool 9223 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9224 { 9225 #if 0 9226 // ARM pseudo code... 9227 if ConditionPassed() then 9228 EncodingSpecificOperations(); 9229 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9230 if d == 15 then 9231 ALUWritePC(result); // setflags is always FALSE here 9232 else 9233 R[d] = result; 9234 if setflags then 9235 APSR.N = result<31>; 9236 APSR.Z = IsZeroBit(result); 9237 APSR.C = carry; 9238 APSR.V = overflow; 9239 #endif 9240 9241 bool success = false; 9242 9243 if (ConditionPassed(opcode)) 9244 { 9245 uint32_t Rd; // the destination register 9246 uint32_t Rn; // the first operand 9247 bool setflags; 9248 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9249 switch (encoding) { 9250 case eEncodingA1: 9251 Rd = Bits32(opcode, 15, 12); 9252 Rn = Bits32(opcode, 19, 16); 9253 setflags = BitIsSet(opcode, 20); 9254 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9255 9256 // if Rn == '1111' && S == '0' then SEE ADR; 9257 if (Rn == 15 && !setflags) 9258 return EmulateADR (opcode, eEncodingA2); 9259 9260 // if Rn == '1101' then SEE SUB (SP minus immediate); 9261 if (Rn == 13) 9262 return EmulateSUBSPImm (opcode, eEncodingA1); 9263 9264 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9265 if (Rd == 15 && setflags) 9266 return EmulateSUBSPcLrEtc (opcode, encoding); 9267 break; 9268 default: 9269 return false; 9270 } 9271 // Read the register value from the operand register Rn. 9272 uint32_t reg_val = ReadCoreReg(Rn, &success); 9273 if (!success) 9274 return false; 9275 9276 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9277 9278 EmulateInstruction::Context context; 9279 if (Rd == 13) 9280 context.type = EmulateInstruction::eContextAdjustStackPointer; 9281 else 9282 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9283 9284 RegisterInfo dwarf_reg; 9285 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 9286 int64_t imm32_signed = imm32; 9287 context.SetRegisterPlusOffset (dwarf_reg, -imm32_signed); 9288 9289 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9290 return false; 9291 } 9292 return true; 9293 } 9294 9295 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9296 // immediate value. It updates the condition flags based on the result, and discards the result. 9297 bool 9298 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9299 { 9300 #if 0 9301 // ARM pseudo code... 9302 if ConditionPassed() then 9303 EncodingSpecificOperations(); 9304 result = R[n] EOR imm32; 9305 APSR.N = result<31>; 9306 APSR.Z = IsZeroBit(result); 9307 APSR.C = carry; 9308 // APSR.V unchanged 9309 #endif 9310 9311 bool success = false; 9312 9313 if (ConditionPassed(opcode)) 9314 { 9315 uint32_t Rn; 9316 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9317 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9318 switch (encoding) 9319 { 9320 case eEncodingT1: 9321 Rn = Bits32(opcode, 19, 16); 9322 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9323 if (BadReg(Rn)) 9324 return false; 9325 break; 9326 case eEncodingA1: 9327 Rn = Bits32(opcode, 19, 16); 9328 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9329 break; 9330 default: 9331 return false; 9332 } 9333 9334 // Read the first operand. 9335 uint32_t val1 = ReadCoreReg(Rn, &success); 9336 if (!success) 9337 return false; 9338 9339 uint32_t result = val1 ^ imm32; 9340 9341 EmulateInstruction::Context context; 9342 context.type = EmulateInstruction::eContextImmediate; 9343 context.SetNoArgs (); 9344 9345 if (!WriteFlags(context, result, carry)) 9346 return false; 9347 } 9348 return true; 9349 } 9350 9351 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9352 // optionally-shifted register value. It updates the condition flags based on the result, and discards 9353 // the result. 9354 bool 9355 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9356 { 9357 #if 0 9358 // ARM pseudo code... 9359 if ConditionPassed() then 9360 EncodingSpecificOperations(); 9361 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9362 result = R[n] EOR shifted; 9363 APSR.N = result<31>; 9364 APSR.Z = IsZeroBit(result); 9365 APSR.C = carry; 9366 // APSR.V unchanged 9367 #endif 9368 9369 bool success = false; 9370 9371 if (ConditionPassed(opcode)) 9372 { 9373 uint32_t Rn, Rm; 9374 ARM_ShifterType shift_t; 9375 uint32_t shift_n; // the shift applied to the value read from Rm 9376 uint32_t carry; 9377 switch (encoding) 9378 { 9379 case eEncodingT1: 9380 Rn = Bits32(opcode, 19, 16); 9381 Rm = Bits32(opcode, 3, 0); 9382 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9383 if (BadReg(Rn) || BadReg(Rm)) 9384 return false; 9385 break; 9386 case eEncodingA1: 9387 Rn = Bits32(opcode, 19, 16); 9388 Rm = Bits32(opcode, 3, 0); 9389 shift_n = DecodeImmShiftARM(opcode, shift_t); 9390 break; 9391 default: 9392 return false; 9393 } 9394 9395 // Read the first operand. 9396 uint32_t val1 = ReadCoreReg(Rn, &success); 9397 if (!success) 9398 return false; 9399 9400 // Read the second operand. 9401 uint32_t val2 = ReadCoreReg(Rm, &success); 9402 if (!success) 9403 return false; 9404 9405 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9406 if (!success) 9407 return false; 9408 uint32_t result = val1 ^ shifted; 9409 9410 EmulateInstruction::Context context; 9411 context.type = EmulateInstruction::eContextImmediate; 9412 context.SetNoArgs (); 9413 9414 if (!WriteFlags(context, result, carry)) 9415 return false; 9416 } 9417 return true; 9418 } 9419 9420 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9421 // It updates the condition flags based on the result, and discards the result. 9422 bool 9423 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9424 { 9425 #if 0 9426 // ARM pseudo code... 9427 if ConditionPassed() then 9428 EncodingSpecificOperations(); 9429 result = R[n] AND imm32; 9430 APSR.N = result<31>; 9431 APSR.Z = IsZeroBit(result); 9432 APSR.C = carry; 9433 // APSR.V unchanged 9434 #endif 9435 9436 bool success = false; 9437 9438 if (ConditionPassed(opcode)) 9439 { 9440 uint32_t Rn; 9441 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9442 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9443 switch (encoding) 9444 { 9445 case eEncodingT1: 9446 Rn = Bits32(opcode, 19, 16); 9447 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9448 if (BadReg(Rn)) 9449 return false; 9450 break; 9451 case eEncodingA1: 9452 Rn = Bits32(opcode, 19, 16); 9453 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9454 break; 9455 default: 9456 return false; 9457 } 9458 9459 // Read the first operand. 9460 uint32_t val1 = ReadCoreReg(Rn, &success); 9461 if (!success) 9462 return false; 9463 9464 uint32_t result = val1 & imm32; 9465 9466 EmulateInstruction::Context context; 9467 context.type = EmulateInstruction::eContextImmediate; 9468 context.SetNoArgs (); 9469 9470 if (!WriteFlags(context, result, carry)) 9471 return false; 9472 } 9473 return true; 9474 } 9475 9476 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9477 // It updates the condition flags based on the result, and discards the result. 9478 bool 9479 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9480 { 9481 #if 0 9482 // ARM pseudo code... 9483 if ConditionPassed() then 9484 EncodingSpecificOperations(); 9485 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9486 result = R[n] AND shifted; 9487 APSR.N = result<31>; 9488 APSR.Z = IsZeroBit(result); 9489 APSR.C = carry; 9490 // APSR.V unchanged 9491 #endif 9492 9493 bool success = false; 9494 9495 if (ConditionPassed(opcode)) 9496 { 9497 uint32_t Rn, Rm; 9498 ARM_ShifterType shift_t; 9499 uint32_t shift_n; // the shift applied to the value read from Rm 9500 uint32_t carry; 9501 switch (encoding) 9502 { 9503 case eEncodingT1: 9504 Rn = Bits32(opcode, 2, 0); 9505 Rm = Bits32(opcode, 5, 3); 9506 shift_t = SRType_LSL; 9507 shift_n = 0; 9508 break; 9509 case eEncodingT2: 9510 Rn = Bits32(opcode, 19, 16); 9511 Rm = Bits32(opcode, 3, 0); 9512 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9513 if (BadReg(Rn) || BadReg(Rm)) 9514 return false; 9515 break; 9516 case eEncodingA1: 9517 Rn = Bits32(opcode, 19, 16); 9518 Rm = Bits32(opcode, 3, 0); 9519 shift_n = DecodeImmShiftARM(opcode, shift_t); 9520 break; 9521 default: 9522 return false; 9523 } 9524 9525 // Read the first operand. 9526 uint32_t val1 = ReadCoreReg(Rn, &success); 9527 if (!success) 9528 return false; 9529 9530 // Read the second operand. 9531 uint32_t val2 = ReadCoreReg(Rm, &success); 9532 if (!success) 9533 return false; 9534 9535 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9536 if (!success) 9537 return false; 9538 uint32_t result = val1 & shifted; 9539 9540 EmulateInstruction::Context context; 9541 context.type = EmulateInstruction::eContextImmediate; 9542 context.SetNoArgs (); 9543 9544 if (!WriteFlags(context, result, carry)) 9545 return false; 9546 } 9547 return true; 9548 } 9549 9550 // A8.6.216 SUB (SP minus register) 9551 bool 9552 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9553 { 9554 #if 0 9555 if ConditionPassed() then 9556 EncodingSpecificOperations(); 9557 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9558 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 9559 if d == 15 then // Can only occur for ARM encoding 9560 ALUWritePC(result); // setflags is always FALSE here 9561 else 9562 R[d] = result; 9563 if setflags then 9564 APSR.N = result<31>; 9565 APSR.Z = IsZeroBit(result); 9566 APSR.C = carry; 9567 APSR.V = overflow; 9568 #endif 9569 9570 bool success = false; 9571 9572 if (ConditionPassed(opcode)) 9573 { 9574 uint32_t d; 9575 uint32_t m; 9576 bool setflags; 9577 ARM_ShifterType shift_t; 9578 uint32_t shift_n; 9579 9580 switch (encoding) 9581 { 9582 case eEncodingT1: 9583 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 9584 d = Bits32 (opcode, 11, 8); 9585 m = Bits32 (opcode, 3, 0); 9586 setflags = BitIsSet (opcode, 20); 9587 9588 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9589 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9590 9591 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9592 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9593 return false; 9594 9595 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9596 if ((d == 15) || BadReg (m)) 9597 return false; 9598 break; 9599 9600 case eEncodingA1: 9601 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 9602 d = Bits32 (opcode, 15, 12); 9603 m = Bits32 (opcode, 3, 0); 9604 setflags = BitIsSet (opcode, 20); 9605 9606 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9607 if (d == 15 && setflags) 9608 EmulateSUBSPcLrEtc (opcode, encoding); 9609 9610 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9611 shift_n = DecodeImmShiftARM (opcode, shift_t); 9612 break; 9613 9614 default: 9615 return false; 9616 } 9617 9618 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9619 uint32_t Rm = ReadCoreReg (m, &success); 9620 if (!success) 9621 return false; 9622 9623 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9624 if (!success) 9625 return false; 9626 9627 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 9628 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9629 if (!success) 9630 return false; 9631 9632 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9633 9634 EmulateInstruction::Context context; 9635 context.type = eContextArithmetic; 9636 RegisterInfo sp_reg; 9637 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9638 RegisterInfo dwarf_reg; 9639 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9640 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9641 9642 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9643 return false; 9644 } 9645 return true; 9646 } 9647 9648 9649 // A8.6.7 ADD (register-shifted register) 9650 bool 9651 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9652 { 9653 #if 0 9654 if ConditionPassed() then 9655 EncodingSpecificOperations(); 9656 shift_n = UInt(R[s]<7:0>); 9657 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9658 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 9659 R[d] = result; 9660 if setflags then 9661 APSR.N = result<31>; 9662 APSR.Z = IsZeroBit(result); 9663 APSR.C = carry; 9664 APSR.V = overflow; 9665 #endif 9666 9667 bool success = false; 9668 9669 if (ConditionPassed(opcode)) 9670 { 9671 uint32_t d; 9672 uint32_t n; 9673 uint32_t m; 9674 uint32_t s; 9675 bool setflags; 9676 ARM_ShifterType shift_t; 9677 9678 switch (encoding) 9679 { 9680 case eEncodingA1: 9681 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9682 d = Bits32 (opcode, 15, 12); 9683 n = Bits32 (opcode, 19, 16); 9684 m = Bits32 (opcode, 3, 0); 9685 s = Bits32 (opcode, 11, 8); 9686 9687 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 9688 setflags = BitIsSet (opcode, 20); 9689 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9690 9691 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9692 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9693 return false; 9694 break; 9695 9696 default: 9697 return false; 9698 } 9699 9700 // shift_n = UInt(R[s]<7:0>); 9701 uint32_t Rs = ReadCoreReg (s, &success); 9702 if (!success) 9703 return false; 9704 9705 uint32_t shift_n = Bits32 (Rs, 7, 0); 9706 9707 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9708 uint32_t Rm = ReadCoreReg (m, &success); 9709 if (!success) 9710 return false; 9711 9712 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9713 if (!success) 9714 return false; 9715 9716 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 9717 uint32_t Rn = ReadCoreReg (n, &success); 9718 if (!success) 9719 return false; 9720 9721 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9722 9723 // R[d] = result; 9724 EmulateInstruction::Context context; 9725 context.type = eContextArithmetic; 9726 RegisterInfo reg_n; 9727 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9728 RegisterInfo reg_m; 9729 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9730 9731 context.SetRegisterRegisterOperands (reg_n, reg_m); 9732 9733 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9734 return false; 9735 9736 // if setflags then 9737 // APSR.N = result<31>; 9738 // APSR.Z = IsZeroBit(result); 9739 // APSR.C = carry; 9740 // APSR.V = overflow; 9741 if (setflags) 9742 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9743 } 9744 return true; 9745 } 9746 9747 // A8.6.213 SUB (register) 9748 bool 9749 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9750 { 9751 #if 0 9752 if ConditionPassed() then 9753 EncodingSpecificOperations(); 9754 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9755 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 9756 if d == 15 then // Can only occur for ARM encoding 9757 ALUWritePC(result); // setflags is always FALSE here 9758 else 9759 R[d] = result; 9760 if setflags then 9761 APSR.N = result<31>; 9762 APSR.Z = IsZeroBit(result); 9763 APSR.C = carry; 9764 APSR.V = overflow; 9765 #endif 9766 9767 bool success = false; 9768 9769 if (ConditionPassed(opcode)) 9770 { 9771 uint32_t d; 9772 uint32_t n; 9773 uint32_t m; 9774 bool setflags; 9775 ARM_ShifterType shift_t; 9776 uint32_t shift_n; 9777 9778 switch (encoding) 9779 { 9780 case eEncodingT1: 9781 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9782 d = Bits32 (opcode, 2, 0); 9783 n = Bits32 (opcode, 5, 3); 9784 m = Bits32 (opcode, 8, 6); 9785 setflags = !InITBlock(); 9786 9787 // (shift_t, shift_n) = (SRType_LSL, 0); 9788 shift_t = SRType_LSL; 9789 shift_n = 0; 9790 9791 break; 9792 9793 case eEncodingT2: 9794 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 9795 d = Bits32 (opcode, 11, 8); 9796 n = Bits32 (opcode, 19, 16); 9797 m = Bits32 (opcode, 3, 0); 9798 setflags = BitIsSet (opcode, 20); 9799 9800 // if Rd == "1111" && S == "1" then SEE CMP (register); 9801 if (d == 15 && setflags == 1) 9802 return EmulateCMPImm (opcode, eEncodingT3); 9803 9804 // if Rn == "1101" then SEE SUB (SP minus register); 9805 if (n == 13) 9806 return EmulateSUBSPReg (opcode, eEncodingT1); 9807 9808 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9809 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9810 9811 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9812 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9813 return false; 9814 9815 break; 9816 9817 case eEncodingA1: 9818 // if Rn == '1101' then SEE SUB (SP minus register); 9819 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 9820 d = Bits32 (opcode, 15, 12); 9821 n = Bits32 (opcode, 19, 16); 9822 m = Bits32 (opcode, 3, 0); 9823 setflags = BitIsSet (opcode, 20); 9824 9825 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9826 if ((d == 15) && setflags) 9827 EmulateSUBSPcLrEtc (opcode, encoding); 9828 9829 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9830 shift_n = DecodeImmShiftARM (opcode, shift_t); 9831 9832 break; 9833 9834 default: 9835 return false; 9836 } 9837 9838 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9839 uint32_t Rm = ReadCoreReg (m, &success); 9840 if (!success) 9841 return false; 9842 9843 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9844 if (!success) 9845 return false; 9846 9847 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 9848 uint32_t Rn = ReadCoreReg (n, &success); 9849 if (!success) 9850 return false; 9851 9852 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9853 9854 // if d == 15 then // Can only occur for ARM encoding 9855 // ALUWritePC(result); // setflags is always FALSE here 9856 // else 9857 // R[d] = result; 9858 // if setflags then 9859 // APSR.N = result<31>; 9860 // APSR.Z = IsZeroBit(result); 9861 // APSR.C = carry; 9862 // APSR.V = overflow; 9863 9864 EmulateInstruction::Context context; 9865 context.type = eContextArithmetic; 9866 RegisterInfo reg_n; 9867 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9868 RegisterInfo reg_m; 9869 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9870 context.SetRegisterRegisterOperands (reg_n, reg_m); 9871 9872 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9873 return false; 9874 } 9875 return true; 9876 } 9877 9878 // A8.6.202 STREX 9879 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9880 // word from a register to memory if the executing processor has exclusive access to the memory addressed. 9881 bool 9882 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9883 { 9884 #if 0 9885 if ConditionPassed() then 9886 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9887 address = R[n] + imm32; 9888 if ExclusiveMonitorsPass(address,4) then 9889 MemA[address,4] = R[t]; 9890 R[d] = 0; 9891 else 9892 R[d] = 1; 9893 #endif 9894 9895 bool success = false; 9896 9897 if (ConditionPassed(opcode)) 9898 { 9899 uint32_t d; 9900 uint32_t t; 9901 uint32_t n; 9902 uint32_t imm32; 9903 const uint32_t addr_byte_size = GetAddressByteSize(); 9904 9905 switch (encoding) 9906 { 9907 case eEncodingT1: 9908 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 9909 d = Bits32 (opcode, 11, 8); 9910 t = Bits32 (opcode, 15, 12); 9911 n = Bits32 (opcode, 19, 16); 9912 imm32 = Bits32 (opcode, 7, 0) << 2; 9913 9914 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9915 if (BadReg (d) || BadReg (t) || (n == 15)) 9916 return false; 9917 9918 // if d == n || d == t then UNPREDICTABLE; 9919 if ((d == n) || (d == t)) 9920 return false; 9921 9922 break; 9923 9924 case eEncodingA1: 9925 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9926 d = Bits32 (opcode, 15, 12); 9927 t = Bits32 (opcode, 3, 0); 9928 n = Bits32 (opcode, 19, 16); 9929 imm32 = 0; 9930 9931 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9932 if ((d == 15) || (t == 15) || (n == 15)) 9933 return false; 9934 9935 // if d == n || d == t then UNPREDICTABLE; 9936 if ((d == n) || (d == t)) 9937 return false; 9938 9939 break; 9940 9941 default: 9942 return false; 9943 } 9944 9945 // address = R[n] + imm32; 9946 uint32_t Rn = ReadCoreReg (n, &success); 9947 if (!success) 9948 return false; 9949 9950 addr_t address = Rn + imm32; 9951 9952 RegisterInfo base_reg; 9953 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9954 RegisterInfo data_reg; 9955 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9956 EmulateInstruction::Context context; 9957 context.type = eContextRegisterStore; 9958 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9959 9960 // if ExclusiveMonitorsPass(address,4) then 9961 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9962 // always return true. 9963 if (true) 9964 { 9965 // MemA[address,4] = R[t]; 9966 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9967 if (!success) 9968 return false; 9969 9970 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9971 return false; 9972 9973 // R[d] = 0; 9974 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9975 return false; 9976 } 9977 #if 0 // unreachable because if true 9978 else 9979 { 9980 // R[d] = 1; 9981 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9982 return false; 9983 } 9984 #endif // unreachable because if true 9985 } 9986 return true; 9987 } 9988 9989 // A8.6.197 STRB (immediate, ARM) 9990 bool 9991 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9992 { 9993 #if 0 9994 if ConditionPassed() then 9995 EncodingSpecificOperations(); 9996 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 9997 address = if index then offset_addr else R[n]; 9998 MemU[address,1] = R[t]<7:0>; 9999 if wback then R[n] = offset_addr; 10000 #endif 10001 10002 bool success = false; 10003 10004 if (ConditionPassed(opcode)) 10005 { 10006 uint32_t t; 10007 uint32_t n; 10008 uint32_t imm32; 10009 bool index; 10010 bool add; 10011 bool wback; 10012 10013 switch (encoding) 10014 { 10015 case eEncodingA1: 10016 // if P == '0' && W == '1' then SEE STRBT; 10017 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10018 t = Bits32 (opcode, 15, 12); 10019 n = Bits32 (opcode, 19, 16); 10020 imm32 = Bits32 (opcode, 11, 0); 10021 10022 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10023 index = BitIsSet (opcode, 24); 10024 add = BitIsSet (opcode, 23); 10025 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10026 10027 // if t == 15 then UNPREDICTABLE; 10028 if (t == 15) 10029 return false; 10030 10031 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10032 if (wback && ((n == 15) || (n == t))) 10033 return false; 10034 10035 break; 10036 10037 default: 10038 return false; 10039 } 10040 10041 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10042 uint32_t Rn = ReadCoreReg (n, &success); 10043 if (!success) 10044 return false; 10045 10046 addr_t offset_addr; 10047 if (add) 10048 offset_addr = Rn + imm32; 10049 else 10050 offset_addr = Rn - imm32; 10051 10052 // address = if index then offset_addr else R[n]; 10053 addr_t address; 10054 if (index) 10055 address = offset_addr; 10056 else 10057 address = Rn; 10058 10059 // MemU[address,1] = R[t]<7:0>; 10060 uint32_t Rt = ReadCoreReg (t, &success); 10061 if (!success) 10062 return false; 10063 10064 RegisterInfo base_reg; 10065 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10066 RegisterInfo data_reg; 10067 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10068 EmulateInstruction::Context context; 10069 context.type = eContextRegisterStore; 10070 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10071 10072 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 10073 return false; 10074 10075 // if wback then R[n] = offset_addr; 10076 if (wback) 10077 { 10078 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10079 return false; 10080 } 10081 } 10082 return true; 10083 } 10084 10085 // A8.6.194 STR (immediate, ARM) 10086 bool 10087 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 10088 { 10089 #if 0 10090 if ConditionPassed() then 10091 EncodingSpecificOperations(); 10092 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10093 address = if index then offset_addr else R[n]; 10094 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10095 if wback then R[n] = offset_addr; 10096 #endif 10097 10098 bool success = false; 10099 10100 if (ConditionPassed(opcode)) 10101 { 10102 uint32_t t; 10103 uint32_t n; 10104 uint32_t imm32; 10105 bool index; 10106 bool add; 10107 bool wback; 10108 10109 const uint32_t addr_byte_size = GetAddressByteSize(); 10110 10111 switch (encoding) 10112 { 10113 case eEncodingA1: 10114 // if P == '0' && W == '1' then SEE STRT; 10115 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH; 10116 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10117 t = Bits32 (opcode, 15, 12); 10118 n = Bits32 (opcode, 19, 16); 10119 imm32 = Bits32 (opcode, 11, 0); 10120 10121 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10122 index = BitIsSet (opcode, 24); 10123 add = BitIsSet (opcode, 23); 10124 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10125 10126 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10127 if (wback && ((n == 15) || (n == t))) 10128 return false; 10129 10130 break; 10131 10132 default: 10133 return false; 10134 } 10135 10136 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10137 uint32_t Rn = ReadCoreReg (n, &success); 10138 if (!success) 10139 return false; 10140 10141 addr_t offset_addr; 10142 if (add) 10143 offset_addr = Rn + imm32; 10144 else 10145 offset_addr = Rn - imm32; 10146 10147 // address = if index then offset_addr else R[n]; 10148 addr_t address; 10149 if (index) 10150 address = offset_addr; 10151 else 10152 address = Rn; 10153 10154 RegisterInfo base_reg; 10155 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10156 RegisterInfo data_reg; 10157 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10158 EmulateInstruction::Context context; 10159 context.type = eContextRegisterStore; 10160 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10161 10162 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10163 uint32_t Rt = ReadCoreReg (t, &success); 10164 if (!success) 10165 return false; 10166 10167 if (t == 15) 10168 { 10169 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10170 if (!success) 10171 return false; 10172 10173 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10174 return false; 10175 } 10176 else 10177 { 10178 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10179 return false; 10180 } 10181 10182 // if wback then R[n] = offset_addr; 10183 if (wback) 10184 { 10185 context.type = eContextAdjustBaseRegister; 10186 context.SetImmediate (offset_addr); 10187 10188 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10189 return false; 10190 } 10191 } 10192 return true; 10193 } 10194 10195 // A8.6.66 LDRD (immediate) 10196 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10197 // words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10198 bool 10199 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10200 { 10201 #if 0 10202 if ConditionPassed() then 10203 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10204 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10205 address = if index then offset_addr else R[n]; 10206 R[t] = MemA[address,4]; 10207 R[t2] = MemA[address+4,4]; 10208 if wback then R[n] = offset_addr; 10209 #endif 10210 10211 bool success = false; 10212 10213 if (ConditionPassed(opcode)) 10214 { 10215 uint32_t t; 10216 uint32_t t2; 10217 uint32_t n; 10218 uint32_t imm32; 10219 bool index; 10220 bool add; 10221 bool wback; 10222 10223 switch (encoding) 10224 { 10225 case eEncodingT1: 10226 //if P == '0' && W == '0' then SEE 'Related encodings'; 10227 //if Rn == '1111' then SEE LDRD (literal); 10228 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 10229 t = Bits32 (opcode, 15, 12); 10230 t2 = Bits32 (opcode, 11, 8); 10231 n = Bits32 (opcode, 19, 16); 10232 imm32 = Bits32 (opcode, 7, 0) << 2; 10233 10234 //index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10235 index = BitIsSet (opcode, 24); 10236 add = BitIsSet (opcode, 23); 10237 wback = BitIsSet (opcode, 21); 10238 10239 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10240 if (wback && ((n == t) || (n == t2))) 10241 return false; 10242 10243 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10244 if (BadReg (t) || BadReg (t2) || (t == t2)) 10245 return false; 10246 10247 break; 10248 10249 case eEncodingA1: 10250 //if Rn == '1111' then SEE LDRD (literal); 10251 //if Rt<0> == '1' then UNPREDICTABLE; 10252 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10253 t = Bits32 (opcode, 15, 12); 10254 if (BitIsSet (t, 0)) 10255 return false; 10256 t2 = t + 1; 10257 n = Bits32 (opcode, 19, 16); 10258 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10259 10260 //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10261 index = BitIsSet (opcode, 24); 10262 add = BitIsSet (opcode, 23); 10263 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10264 10265 //if P == '0' && W == '1' then UNPREDICTABLE; 10266 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10267 return false; 10268 10269 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10270 if (wback && ((n == t) || (n == t2))) 10271 return false; 10272 10273 //if t2 == 15 then UNPREDICTABLE; 10274 if (t2 == 15) 10275 return false; 10276 10277 break; 10278 10279 default: 10280 return false; 10281 } 10282 10283 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10284 uint32_t Rn = ReadCoreReg (n, &success); 10285 if (!success) 10286 return false; 10287 10288 addr_t offset_addr; 10289 if (add) 10290 offset_addr = Rn + imm32; 10291 else 10292 offset_addr = Rn - imm32; 10293 10294 //address = if index then offset_addr else R[n]; 10295 addr_t address; 10296 if (index) 10297 address = offset_addr; 10298 else 10299 address = Rn; 10300 10301 //R[t] = MemA[address,4]; 10302 RegisterInfo base_reg; 10303 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10304 10305 EmulateInstruction::Context context; 10306 if (n == 13) 10307 context.type = eContextPopRegisterOffStack; 10308 else 10309 context.type = eContextRegisterLoad; 10310 context.SetRegisterPlusOffset (base_reg, address - Rn); 10311 10312 const uint32_t addr_byte_size = GetAddressByteSize(); 10313 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10314 if (!success) 10315 return false; 10316 10317 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10318 return false; 10319 10320 //R[t2] = MemA[address+4,4]; 10321 10322 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10323 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10324 if (!success) 10325 return false; 10326 10327 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10328 return false; 10329 10330 //if wback then R[n] = offset_addr; 10331 if (wback) 10332 { 10333 context.type = eContextAdjustBaseRegister; 10334 context.SetAddress (offset_addr); 10335 10336 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10337 return false; 10338 } 10339 } 10340 return true; 10341 } 10342 10343 // A8.6.68 LDRD (register) 10344 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10345 // words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10346 bool 10347 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10348 { 10349 #if 0 10350 if ConditionPassed() then 10351 EncodingSpecificOperations(); 10352 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10353 address = if index then offset_addr else R[n]; 10354 R[t] = MemA[address,4]; 10355 R[t2] = MemA[address+4,4]; 10356 if wback then R[n] = offset_addr; 10357 #endif 10358 10359 bool success = false; 10360 10361 if (ConditionPassed(opcode)) 10362 { 10363 uint32_t t; 10364 uint32_t t2; 10365 uint32_t n; 10366 uint32_t m; 10367 bool index; 10368 bool add; 10369 bool wback; 10370 10371 switch (encoding) 10372 { 10373 case eEncodingA1: 10374 // if Rt<0> == '1' then UNPREDICTABLE; 10375 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10376 t = Bits32 (opcode, 15, 12); 10377 if (BitIsSet (t, 0)) 10378 return false; 10379 t2 = t + 1; 10380 n = Bits32 (opcode, 19, 16); 10381 m = Bits32 (opcode, 3, 0); 10382 10383 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10384 index = BitIsSet (opcode, 24); 10385 add = BitIsSet (opcode, 23); 10386 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10387 10388 // if P == '0' && W == '1' then UNPREDICTABLE; 10389 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10390 return false; 10391 10392 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10393 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10394 return false; 10395 10396 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10397 if (wback && ((n == 15) || (n == t) || (n == t2))) 10398 return false; 10399 10400 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10401 if ((ArchVersion() < 6) && wback && (m == n)) 10402 return false; 10403 break; 10404 10405 default: 10406 return false; 10407 } 10408 10409 uint32_t Rn = ReadCoreReg (n, &success); 10410 if (!success) 10411 return false; 10412 RegisterInfo base_reg; 10413 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10414 10415 uint32_t Rm = ReadCoreReg (m, &success); 10416 if (!success) 10417 return false; 10418 RegisterInfo offset_reg; 10419 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10420 10421 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10422 addr_t offset_addr; 10423 if (add) 10424 offset_addr = Rn + Rm; 10425 else 10426 offset_addr = Rn - Rm; 10427 10428 // address = if index then offset_addr else R[n]; 10429 addr_t address; 10430 if (index) 10431 address = offset_addr; 10432 else 10433 address = Rn; 10434 10435 EmulateInstruction::Context context; 10436 if (n == 13) 10437 context.type = eContextPopRegisterOffStack; 10438 else 10439 context.type = eContextRegisterLoad; 10440 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 10441 10442 // R[t] = MemA[address,4]; 10443 const uint32_t addr_byte_size = GetAddressByteSize(); 10444 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10445 if (!success) 10446 return false; 10447 10448 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10449 return false; 10450 10451 // R[t2] = MemA[address+4,4]; 10452 10453 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10454 if (!success) 10455 return false; 10456 10457 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10458 return false; 10459 10460 // if wback then R[n] = offset_addr; 10461 if (wback) 10462 { 10463 context.type = eContextAdjustBaseRegister; 10464 context.SetAddress (offset_addr); 10465 10466 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10467 return false; 10468 } 10469 } 10470 return true; 10471 } 10472 10473 // A8.6.200 STRD (immediate) 10474 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10475 // stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10476 bool 10477 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10478 { 10479 #if 0 10480 if ConditionPassed() then 10481 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10482 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10483 address = if index then offset_addr else R[n]; 10484 MemA[address,4] = R[t]; 10485 MemA[address+4,4] = R[t2]; 10486 if wback then R[n] = offset_addr; 10487 #endif 10488 10489 bool success = false; 10490 10491 if (ConditionPassed(opcode)) 10492 { 10493 uint32_t t; 10494 uint32_t t2; 10495 uint32_t n; 10496 uint32_t imm32; 10497 bool index; 10498 bool add; 10499 bool wback; 10500 10501 switch (encoding) 10502 { 10503 case eEncodingT1: 10504 // if P == '0' && W == '0' then SEE 'Related encodings'; 10505 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 10506 t = Bits32 (opcode, 15, 12); 10507 t2 = Bits32 (opcode, 11, 8); 10508 n = Bits32 (opcode, 19, 16); 10509 imm32 = Bits32 (opcode, 7, 0) << 2; 10510 10511 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10512 index = BitIsSet (opcode, 24); 10513 add = BitIsSet (opcode, 23); 10514 wback = BitIsSet (opcode, 21); 10515 10516 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10517 if (wback && ((n == t) || (n == t2))) 10518 return false; 10519 10520 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10521 if ((n == 15) || BadReg (t) || BadReg (t2)) 10522 return false; 10523 10524 break; 10525 10526 case eEncodingA1: 10527 // if Rt<0> == '1' then UNPREDICTABLE; 10528 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10529 t = Bits32 (opcode, 15, 12); 10530 if (BitIsSet (t, 0)) 10531 return false; 10532 10533 t2 = t + 1; 10534 n = Bits32 (opcode, 19, 16); 10535 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10536 10537 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10538 index = BitIsSet (opcode, 24); 10539 add = BitIsSet (opcode, 23); 10540 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10541 10542 // if P == '0' && W == '1' then UNPREDICTABLE; 10543 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10544 return false; 10545 10546 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10547 if (wback && ((n == 15) || (n == t) || (n == t2))) 10548 return false; 10549 10550 // if t2 == 15 then UNPREDICTABLE; 10551 if (t2 == 15) 10552 return false; 10553 10554 break; 10555 10556 default: 10557 return false; 10558 } 10559 10560 RegisterInfo base_reg; 10561 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10562 10563 uint32_t Rn = ReadCoreReg (n, &success); 10564 if (!success) 10565 return false; 10566 10567 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10568 addr_t offset_addr; 10569 if (add) 10570 offset_addr = Rn + imm32; 10571 else 10572 offset_addr = Rn - imm32; 10573 10574 //address = if index then offset_addr else R[n]; 10575 addr_t address; 10576 if (index) 10577 address = offset_addr; 10578 else 10579 address = Rn; 10580 10581 //MemA[address,4] = R[t]; 10582 RegisterInfo data_reg; 10583 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10584 10585 uint32_t data = ReadCoreReg (t, &success); 10586 if (!success) 10587 return false; 10588 10589 EmulateInstruction::Context context; 10590 if (n == 13) 10591 context.type = eContextPushRegisterOnStack; 10592 else 10593 context.type = eContextRegisterStore; 10594 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10595 10596 const uint32_t addr_byte_size = GetAddressByteSize(); 10597 10598 if (!MemAWrite (context, address, data, addr_byte_size)) 10599 return false; 10600 10601 //MemA[address+4,4] = R[t2]; 10602 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10603 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10604 10605 data = ReadCoreReg (t2, &success); 10606 if (!success) 10607 return false; 10608 10609 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10610 return false; 10611 10612 //if wback then R[n] = offset_addr; 10613 if (wback) 10614 { 10615 context.type = eContextAdjustBaseRegister; 10616 context.SetAddress (offset_addr); 10617 10618 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10619 return false; 10620 } 10621 } 10622 return true; 10623 } 10624 10625 10626 // A8.6.201 STRD (register) 10627 bool 10628 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10629 { 10630 #if 0 10631 if ConditionPassed() then 10632 EncodingSpecificOperations(); 10633 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10634 address = if index then offset_addr else R[n]; 10635 MemA[address,4] = R[t]; 10636 MemA[address+4,4] = R[t2]; 10637 if wback then R[n] = offset_addr; 10638 #endif 10639 10640 bool success = false; 10641 10642 if (ConditionPassed(opcode)) 10643 { 10644 uint32_t t; 10645 uint32_t t2; 10646 uint32_t n; 10647 uint32_t m; 10648 bool index; 10649 bool add; 10650 bool wback; 10651 10652 switch (encoding) 10653 { 10654 case eEncodingA1: 10655 // if Rt<0> == '1' then UNPREDICTABLE; 10656 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10657 t = Bits32 (opcode, 15, 12); 10658 if (BitIsSet (t, 0)) 10659 return false; 10660 10661 t2 = t+1; 10662 n = Bits32 (opcode, 19, 16); 10663 m = Bits32 (opcode, 3, 0); 10664 10665 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10666 index = BitIsSet (opcode, 24); 10667 add = BitIsSet (opcode, 23); 10668 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10669 10670 // if P == '0' && W == '1' then UNPREDICTABLE; 10671 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10672 return false; 10673 10674 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10675 if ((t2 == 15) || (m == 15)) 10676 return false; 10677 10678 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10679 if (wback && ((n == 15) || (n == t) || (n == t2))) 10680 return false; 10681 10682 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10683 if ((ArchVersion() < 6) && wback && (m == n)) 10684 return false; 10685 10686 break; 10687 10688 default: 10689 return false; 10690 } 10691 10692 RegisterInfo base_reg; 10693 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10694 RegisterInfo offset_reg; 10695 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10696 RegisterInfo data_reg; 10697 10698 uint32_t Rn = ReadCoreReg (n, &success); 10699 if (!success) 10700 return false; 10701 10702 uint32_t Rm = ReadCoreReg (m, &success); 10703 if (!success) 10704 return false; 10705 10706 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10707 addr_t offset_addr; 10708 if (add) 10709 offset_addr = Rn + Rm; 10710 else 10711 offset_addr = Rn - Rm; 10712 10713 // address = if index then offset_addr else R[n]; 10714 addr_t address; 10715 if (index) 10716 address = offset_addr; 10717 else 10718 address = Rn; 10719 // MemA[address,4] = R[t]; 10720 uint32_t Rt = ReadCoreReg (t, &success); 10721 if (!success) 10722 return false; 10723 10724 EmulateInstruction::Context context; 10725 if (t == 13) 10726 context.type = eContextPushRegisterOnStack; 10727 else 10728 context.type = eContextRegisterStore; 10729 10730 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10731 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10732 10733 const uint32_t addr_byte_size = GetAddressByteSize(); 10734 10735 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10736 return false; 10737 10738 // MemA[address+4,4] = R[t2]; 10739 uint32_t Rt2 = ReadCoreReg (t2, &success); 10740 if (!success) 10741 return false; 10742 10743 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10744 10745 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10746 10747 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10748 return false; 10749 10750 // if wback then R[n] = offset_addr; 10751 if (wback) 10752 { 10753 context.type = eContextAdjustBaseRegister; 10754 context.SetAddress (offset_addr); 10755 10756 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10757 return false; 10758 10759 } 10760 } 10761 return true; 10762 } 10763 10764 // A8.6.319 VLDM 10765 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10766 // an ARM core register. 10767 bool 10768 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10769 { 10770 #if 0 10771 if ConditionPassed() then 10772 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10773 address = if add then R[n] else R[n]-imm32; 10774 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10775 for r = 0 to regs-1 10776 if single_regs then 10777 S[d+r] = MemA[address,4]; address = address+4; 10778 else 10779 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10780 // Combine the word-aligned words in the correct order for current endianness. 10781 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10782 #endif 10783 10784 bool success = false; 10785 10786 if (ConditionPassed(opcode)) 10787 { 10788 bool single_regs; 10789 bool add; 10790 bool wback; 10791 uint32_t d; 10792 uint32_t n; 10793 uint32_t imm32; 10794 uint32_t regs; 10795 10796 switch (encoding) 10797 { 10798 case eEncodingT1: 10799 case eEncodingA1: 10800 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10801 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 10802 // if P == '1' && W == '0' then SEE VLDR; 10803 // if P == U && W == '1' then UNDEFINED; 10804 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10805 return false; 10806 10807 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10808 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 10809 single_regs = false; 10810 add = BitIsSet (opcode, 23); 10811 wback = BitIsSet (opcode, 21); 10812 10813 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 10814 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10815 n = Bits32 (opcode, 19, 16); 10816 imm32 = Bits32 (opcode, 7, 0) << 2; 10817 10818 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 10819 regs = Bits32 (opcode, 7, 0) / 2; 10820 10821 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10822 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10823 return false; 10824 10825 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10826 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10827 return false; 10828 10829 break; 10830 10831 case eEncodingT2: 10832 case eEncodingA2: 10833 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10834 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 10835 // if P == '1' && W == '0' then SEE VLDR; 10836 // if P == U && W == '1' then UNDEFINED; 10837 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10838 return false; 10839 10840 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10841 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); 10842 single_regs = true; 10843 add = BitIsSet (opcode, 23); 10844 wback = BitIsSet (opcode, 21); 10845 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10846 n = Bits32 (opcode, 19, 16); 10847 10848 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 10849 imm32 = Bits32 (opcode, 7, 0) << 2; 10850 regs = Bits32 (opcode, 7, 0); 10851 10852 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10853 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10854 return false; 10855 10856 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10857 if ((regs == 0) || ((d + regs) > 32)) 10858 return false; 10859 break; 10860 10861 default: 10862 return false; 10863 } 10864 10865 RegisterInfo base_reg; 10866 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10867 10868 uint32_t Rn = ReadCoreReg (n, &success); 10869 if (!success) 10870 return false; 10871 10872 // address = if add then R[n] else R[n]-imm32; 10873 addr_t address; 10874 if (add) 10875 address = Rn; 10876 else 10877 address = Rn - imm32; 10878 10879 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10880 EmulateInstruction::Context context; 10881 10882 if (wback) 10883 { 10884 uint32_t value; 10885 if (add) 10886 value = Rn + imm32; 10887 else 10888 value = Rn - imm32; 10889 10890 context.type = eContextAdjustBaseRegister; 10891 context.SetImmediateSigned (value - Rn); 10892 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10893 return false; 10894 10895 } 10896 10897 const uint32_t addr_byte_size = GetAddressByteSize(); 10898 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10899 10900 context.type = eContextRegisterLoad; 10901 10902 // for r = 0 to regs-1 10903 for (uint32_t r = 0; r < regs; ++r) 10904 { 10905 if (single_regs) 10906 { 10907 // S[d+r] = MemA[address,4]; address = address+4; 10908 context.SetRegisterPlusOffset (base_reg, address - Rn); 10909 10910 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10911 if (!success) 10912 return false; 10913 10914 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10915 return false; 10916 10917 address = address + 4; 10918 } 10919 else 10920 { 10921 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10922 context.SetRegisterPlusOffset (base_reg, address - Rn); 10923 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10924 if (!success) 10925 return false; 10926 10927 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10928 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10929 if (!success) 10930 return false; 10931 10932 address = address + 8; 10933 // // Combine the word-aligned words in the correct order for current endianness. 10934 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10935 uint64_t data; 10936 if (GetByteOrder() == eByteOrderBig) 10937 { 10938 data = word1; 10939 data = (data << 32) | word2; 10940 } 10941 else 10942 { 10943 data = word2; 10944 data = (data << 32) | word1; 10945 } 10946 10947 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10948 return false; 10949 } 10950 } 10951 } 10952 return true; 10953 } 10954 10955 // A8.6.399 VSTM 10956 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10957 // ARM core register. 10958 bool 10959 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10960 { 10961 #if 0 10962 if ConditionPassed() then 10963 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10964 address = if add then R[n] else R[n]-imm32; 10965 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10966 for r = 0 to regs-1 10967 if single_regs then 10968 MemA[address,4] = S[d+r]; address = address+4; 10969 else 10970 // Store as two word-aligned words in the correct order for current endianness. 10971 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10972 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10973 address = address+8; 10974 #endif 10975 10976 bool success = false; 10977 10978 if (ConditionPassed (opcode)) 10979 { 10980 bool single_regs; 10981 bool add; 10982 bool wback; 10983 uint32_t d; 10984 uint32_t n; 10985 uint32_t imm32; 10986 uint32_t regs; 10987 10988 switch (encoding) 10989 { 10990 case eEncodingT1: 10991 case eEncodingA1: 10992 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10993 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 10994 // if P == '1' && W == '0' then SEE VSTR; 10995 // if P == U && W == '1' then UNDEFINED; 10996 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10997 return false; 10998 10999 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 11000 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11001 single_regs = false; 11002 add = BitIsSet (opcode, 23); 11003 wback = BitIsSet (opcode, 21); 11004 11005 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11006 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11007 n = Bits32 (opcode, 19, 16); 11008 imm32 = Bits32 (opcode, 7, 0) << 2; 11009 11010 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11011 regs = Bits32 (opcode, 7, 0) / 2; 11012 11013 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 11014 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11015 return false; 11016 11017 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11018 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11019 return false; 11020 11021 break; 11022 11023 case eEncodingT2: 11024 case eEncodingA2: 11025 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11026 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11027 // if P == '1' && W == '0' then SEE VSTR; 11028 // if P == U && W == '1' then UNDEFINED; 11029 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 11030 return false; 11031 11032 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 11033 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); 11034 single_regs = true; 11035 add = BitIsSet (opcode, 23); 11036 wback = BitIsSet (opcode, 21); 11037 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11038 n = Bits32 (opcode, 19, 16); 11039 11040 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11041 imm32 = Bits32 (opcode, 7, 0) << 2; 11042 regs = Bits32 (opcode, 7, 0); 11043 11044 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 11045 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 11046 return false; 11047 11048 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11049 if ((regs == 0) || ((d + regs) > 32)) 11050 return false; 11051 11052 break; 11053 11054 default: 11055 return false; 11056 } 11057 11058 RegisterInfo base_reg; 11059 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11060 11061 uint32_t Rn = ReadCoreReg (n, &success); 11062 if (!success) 11063 return false; 11064 11065 // address = if add then R[n] else R[n]-imm32; 11066 addr_t address; 11067 if (add) 11068 address = Rn; 11069 else 11070 address = Rn - imm32; 11071 11072 EmulateInstruction::Context context; 11073 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11074 if (wback) 11075 { 11076 uint32_t value; 11077 if (add) 11078 value = Rn + imm32; 11079 else 11080 value = Rn - imm32; 11081 11082 context.type = eContextAdjustBaseRegister; 11083 context.SetRegisterPlusOffset (base_reg, value - Rn); 11084 11085 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11086 return false; 11087 } 11088 11089 const uint32_t addr_byte_size = GetAddressByteSize(); 11090 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11091 11092 context.type = eContextRegisterStore; 11093 // for r = 0 to regs-1 11094 for (uint32_t r = 0; r < regs; ++r) 11095 { 11096 11097 if (single_regs) 11098 { 11099 // MemA[address,4] = S[d+r]; address = address+4; 11100 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 11101 if (!success) 11102 return false; 11103 11104 RegisterInfo data_reg; 11105 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11106 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11107 if (!MemAWrite (context, address, data, addr_byte_size)) 11108 return false; 11109 11110 address = address + 4; 11111 } 11112 else 11113 { 11114 // // Store as two word-aligned words in the correct order for current endianness. 11115 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11116 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11117 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 11118 if (!success) 11119 return false; 11120 11121 RegisterInfo data_reg; 11122 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11123 11124 if (GetByteOrder() == eByteOrderBig) 11125 { 11126 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11127 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11128 return false; 11129 11130 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11131 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 11132 return false; 11133 } 11134 else 11135 { 11136 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11137 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11138 return false; 11139 11140 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11141 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11142 return false; 11143 } 11144 // address = address+8; 11145 address = address + 8; 11146 } 11147 } 11148 } 11149 return true; 11150 } 11151 11152 // A8.6.320 11153 // This instruction loads a single extension register from memory, using an address from an ARM core register, with 11154 // an optional offset. 11155 bool 11156 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 11157 { 11158 #if 0 11159 if ConditionPassed() then 11160 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11161 base = if n == 15 then Align(PC,4) else R[n]; 11162 address = if add then (base + imm32) else (base - imm32); 11163 if single_reg then 11164 S[d] = MemA[address,4]; 11165 else 11166 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11167 // Combine the word-aligned words in the correct order for current endianness. 11168 D[d] = if BigEndian() then word1:word2 else word2:word1; 11169 #endif 11170 11171 bool success = false; 11172 11173 if (ConditionPassed (opcode)) 11174 { 11175 bool single_reg; 11176 bool add; 11177 uint32_t imm32; 11178 uint32_t d; 11179 uint32_t n; 11180 11181 switch (encoding) 11182 { 11183 case eEncodingT1: 11184 case eEncodingA1: 11185 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11186 single_reg = false; 11187 add = BitIsSet (opcode, 23); 11188 imm32 = Bits32 (opcode, 7, 0) << 2; 11189 11190 // d = UInt(D:Vd); n = UInt(Rn); 11191 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11192 n = Bits32 (opcode, 19, 16); 11193 11194 break; 11195 11196 case eEncodingT2: 11197 case eEncodingA2: 11198 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11199 single_reg = true; 11200 add = BitIsSet (opcode, 23); 11201 imm32 = Bits32 (opcode, 7, 0) << 2; 11202 11203 // d = UInt(Vd:D); n = UInt(Rn); 11204 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11205 n = Bits32 (opcode, 19, 16); 11206 11207 break; 11208 11209 default: 11210 return false; 11211 } 11212 RegisterInfo base_reg; 11213 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11214 11215 uint32_t Rn = ReadCoreReg (n, &success); 11216 if (!success) 11217 return false; 11218 11219 // base = if n == 15 then Align(PC,4) else R[n]; 11220 uint32_t base; 11221 if (n == 15) 11222 base = AlignPC (Rn); 11223 else 11224 base = Rn; 11225 11226 // address = if add then (base + imm32) else (base - imm32); 11227 addr_t address; 11228 if (add) 11229 address = base + imm32; 11230 else 11231 address = base - imm32; 11232 11233 const uint32_t addr_byte_size = GetAddressByteSize(); 11234 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11235 11236 EmulateInstruction::Context context; 11237 context.type = eContextRegisterLoad; 11238 context.SetRegisterPlusOffset (base_reg, address - base); 11239 11240 if (single_reg) 11241 { 11242 // S[d] = MemA[address,4]; 11243 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11244 if (!success) 11245 return false; 11246 11247 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11248 return false; 11249 } 11250 else 11251 { 11252 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11253 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11254 if (!success) 11255 return false; 11256 11257 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11258 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11259 if (!success) 11260 return false; 11261 // // Combine the word-aligned words in the correct order for current endianness. 11262 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11263 uint64_t data64; 11264 if (GetByteOrder() == eByteOrderBig) 11265 { 11266 data64 = word1; 11267 data64 = (data64 << 32) | word2; 11268 } 11269 else 11270 { 11271 data64 = word2; 11272 data64 = (data64 << 32) | word1; 11273 } 11274 11275 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11276 return false; 11277 } 11278 } 11279 return true; 11280 } 11281 11282 // A8.6.400 VSTR 11283 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11284 // optional offset. 11285 bool 11286 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11287 { 11288 #if 0 11289 if ConditionPassed() then 11290 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11291 address = if add then (R[n] + imm32) else (R[n] - imm32); 11292 if single_reg then 11293 MemA[address,4] = S[d]; 11294 else 11295 // Store as two word-aligned words in the correct order for current endianness. 11296 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11297 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11298 #endif 11299 11300 bool success = false; 11301 11302 if (ConditionPassed (opcode)) 11303 { 11304 bool single_reg; 11305 bool add; 11306 uint32_t imm32; 11307 uint32_t d; 11308 uint32_t n; 11309 11310 switch (encoding) 11311 { 11312 case eEncodingT1: 11313 case eEncodingA1: 11314 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11315 single_reg = false; 11316 add = BitIsSet (opcode, 23); 11317 imm32 = Bits32 (opcode, 7, 0) << 2; 11318 11319 // d = UInt(D:Vd); n = UInt(Rn); 11320 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11321 n = Bits32 (opcode, 19, 16); 11322 11323 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11324 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11325 return false; 11326 11327 break; 11328 11329 case eEncodingT2: 11330 case eEncodingA2: 11331 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11332 single_reg = true; 11333 add = BitIsSet (opcode, 23); 11334 imm32 = Bits32 (opcode, 7, 0) << 2; 11335 11336 // d = UInt(Vd:D); n = UInt(Rn); 11337 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11338 n = Bits32 (opcode, 19, 16); 11339 11340 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11341 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11342 return false; 11343 11344 break; 11345 11346 default: 11347 return false; 11348 } 11349 11350 RegisterInfo base_reg; 11351 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11352 11353 uint32_t Rn = ReadCoreReg (n, &success); 11354 if (!success) 11355 return false; 11356 11357 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11358 addr_t address; 11359 if (add) 11360 address = Rn + imm32; 11361 else 11362 address = Rn - imm32; 11363 11364 const uint32_t addr_byte_size = GetAddressByteSize(); 11365 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11366 11367 RegisterInfo data_reg; 11368 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11369 EmulateInstruction::Context context; 11370 context.type = eContextRegisterStore; 11371 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11372 11373 if (single_reg) 11374 { 11375 // MemA[address,4] = S[d]; 11376 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11377 if (!success) 11378 return false; 11379 11380 if (!MemAWrite (context, address, data, addr_byte_size)) 11381 return false; 11382 } 11383 else 11384 { 11385 // // Store as two word-aligned words in the correct order for current endianness. 11386 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11387 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11388 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11389 if (!success) 11390 return false; 11391 11392 if (GetByteOrder() == eByteOrderBig) 11393 { 11394 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11395 return false; 11396 11397 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11398 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11399 return false; 11400 } 11401 else 11402 { 11403 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11404 return false; 11405 11406 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11407 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11408 return false; 11409 } 11410 } 11411 } 11412 return true; 11413 } 11414 11415 // A8.6.307 VLDI1 (multiple single elements) 11416 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11417 // element of each register is loaded. 11418 bool 11419 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11420 { 11421 #if 0 11422 if ConditionPassed() then 11423 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11424 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11425 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11426 for r = 0 to regs-1 11427 for e = 0 to elements-1 11428 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11429 address = address + ebytes; 11430 #endif 11431 11432 bool success = false; 11433 11434 if (ConditionPassed (opcode)) 11435 { 11436 uint32_t regs; 11437 uint32_t alignment; 11438 uint32_t ebytes; 11439 uint32_t esize; 11440 uint32_t elements; 11441 uint32_t d; 11442 uint32_t n; 11443 uint32_t m; 11444 bool wback; 11445 bool register_index; 11446 11447 switch (encoding) 11448 { 11449 case eEncodingT1: 11450 case eEncodingA1: 11451 { 11452 // case type of 11453 // when '0111' 11454 // regs = 1; if align<1> == '1' then UNDEFINED; 11455 // when '1010' 11456 // regs = 2; if align == '11' then UNDEFINED; 11457 // when '0110' 11458 // regs = 3; if align<1> == '1' then UNDEFINED; 11459 // when '0010' 11460 // regs = 4; 11461 // otherwise 11462 // SEE 'Related encodings'; 11463 uint32_t type = Bits32 (opcode, 11, 8); 11464 uint32_t align = Bits32 (opcode, 5, 4); 11465 if (type == 7) // '0111' 11466 { 11467 regs = 1; 11468 if (BitIsSet (align, 1)) 11469 return false; 11470 } 11471 else if (type == 10) // '1010' 11472 { 11473 regs = 2; 11474 if (align == 3) 11475 return false; 11476 11477 } 11478 else if (type == 6) // '0110' 11479 { 11480 regs = 3; 11481 if (BitIsSet (align, 1)) 11482 return false; 11483 } 11484 else if (type == 2) // '0010' 11485 { 11486 regs = 4; 11487 } 11488 else 11489 return false; 11490 11491 // alignment = if align == '00' then 1 else 4 << UInt(align); 11492 if (align == 0) 11493 alignment = 1; 11494 else 11495 alignment = 4 << align; 11496 11497 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11498 ebytes = 1 << Bits32 (opcode, 7, 6); 11499 esize = 8 * ebytes; 11500 elements = 8 / ebytes; 11501 11502 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11503 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11504 n = Bits32 (opcode, 19, 15); 11505 m = Bits32 (opcode, 3, 0); 11506 11507 // wback = (m != 15); register_index = (m != 15 && m != 13); 11508 wback = (m != 15); 11509 register_index = ((m != 15) && (m != 13)); 11510 11511 // if d+regs > 32 then UNPREDICTABLE; 11512 if ((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 = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11529 addr_t address = Rn; 11530 if ((address % alignment) != 0) 11531 return false; 11532 11533 EmulateInstruction::Context context; 11534 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11535 if (wback) 11536 { 11537 uint32_t Rm = ReadCoreReg (m, &success); 11538 if (!success) 11539 return false; 11540 11541 uint32_t offset; 11542 if (register_index) 11543 offset = Rm; 11544 else 11545 offset = 8 * regs; 11546 11547 uint32_t value = Rn + offset; 11548 context.type = eContextAdjustBaseRegister; 11549 context.SetRegisterPlusOffset (base_reg, offset); 11550 11551 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11552 return false; 11553 11554 } 11555 11556 // for r = 0 to regs-1 11557 for (uint32_t r = 0; r < regs; ++r) 11558 { 11559 // for e = 0 to elements-1 11560 uint64_t assembled_data = 0; 11561 for (uint32_t e = 0; e < elements; ++e) 11562 { 11563 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11564 context.type = eContextRegisterLoad; 11565 context.SetRegisterPlusOffset (base_reg, address - Rn); 11566 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11567 if (!success) 11568 return false; 11569 11570 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11571 11572 // address = address + ebytes; 11573 address = address + ebytes; 11574 } 11575 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11576 return false; 11577 } 11578 } 11579 return true; 11580 } 11581 11582 // A8.6.308 VLD1 (single element to one lane) 11583 // 11584 bool 11585 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11586 { 11587 #if 0 11588 if ConditionPassed() then 11589 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11590 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11591 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11592 Elem[D[d],index,esize] = MemU[address,ebytes]; 11593 #endif 11594 11595 bool success = false; 11596 11597 if (ConditionPassed (opcode)) 11598 { 11599 uint32_t ebytes; 11600 uint32_t esize; 11601 uint32_t index; 11602 uint32_t alignment; 11603 uint32_t d; 11604 uint32_t n; 11605 uint32_t m; 11606 bool wback; 11607 bool register_index; 11608 11609 switch (encoding) 11610 { 11611 case eEncodingT1: 11612 case eEncodingA1: 11613 { 11614 uint32_t size = Bits32 (opcode, 11, 10); 11615 uint32_t index_align = Bits32 (opcode, 7, 4); 11616 // if size == '11' then SEE VLD1 (single element to all lanes); 11617 if (size == 3) 11618 return EmulateVLD1SingleAll (opcode, encoding); 11619 // case size of 11620 if (size == 0) // when '00' 11621 { 11622 // if index_align<0> != '0' then UNDEFINED; 11623 if (BitIsClear (index_align, 0)) 11624 return false; 11625 11626 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11627 ebytes = 1; 11628 esize = 8; 11629 index = Bits32 (index_align, 3, 1); 11630 alignment = 1; 11631 } 11632 else if (size == 1) // when '01' 11633 { 11634 // if index_align<1> != '0' then UNDEFINED; 11635 if (BitIsClear (index_align, 1)) 11636 return false; 11637 11638 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11639 ebytes = 2; 11640 esize = 16; 11641 index = Bits32 (index_align, 3, 2); 11642 11643 // alignment = if index_align<0> == '0' then 1 else 2; 11644 if (BitIsClear (index_align, 0)) 11645 alignment = 1; 11646 else 11647 alignment = 2; 11648 } 11649 else if (size == 2) // when '10' 11650 { 11651 // if index_align<2> != '0' then UNDEFINED; 11652 if (BitIsClear (index_align, 2)) 11653 return false; 11654 11655 // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED; 11656 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11657 return false; 11658 11659 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11660 ebytes = 4; 11661 esize = 32; 11662 index = Bit32 (index_align, 3); 11663 11664 // alignment = if index_align<1:0> == '00' then 1 else 4; 11665 if (Bits32 (index_align, 1, 0) == 0) 11666 alignment = 1; 11667 else 11668 alignment = 4; 11669 } 11670 else 11671 { 11672 return false; 11673 } 11674 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11675 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11676 n = Bits32 (opcode, 19, 16); 11677 m = Bits32 (opcode, 3, 0); 11678 11679 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11680 wback = (m != 15); 11681 register_index = ((m != 15) && (m != 13)); 11682 11683 if (n == 15) 11684 return false; 11685 11686 } 11687 break; 11688 11689 default: 11690 return false; 11691 } 11692 11693 RegisterInfo base_reg; 11694 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11695 11696 uint32_t Rn = ReadCoreReg (n, &success); 11697 if (!success) 11698 return false; 11699 11700 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11701 addr_t address = Rn; 11702 if ((address % alignment) != 0) 11703 return false; 11704 11705 EmulateInstruction::Context context; 11706 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11707 if (wback) 11708 { 11709 uint32_t Rm = ReadCoreReg (m, &success); 11710 if (!success) 11711 return false; 11712 11713 uint32_t offset; 11714 if (register_index) 11715 offset = Rm; 11716 else 11717 offset = ebytes; 11718 11719 uint32_t value = Rn + offset; 11720 11721 context.type = eContextAdjustBaseRegister; 11722 context.SetRegisterPlusOffset (base_reg, offset); 11723 11724 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11725 return false; 11726 } 11727 11728 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11729 uint32_t element = MemURead (context, address, esize, 0, &success); 11730 if (!success) 11731 return false; 11732 11733 element = element << (index * esize); 11734 11735 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11736 if (!success) 11737 return false; 11738 11739 uint64_t all_ones = -1; 11740 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11741 // at element & to the right of element. 11742 if (index > 0) 11743 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11744 // now mask should be 0's where element goes & 1's 11745 // everywhere else. 11746 11747 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11748 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11749 11750 context.type = eContextRegisterLoad; 11751 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11752 return false; 11753 } 11754 return true; 11755 } 11756 11757 // A8.6.391 VST1 (multiple single elements) 11758 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without 11759 // interleaving. Every element of each register is stored. 11760 bool 11761 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11762 { 11763 #if 0 11764 if ConditionPassed() then 11765 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11766 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11767 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11768 for r = 0 to regs-1 11769 for e = 0 to elements-1 11770 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11771 address = address + ebytes; 11772 #endif 11773 11774 bool success = false; 11775 11776 if (ConditionPassed (opcode)) 11777 { 11778 uint32_t regs; 11779 uint32_t alignment; 11780 uint32_t ebytes; 11781 uint32_t esize; 11782 uint32_t elements; 11783 uint32_t d; 11784 uint32_t n; 11785 uint32_t m; 11786 bool wback; 11787 bool register_index; 11788 11789 switch (encoding) 11790 { 11791 case eEncodingT1: 11792 case eEncodingA1: 11793 { 11794 uint32_t type = Bits32 (opcode, 11, 8); 11795 uint32_t align = Bits32 (opcode, 5, 4); 11796 11797 // case type of 11798 if (type == 7) // when '0111' 11799 { 11800 // regs = 1; if align<1> == '1' then UNDEFINED; 11801 regs = 1; 11802 if (BitIsSet (align, 1)) 11803 return false; 11804 } 11805 else if (type == 10) // when '1010' 11806 { 11807 // regs = 2; if align == '11' then UNDEFINED; 11808 regs = 2; 11809 if (align == 3) 11810 return false; 11811 } 11812 else if (type == 6) // when '0110' 11813 { 11814 // regs = 3; if align<1> == '1' then UNDEFINED; 11815 regs = 3; 11816 if (BitIsSet (align, 1)) 11817 return false; 11818 } 11819 else if (type == 2) // when '0010' 11820 // regs = 4; 11821 regs = 4; 11822 else // otherwise 11823 // SEE 'Related encodings'; 11824 return false; 11825 11826 // alignment = if align == '00' then 1 else 4 << UInt(align); 11827 if (align == 0) 11828 alignment = 1; 11829 else 11830 alignment = 4 << align; 11831 11832 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11833 ebytes = 1 << Bits32 (opcode,7, 6); 11834 esize = 8 * ebytes; 11835 elements = 8 / ebytes; 11836 11837 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11838 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11839 n = Bits32 (opcode, 19, 16); 11840 m = Bits32 (opcode, 3, 0); 11841 11842 // wback = (m != 15); register_index = (m != 15 && m != 13); 11843 wback = (m != 15); 11844 register_index = ((m != 15) && (m != 13)); 11845 11846 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11847 if ((d + regs) > 32) 11848 return false; 11849 11850 if (n == 15) 11851 return false; 11852 11853 } 11854 break; 11855 11856 default: 11857 return false; 11858 } 11859 11860 RegisterInfo base_reg; 11861 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11862 11863 uint32_t Rn = ReadCoreReg (n, &success); 11864 if (!success) 11865 return false; 11866 11867 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11868 addr_t address = Rn; 11869 if ((address % alignment) != 0) 11870 return false; 11871 11872 EmulateInstruction::Context context; 11873 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11874 if (wback) 11875 { 11876 uint32_t Rm = ReadCoreReg (m, &success); 11877 if (!success) 11878 return false; 11879 11880 uint32_t offset; 11881 if (register_index) 11882 offset = Rm; 11883 else 11884 offset = 8 * regs; 11885 11886 context.type = eContextAdjustBaseRegister; 11887 context.SetRegisterPlusOffset (base_reg, offset); 11888 11889 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11890 return false; 11891 } 11892 11893 RegisterInfo data_reg; 11894 context.type = eContextRegisterStore; 11895 // for r = 0 to regs-1 11896 for (uint32_t r = 0; r < regs; ++r) 11897 { 11898 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11899 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11900 if (!success) 11901 return false; 11902 11903 // for e = 0 to elements-1 11904 for (uint32_t e = 0; e < elements; ++e) 11905 { 11906 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11907 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11908 11909 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11910 if (!MemUWrite (context, address, word, ebytes)) 11911 return false; 11912 11913 // address = address + ebytes; 11914 address = address + ebytes; 11915 } 11916 } 11917 } 11918 return true; 11919 } 11920 11921 // A8.6.392 VST1 (single element from one lane) 11922 // This instruction stores one element to memory from one element of a register. 11923 bool 11924 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11925 { 11926 #if 0 11927 if ConditionPassed() then 11928 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11929 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11930 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11931 MemU[address,ebytes] = Elem[D[d],index,esize]; 11932 #endif 11933 11934 bool success = false; 11935 11936 if (ConditionPassed (opcode)) 11937 { 11938 uint32_t ebytes; 11939 uint32_t esize; 11940 uint32_t index; 11941 uint32_t alignment; 11942 uint32_t d; 11943 uint32_t n; 11944 uint32_t m; 11945 bool wback; 11946 bool register_index; 11947 11948 switch (encoding) 11949 { 11950 case eEncodingT1: 11951 case eEncodingA1: 11952 { 11953 uint32_t size = Bits32 (opcode, 11, 10); 11954 uint32_t index_align = Bits32 (opcode, 7, 4); 11955 11956 // if size == '11' then UNDEFINED; 11957 if (size == 3) 11958 return false; 11959 11960 // case size of 11961 if (size == 0) // when '00' 11962 { 11963 // if index_align<0> != '0' then UNDEFINED; 11964 if (BitIsClear (index_align, 0)) 11965 return false; 11966 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11967 ebytes = 1; 11968 esize = 8; 11969 index = Bits32 (index_align, 3, 1); 11970 alignment = 1; 11971 } 11972 else if (size == 1) // when '01' 11973 { 11974 // if index_align<1> != '0' then UNDEFINED; 11975 if (BitIsClear (index_align, 1)) 11976 return false; 11977 11978 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11979 ebytes = 2; 11980 esize = 16; 11981 index = Bits32 (index_align, 3, 2); 11982 11983 // alignment = if index_align<0> == '0' then 1 else 2; 11984 if (BitIsClear (index_align, 0)) 11985 alignment = 1; 11986 else 11987 alignment = 2; 11988 } 11989 else if (size == 2) // when '10' 11990 { 11991 // if index_align<2> != '0' then UNDEFINED; 11992 if (BitIsClear (index_align, 2)) 11993 return false; 11994 11995 // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED; 11996 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11997 return false; 11998 11999 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12000 ebytes = 4; 12001 esize = 32; 12002 index = Bit32 (index_align, 3); 12003 12004 // alignment = if index_align<1:0> == '00' then 1 else 4; 12005 if (Bits32 (index_align, 1, 0) == 0) 12006 alignment = 1; 12007 else 12008 alignment = 4; 12009 } 12010 else 12011 { 12012 return false; 12013 } 12014 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12015 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 12016 n = Bits32 (opcode, 19, 16); 12017 m = Bits32 (opcode, 3, 0); 12018 12019 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 12020 wback = (m != 15); 12021 register_index = ((m != 15) && (m != 13)); 12022 12023 if (n == 15) 12024 return false; 12025 } 12026 break; 12027 12028 default: 12029 return false; 12030 } 12031 12032 RegisterInfo base_reg; 12033 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12034 12035 uint32_t Rn = ReadCoreReg (n, &success); 12036 if (!success) 12037 return false; 12038 12039 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12040 addr_t address = Rn; 12041 if ((address % alignment) != 0) 12042 return false; 12043 12044 EmulateInstruction::Context context; 12045 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12046 if (wback) 12047 { 12048 uint32_t Rm = ReadCoreReg (m, &success); 12049 if (!success) 12050 return false; 12051 12052 uint32_t offset; 12053 if (register_index) 12054 offset = Rm; 12055 else 12056 offset = ebytes; 12057 12058 context.type = eContextAdjustBaseRegister; 12059 context.SetRegisterPlusOffset (base_reg, offset); 12060 12061 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12062 return false; 12063 } 12064 12065 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12066 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12067 if (!success) 12068 return false; 12069 12070 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 12071 12072 RegisterInfo data_reg; 12073 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12074 context.type = eContextRegisterStore; 12075 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 12076 12077 if (!MemUWrite (context, address, word, ebytes)) 12078 return false; 12079 } 12080 return true; 12081 } 12082 12083 // A8.6.309 VLD1 (single element to all lanes) 12084 // This instruction loads one element from memory into every element of one or two vectors. 12085 bool 12086 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 12087 { 12088 #if 0 12089 if ConditionPassed() then 12090 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12091 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12092 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12093 replicated_element = Replicate(MemU[address,ebytes], elements); 12094 for r = 0 to regs-1 12095 D[d+r] = replicated_element; 12096 #endif 12097 12098 bool success = false; 12099 12100 if (ConditionPassed (opcode)) 12101 { 12102 uint32_t ebytes; 12103 uint32_t elements; 12104 uint32_t regs; 12105 uint32_t alignment; 12106 uint32_t d; 12107 uint32_t n; 12108 uint32_t m; 12109 bool wback; 12110 bool register_index; 12111 12112 switch (encoding) 12113 { 12114 case eEncodingT1: 12115 case eEncodingA1: 12116 { 12117 //if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12118 uint32_t size = Bits32 (opcode, 7, 6); 12119 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 12120 return false; 12121 12122 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' then 1 else 2; 12123 ebytes = 1 << size; 12124 elements = 8 / ebytes; 12125 if (BitIsClear (opcode, 5)) 12126 regs = 1; 12127 else 12128 regs = 2; 12129 12130 //alignment = if a == '0' then 1 else ebytes; 12131 if (BitIsClear (opcode, 4)) 12132 alignment = 1; 12133 else 12134 alignment = ebytes; 12135 12136 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12137 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 12138 n = Bits32 (opcode, 19, 16); 12139 m = Bits32 (opcode, 3, 0); 12140 12141 //wback = (m != 15); register_index = (m != 15 && m != 13); 12142 wback = (m != 15); 12143 register_index = ((m != 15) && (m != 13)); 12144 12145 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12146 if ((d + regs) > 32) 12147 return false; 12148 12149 if (n == 15) 12150 return false; 12151 } 12152 break; 12153 12154 default: 12155 return false; 12156 } 12157 12158 RegisterInfo base_reg; 12159 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12160 12161 uint32_t Rn = ReadCoreReg (n, &success); 12162 if (!success) 12163 return false; 12164 12165 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12166 addr_t address = Rn; 12167 if ((address % alignment) != 0) 12168 return false; 12169 12170 EmulateInstruction::Context context; 12171 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12172 if (wback) 12173 { 12174 uint32_t Rm = ReadCoreReg (m, &success); 12175 if (!success) 12176 return false; 12177 12178 uint32_t offset; 12179 if (register_index) 12180 offset = Rm; 12181 else 12182 offset = ebytes; 12183 12184 context.type = eContextAdjustBaseRegister; 12185 context.SetRegisterPlusOffset (base_reg, offset); 12186 12187 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12188 return false; 12189 } 12190 12191 // replicated_element = Replicate(MemU[address,ebytes], elements); 12192 12193 context.type = eContextRegisterLoad; 12194 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12195 if (!success) 12196 return false; 12197 12198 uint64_t replicated_element = 0; 12199 uint32_t esize = ebytes * 8; 12200 for (uint32_t e = 0; e < elements; ++e) 12201 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12202 12203 // for r = 0 to regs-1 12204 for (uint32_t r = 0; r < regs; ++r) 12205 { 12206 // D[d+r] = replicated_element; 12207 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12208 return false; 12209 } 12210 } 12211 return true; 12212 } 12213 12214 // B6.2.13 SUBS PC, LR and related instructions 12215 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12216 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12217 bool 12218 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12219 { 12220 #if 0 12221 if ConditionPassed() then 12222 EncodingSpecificOperations(); 12223 if CurrentInstrSet() == InstrSet_ThumbEE then 12224 UNPREDICTABLE; 12225 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12226 case opcode of 12227 when '0000' result = R[n] AND operand2; // AND 12228 when '0001' result = R[n] EOR operand2; // EOR 12229 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12230 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12231 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12232 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12233 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12234 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12235 when '1100' result = R[n] OR operand2; // ORR 12236 when '1101' result = operand2; // MOV 12237 when '1110' result = R[n] AND NOT(operand2); // BIC 12238 when '1111' result = NOT(operand2); // MVN 12239 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12240 BranchWritePC(result); 12241 #endif 12242 12243 bool success = false; 12244 12245 if (ConditionPassed (opcode)) 12246 { 12247 uint32_t n; 12248 uint32_t m; 12249 uint32_t imm32; 12250 bool register_form; 12251 ARM_ShifterType shift_t; 12252 uint32_t shift_n; 12253 uint32_t code; 12254 12255 switch (encoding) 12256 { 12257 case eEncodingT1: 12258 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12259 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; // = SUB 12260 n = 14; 12261 imm32 = Bits32 (opcode, 7, 0); 12262 register_form = false; 12263 code = 2; 12264 12265 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12266 if (InITBlock() && !LastInITBlock()) 12267 return false; 12268 12269 break; 12270 12271 case eEncodingA1: 12272 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12273 n = Bits32 (opcode, 19, 16); 12274 imm32 = ARMExpandImm (opcode); 12275 register_form = false; 12276 code = Bits32 (opcode, 24, 21); 12277 12278 break; 12279 12280 case eEncodingA2: 12281 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12282 n = Bits32 (opcode, 19, 16); 12283 m = Bits32 (opcode, 3, 0); 12284 register_form = true; 12285 12286 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12287 shift_n = DecodeImmShiftARM (opcode, shift_t); 12288 12289 break; 12290 12291 default: 12292 return false; 12293 } 12294 12295 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12296 uint32_t operand2; 12297 if (register_form) 12298 { 12299 uint32_t Rm = ReadCoreReg (m, &success); 12300 if (!success) 12301 return false; 12302 12303 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12304 if (!success) 12305 return false; 12306 } 12307 else 12308 { 12309 operand2 = imm32; 12310 } 12311 12312 uint32_t Rn = ReadCoreReg (n, &success); 12313 if (!success) 12314 return false; 12315 12316 AddWithCarryResult result; 12317 12318 // case opcode of 12319 switch (code) 12320 { 12321 case 0: // when '0000' 12322 // result = R[n] AND operand2; // AND 12323 result.result = Rn & operand2; 12324 break; 12325 12326 case 1: // when '0001' 12327 // result = R[n] EOR operand2; // EOR 12328 result.result = Rn ^ operand2; 12329 break; 12330 12331 case 2: // when '0010' 12332 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12333 result = AddWithCarry (Rn, ~(operand2), 1); 12334 break; 12335 12336 case 3: // when '0011' 12337 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12338 result = AddWithCarry (~(Rn), operand2, 1); 12339 break; 12340 12341 case 4: // when '0100' 12342 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12343 result = AddWithCarry (Rn, operand2, 0); 12344 break; 12345 12346 case 5: // when '0101' 12347 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12348 result = AddWithCarry (Rn, operand2, APSR_C); 12349 break; 12350 12351 case 6: // when '0110' 12352 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12353 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12354 break; 12355 12356 case 7: // when '0111' 12357 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12358 result = AddWithCarry (~(Rn), operand2, APSR_C); 12359 break; 12360 12361 case 10: // when '1100' 12362 // result = R[n] OR operand2; // ORR 12363 result.result = Rn | operand2; 12364 break; 12365 12366 case 11: // when '1101' 12367 // result = operand2; // MOV 12368 result.result = operand2; 12369 break; 12370 12371 case 12: // when '1110' 12372 // result = R[n] AND NOT(operand2); // BIC 12373 result.result = Rn & ~(operand2); 12374 break; 12375 12376 case 15: // when '1111' 12377 // result = NOT(operand2); // MVN 12378 result.result = ~(operand2); 12379 break; 12380 12381 default: 12382 return false; 12383 } 12384 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12385 12386 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12387 // the best. 12388 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12389 if (!success) 12390 return false; 12391 12392 CPSRWriteByInstr (spsr, 15, true); 12393 12394 // BranchWritePC(result); 12395 EmulateInstruction::Context context; 12396 context.type = eContextAdjustPC; 12397 context.SetImmediate (result.result); 12398 12399 BranchWritePC (context, result.result); 12400 } 12401 return true; 12402 } 12403 12404 EmulateInstructionARM::ARMOpcode* 12405 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12406 { 12407 static ARMOpcode 12408 g_arm_opcodes[] = 12409 { 12410 //---------------------------------------------------------------------- 12411 // Prologue instructions 12412 //---------------------------------------------------------------------- 12413 12414 // push register(s) 12415 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12416 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12417 12418 // set r7 to point to a stack offset 12419 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12420 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12421 // copy the stack pointer to ip 12422 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12423 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12424 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12425 12426 // adjust the stack pointer 12427 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12428 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12429 12430 // push one register 12431 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12432 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12433 12434 // vector push consecutive extension register(s) 12435 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12436 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12437 12438 //---------------------------------------------------------------------- 12439 // Epilogue instructions 12440 //---------------------------------------------------------------------- 12441 12442 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12443 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12444 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12445 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12446 12447 //---------------------------------------------------------------------- 12448 // Supervisor Call (previously Software Interrupt) 12449 //---------------------------------------------------------------------- 12450 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12451 12452 //---------------------------------------------------------------------- 12453 // Branch instructions 12454 //---------------------------------------------------------------------- 12455 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>". 12456 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12457 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12458 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12459 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12460 // for example, "bx lr" 12461 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12462 // bxj 12463 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12464 12465 //---------------------------------------------------------------------- 12466 // Data-processing instructions 12467 //---------------------------------------------------------------------- 12468 // adc (immediate) 12469 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12470 // adc (register) 12471 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12472 // add (immediate) 12473 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12474 // add (register) 12475 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12476 // add (register-shifted register) 12477 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12478 // adr 12479 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12480 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12481 // and (immediate) 12482 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12483 // and (register) 12484 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12485 // bic (immediate) 12486 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12487 // bic (register) 12488 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12489 // eor (immediate) 12490 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12491 // eor (register) 12492 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12493 // orr (immediate) 12494 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12495 // orr (register) 12496 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12497 // rsb (immediate) 12498 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12499 // rsb (register) 12500 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12501 // rsc (immediate) 12502 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12503 // rsc (register) 12504 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12505 // sbc (immediate) 12506 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12507 // sbc (register) 12508 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12509 // sub (immediate, ARM) 12510 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12511 // sub (sp minus immediate) 12512 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12513 // sub (register) 12514 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12515 // teq (immediate) 12516 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12517 // teq (register) 12518 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12519 // tst (immediate) 12520 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12521 // tst (register) 12522 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12523 12524 // mov (immediate) 12525 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12526 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12527 // mov (register) 12528 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12529 // mvn (immediate) 12530 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12531 // mvn (register) 12532 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12533 // cmn (immediate) 12534 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12535 // cmn (register) 12536 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12537 // cmp (immediate) 12538 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12539 // cmp (register) 12540 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12541 // asr (immediate) 12542 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12543 // asr (register) 12544 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12545 // lsl (immediate) 12546 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12547 // lsl (register) 12548 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12549 // lsr (immediate) 12550 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12551 // lsr (register) 12552 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12553 // rrx is a special case encoding of ror (immediate) 12554 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12555 // ror (immediate) 12556 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12557 // ror (register) 12558 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12559 // mul 12560 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12561 12562 // subs pc, lr and related instructions 12563 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12564 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12565 12566 //---------------------------------------------------------------------- 12567 // Load instructions 12568 //---------------------------------------------------------------------- 12569 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12570 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12571 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12572 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12573 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12574 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12575 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12576 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12577 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12578 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12579 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12580 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12581 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12582 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12583 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12584 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12585 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12586 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12587 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12588 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12589 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12590 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12591 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12592 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12593 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12594 12595 //---------------------------------------------------------------------- 12596 // Store instructions 12597 //---------------------------------------------------------------------- 12598 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12599 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12600 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12601 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12602 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12603 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12604 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12605 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12606 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12607 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12608 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12609 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12610 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12611 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12612 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12613 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12614 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12615 12616 //---------------------------------------------------------------------- 12617 // Other instructions 12618 //---------------------------------------------------------------------- 12619 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12620 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12621 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12622 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12623 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12624 12625 }; 12626 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 12627 12628 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12629 { 12630 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12631 (g_arm_opcodes[i].variants & arm_isa) != 0) 12632 return &g_arm_opcodes[i]; 12633 } 12634 return NULL; 12635 } 12636 12637 12638 EmulateInstructionARM::ARMOpcode* 12639 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12640 { 12641 12642 static ARMOpcode 12643 g_thumb_opcodes[] = 12644 { 12645 //---------------------------------------------------------------------- 12646 // Prologue instructions 12647 //---------------------------------------------------------------------- 12648 12649 // push register(s) 12650 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12651 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12652 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12653 12654 // set r7 to point to a stack offset 12655 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12656 // copy the stack pointer to r7 12657 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12658 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12659 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12660 12661 // PC-relative load into register (see also EmulateADDSPRm) 12662 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12663 12664 // adjust the stack pointer 12665 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12666 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12667 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12668 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12669 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12670 12671 // vector push consecutive extension register(s) 12672 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12673 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12674 12675 //---------------------------------------------------------------------- 12676 // Epilogue instructions 12677 //---------------------------------------------------------------------- 12678 12679 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12680 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12681 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12682 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12683 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12684 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12685 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12686 12687 //---------------------------------------------------------------------- 12688 // Supervisor Call (previously Software Interrupt) 12689 //---------------------------------------------------------------------- 12690 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12691 12692 //---------------------------------------------------------------------- 12693 // If Then makes up to four following instructions conditional. 12694 //---------------------------------------------------------------------- 12695 // The next 5 opcode _must_ come before the if then instruction 12696 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12697 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12698 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12699 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12700 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12701 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12702 12703 //---------------------------------------------------------------------- 12704 // Branch instructions 12705 //---------------------------------------------------------------------- 12706 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12707 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12708 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12709 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12710 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12711 // J1 == J2 == 1 12712 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12713 // J1 == J2 == 1 12714 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12715 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12716 // for example, "bx lr" 12717 { 0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12718 // bxj 12719 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12720 // compare and branch 12721 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12722 // table branch byte 12723 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12724 // table branch halfword 12725 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12726 12727 //---------------------------------------------------------------------- 12728 // Data-processing instructions 12729 //---------------------------------------------------------------------- 12730 // adc (immediate) 12731 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12732 // adc (register) 12733 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12734 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12735 // add (register) 12736 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12737 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12738 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12739 // adr 12740 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12741 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12742 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12743 // and (immediate) 12744 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12745 // and (register) 12746 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12747 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12748 // bic (immediate) 12749 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12750 // bic (register) 12751 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12752 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12753 // eor (immediate) 12754 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12755 // eor (register) 12756 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12757 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12758 // orr (immediate) 12759 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12760 // orr (register) 12761 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12762 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12763 // rsb (immediate) 12764 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12765 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12766 // rsb (register) 12767 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12768 // sbc (immediate) 12769 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12770 // sbc (register) 12771 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12772 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12773 // add (immediate, Thumb) 12774 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12775 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12776 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12777 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12778 // sub (immediate, Thumb) 12779 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12780 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12781 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12782 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12783 // sub (sp minus immediate) 12784 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12785 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12786 // sub (register) 12787 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12788 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12789 // teq (immediate) 12790 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12791 // teq (register) 12792 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12793 // tst (immediate) 12794 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12795 // tst (register) 12796 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12797 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12798 12799 12800 // move from high register to high register 12801 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12802 // move from low register to low register 12803 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12804 // mov{s}<c>.w <Rd>, <Rm> 12805 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12806 // move immediate 12807 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12808 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12809 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12810 // mvn (immediate) 12811 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12812 // mvn (register) 12813 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12814 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12815 // cmn (immediate) 12816 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12817 // cmn (register) 12818 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12819 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12820 // cmp (immediate) 12821 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12822 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12823 // cmp (register) (Rn and Rm both from r0-r7) 12824 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12825 // cmp (register) (Rn and Rm not both from r0-r7) 12826 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12827 { 0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 12828 // asr (immediate) 12829 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12830 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12831 // asr (register) 12832 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12833 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12834 // lsl (immediate) 12835 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12836 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12837 // lsl (register) 12838 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12839 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12840 // lsr (immediate) 12841 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12842 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12843 // lsr (register) 12844 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12845 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12846 // rrx is a special case encoding of ror (immediate) 12847 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12848 // ror (immediate) 12849 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12850 // ror (register) 12851 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12852 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12853 // mul 12854 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12855 // mul 12856 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12857 12858 // subs pc, lr and related instructions 12859 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12860 12861 //---------------------------------------------------------------------- 12862 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12863 // otherwise the wrong instructions will be selected. 12864 //---------------------------------------------------------------------- 12865 12866 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12867 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12868 12869 //---------------------------------------------------------------------- 12870 // Load instructions 12871 //---------------------------------------------------------------------- 12872 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12873 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12874 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12875 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12876 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12877 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12878 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12879 // Thumb2 PC-relative load into register 12880 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12881 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12882 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12883 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12884 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12885 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12886 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12887 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12888 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12889 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12890 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12891 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12892 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12893 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12894 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12895 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12896 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12897 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12898 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12899 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12900 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12901 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12902 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12903 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12904 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12905 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12906 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12907 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12908 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12909 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12910 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12911 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12912 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12913 12914 //---------------------------------------------------------------------- 12915 // Store instructions 12916 //---------------------------------------------------------------------- 12917 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12918 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12919 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12920 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12921 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12922 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12923 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12924 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12925 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12926 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12927 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12928 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12929 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12930 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12931 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12932 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12933 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12934 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12935 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12936 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12937 { 0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12938 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12939 12940 //---------------------------------------------------------------------- 12941 // Other instructions 12942 //---------------------------------------------------------------------- 12943 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12944 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12945 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12946 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12947 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12948 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12949 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12950 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12951 }; 12952 12953 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 12954 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12955 { 12956 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12957 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12958 return &g_thumb_opcodes[i]; 12959 } 12960 return NULL; 12961 } 12962 12963 bool 12964 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12965 { 12966 m_arch = arch; 12967 m_arm_isa = 0; 12968 const char *arch_cstr = arch.GetArchitectureName (); 12969 if (arch_cstr) 12970 { 12971 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12972 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12973 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12974 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12975 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12976 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12977 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12978 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12979 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12980 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12981 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12982 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12983 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12984 } 12985 return m_arm_isa != 0; 12986 } 12987 12988 bool 12989 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12990 { 12991 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12992 { 12993 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12994 m_opcode_mode = eModeThumb; 12995 else 12996 { 12997 AddressClass addr_class = inst_addr.GetAddressClass(); 12998 12999 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 13000 m_opcode_mode = eModeARM; 13001 else if (addr_class == eAddressClassCodeAlternateISA) 13002 m_opcode_mode = eModeThumb; 13003 else 13004 return false; 13005 } 13006 if (m_opcode_mode == eModeThumb) 13007 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13008 else 13009 m_opcode_cpsr = CPSR_MODE_USR; 13010 return true; 13011 } 13012 return false; 13013 } 13014 13015 bool 13016 EmulateInstructionARM::ReadInstruction () 13017 { 13018 bool success = false; 13019 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13020 if (success) 13021 { 13022 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 13023 if (success) 13024 { 13025 Context read_inst_context; 13026 read_inst_context.type = eContextReadOpcode; 13027 read_inst_context.SetNoArgs (); 13028 13029 if (m_opcode_cpsr & MASK_CPSR_T) 13030 { 13031 m_opcode_mode = eModeThumb; 13032 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13033 13034 if (success) 13035 { 13036 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 13037 { 13038 m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder()); 13039 } 13040 else 13041 { 13042 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder()); 13043 } 13044 } 13045 } 13046 else 13047 { 13048 m_opcode_mode = eModeARM; 13049 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder()); 13050 } 13051 } 13052 } 13053 if (!success) 13054 { 13055 m_opcode_mode = eModeInvalid; 13056 m_addr = LLDB_INVALID_ADDRESS; 13057 } 13058 return success; 13059 } 13060 13061 uint32_t 13062 EmulateInstructionARM::ArchVersion () 13063 { 13064 return m_arm_isa; 13065 } 13066 13067 bool 13068 EmulateInstructionARM::ConditionPassed (const uint32_t opcode) 13069 { 13070 // If we are ignoring conditions, then always return true. 13071 // this allows us to iterate over disassembly code and still 13072 // emulate an instruction even if we don't have all the right 13073 // bits set in the CPSR register... 13074 if (m_ignore_conditions) 13075 return true; 13076 13077 const uint32_t cond = CurrentCond (opcode); 13078 if (cond == UINT32_MAX) 13079 return false; 13080 13081 bool result = false; 13082 switch (UnsignedBits(cond, 3, 1)) 13083 { 13084 case 0: 13085 if (m_opcode_cpsr == 0) 13086 result = true; 13087 else 13088 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13089 break; 13090 case 1: 13091 if (m_opcode_cpsr == 0) 13092 result = true; 13093 else 13094 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13095 break; 13096 case 2: 13097 if (m_opcode_cpsr == 0) 13098 result = true; 13099 else 13100 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13101 break; 13102 case 3: 13103 if (m_opcode_cpsr == 0) 13104 result = true; 13105 else 13106 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13107 break; 13108 case 4: 13109 if (m_opcode_cpsr == 0) 13110 result = true; 13111 else 13112 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13113 break; 13114 case 5: 13115 if (m_opcode_cpsr == 0) 13116 result = true; 13117 else 13118 { 13119 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13120 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13121 result = n == v; 13122 } 13123 break; 13124 case 6: 13125 if (m_opcode_cpsr == 0) 13126 result = true; 13127 else 13128 { 13129 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13130 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13131 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13132 } 13133 break; 13134 case 7: 13135 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13136 // opcodes different meanings, but always means execution happens. 13137 return true; 13138 } 13139 13140 if (cond & 1) 13141 result = !result; 13142 return result; 13143 } 13144 13145 uint32_t 13146 EmulateInstructionARM::CurrentCond (const uint32_t opcode) 13147 { 13148 switch (m_opcode_mode) 13149 { 13150 case eModeInvalid: 13151 break; 13152 13153 case eModeARM: 13154 return UnsignedBits(opcode, 31, 28); 13155 13156 case eModeThumb: 13157 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13158 // 'cond' field of the encoding. 13159 { 13160 const uint32_t byte_size = m_opcode.GetByteSize(); 13161 if (byte_size == 2) 13162 { 13163 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 13164 return Bits32(opcode, 11, 8); 13165 } 13166 else if (byte_size == 4) 13167 { 13168 if (Bits32(opcode, 31, 27) == 0x1e && 13169 Bits32(opcode, 15, 14) == 0x02 && 13170 Bits32(opcode, 12, 12) == 0x00 && 13171 Bits32(opcode, 25, 22) <= 0x0d) 13172 { 13173 return Bits32(opcode, 25, 22); 13174 } 13175 } 13176 else 13177 // We have an invalid thumb instruction, let's bail out. 13178 break; 13179 13180 return m_it_session.GetCond(); 13181 } 13182 } 13183 return UINT32_MAX; // Return invalid value 13184 } 13185 13186 bool 13187 EmulateInstructionARM::InITBlock() 13188 { 13189 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13190 } 13191 13192 bool 13193 EmulateInstructionARM::LastInITBlock() 13194 { 13195 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13196 } 13197 13198 bool 13199 EmulateInstructionARM::BadMode (uint32_t mode) 13200 { 13201 13202 switch (mode) 13203 { 13204 case 16: return false; // '10000' 13205 case 17: return false; // '10001' 13206 case 18: return false; // '10010' 13207 case 19: return false; // '10011' 13208 case 22: return false; // '10110' 13209 case 23: return false; // '10111' 13210 case 27: return false; // '11011' 13211 case 31: return false; // '11111' 13212 default: return true; 13213 } 13214 return true; 13215 } 13216 13217 bool 13218 EmulateInstructionARM::CurrentModeIsPrivileged () 13219 { 13220 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13221 13222 if (BadMode (mode)) 13223 return false; 13224 13225 if (mode == 16) 13226 return false; 13227 13228 return true; 13229 } 13230 13231 void 13232 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13233 { 13234 bool privileged = CurrentModeIsPrivileged(); 13235 13236 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13237 13238 if (BitIsSet (bytemask, 3)) 13239 { 13240 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13241 if (affect_execstate) 13242 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13243 } 13244 13245 if (BitIsSet (bytemask, 2)) 13246 { 13247 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13248 } 13249 13250 if (BitIsSet (bytemask, 1)) 13251 { 13252 if (affect_execstate) 13253 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13254 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13255 if (privileged) 13256 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13257 } 13258 13259 if (BitIsSet (bytemask, 0)) 13260 { 13261 if (privileged) 13262 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13263 if (affect_execstate) 13264 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13265 if (privileged) 13266 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13267 } 13268 13269 m_opcode_cpsr = tmp_cpsr; 13270 } 13271 13272 13273 bool 13274 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13275 { 13276 addr_t target; 13277 13278 // Check the current instruction set. 13279 if (CurrentInstrSet() == eModeARM) 13280 target = addr & 0xfffffffc; 13281 else 13282 target = addr & 0xfffffffe; 13283 13284 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13285 return false; 13286 13287 return true; 13288 } 13289 13290 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13291 bool 13292 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13293 { 13294 addr_t target; 13295 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13296 // we want to record it and issue a WriteRegister callback so the clients 13297 // can track the mode changes accordingly. 13298 bool cpsr_changed = false; 13299 13300 if (BitIsSet(addr, 0)) 13301 { 13302 if (CurrentInstrSet() != eModeThumb) 13303 { 13304 SelectInstrSet(eModeThumb); 13305 cpsr_changed = true; 13306 } 13307 target = addr & 0xfffffffe; 13308 context.SetISA (eModeThumb); 13309 } 13310 else if (BitIsClear(addr, 1)) 13311 { 13312 if (CurrentInstrSet() != eModeARM) 13313 { 13314 SelectInstrSet(eModeARM); 13315 cpsr_changed = true; 13316 } 13317 target = addr & 0xfffffffc; 13318 context.SetISA (eModeARM); 13319 } 13320 else 13321 return false; // address<1:0> == '10' => UNPREDICTABLE 13322 13323 if (cpsr_changed) 13324 { 13325 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13326 return false; 13327 } 13328 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13329 return false; 13330 13331 return true; 13332 } 13333 13334 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13335 bool 13336 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13337 { 13338 if (ArchVersion() >= ARMv5T) 13339 return BXWritePC(context, addr); 13340 else 13341 return BranchWritePC((const Context)context, addr); 13342 } 13343 13344 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13345 bool 13346 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13347 { 13348 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13349 return BXWritePC(context, addr); 13350 else 13351 return BranchWritePC((const Context)context, addr); 13352 } 13353 13354 EmulateInstructionARM::Mode 13355 EmulateInstructionARM::CurrentInstrSet () 13356 { 13357 return m_opcode_mode; 13358 } 13359 13360 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13361 // ReadInstruction() is performed. This function has a side effect of updating 13362 // the m_new_inst_cpsr member variable if necessary. 13363 bool 13364 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13365 { 13366 m_new_inst_cpsr = m_opcode_cpsr; 13367 switch (arm_or_thumb) 13368 { 13369 default: 13370 return false; 13371 case eModeARM: 13372 // Clear the T bit. 13373 m_new_inst_cpsr &= ~MASK_CPSR_T; 13374 break; 13375 case eModeThumb: 13376 // Set the T bit. 13377 m_new_inst_cpsr |= MASK_CPSR_T; 13378 break; 13379 } 13380 return true; 13381 } 13382 13383 // This function returns TRUE if the processor currently provides support for 13384 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13385 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13386 bool 13387 EmulateInstructionARM::UnalignedSupport() 13388 { 13389 return (ArchVersion() >= ARMv7); 13390 } 13391 13392 // The main addition and subtraction instructions can produce status information 13393 // about both unsigned carry and signed overflow conditions. This status 13394 // information can be used to synthesize multi-word additions and subtractions. 13395 EmulateInstructionARM::AddWithCarryResult 13396 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13397 { 13398 uint32_t result; 13399 uint8_t carry_out; 13400 uint8_t overflow; 13401 13402 uint64_t unsigned_sum = x + y + carry_in; 13403 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13404 13405 result = UnsignedBits(unsigned_sum, 31, 0); 13406 // carry_out = (result == unsigned_sum ? 0 : 1); 13407 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13408 13409 if (carry_in) 13410 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13411 else 13412 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13413 13414 AddWithCarryResult res = { result, carry_out, overflow }; 13415 return res; 13416 } 13417 13418 uint32_t 13419 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13420 { 13421 lldb::RegisterKind reg_kind; 13422 uint32_t reg_num; 13423 switch (num) 13424 { 13425 case SP_REG: 13426 reg_kind = eRegisterKindGeneric; 13427 reg_num = LLDB_REGNUM_GENERIC_SP; 13428 break; 13429 case LR_REG: 13430 reg_kind = eRegisterKindGeneric; 13431 reg_num = LLDB_REGNUM_GENERIC_RA; 13432 break; 13433 case PC_REG: 13434 reg_kind = eRegisterKindGeneric; 13435 reg_num = LLDB_REGNUM_GENERIC_PC; 13436 break; 13437 default: 13438 if (num < SP_REG) 13439 { 13440 reg_kind = eRegisterKindDWARF; 13441 reg_num = dwarf_r0 + num; 13442 } 13443 else 13444 { 13445 //assert(0 && "Invalid register number"); 13446 *success = false; 13447 return UINT32_MAX; 13448 } 13449 break; 13450 } 13451 13452 // Read our register. 13453 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13454 13455 // When executing an ARM instruction , PC reads as the address of the current 13456 // instruction plus 8. 13457 // When executing a Thumb instruction , PC reads as the address of the current 13458 // instruction plus 4. 13459 if (num == 15) 13460 { 13461 if (CurrentInstrSet() == eModeARM) 13462 val += 8; 13463 else 13464 val += 4; 13465 } 13466 13467 return val; 13468 } 13469 13470 // Write the result to the ARM core register Rd, and optionally update the 13471 // condition flags based on the result. 13472 // 13473 // This helper method tries to encapsulate the following pseudocode from the 13474 // ARM Architecture Reference Manual: 13475 // 13476 // if d == 15 then // Can only occur for encoding A1 13477 // ALUWritePC(result); // setflags is always FALSE here 13478 // else 13479 // R[d] = result; 13480 // if setflags then 13481 // APSR.N = result<31>; 13482 // APSR.Z = IsZeroBit(result); 13483 // APSR.C = carry; 13484 // // APSR.V unchanged 13485 // 13486 // In the above case, the API client does not pass in the overflow arg, which 13487 // defaults to ~0u. 13488 bool 13489 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13490 const uint32_t result, 13491 const uint32_t Rd, 13492 bool setflags, 13493 const uint32_t carry, 13494 const uint32_t overflow) 13495 { 13496 if (Rd == 15) 13497 { 13498 if (!ALUWritePC (context, result)) 13499 return false; 13500 } 13501 else 13502 { 13503 lldb::RegisterKind reg_kind; 13504 uint32_t reg_num; 13505 switch (Rd) 13506 { 13507 case SP_REG: 13508 reg_kind = eRegisterKindGeneric; 13509 reg_num = LLDB_REGNUM_GENERIC_SP; 13510 break; 13511 case LR_REG: 13512 reg_kind = eRegisterKindGeneric; 13513 reg_num = LLDB_REGNUM_GENERIC_RA; 13514 break; 13515 default: 13516 reg_kind = eRegisterKindDWARF; 13517 reg_num = dwarf_r0 + Rd; 13518 } 13519 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13520 return false; 13521 if (setflags) 13522 return WriteFlags (context, result, carry, overflow); 13523 } 13524 return true; 13525 } 13526 13527 // This helper method tries to encapsulate the following pseudocode from the 13528 // ARM Architecture Reference Manual: 13529 // 13530 // APSR.N = result<31>; 13531 // APSR.Z = IsZeroBit(result); 13532 // APSR.C = carry; 13533 // APSR.V = overflow 13534 // 13535 // Default arguments can be specified for carry and overflow parameters, which means 13536 // not to update the respective flags. 13537 bool 13538 EmulateInstructionARM::WriteFlags (Context &context, 13539 const uint32_t result, 13540 const uint32_t carry, 13541 const uint32_t overflow) 13542 { 13543 m_new_inst_cpsr = m_opcode_cpsr; 13544 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13545 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13546 if (carry != ~0u) 13547 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13548 if (overflow != ~0u) 13549 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13550 if (m_new_inst_cpsr != m_opcode_cpsr) 13551 { 13552 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13553 return false; 13554 } 13555 return true; 13556 } 13557 13558 bool 13559 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13560 { 13561 // Advance the ITSTATE bits to their values for the next instruction. 13562 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13563 m_it_session.ITAdvance(); 13564 13565 ARMOpcode *opcode_data = NULL; 13566 13567 if (m_opcode_mode == eModeThumb) 13568 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13569 else if (m_opcode_mode == eModeARM) 13570 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13571 13572 if (opcode_data == NULL) 13573 return false; 13574 13575 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13576 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13577 13578 bool success = false; 13579 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13580 { 13581 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13582 dwarf_cpsr, 13583 0, 13584 &success); 13585 } 13586 13587 // Only return false if we are unable to read the CPSR if we care about conditions 13588 if (success == false && m_ignore_conditions == false) 13589 return false; 13590 13591 uint32_t orig_pc_value = 0; 13592 if (auto_advance_pc) 13593 { 13594 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13595 if (!success) 13596 return false; 13597 } 13598 13599 // Call the Emulate... function. 13600 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13601 if (!success) 13602 return false; 13603 13604 if (auto_advance_pc) 13605 { 13606 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13607 if (!success) 13608 return false; 13609 13610 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13611 { 13612 if (opcode_data->size == eSize32) 13613 after_pc_value += 4; 13614 else if (opcode_data->size == eSize16) 13615 after_pc_value += 2; 13616 13617 EmulateInstruction::Context context; 13618 context.type = eContextAdvancePC; 13619 context.SetNoArgs(); 13620 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13621 return false; 13622 13623 } 13624 } 13625 return true; 13626 } 13627 13628 bool 13629 EmulateInstructionARM::IsInstructionConditional() 13630 { 13631 const uint32_t cond = CurrentCond (m_opcode.GetOpcode32()); 13632 return cond != 0xe && cond != 0xf && cond != UINT32_MAX; 13633 } 13634 13635 bool 13636 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13637 { 13638 if (!test_data) 13639 { 13640 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13641 return false; 13642 } 13643 13644 static ConstString opcode_key ("opcode"); 13645 static ConstString before_key ("before_state"); 13646 static ConstString after_key ("after_state"); 13647 13648 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13649 13650 uint32_t test_opcode; 13651 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13652 { 13653 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13654 return false; 13655 } 13656 test_opcode = value_sp->GetUInt64Value (); 13657 13658 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13659 { 13660 m_opcode_mode = eModeARM; 13661 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13662 } 13663 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13664 { 13665 m_opcode_mode = eModeThumb; 13666 if (test_opcode < 0x10000) 13667 m_opcode.SetOpcode16 (test_opcode, GetByteOrder()); 13668 else 13669 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13670 13671 } 13672 else 13673 { 13674 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13675 return false; 13676 } 13677 13678 EmulationStateARM before_state; 13679 EmulationStateARM after_state; 13680 13681 value_sp = test_data->GetValueForKey (before_key); 13682 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13683 { 13684 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13685 return false; 13686 } 13687 13688 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13689 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13690 { 13691 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13692 return false; 13693 } 13694 13695 value_sp = test_data->GetValueForKey (after_key); 13696 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13697 { 13698 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13699 return false; 13700 } 13701 13702 state_dictionary = value_sp->GetAsDictionary (); 13703 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13704 { 13705 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13706 return false; 13707 } 13708 13709 SetBaton ((void *) &before_state); 13710 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13711 &EmulationStateARM::WritePseudoMemory, 13712 &EmulationStateARM::ReadPseudoRegister, 13713 &EmulationStateARM::WritePseudoRegister); 13714 13715 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13716 if (!success) 13717 { 13718 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13719 return false; 13720 } 13721 13722 success = before_state.CompareState (after_state); 13723 if (!success) 13724 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13725 13726 return success; 13727 } 13728 // 13729 // 13730 //const char * 13731 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13732 //{ 13733 // if (reg_kind == eRegisterKindGeneric) 13734 // { 13735 // switch (reg_num) 13736 // { 13737 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 13738 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 13739 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 13740 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 13741 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13742 // default: return NULL; 13743 // } 13744 // } 13745 // else if (reg_kind == eRegisterKindDWARF) 13746 // { 13747 // return GetARMDWARFRegisterName (reg_num); 13748 // } 13749 // return NULL; 13750 //} 13751 // 13752 bool 13753 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13754 { 13755 unwind_plan.Clear(); 13756 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13757 13758 UnwindPlan::RowSP row(new UnwindPlan::Row); 13759 13760 // Our previous Call Frame Address is the stack pointer 13761 row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0); 13762 13763 unwind_plan.AppendRow (row); 13764 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13765 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 13766 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 13767 unwind_plan.SetReturnAddressRegister (dwarf_lr); 13768 return true; 13769 } 13770