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().isAndroid()) 294 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android 295 bool is_apple = false; 296 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 297 is_apple = true; 298 switch (m_arch.GetTriple().getOS()) 299 { 300 case llvm::Triple::Darwin: 301 case llvm::Triple::MacOSX: 302 case llvm::Triple::IOS: 303 case llvm::Triple::TvOS: 304 case llvm::Triple::WatchOS: 305 is_apple = true; 306 break; 307 default: 308 break; 309 } 310 311 /* On Apple iOS et al, the frame pointer register is always r7. 312 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 313 */ 314 315 uint32_t fp_regnum = 11; 316 317 if (is_apple) 318 fp_regnum = 7; 319 320 if (m_opcode_mode == eModeThumb) 321 fp_regnum = 7; 322 323 return fp_regnum; 324 } 325 326 uint32_t 327 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 328 { 329 bool is_apple = false; 330 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 331 is_apple = true; 332 switch (m_arch.GetTriple().getOS()) 333 { 334 case llvm::Triple::Darwin: 335 case llvm::Triple::MacOSX: 336 case llvm::Triple::IOS: 337 is_apple = true; 338 break; 339 default: 340 break; 341 } 342 343 /* On Apple iOS et al, the frame pointer register is always r7. 344 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 345 */ 346 347 uint32_t fp_regnum = dwarf_r11; 348 349 if (is_apple) 350 fp_regnum = dwarf_r7; 351 352 if (m_opcode_mode == eModeThumb) 353 fp_regnum = dwarf_r7; 354 355 return fp_regnum; 356 } 357 358 // Push Multiple Registers stores multiple registers to the stack, storing to 359 // consecutive memory locations ending just below the address in SP, and updates 360 // SP to point to the start of the stored data. 361 bool 362 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 363 { 364 #if 0 365 // ARM pseudo code... 366 if (ConditionPassed()) 367 { 368 EncodingSpecificOperations(); 369 NullCheckIfThumbEE(13); 370 address = SP - 4*BitCount(registers); 371 372 for (i = 0 to 14) 373 { 374 if (registers<i> == '1') 375 { 376 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 377 MemA[address,4] = bits(32) UNKNOWN; 378 else 379 MemA[address,4] = R[i]; 380 address = address + 4; 381 } 382 } 383 384 if (registers<15> == '1') // Only possible for encoding A1 or A2 385 MemA[address,4] = PCStoreValue(); 386 387 SP = SP - 4*BitCount(registers); 388 } 389 #endif 390 391 bool success = false; 392 if (ConditionPassed(opcode)) 393 { 394 const uint32_t addr_byte_size = GetAddressByteSize(); 395 const addr_t sp = ReadCoreReg (SP_REG, &success); 396 if (!success) 397 return false; 398 uint32_t registers = 0; 399 uint32_t Rt; // the source register 400 switch (encoding) { 401 case eEncodingT1: 402 registers = Bits32(opcode, 7, 0); 403 // The M bit represents LR. 404 if (Bit32(opcode, 8)) 405 registers |= (1u << 14); 406 // if BitCount(registers) < 1 then UNPREDICTABLE; 407 if (BitCount(registers) < 1) 408 return false; 409 break; 410 case eEncodingT2: 411 // Ignore bits 15 & 13. 412 registers = Bits32(opcode, 15, 0) & ~0xa000; 413 // if BitCount(registers) < 2 then UNPREDICTABLE; 414 if (BitCount(registers) < 2) 415 return false; 416 break; 417 case eEncodingT3: 418 Rt = Bits32(opcode, 15, 12); 419 // if BadReg(t) then UNPREDICTABLE; 420 if (BadReg(Rt)) 421 return false; 422 registers = (1u << Rt); 423 break; 424 case eEncodingA1: 425 registers = Bits32(opcode, 15, 0); 426 // Instead of return false, let's handle the following case as well, 427 // which amounts to pushing one reg onto the full descending stacks. 428 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 429 break; 430 case eEncodingA2: 431 Rt = Bits32(opcode, 15, 12); 432 // if t == 13 then UNPREDICTABLE; 433 if (Rt == dwarf_sp) 434 return false; 435 registers = (1u << Rt); 436 break; 437 default: 438 return false; 439 } 440 addr_t sp_offset = addr_byte_size * BitCount (registers); 441 addr_t addr = sp - sp_offset; 442 uint32_t i; 443 444 EmulateInstruction::Context context; 445 context.type = EmulateInstruction::eContextPushRegisterOnStack; 446 RegisterInfo reg_info; 447 RegisterInfo sp_reg; 448 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 449 for (i=0; i<15; ++i) 450 { 451 if (BitIsSet (registers, i)) 452 { 453 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 454 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 455 uint32_t reg_value = ReadCoreReg(i, &success); 456 if (!success) 457 return false; 458 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 459 return false; 460 addr += addr_byte_size; 461 } 462 } 463 464 if (BitIsSet (registers, 15)) 465 { 466 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 467 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 468 const uint32_t pc = ReadCoreReg(PC_REG, &success); 469 if (!success) 470 return false; 471 if (!MemAWrite (context, addr, pc, addr_byte_size)) 472 return false; 473 } 474 475 context.type = EmulateInstruction::eContextAdjustStackPointer; 476 context.SetImmediateSigned (-sp_offset); 477 478 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 479 return false; 480 } 481 return true; 482 } 483 484 // Pop Multiple Registers loads multiple registers from the stack, loading from 485 // consecutive memory locations staring at the address in SP, and updates 486 // SP to point just above the loaded data. 487 bool 488 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 489 { 490 #if 0 491 // ARM pseudo code... 492 if (ConditionPassed()) 493 { 494 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 495 address = SP; 496 for i = 0 to 14 497 if registers<i> == '1' then 498 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 499 if registers<15> == '1' then 500 if UnalignedAllowed then 501 LoadWritePC(MemU[address,4]); 502 else 503 LoadWritePC(MemA[address,4]); 504 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 505 if registers<13> == '1' then SP = bits(32) UNKNOWN; 506 } 507 #endif 508 509 bool success = false; 510 511 if (ConditionPassed(opcode)) 512 { 513 const uint32_t addr_byte_size = GetAddressByteSize(); 514 const addr_t sp = ReadCoreReg (SP_REG, &success); 515 if (!success) 516 return false; 517 uint32_t registers = 0; 518 uint32_t Rt; // the destination register 519 switch (encoding) { 520 case eEncodingT1: 521 registers = Bits32(opcode, 7, 0); 522 // The P bit represents PC. 523 if (Bit32(opcode, 8)) 524 registers |= (1u << 15); 525 // if BitCount(registers) < 1 then UNPREDICTABLE; 526 if (BitCount(registers) < 1) 527 return false; 528 break; 529 case eEncodingT2: 530 // Ignore bit 13. 531 registers = Bits32(opcode, 15, 0) & ~0x2000; 532 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 533 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 534 return false; 535 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 536 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 537 return false; 538 break; 539 case eEncodingT3: 540 Rt = Bits32(opcode, 15, 12); 541 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 542 if (Rt == 13) 543 return false; 544 if (Rt == 15 && InITBlock() && !LastInITBlock()) 545 return false; 546 registers = (1u << Rt); 547 break; 548 case eEncodingA1: 549 registers = Bits32(opcode, 15, 0); 550 // Instead of return false, let's handle the following case as well, 551 // which amounts to popping one reg from the full descending stacks. 552 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 553 554 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 555 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 556 return false; 557 break; 558 case eEncodingA2: 559 Rt = Bits32(opcode, 15, 12); 560 // if t == 13 then UNPREDICTABLE; 561 if (Rt == dwarf_sp) 562 return false; 563 registers = (1u << Rt); 564 break; 565 default: 566 return false; 567 } 568 addr_t sp_offset = addr_byte_size * BitCount (registers); 569 addr_t addr = sp; 570 uint32_t i, data; 571 572 EmulateInstruction::Context context; 573 context.type = EmulateInstruction::eContextPopRegisterOffStack; 574 575 RegisterInfo sp_reg; 576 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 577 578 for (i=0; i<15; ++i) 579 { 580 if (BitIsSet (registers, i)) 581 { 582 context.SetAddress(addr); 583 data = MemARead(context, addr, 4, 0, &success); 584 if (!success) 585 return false; 586 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 587 return false; 588 addr += addr_byte_size; 589 } 590 } 591 592 if (BitIsSet (registers, 15)) 593 { 594 context.SetRegisterPlusOffset (sp_reg, addr - sp); 595 data = MemARead(context, addr, 4, 0, &success); 596 if (!success) 597 return false; 598 // In ARMv5T and above, this is an interworking branch. 599 if (!LoadWritePC(context, data)) 600 return false; 601 //addr += addr_byte_size; 602 } 603 604 context.type = EmulateInstruction::eContextAdjustStackPointer; 605 context.SetImmediateSigned (sp_offset); 606 607 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 608 return false; 609 } 610 return true; 611 } 612 613 // Set r7 or ip to point to saved value residing within the stack. 614 // ADD (SP plus immediate) 615 bool 616 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 617 { 618 #if 0 619 // ARM pseudo code... 620 if (ConditionPassed()) 621 { 622 EncodingSpecificOperations(); 623 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 624 if d == 15 then 625 ALUWritePC(result); // setflags is always FALSE here 626 else 627 R[d] = result; 628 if setflags then 629 APSR.N = result<31>; 630 APSR.Z = IsZeroBit(result); 631 APSR.C = carry; 632 APSR.V = overflow; 633 } 634 #endif 635 636 bool success = false; 637 638 if (ConditionPassed(opcode)) 639 { 640 const addr_t sp = ReadCoreReg (SP_REG, &success); 641 if (!success) 642 return false; 643 uint32_t Rd; // the destination register 644 uint32_t imm32; 645 switch (encoding) { 646 case eEncodingT1: 647 Rd = 7; 648 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 649 break; 650 case eEncodingA1: 651 Rd = Bits32(opcode, 15, 12); 652 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 653 break; 654 default: 655 return false; 656 } 657 addr_t sp_offset = imm32; 658 addr_t addr = sp + sp_offset; // a pointer to the stack area 659 660 EmulateInstruction::Context context; 661 if (Rd == GetFramePointerRegisterNumber()) 662 context.type = eContextSetFramePointer; 663 else 664 context.type = EmulateInstruction::eContextRegisterPlusOffset; 665 RegisterInfo sp_reg; 666 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 667 context.SetRegisterPlusOffset (sp_reg, sp_offset); 668 669 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 670 return false; 671 } 672 return true; 673 } 674 675 // Set r7 or ip to the current stack pointer. 676 // MOV (register) 677 bool 678 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 679 { 680 #if 0 681 // ARM pseudo code... 682 if (ConditionPassed()) 683 { 684 EncodingSpecificOperations(); 685 result = R[m]; 686 if d == 15 then 687 ALUWritePC(result); // setflags is always FALSE here 688 else 689 R[d] = result; 690 if setflags then 691 APSR.N = result<31>; 692 APSR.Z = IsZeroBit(result); 693 // APSR.C unchanged 694 // APSR.V unchanged 695 } 696 #endif 697 698 bool success = false; 699 700 if (ConditionPassed(opcode)) 701 { 702 const addr_t sp = ReadCoreReg (SP_REG, &success); 703 if (!success) 704 return false; 705 uint32_t Rd; // the destination register 706 switch (encoding) { 707 case eEncodingT1: 708 Rd = 7; 709 break; 710 case eEncodingA1: 711 Rd = 12; 712 break; 713 default: 714 return false; 715 } 716 717 EmulateInstruction::Context context; 718 if (Rd == GetFramePointerRegisterNumber()) 719 context.type = EmulateInstruction::eContextSetFramePointer; 720 else 721 context.type = EmulateInstruction::eContextRegisterPlusOffset; 722 RegisterInfo sp_reg; 723 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 724 context.SetRegisterPlusOffset (sp_reg, 0); 725 726 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 727 return false; 728 } 729 return true; 730 } 731 732 // Move from high register (r8-r15) to low register (r0-r7). 733 // MOV (register) 734 bool 735 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 736 { 737 return EmulateMOVRdRm (opcode, encoding); 738 } 739 740 // Move from register to register. 741 // MOV (register) 742 bool 743 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 744 { 745 #if 0 746 // ARM pseudo code... 747 if (ConditionPassed()) 748 { 749 EncodingSpecificOperations(); 750 result = R[m]; 751 if d == 15 then 752 ALUWritePC(result); // setflags is always FALSE here 753 else 754 R[d] = result; 755 if setflags then 756 APSR.N = result<31>; 757 APSR.Z = IsZeroBit(result); 758 // APSR.C unchanged 759 // APSR.V unchanged 760 } 761 #endif 762 763 bool success = false; 764 765 if (ConditionPassed(opcode)) 766 { 767 uint32_t Rm; // the source register 768 uint32_t Rd; // the destination register 769 bool setflags; 770 switch (encoding) { 771 case eEncodingT1: 772 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 773 Rm = Bits32(opcode, 6, 3); 774 setflags = false; 775 if (Rd == 15 && InITBlock() && !LastInITBlock()) 776 return false; 777 break; 778 case eEncodingT2: 779 Rd = Bits32(opcode, 2, 0); 780 Rm = Bits32(opcode, 5, 3); 781 setflags = true; 782 if (InITBlock()) 783 return false; 784 break; 785 case eEncodingT3: 786 Rd = Bits32(opcode, 11, 8); 787 Rm = Bits32(opcode, 3, 0); 788 setflags = BitIsSet(opcode, 20); 789 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 790 if (setflags && (BadReg(Rd) || BadReg(Rm))) 791 return false; 792 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 793 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 794 return false; 795 break; 796 case eEncodingA1: 797 Rd = Bits32(opcode, 15, 12); 798 Rm = Bits32(opcode, 3, 0); 799 setflags = BitIsSet(opcode, 20); 800 801 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 802 if (Rd == 15 && setflags) 803 return EmulateSUBSPcLrEtc (opcode, encoding); 804 break; 805 default: 806 return false; 807 } 808 uint32_t result = ReadCoreReg(Rm, &success); 809 if (!success) 810 return false; 811 812 // The context specifies that Rm is to be moved into Rd. 813 EmulateInstruction::Context context; 814 if (Rd == 13) 815 context.type = EmulateInstruction::eContextAdjustStackPointer; 816 else 817 context.type = EmulateInstruction::eContextRegisterPlusOffset; 818 RegisterInfo dwarf_reg; 819 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 820 context.SetRegisterPlusOffset (dwarf_reg, 0); 821 822 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 823 return false; 824 } 825 return true; 826 } 827 828 // Move (immediate) writes an immediate value to the destination register. It 829 // can optionally update the condition flags based on the value. 830 // MOV (immediate) 831 bool 832 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 833 { 834 #if 0 835 // ARM pseudo code... 836 if (ConditionPassed()) 837 { 838 EncodingSpecificOperations(); 839 result = imm32; 840 if d == 15 then // Can only occur for ARM encoding 841 ALUWritePC(result); // setflags is always FALSE here 842 else 843 R[d] = result; 844 if setflags then 845 APSR.N = result<31>; 846 APSR.Z = IsZeroBit(result); 847 APSR.C = carry; 848 // APSR.V unchanged 849 } 850 #endif 851 852 if (ConditionPassed(opcode)) 853 { 854 uint32_t Rd; // the destination register 855 uint32_t imm32; // the immediate value to be written to Rd 856 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 857 // for setflags == false, this value is a don't care 858 // initialized to 0 to silence the static analyzer 859 bool setflags; 860 switch (encoding) { 861 case eEncodingT1: 862 Rd = Bits32(opcode, 10, 8); 863 setflags = !InITBlock(); 864 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 865 carry = APSR_C; 866 867 break; 868 869 case eEncodingT2: 870 Rd = Bits32(opcode, 11, 8); 871 setflags = BitIsSet(opcode, 20); 872 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 873 if (BadReg(Rd)) 874 return false; 875 876 break; 877 878 case eEncodingT3: 879 { 880 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 881 Rd = Bits32 (opcode, 11, 8); 882 setflags = false; 883 uint32_t imm4 = Bits32 (opcode, 19, 16); 884 uint32_t imm3 = Bits32 (opcode, 14, 12); 885 uint32_t i = Bit32 (opcode, 26); 886 uint32_t imm8 = Bits32 (opcode, 7, 0); 887 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 888 889 // if BadReg(d) then UNPREDICTABLE; 890 if (BadReg (Rd)) 891 return false; 892 } 893 break; 894 895 case eEncodingA1: 896 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 897 Rd = Bits32 (opcode, 15, 12); 898 setflags = BitIsSet (opcode, 20); 899 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 900 901 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 902 if ((Rd == 15) && setflags) 903 return EmulateSUBSPcLrEtc (opcode, encoding); 904 905 break; 906 907 case eEncodingA2: 908 { 909 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 910 Rd = Bits32 (opcode, 15, 12); 911 setflags = false; 912 uint32_t imm4 = Bits32 (opcode, 19, 16); 913 uint32_t imm12 = Bits32 (opcode, 11, 0); 914 imm32 = (imm4 << 12) | imm12; 915 916 // if d == 15 then UNPREDICTABLE; 917 if (Rd == 15) 918 return false; 919 } 920 break; 921 922 default: 923 return false; 924 } 925 uint32_t result = imm32; 926 927 // The context specifies that an immediate is to be moved into Rd. 928 EmulateInstruction::Context context; 929 context.type = EmulateInstruction::eContextImmediate; 930 context.SetNoArgs (); 931 932 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 933 return false; 934 } 935 return true; 936 } 937 938 // MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 939 // register. These 32 bits do not depend on whether the source register values are considered to be signed values or 940 // unsigned values. 941 // 942 // Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 943 // limited to only a few forms of the instruction. 944 bool 945 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 946 { 947 #if 0 948 if ConditionPassed() then 949 EncodingSpecificOperations(); 950 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 951 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 952 result = operand1 * operand2; 953 R[d] = result<31:0>; 954 if setflags then 955 APSR.N = result<31>; 956 APSR.Z = IsZeroBit(result); 957 if ArchVersion() == 4 then 958 APSR.C = bit UNKNOWN; 959 // else APSR.C unchanged 960 // APSR.V always unchanged 961 #endif 962 963 if (ConditionPassed(opcode)) 964 { 965 uint32_t d; 966 uint32_t n; 967 uint32_t m; 968 bool setflags; 969 970 // EncodingSpecificOperations(); 971 switch (encoding) 972 { 973 case eEncodingT1: 974 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 975 d = Bits32 (opcode, 2, 0); 976 n = Bits32 (opcode, 5, 3); 977 m = Bits32 (opcode, 2, 0); 978 setflags = !InITBlock(); 979 980 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 981 if ((ArchVersion() < ARMv6) && (d == n)) 982 return false; 983 984 break; 985 986 case eEncodingT2: 987 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 988 d = Bits32 (opcode, 11, 8); 989 n = Bits32 (opcode, 19, 16); 990 m = Bits32 (opcode, 3, 0); 991 setflags = false; 992 993 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 994 if (BadReg (d) || BadReg (n) || BadReg (m)) 995 return false; 996 997 break; 998 999 case eEncodingA1: 1000 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 1001 d = Bits32 (opcode, 19, 16); 1002 n = Bits32 (opcode, 3, 0); 1003 m = Bits32 (opcode, 11, 8); 1004 setflags = BitIsSet (opcode, 20); 1005 1006 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1007 if ((d == 15) || (n == 15) || (m == 15)) 1008 return false; 1009 1010 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1011 if ((ArchVersion() < ARMv6) && (d == n)) 1012 return false; 1013 1014 break; 1015 1016 default: 1017 return false; 1018 } 1019 1020 bool success = false; 1021 1022 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1023 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1024 if (!success) 1025 return false; 1026 1027 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1028 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1029 if (!success) 1030 return false; 1031 1032 // result = operand1 * operand2; 1033 uint64_t result = operand1 * operand2; 1034 1035 // R[d] = result<31:0>; 1036 RegisterInfo op1_reg; 1037 RegisterInfo op2_reg; 1038 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1039 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1040 1041 EmulateInstruction::Context context; 1042 context.type = eContextArithmetic; 1043 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 1044 1045 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 1046 return false; 1047 1048 // if setflags then 1049 if (setflags) 1050 { 1051 // APSR.N = result<31>; 1052 // APSR.Z = IsZeroBit(result); 1053 m_new_inst_cpsr = m_opcode_cpsr; 1054 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 1055 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1056 if (m_new_inst_cpsr != m_opcode_cpsr) 1057 { 1058 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1059 return false; 1060 } 1061 1062 // if ArchVersion() == 4 then 1063 // APSR.C = bit UNKNOWN; 1064 } 1065 } 1066 return true; 1067 } 1068 1069 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1070 // It can optionally update the condition flags based on the value. 1071 bool 1072 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1073 { 1074 #if 0 1075 // ARM pseudo code... 1076 if (ConditionPassed()) 1077 { 1078 EncodingSpecificOperations(); 1079 result = NOT(imm32); 1080 if d == 15 then // Can only occur for ARM encoding 1081 ALUWritePC(result); // setflags is always FALSE here 1082 else 1083 R[d] = result; 1084 if setflags then 1085 APSR.N = result<31>; 1086 APSR.Z = IsZeroBit(result); 1087 APSR.C = carry; 1088 // APSR.V unchanged 1089 } 1090 #endif 1091 1092 if (ConditionPassed(opcode)) 1093 { 1094 uint32_t Rd; // the destination register 1095 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1096 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1097 bool setflags; 1098 switch (encoding) { 1099 case eEncodingT1: 1100 Rd = Bits32(opcode, 11, 8); 1101 setflags = BitIsSet(opcode, 20); 1102 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1103 break; 1104 case eEncodingA1: 1105 Rd = Bits32(opcode, 15, 12); 1106 setflags = BitIsSet(opcode, 20); 1107 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1108 1109 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1110 if (Rd == 15 && setflags) 1111 return EmulateSUBSPcLrEtc (opcode, encoding); 1112 break; 1113 default: 1114 return false; 1115 } 1116 uint32_t result = ~imm32; 1117 1118 // The context specifies that an immediate is to be moved into Rd. 1119 EmulateInstruction::Context context; 1120 context.type = EmulateInstruction::eContextImmediate; 1121 context.SetNoArgs (); 1122 1123 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1124 return false; 1125 } 1126 return true; 1127 } 1128 1129 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1130 // It can optionally update the condition flags based on the result. 1131 bool 1132 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1133 { 1134 #if 0 1135 // ARM pseudo code... 1136 if (ConditionPassed()) 1137 { 1138 EncodingSpecificOperations(); 1139 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1140 result = NOT(shifted); 1141 if d == 15 then // Can only occur for ARM encoding 1142 ALUWritePC(result); // setflags is always FALSE here 1143 else 1144 R[d] = result; 1145 if setflags then 1146 APSR.N = result<31>; 1147 APSR.Z = IsZeroBit(result); 1148 APSR.C = carry; 1149 // APSR.V unchanged 1150 } 1151 #endif 1152 1153 if (ConditionPassed(opcode)) 1154 { 1155 uint32_t Rm; // the source register 1156 uint32_t Rd; // the destination register 1157 ARM_ShifterType shift_t; 1158 uint32_t shift_n; // the shift applied to the value read from Rm 1159 bool setflags; 1160 uint32_t carry; // the carry bit after the shift operation 1161 switch (encoding) { 1162 case eEncodingT1: 1163 Rd = Bits32(opcode, 2, 0); 1164 Rm = Bits32(opcode, 5, 3); 1165 setflags = !InITBlock(); 1166 shift_t = SRType_LSL; 1167 shift_n = 0; 1168 if (InITBlock()) 1169 return false; 1170 break; 1171 case eEncodingT2: 1172 Rd = Bits32(opcode, 11, 8); 1173 Rm = Bits32(opcode, 3, 0); 1174 setflags = BitIsSet(opcode, 20); 1175 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1176 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1177 if (BadReg(Rd) || BadReg(Rm)) 1178 return false; 1179 break; 1180 case eEncodingA1: 1181 Rd = Bits32(opcode, 15, 12); 1182 Rm = Bits32(opcode, 3, 0); 1183 setflags = BitIsSet(opcode, 20); 1184 shift_n = DecodeImmShiftARM(opcode, shift_t); 1185 break; 1186 default: 1187 return false; 1188 } 1189 bool success = false; 1190 uint32_t value = ReadCoreReg(Rm, &success); 1191 if (!success) 1192 return false; 1193 1194 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1195 if (!success) 1196 return false; 1197 uint32_t result = ~shifted; 1198 1199 // The context specifies that an immediate is to be moved into Rd. 1200 EmulateInstruction::Context context; 1201 context.type = EmulateInstruction::eContextImmediate; 1202 context.SetNoArgs (); 1203 1204 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1205 return false; 1206 } 1207 return true; 1208 } 1209 1210 // PC relative immediate load into register, possibly followed by ADD (SP plus register). 1211 // LDR (literal) 1212 bool 1213 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1214 { 1215 #if 0 1216 // ARM pseudo code... 1217 if (ConditionPassed()) 1218 { 1219 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1220 base = Align(PC,4); 1221 address = if add then (base + imm32) else (base - imm32); 1222 data = MemU[address,4]; 1223 if t == 15 then 1224 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1225 elsif UnalignedSupport() || address<1:0> = '00' then 1226 R[t] = data; 1227 else // Can only apply before ARMv7 1228 if CurrentInstrSet() == InstrSet_ARM then 1229 R[t] = ROR(data, 8*UInt(address<1:0>)); 1230 else 1231 R[t] = bits(32) UNKNOWN; 1232 } 1233 #endif 1234 1235 if (ConditionPassed(opcode)) 1236 { 1237 bool success = false; 1238 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1239 if (!success) 1240 return false; 1241 1242 // PC relative immediate load context 1243 EmulateInstruction::Context context; 1244 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1245 RegisterInfo pc_reg; 1246 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1247 context.SetRegisterPlusOffset (pc_reg, 0); 1248 1249 uint32_t Rt; // the destination register 1250 uint32_t imm32; // immediate offset from the PC 1251 bool add; // +imm32 or -imm32? 1252 addr_t base; // the base address 1253 addr_t address; // the PC relative address 1254 uint32_t data; // the literal data value from the PC relative load 1255 switch (encoding) { 1256 case eEncodingT1: 1257 Rt = Bits32(opcode, 10, 8); 1258 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1259 add = true; 1260 break; 1261 case eEncodingT2: 1262 Rt = Bits32(opcode, 15, 12); 1263 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1264 add = BitIsSet(opcode, 23); 1265 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1266 return false; 1267 break; 1268 default: 1269 return false; 1270 } 1271 1272 base = Align(pc, 4); 1273 if (add) 1274 address = base + imm32; 1275 else 1276 address = base - imm32; 1277 1278 context.SetRegisterPlusOffset(pc_reg, address - base); 1279 data = MemURead(context, address, 4, 0, &success); 1280 if (!success) 1281 return false; 1282 1283 if (Rt == 15) 1284 { 1285 if (Bits32(address, 1, 0) == 0) 1286 { 1287 // In ARMv5T and above, this is an interworking branch. 1288 if (!LoadWritePC(context, data)) 1289 return false; 1290 } 1291 else 1292 return false; 1293 } 1294 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1295 { 1296 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1297 return false; 1298 } 1299 else // We don't handle ARM for now. 1300 return false; 1301 1302 } 1303 return true; 1304 } 1305 1306 // An add operation to adjust the SP. 1307 // ADD (SP plus immediate) 1308 bool 1309 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1310 { 1311 #if 0 1312 // ARM pseudo code... 1313 if (ConditionPassed()) 1314 { 1315 EncodingSpecificOperations(); 1316 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1317 if d == 15 then // Can only occur for ARM encoding 1318 ALUWritePC(result); // setflags is always FALSE here 1319 else 1320 R[d] = result; 1321 if setflags then 1322 APSR.N = result<31>; 1323 APSR.Z = IsZeroBit(result); 1324 APSR.C = carry; 1325 APSR.V = overflow; 1326 } 1327 #endif 1328 1329 bool success = false; 1330 1331 if (ConditionPassed(opcode)) 1332 { 1333 const addr_t sp = ReadCoreReg (SP_REG, &success); 1334 if (!success) 1335 return false; 1336 uint32_t imm32; // the immediate operand 1337 uint32_t d; 1338 bool setflags; 1339 switch (encoding) 1340 { 1341 case eEncodingT1: 1342 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1343 d = Bits32 (opcode, 10, 8); 1344 imm32 = (Bits32 (opcode, 7, 0) << 2); 1345 setflags = false; 1346 break; 1347 1348 case eEncodingT2: 1349 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1350 d = 13; 1351 imm32 = ThumbImm7Scaled (opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1352 setflags = false; 1353 break; 1354 1355 case eEncodingT3: 1356 // d = UInt(Rd); setflags = (S == "1"); imm32 = ThumbExpandImm(i:imm3:imm8); 1357 d = Bits32 (opcode, 11, 8); 1358 imm32 = ThumbExpandImm (opcode); 1359 setflags = Bit32 (opcode, 20); 1360 1361 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 1362 if (d == 15 && setflags == 1) 1363 return false; // CMN (immediate) not yet supported 1364 1365 // if d == 15 && S == "0" then UNPREDICTABLE; 1366 if (d == 15 && setflags == 0) 1367 return false; 1368 break; 1369 1370 case eEncodingT4: 1371 { 1372 // if Rn == '1111' then SEE ADR; 1373 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 1374 d = Bits32 (opcode, 11, 8); 1375 setflags = false; 1376 uint32_t i = Bit32 (opcode, 26); 1377 uint32_t imm3 = Bits32 (opcode, 14, 12); 1378 uint32_t imm8 = Bits32 (opcode, 7, 0); 1379 imm32 = (i << 11) | (imm3 << 8) | imm8; 1380 1381 // if d == 15 then UNPREDICTABLE; 1382 if (d == 15) 1383 return false; 1384 } 1385 break; 1386 1387 default: 1388 return false; 1389 } 1390 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 1391 AddWithCarryResult res = AddWithCarry (sp, imm32, 0); 1392 1393 EmulateInstruction::Context context; 1394 if (d == 13) 1395 context.type = EmulateInstruction::eContextAdjustStackPointer; 1396 else 1397 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1398 1399 RegisterInfo sp_reg; 1400 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1401 context.SetRegisterPlusOffset (sp_reg, res.result - sp); 1402 1403 if (d == 15) 1404 { 1405 if (!ALUWritePC (context, res.result)) 1406 return false; 1407 } 1408 else 1409 { 1410 // R[d] = result; 1411 // if setflags then 1412 // APSR.N = result<31>; 1413 // APSR.Z = IsZeroBit(result); 1414 // APSR.C = carry; 1415 // APSR.V = overflow; 1416 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 1417 return false; 1418 } 1419 } 1420 return true; 1421 } 1422 1423 // An add operation to adjust the SP. 1424 // ADD (SP plus register) 1425 bool 1426 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1427 { 1428 #if 0 1429 // ARM pseudo code... 1430 if (ConditionPassed()) 1431 { 1432 EncodingSpecificOperations(); 1433 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1434 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1435 if d == 15 then 1436 ALUWritePC(result); // setflags is always FALSE here 1437 else 1438 R[d] = result; 1439 if setflags then 1440 APSR.N = result<31>; 1441 APSR.Z = IsZeroBit(result); 1442 APSR.C = carry; 1443 APSR.V = overflow; 1444 } 1445 #endif 1446 1447 bool success = false; 1448 1449 if (ConditionPassed(opcode)) 1450 { 1451 const addr_t sp = ReadCoreReg (SP_REG, &success); 1452 if (!success) 1453 return false; 1454 uint32_t Rm; // the second operand 1455 switch (encoding) { 1456 case eEncodingT2: 1457 Rm = Bits32(opcode, 6, 3); 1458 break; 1459 default: 1460 return false; 1461 } 1462 int32_t reg_value = ReadCoreReg(Rm, &success); 1463 if (!success) 1464 return false; 1465 1466 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1467 1468 EmulateInstruction::Context context; 1469 context.type = eContextArithmetic; 1470 RegisterInfo sp_reg; 1471 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1472 1473 RegisterInfo other_reg; 1474 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1475 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1476 1477 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1478 return false; 1479 } 1480 return true; 1481 } 1482 1483 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1484 // at a PC-relative address, and changes instruction set from ARM to Thumb, or 1485 // from Thumb to ARM. 1486 // BLX (immediate) 1487 bool 1488 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1489 { 1490 #if 0 1491 // ARM pseudo code... 1492 if (ConditionPassed()) 1493 { 1494 EncodingSpecificOperations(); 1495 if CurrentInstrSet() == InstrSet_ARM then 1496 LR = PC - 4; 1497 else 1498 LR = PC<31:1> : '1'; 1499 if targetInstrSet == InstrSet_ARM then 1500 targetAddress = Align(PC,4) + imm32; 1501 else 1502 targetAddress = PC + imm32; 1503 SelectInstrSet(targetInstrSet); 1504 BranchWritePC(targetAddress); 1505 } 1506 #endif 1507 1508 bool success = true; 1509 1510 if (ConditionPassed(opcode)) 1511 { 1512 EmulateInstruction::Context context; 1513 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1514 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1515 if (!success) 1516 return false; 1517 addr_t lr; // next instruction address 1518 addr_t target; // target address 1519 int32_t imm32; // PC-relative offset 1520 switch (encoding) { 1521 case eEncodingT1: 1522 { 1523 lr = pc | 1u; // return address 1524 uint32_t S = Bit32(opcode, 26); 1525 uint32_t imm10 = Bits32(opcode, 25, 16); 1526 uint32_t J1 = Bit32(opcode, 13); 1527 uint32_t J2 = Bit32(opcode, 11); 1528 uint32_t imm11 = Bits32(opcode, 10, 0); 1529 uint32_t I1 = !(J1 ^ S); 1530 uint32_t I2 = !(J2 ^ S); 1531 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1532 imm32 = llvm::SignExtend32<25>(imm25); 1533 target = pc + imm32; 1534 SelectInstrSet (eModeThumb); 1535 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1536 if (InITBlock() && !LastInITBlock()) 1537 return false; 1538 break; 1539 } 1540 case eEncodingT2: 1541 { 1542 lr = pc | 1u; // return address 1543 uint32_t S = Bit32(opcode, 26); 1544 uint32_t imm10H = Bits32(opcode, 25, 16); 1545 uint32_t J1 = Bit32(opcode, 13); 1546 uint32_t J2 = Bit32(opcode, 11); 1547 uint32_t imm10L = Bits32(opcode, 10, 1); 1548 uint32_t I1 = !(J1 ^ S); 1549 uint32_t I2 = !(J2 ^ S); 1550 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1551 imm32 = llvm::SignExtend32<25>(imm25); 1552 target = Align(pc, 4) + imm32; 1553 SelectInstrSet (eModeARM); 1554 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1555 if (InITBlock() && !LastInITBlock()) 1556 return false; 1557 break; 1558 } 1559 case eEncodingA1: 1560 lr = pc - 4; // return address 1561 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1562 target = Align(pc, 4) + imm32; 1563 SelectInstrSet (eModeARM); 1564 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1565 break; 1566 case eEncodingA2: 1567 lr = pc - 4; // return address 1568 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1569 target = pc + imm32; 1570 SelectInstrSet (eModeThumb); 1571 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1572 break; 1573 default: 1574 return false; 1575 } 1576 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1577 return false; 1578 if (!BranchWritePC(context, target)) 1579 return false; 1580 if (m_opcode_cpsr != m_new_inst_cpsr) 1581 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1582 return false; 1583 } 1584 return true; 1585 } 1586 1587 // Branch with Link and Exchange (register) calls a subroutine at an address and 1588 // instruction set specified by a register. 1589 // BLX (register) 1590 bool 1591 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1592 { 1593 #if 0 1594 // ARM pseudo code... 1595 if (ConditionPassed()) 1596 { 1597 EncodingSpecificOperations(); 1598 target = R[m]; 1599 if CurrentInstrSet() == InstrSet_ARM then 1600 next_instr_addr = PC - 4; 1601 LR = next_instr_addr; 1602 else 1603 next_instr_addr = PC - 2; 1604 LR = next_instr_addr<31:1> : '1'; 1605 BXWritePC(target); 1606 } 1607 #endif 1608 1609 bool success = false; 1610 1611 if (ConditionPassed(opcode)) 1612 { 1613 EmulateInstruction::Context context; 1614 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1615 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1616 addr_t lr; // next instruction address 1617 if (!success) 1618 return false; 1619 uint32_t Rm; // the register with the target address 1620 switch (encoding) { 1621 case eEncodingT1: 1622 lr = (pc - 2) | 1u; // return address 1623 Rm = Bits32(opcode, 6, 3); 1624 // if m == 15 then UNPREDICTABLE; 1625 if (Rm == 15) 1626 return false; 1627 if (InITBlock() && !LastInITBlock()) 1628 return false; 1629 break; 1630 case eEncodingA1: 1631 lr = pc - 4; // return address 1632 Rm = Bits32(opcode, 3, 0); 1633 // if m == 15 then UNPREDICTABLE; 1634 if (Rm == 15) 1635 return false; 1636 break; 1637 default: 1638 return false; 1639 } 1640 addr_t target = ReadCoreReg (Rm, &success); 1641 if (!success) 1642 return false; 1643 RegisterInfo dwarf_reg; 1644 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1645 context.SetRegister (dwarf_reg); 1646 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1647 return false; 1648 if (!BXWritePC(context, target)) 1649 return false; 1650 } 1651 return true; 1652 } 1653 1654 // Branch and Exchange causes a branch to an address and instruction set specified by a register. 1655 bool 1656 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1657 { 1658 #if 0 1659 // ARM pseudo code... 1660 if (ConditionPassed()) 1661 { 1662 EncodingSpecificOperations(); 1663 BXWritePC(R[m]); 1664 } 1665 #endif 1666 1667 if (ConditionPassed(opcode)) 1668 { 1669 EmulateInstruction::Context context; 1670 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1671 uint32_t Rm; // the register with the target address 1672 switch (encoding) { 1673 case eEncodingT1: 1674 Rm = Bits32(opcode, 6, 3); 1675 if (InITBlock() && !LastInITBlock()) 1676 return false; 1677 break; 1678 case eEncodingA1: 1679 Rm = Bits32(opcode, 3, 0); 1680 break; 1681 default: 1682 return false; 1683 } 1684 bool success = false; 1685 addr_t target = ReadCoreReg (Rm, &success); 1686 if (!success) 1687 return false; 1688 1689 RegisterInfo dwarf_reg; 1690 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1691 context.SetRegister (dwarf_reg); 1692 if (!BXWritePC(context, target)) 1693 return false; 1694 } 1695 return true; 1696 } 1697 1698 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1699 // address and instruction set specified by a register as though it were a BX instruction. 1700 // 1701 // TODO: Emulate Jazelle architecture? 1702 // We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1703 bool 1704 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1705 { 1706 #if 0 1707 // ARM pseudo code... 1708 if (ConditionPassed()) 1709 { 1710 EncodingSpecificOperations(); 1711 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1712 BXWritePC(R[m]); 1713 else 1714 if JazelleAcceptsExecution() then 1715 SwitchToJazelleExecution(); 1716 else 1717 SUBARCHITECTURE_DEFINED handler call; 1718 } 1719 #endif 1720 1721 if (ConditionPassed(opcode)) 1722 { 1723 EmulateInstruction::Context context; 1724 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1725 uint32_t Rm; // the register with the target address 1726 switch (encoding) { 1727 case eEncodingT1: 1728 Rm = Bits32(opcode, 19, 16); 1729 if (BadReg(Rm)) 1730 return false; 1731 if (InITBlock() && !LastInITBlock()) 1732 return false; 1733 break; 1734 case eEncodingA1: 1735 Rm = Bits32(opcode, 3, 0); 1736 if (Rm == 15) 1737 return false; 1738 break; 1739 default: 1740 return false; 1741 } 1742 bool success = false; 1743 addr_t target = ReadCoreReg (Rm, &success); 1744 if (!success) 1745 return false; 1746 1747 RegisterInfo dwarf_reg; 1748 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1749 context.SetRegister (dwarf_reg); 1750 if (!BXWritePC(context, target)) 1751 return false; 1752 } 1753 return true; 1754 } 1755 1756 // Set r7 to point to some ip offset. 1757 // SUB (immediate) 1758 bool 1759 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1760 { 1761 #if 0 1762 // ARM pseudo code... 1763 if (ConditionPassed()) 1764 { 1765 EncodingSpecificOperations(); 1766 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1767 if d == 15 then // Can only occur for ARM encoding 1768 ALUWritePC(result); // setflags is always FALSE here 1769 else 1770 R[d] = result; 1771 if setflags then 1772 APSR.N = result<31>; 1773 APSR.Z = IsZeroBit(result); 1774 APSR.C = carry; 1775 APSR.V = overflow; 1776 } 1777 #endif 1778 1779 if (ConditionPassed(opcode)) 1780 { 1781 bool success = false; 1782 const addr_t ip = ReadCoreReg (12, &success); 1783 if (!success) 1784 return false; 1785 uint32_t imm32; 1786 switch (encoding) { 1787 case eEncodingA1: 1788 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1789 break; 1790 default: 1791 return false; 1792 } 1793 addr_t ip_offset = imm32; 1794 addr_t addr = ip - ip_offset; // the adjusted ip value 1795 1796 EmulateInstruction::Context context; 1797 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1798 RegisterInfo dwarf_reg; 1799 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1800 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1801 1802 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1803 return false; 1804 } 1805 return true; 1806 } 1807 1808 // Set ip to point to some stack offset. 1809 // SUB (SP minus immediate) 1810 bool 1811 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1812 { 1813 #if 0 1814 // ARM pseudo code... 1815 if (ConditionPassed()) 1816 { 1817 EncodingSpecificOperations(); 1818 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1819 if d == 15 then // Can only occur for ARM encoding 1820 ALUWritePC(result); // setflags is always FALSE here 1821 else 1822 R[d] = result; 1823 if setflags then 1824 APSR.N = result<31>; 1825 APSR.Z = IsZeroBit(result); 1826 APSR.C = carry; 1827 APSR.V = overflow; 1828 } 1829 #endif 1830 1831 if (ConditionPassed(opcode)) 1832 { 1833 bool success = false; 1834 const addr_t sp = ReadCoreReg (SP_REG, &success); 1835 if (!success) 1836 return false; 1837 uint32_t imm32; 1838 switch (encoding) { 1839 case eEncodingA1: 1840 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1841 break; 1842 default: 1843 return false; 1844 } 1845 addr_t sp_offset = imm32; 1846 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1847 1848 EmulateInstruction::Context context; 1849 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1850 RegisterInfo dwarf_reg; 1851 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1852 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1853 1854 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1855 return false; 1856 } 1857 return true; 1858 } 1859 1860 // This instruction subtracts an immediate value from the SP value, and writes 1861 // the result to the destination register. 1862 // 1863 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1864 bool 1865 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1866 { 1867 #if 0 1868 // ARM pseudo code... 1869 if (ConditionPassed()) 1870 { 1871 EncodingSpecificOperations(); 1872 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1873 if d == 15 then // Can only occur for ARM encoding 1874 ALUWritePC(result); // setflags is always FALSE here 1875 else 1876 R[d] = result; 1877 if setflags then 1878 APSR.N = result<31>; 1879 APSR.Z = IsZeroBit(result); 1880 APSR.C = carry; 1881 APSR.V = overflow; 1882 } 1883 #endif 1884 1885 bool success = false; 1886 if (ConditionPassed(opcode)) 1887 { 1888 const addr_t sp = ReadCoreReg (SP_REG, &success); 1889 if (!success) 1890 return false; 1891 1892 uint32_t Rd; 1893 bool setflags; 1894 uint32_t imm32; 1895 switch (encoding) { 1896 case eEncodingT1: 1897 Rd = 13; 1898 setflags = false; 1899 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1900 break; 1901 case eEncodingT2: 1902 Rd = Bits32(opcode, 11, 8); 1903 setflags = BitIsSet(opcode, 20); 1904 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1905 if (Rd == 15 && setflags) 1906 return EmulateCMPImm(opcode, eEncodingT2); 1907 if (Rd == 15 && !setflags) 1908 return false; 1909 break; 1910 case eEncodingT3: 1911 Rd = Bits32(opcode, 11, 8); 1912 setflags = false; 1913 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1914 if (Rd == 15) 1915 return false; 1916 break; 1917 case eEncodingA1: 1918 Rd = Bits32(opcode, 15, 12); 1919 setflags = BitIsSet(opcode, 20); 1920 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1921 1922 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1923 if (Rd == 15 && setflags) 1924 return EmulateSUBSPcLrEtc (opcode, encoding); 1925 break; 1926 default: 1927 return false; 1928 } 1929 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1930 1931 EmulateInstruction::Context context; 1932 if (Rd == 13) 1933 { 1934 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1935 // value gets passed down to context.SetImmediateSigned. 1936 context.type = EmulateInstruction::eContextAdjustStackPointer; 1937 context.SetImmediateSigned (-imm64); // the stack pointer offset 1938 } 1939 else 1940 { 1941 context.type = EmulateInstruction::eContextImmediate; 1942 context.SetNoArgs (); 1943 } 1944 1945 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1946 return false; 1947 } 1948 return true; 1949 } 1950 1951 // A store operation to the stack that also updates the SP. 1952 bool 1953 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1954 { 1955 #if 0 1956 // ARM pseudo code... 1957 if (ConditionPassed()) 1958 { 1959 EncodingSpecificOperations(); 1960 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1961 address = if index then offset_addr else R[n]; 1962 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1963 if wback then R[n] = offset_addr; 1964 } 1965 #endif 1966 1967 bool success = false; 1968 if (ConditionPassed(opcode)) 1969 { 1970 const uint32_t addr_byte_size = GetAddressByteSize(); 1971 const addr_t sp = ReadCoreReg (SP_REG, &success); 1972 if (!success) 1973 return false; 1974 uint32_t Rt; // the source register 1975 uint32_t imm12; 1976 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1977 1978 bool index; 1979 bool add; 1980 bool wback; 1981 switch (encoding) { 1982 case eEncodingA1: 1983 Rt = Bits32(opcode, 15, 12); 1984 imm12 = Bits32(opcode, 11, 0); 1985 Rn = Bits32 (opcode, 19, 16); 1986 1987 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1988 return false; 1989 1990 index = BitIsSet (opcode, 24); 1991 add = BitIsSet (opcode, 23); 1992 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 1993 1994 if (wback && ((Rn == 15) || (Rn == Rt))) 1995 return false; 1996 break; 1997 default: 1998 return false; 1999 } 2000 addr_t offset_addr; 2001 if (add) 2002 offset_addr = sp + imm12; 2003 else 2004 offset_addr = sp - imm12; 2005 2006 addr_t addr; 2007 if (index) 2008 addr = offset_addr; 2009 else 2010 addr = sp; 2011 2012 EmulateInstruction::Context context; 2013 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2014 RegisterInfo sp_reg; 2015 RegisterInfo dwarf_reg; 2016 2017 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2018 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2019 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2020 if (Rt != 15) 2021 { 2022 uint32_t reg_value = ReadCoreReg(Rt, &success); 2023 if (!success) 2024 return false; 2025 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 2026 return false; 2027 } 2028 else 2029 { 2030 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2031 if (!success) 2032 return false; 2033 if (!MemUWrite (context, addr, pc, addr_byte_size)) 2034 return false; 2035 } 2036 2037 2038 if (wback) 2039 { 2040 context.type = EmulateInstruction::eContextAdjustStackPointer; 2041 context.SetImmediateSigned (addr - sp); 2042 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 2043 return false; 2044 } 2045 } 2046 return true; 2047 } 2048 2049 // Vector Push stores multiple extension registers to the stack. 2050 // It also updates SP to point to the start of the stored data. 2051 bool 2052 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 2053 { 2054 #if 0 2055 // ARM pseudo code... 2056 if (ConditionPassed()) 2057 { 2058 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2059 address = SP - imm32; 2060 SP = SP - imm32; 2061 if single_regs then 2062 for r = 0 to regs-1 2063 MemA[address,4] = S[d+r]; address = address+4; 2064 else 2065 for r = 0 to regs-1 2066 // Store as two word-aligned words in the correct order for current endianness. 2067 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2068 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2069 address = address+8; 2070 } 2071 #endif 2072 2073 bool success = false; 2074 if (ConditionPassed(opcode)) 2075 { 2076 const uint32_t addr_byte_size = GetAddressByteSize(); 2077 const addr_t sp = ReadCoreReg (SP_REG, &success); 2078 if (!success) 2079 return false; 2080 bool single_regs; 2081 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2082 uint32_t imm32; // stack offset 2083 uint32_t regs; // number of registers 2084 switch (encoding) { 2085 case eEncodingT1: 2086 case eEncodingA1: 2087 single_regs = false; 2088 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2089 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2090 // If UInt(imm8) is odd, see "FSTMX". 2091 regs = Bits32(opcode, 7, 0) / 2; 2092 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2093 if (regs == 0 || regs > 16 || (d + regs) > 32) 2094 return false; 2095 break; 2096 case eEncodingT2: 2097 case eEncodingA2: 2098 single_regs = true; 2099 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2100 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2101 regs = Bits32(opcode, 7, 0); 2102 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2103 if (regs == 0 || regs > 16 || (d + regs) > 32) 2104 return false; 2105 break; 2106 default: 2107 return false; 2108 } 2109 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2110 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2111 addr_t sp_offset = imm32; 2112 addr_t addr = sp - sp_offset; 2113 uint32_t i; 2114 2115 EmulateInstruction::Context context; 2116 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2117 2118 RegisterInfo dwarf_reg; 2119 RegisterInfo sp_reg; 2120 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2121 for (i=0; i<regs; ++i) 2122 { 2123 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2124 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2125 // uint64_t to accommodate 64-bit registers. 2126 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2127 if (!success) 2128 return false; 2129 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2130 return false; 2131 addr += reg_byte_size; 2132 } 2133 2134 context.type = EmulateInstruction::eContextAdjustStackPointer; 2135 context.SetImmediateSigned (-sp_offset); 2136 2137 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2138 return false; 2139 } 2140 return true; 2141 } 2142 2143 // Vector Pop loads multiple extension registers from the stack. 2144 // It also updates SP to point just above the loaded data. 2145 bool 2146 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2147 { 2148 #if 0 2149 // ARM pseudo code... 2150 if (ConditionPassed()) 2151 { 2152 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2153 address = SP; 2154 SP = SP + imm32; 2155 if single_regs then 2156 for r = 0 to regs-1 2157 S[d+r] = MemA[address,4]; address = address+4; 2158 else 2159 for r = 0 to regs-1 2160 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2161 // Combine the word-aligned words in the correct order for current endianness. 2162 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2163 } 2164 #endif 2165 2166 bool success = false; 2167 if (ConditionPassed(opcode)) 2168 { 2169 const uint32_t addr_byte_size = GetAddressByteSize(); 2170 const addr_t sp = ReadCoreReg (SP_REG, &success); 2171 if (!success) 2172 return false; 2173 bool single_regs; 2174 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2175 uint32_t imm32; // stack offset 2176 uint32_t regs; // number of registers 2177 switch (encoding) { 2178 case eEncodingT1: 2179 case eEncodingA1: 2180 single_regs = false; 2181 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2182 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2183 // If UInt(imm8) is odd, see "FLDMX". 2184 regs = Bits32(opcode, 7, 0) / 2; 2185 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2186 if (regs == 0 || regs > 16 || (d + regs) > 32) 2187 return false; 2188 break; 2189 case eEncodingT2: 2190 case eEncodingA2: 2191 single_regs = true; 2192 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2193 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2194 regs = Bits32(opcode, 7, 0); 2195 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2196 if (regs == 0 || regs > 16 || (d + regs) > 32) 2197 return false; 2198 break; 2199 default: 2200 return false; 2201 } 2202 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2203 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2204 addr_t sp_offset = imm32; 2205 addr_t addr = sp; 2206 uint32_t i; 2207 uint64_t data; // uint64_t to accommodate 64-bit registers. 2208 2209 EmulateInstruction::Context context; 2210 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2211 2212 RegisterInfo dwarf_reg; 2213 RegisterInfo sp_reg; 2214 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2215 for (i=0; i<regs; ++i) 2216 { 2217 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2218 context.SetAddress(addr); 2219 data = MemARead(context, addr, reg_byte_size, 0, &success); 2220 if (!success) 2221 return false; 2222 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2223 return false; 2224 addr += reg_byte_size; 2225 } 2226 2227 context.type = EmulateInstruction::eContextAdjustStackPointer; 2228 context.SetImmediateSigned (sp_offset); 2229 2230 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2231 return false; 2232 } 2233 return true; 2234 } 2235 2236 // SVC (previously SWI) 2237 bool 2238 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2239 { 2240 #if 0 2241 // ARM pseudo code... 2242 if (ConditionPassed()) 2243 { 2244 EncodingSpecificOperations(); 2245 CallSupervisor(); 2246 } 2247 #endif 2248 2249 bool success = false; 2250 2251 if (ConditionPassed(opcode)) 2252 { 2253 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2254 addr_t lr; // next instruction address 2255 if (!success) 2256 return false; 2257 uint32_t imm32; // the immediate constant 2258 uint32_t mode; // ARM or Thumb mode 2259 switch (encoding) { 2260 case eEncodingT1: 2261 lr = (pc + 2) | 1u; // return address 2262 imm32 = Bits32(opcode, 7, 0); 2263 mode = eModeThumb; 2264 break; 2265 case eEncodingA1: 2266 lr = pc + 4; // return address 2267 imm32 = Bits32(opcode, 23, 0); 2268 mode = eModeARM; 2269 break; 2270 default: 2271 return false; 2272 } 2273 2274 EmulateInstruction::Context context; 2275 context.type = EmulateInstruction::eContextSupervisorCall; 2276 context.SetISAAndImmediate (mode, imm32); 2277 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2278 return false; 2279 } 2280 return true; 2281 } 2282 2283 // If Then makes up to four following instructions (the IT block) conditional. 2284 bool 2285 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2286 { 2287 #if 0 2288 // ARM pseudo code... 2289 EncodingSpecificOperations(); 2290 ITSTATE.IT<7:0> = firstcond:mask; 2291 #endif 2292 2293 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2294 return true; 2295 } 2296 2297 bool 2298 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2299 { 2300 // NOP, nothing to do... 2301 return true; 2302 } 2303 2304 // Branch causes a branch to a target address. 2305 bool 2306 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2307 { 2308 #if 0 2309 // ARM pseudo code... 2310 if (ConditionPassed()) 2311 { 2312 EncodingSpecificOperations(); 2313 BranchWritePC(PC + imm32); 2314 } 2315 #endif 2316 2317 bool success = false; 2318 2319 if (ConditionPassed(opcode)) 2320 { 2321 EmulateInstruction::Context context; 2322 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2323 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2324 if (!success) 2325 return false; 2326 addr_t target; // target address 2327 int32_t imm32; // PC-relative offset 2328 switch (encoding) { 2329 case eEncodingT1: 2330 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2331 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2332 target = pc + imm32; 2333 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2334 break; 2335 case eEncodingT2: 2336 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2337 target = pc + imm32; 2338 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2339 break; 2340 case eEncodingT3: 2341 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2342 { 2343 if (Bits32(opcode, 25, 23) == 7) 2344 return false; // See Branches and miscellaneous control on page A6-235. 2345 2346 uint32_t S = Bit32(opcode, 26); 2347 uint32_t imm6 = Bits32(opcode, 21, 16); 2348 uint32_t J1 = Bit32(opcode, 13); 2349 uint32_t J2 = Bit32(opcode, 11); 2350 uint32_t imm11 = Bits32(opcode, 10, 0); 2351 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2352 imm32 = llvm::SignExtend32<21>(imm21); 2353 target = pc + imm32; 2354 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2355 break; 2356 } 2357 case eEncodingT4: 2358 { 2359 uint32_t S = Bit32(opcode, 26); 2360 uint32_t imm10 = Bits32(opcode, 25, 16); 2361 uint32_t J1 = Bit32(opcode, 13); 2362 uint32_t J2 = Bit32(opcode, 11); 2363 uint32_t imm11 = Bits32(opcode, 10, 0); 2364 uint32_t I1 = !(J1 ^ S); 2365 uint32_t I2 = !(J2 ^ S); 2366 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2367 imm32 = llvm::SignExtend32<25>(imm25); 2368 target = pc + imm32; 2369 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2370 break; 2371 } 2372 case eEncodingA1: 2373 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2374 target = pc + imm32; 2375 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2376 break; 2377 default: 2378 return false; 2379 } 2380 if (!BranchWritePC(context, target)) 2381 return false; 2382 } 2383 return true; 2384 } 2385 2386 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2387 // zero and conditionally branch forward a constant value. They do not affect the condition flags. 2388 // CBNZ, CBZ 2389 bool 2390 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2391 { 2392 #if 0 2393 // ARM pseudo code... 2394 EncodingSpecificOperations(); 2395 if nonzero ^ IsZero(R[n]) then 2396 BranchWritePC(PC + imm32); 2397 #endif 2398 2399 bool success = false; 2400 2401 // Read the register value from the operand register Rn. 2402 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2403 if (!success) 2404 return false; 2405 2406 EmulateInstruction::Context context; 2407 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2408 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2409 if (!success) 2410 return false; 2411 2412 addr_t target; // target address 2413 uint32_t imm32; // PC-relative offset to branch forward 2414 bool nonzero; 2415 switch (encoding) { 2416 case eEncodingT1: 2417 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2418 nonzero = BitIsSet(opcode, 11); 2419 target = pc + imm32; 2420 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2421 break; 2422 default: 2423 return false; 2424 } 2425 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2426 if (!BranchWritePC(context, target)) 2427 return false; 2428 2429 return true; 2430 } 2431 2432 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2433 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2434 // The branch length is twice the value of the byte returned from the table. 2435 // 2436 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2437 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2438 // The branch length is twice the value of the halfword returned from the table. 2439 // TBB, TBH 2440 bool 2441 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2442 { 2443 #if 0 2444 // ARM pseudo code... 2445 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2446 if is_tbh then 2447 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2448 else 2449 halfwords = UInt(MemU[R[n]+R[m], 1]); 2450 BranchWritePC(PC + 2*halfwords); 2451 #endif 2452 2453 bool success = false; 2454 2455 if (ConditionPassed(opcode)) 2456 { 2457 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2458 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2459 bool is_tbh; // true if table branch halfword 2460 switch (encoding) { 2461 case eEncodingT1: 2462 Rn = Bits32(opcode, 19, 16); 2463 Rm = Bits32(opcode, 3, 0); 2464 is_tbh = BitIsSet(opcode, 4); 2465 if (Rn == 13 || BadReg(Rm)) 2466 return false; 2467 if (InITBlock() && !LastInITBlock()) 2468 return false; 2469 break; 2470 default: 2471 return false; 2472 } 2473 2474 // Read the address of the table from the operand register Rn. 2475 // The PC can be used, in which case the table immediately follows this instruction. 2476 uint32_t base = ReadCoreReg(Rn, &success); 2477 if (!success) 2478 return false; 2479 2480 // the table index 2481 uint32_t index = ReadCoreReg(Rm, &success); 2482 if (!success) 2483 return false; 2484 2485 // the offsetted table address 2486 addr_t addr = base + (is_tbh ? index*2 : index); 2487 2488 // PC-relative offset to branch forward 2489 EmulateInstruction::Context context; 2490 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2491 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2492 if (!success) 2493 return false; 2494 2495 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2496 if (!success) 2497 return false; 2498 2499 // target address 2500 addr_t target = pc + offset; 2501 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2502 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2503 2504 if (!BranchWritePC(context, target)) 2505 return false; 2506 } 2507 2508 return true; 2509 } 2510 2511 // This instruction adds an immediate value to a register value, and writes the result to the destination register. 2512 // It can optionally update the condition flags based on the result. 2513 bool 2514 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2515 { 2516 #if 0 2517 if ConditionPassed() then 2518 EncodingSpecificOperations(); 2519 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2520 R[d] = result; 2521 if setflags then 2522 APSR.N = result<31>; 2523 APSR.Z = IsZeroBit(result); 2524 APSR.C = carry; 2525 APSR.V = overflow; 2526 #endif 2527 2528 bool success = false; 2529 2530 if (ConditionPassed(opcode)) 2531 { 2532 uint32_t d; 2533 uint32_t n; 2534 bool setflags; 2535 uint32_t imm32; 2536 uint32_t carry_out; 2537 2538 //EncodingSpecificOperations(); 2539 switch (encoding) 2540 { 2541 case eEncodingT1: 2542 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2543 d = Bits32 (opcode, 2, 0); 2544 n = Bits32 (opcode, 5, 3); 2545 setflags = !InITBlock(); 2546 imm32 = Bits32 (opcode, 8,6); 2547 2548 break; 2549 2550 case eEncodingT2: 2551 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2552 d = Bits32 (opcode, 10, 8); 2553 n = Bits32 (opcode, 10, 8); 2554 setflags = !InITBlock(); 2555 imm32 = Bits32 (opcode, 7, 0); 2556 2557 break; 2558 2559 case eEncodingT3: 2560 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2561 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2562 d = Bits32 (opcode, 11, 8); 2563 n = Bits32 (opcode, 19, 16); 2564 setflags = BitIsSet (opcode, 20); 2565 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2566 2567 // if Rn == '1101' then SEE ADD (SP plus immediate); 2568 if (n == 13) 2569 return EmulateADDSPImm(opcode, eEncodingT3); 2570 2571 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2572 if (BadReg (d) || (n == 15)) 2573 return false; 2574 2575 break; 2576 2577 case eEncodingT4: 2578 { 2579 // if Rn == '1111' then SEE ADR; 2580 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2581 d = Bits32 (opcode, 11, 8); 2582 n = Bits32 (opcode, 19, 16); 2583 setflags = false; 2584 uint32_t i = Bit32 (opcode, 26); 2585 uint32_t imm3 = Bits32 (opcode, 14, 12); 2586 uint32_t imm8 = Bits32 (opcode, 7, 0); 2587 imm32 = (i << 11) | (imm3 << 8) | imm8; 2588 2589 // if Rn == '1101' then SEE ADD (SP plus immediate); 2590 if (n == 13) 2591 return EmulateADDSPImm(opcode, eEncodingT4); 2592 2593 // if BadReg(d) then UNPREDICTABLE; 2594 if (BadReg (d)) 2595 return false; 2596 2597 break; 2598 } 2599 2600 default: 2601 return false; 2602 } 2603 2604 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2605 if (!success) 2606 return false; 2607 2608 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2609 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2610 2611 RegisterInfo reg_n; 2612 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2613 2614 EmulateInstruction::Context context; 2615 context.type = eContextArithmetic; 2616 context.SetRegisterPlusOffset (reg_n, imm32); 2617 2618 //R[d] = result; 2619 //if setflags then 2620 //APSR.N = result<31>; 2621 //APSR.Z = IsZeroBit(result); 2622 //APSR.C = carry; 2623 //APSR.V = overflow; 2624 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2625 return false; 2626 2627 } 2628 return true; 2629 } 2630 2631 // This instruction adds an immediate value to a register value, and writes the result to the destination 2632 // register. It can optionally update the condition flags based on the result. 2633 bool 2634 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2635 { 2636 #if 0 2637 // ARM pseudo code... 2638 if ConditionPassed() then 2639 EncodingSpecificOperations(); 2640 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2641 if d == 15 then 2642 ALUWritePC(result); // setflags is always FALSE here 2643 else 2644 R[d] = result; 2645 if setflags then 2646 APSR.N = result<31>; 2647 APSR.Z = IsZeroBit(result); 2648 APSR.C = carry; 2649 APSR.V = overflow; 2650 #endif 2651 2652 bool success = false; 2653 2654 if (ConditionPassed(opcode)) 2655 { 2656 uint32_t Rd, Rn; 2657 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2658 bool setflags; 2659 switch (encoding) 2660 { 2661 case eEncodingA1: 2662 Rd = Bits32(opcode, 15, 12); 2663 Rn = Bits32(opcode, 19, 16); 2664 setflags = BitIsSet(opcode, 20); 2665 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2666 break; 2667 default: 2668 return false; 2669 } 2670 2671 // Read the first operand. 2672 uint32_t val1 = ReadCoreReg(Rn, &success); 2673 if (!success) 2674 return false; 2675 2676 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2677 2678 EmulateInstruction::Context context; 2679 if (Rd == 13) 2680 context.type = EmulateInstruction::eContextAdjustStackPointer; 2681 else if (Rd == GetFramePointerRegisterNumber()) 2682 context.type = EmulateInstruction::eContextSetFramePointer; 2683 else 2684 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2685 2686 RegisterInfo dwarf_reg; 2687 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2688 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2689 2690 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2691 return false; 2692 } 2693 return true; 2694 } 2695 2696 // This instruction adds a register value and an optionally-shifted register value, and writes the result 2697 // to the destination register. It can optionally update the condition flags based on the result. 2698 bool 2699 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2700 { 2701 #if 0 2702 // ARM pseudo code... 2703 if ConditionPassed() then 2704 EncodingSpecificOperations(); 2705 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2706 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2707 if d == 15 then 2708 ALUWritePC(result); // setflags is always FALSE here 2709 else 2710 R[d] = result; 2711 if setflags then 2712 APSR.N = result<31>; 2713 APSR.Z = IsZeroBit(result); 2714 APSR.C = carry; 2715 APSR.V = overflow; 2716 #endif 2717 2718 bool success = false; 2719 2720 if (ConditionPassed(opcode)) 2721 { 2722 uint32_t Rd, Rn, Rm; 2723 ARM_ShifterType shift_t; 2724 uint32_t shift_n; // the shift applied to the value read from Rm 2725 bool setflags; 2726 switch (encoding) 2727 { 2728 case eEncodingT1: 2729 Rd = Bits32(opcode, 2, 0); 2730 Rn = Bits32(opcode, 5, 3); 2731 Rm = Bits32(opcode, 8, 6); 2732 setflags = !InITBlock(); 2733 shift_t = SRType_LSL; 2734 shift_n = 0; 2735 break; 2736 case eEncodingT2: 2737 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2738 Rm = Bits32(opcode, 6, 3); 2739 setflags = false; 2740 shift_t = SRType_LSL; 2741 shift_n = 0; 2742 if (Rn == 15 && Rm == 15) 2743 return false; 2744 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2745 return false; 2746 break; 2747 case eEncodingA1: 2748 Rd = Bits32(opcode, 15, 12); 2749 Rn = Bits32(opcode, 19, 16); 2750 Rm = Bits32(opcode, 3, 0); 2751 setflags = BitIsSet(opcode, 20); 2752 shift_n = DecodeImmShiftARM(opcode, shift_t); 2753 break; 2754 default: 2755 return false; 2756 } 2757 2758 // Read the first operand. 2759 uint32_t val1 = ReadCoreReg(Rn, &success); 2760 if (!success) 2761 return false; 2762 2763 // Read the second operand. 2764 uint32_t val2 = ReadCoreReg(Rm, &success); 2765 if (!success) 2766 return false; 2767 2768 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2769 if (!success) 2770 return false; 2771 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2772 2773 EmulateInstruction::Context context; 2774 context.type = eContextArithmetic; 2775 RegisterInfo op1_reg; 2776 RegisterInfo op2_reg; 2777 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2778 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2779 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2780 2781 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2782 return false; 2783 } 2784 return true; 2785 } 2786 2787 // Compare Negative (immediate) adds a register value and an immediate value. 2788 // It updates the condition flags based on the result, and discards the result. 2789 bool 2790 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2791 { 2792 #if 0 2793 // ARM pseudo code... 2794 if ConditionPassed() then 2795 EncodingSpecificOperations(); 2796 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2797 APSR.N = result<31>; 2798 APSR.Z = IsZeroBit(result); 2799 APSR.C = carry; 2800 APSR.V = overflow; 2801 #endif 2802 2803 bool success = false; 2804 2805 uint32_t Rn; // the first operand 2806 uint32_t imm32; // the immediate value to be compared with 2807 switch (encoding) { 2808 case eEncodingT1: 2809 Rn = Bits32(opcode, 19, 16); 2810 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2811 if (Rn == 15) 2812 return false; 2813 break; 2814 case eEncodingA1: 2815 Rn = Bits32(opcode, 19, 16); 2816 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2817 break; 2818 default: 2819 return false; 2820 } 2821 // Read the register value from the operand register Rn. 2822 uint32_t reg_val = ReadCoreReg(Rn, &success); 2823 if (!success) 2824 return false; 2825 2826 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2827 2828 EmulateInstruction::Context context; 2829 context.type = EmulateInstruction::eContextImmediate; 2830 context.SetNoArgs (); 2831 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2832 return false; 2833 2834 return true; 2835 } 2836 2837 // Compare Negative (register) adds a register value and an optionally-shifted register value. 2838 // It updates the condition flags based on the result, and discards the result. 2839 bool 2840 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2841 { 2842 #if 0 2843 // ARM pseudo code... 2844 if ConditionPassed() then 2845 EncodingSpecificOperations(); 2846 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2847 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2848 APSR.N = result<31>; 2849 APSR.Z = IsZeroBit(result); 2850 APSR.C = carry; 2851 APSR.V = overflow; 2852 #endif 2853 2854 bool success = false; 2855 2856 uint32_t Rn; // the first operand 2857 uint32_t Rm; // the second operand 2858 ARM_ShifterType shift_t; 2859 uint32_t shift_n; // the shift applied to the value read from Rm 2860 switch (encoding) { 2861 case eEncodingT1: 2862 Rn = Bits32(opcode, 2, 0); 2863 Rm = Bits32(opcode, 5, 3); 2864 shift_t = SRType_LSL; 2865 shift_n = 0; 2866 break; 2867 case eEncodingT2: 2868 Rn = Bits32(opcode, 19, 16); 2869 Rm = Bits32(opcode, 3, 0); 2870 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2871 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2872 if (Rn == 15 || BadReg(Rm)) 2873 return false; 2874 break; 2875 case eEncodingA1: 2876 Rn = Bits32(opcode, 19, 16); 2877 Rm = Bits32(opcode, 3, 0); 2878 shift_n = DecodeImmShiftARM(opcode, shift_t); 2879 break; 2880 default: 2881 return false; 2882 } 2883 // Read the register value from register Rn. 2884 uint32_t val1 = ReadCoreReg(Rn, &success); 2885 if (!success) 2886 return false; 2887 2888 // Read the register value from register Rm. 2889 uint32_t val2 = ReadCoreReg(Rm, &success); 2890 if (!success) 2891 return false; 2892 2893 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2894 if (!success) 2895 return false; 2896 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2897 2898 EmulateInstruction::Context context; 2899 context.type = EmulateInstruction::eContextImmediate; 2900 context.SetNoArgs(); 2901 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2902 return false; 2903 2904 return true; 2905 } 2906 2907 // Compare (immediate) subtracts an immediate value from a register value. 2908 // It updates the condition flags based on the result, and discards the result. 2909 bool 2910 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2911 { 2912 #if 0 2913 // ARM pseudo code... 2914 if ConditionPassed() then 2915 EncodingSpecificOperations(); 2916 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2917 APSR.N = result<31>; 2918 APSR.Z = IsZeroBit(result); 2919 APSR.C = carry; 2920 APSR.V = overflow; 2921 #endif 2922 2923 bool success = false; 2924 2925 uint32_t Rn; // the first operand 2926 uint32_t imm32; // the immediate value to be compared with 2927 switch (encoding) { 2928 case eEncodingT1: 2929 Rn = Bits32(opcode, 10, 8); 2930 imm32 = Bits32(opcode, 7, 0); 2931 break; 2932 case eEncodingT2: 2933 Rn = Bits32(opcode, 19, 16); 2934 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2935 if (Rn == 15) 2936 return false; 2937 break; 2938 case eEncodingA1: 2939 Rn = Bits32(opcode, 19, 16); 2940 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2941 break; 2942 default: 2943 return false; 2944 } 2945 // Read the register value from the operand register Rn. 2946 uint32_t reg_val = ReadCoreReg(Rn, &success); 2947 if (!success) 2948 return false; 2949 2950 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2951 2952 EmulateInstruction::Context context; 2953 context.type = EmulateInstruction::eContextImmediate; 2954 context.SetNoArgs (); 2955 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2956 return false; 2957 2958 return true; 2959 } 2960 2961 // Compare (register) subtracts an optionally-shifted register value from a register value. 2962 // It updates the condition flags based on the result, and discards the result. 2963 bool 2964 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2965 { 2966 #if 0 2967 // ARM pseudo code... 2968 if ConditionPassed() then 2969 EncodingSpecificOperations(); 2970 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2971 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2972 APSR.N = result<31>; 2973 APSR.Z = IsZeroBit(result); 2974 APSR.C = carry; 2975 APSR.V = overflow; 2976 #endif 2977 2978 bool success = false; 2979 2980 uint32_t Rn; // the first operand 2981 uint32_t Rm; // the second operand 2982 ARM_ShifterType shift_t; 2983 uint32_t shift_n; // the shift applied to the value read from Rm 2984 switch (encoding) { 2985 case eEncodingT1: 2986 Rn = Bits32(opcode, 2, 0); 2987 Rm = Bits32(opcode, 5, 3); 2988 shift_t = SRType_LSL; 2989 shift_n = 0; 2990 break; 2991 case eEncodingT2: 2992 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2993 Rm = Bits32(opcode, 6, 3); 2994 shift_t = SRType_LSL; 2995 shift_n = 0; 2996 if (Rn < 8 && Rm < 8) 2997 return false; 2998 if (Rn == 15 || Rm == 15) 2999 return false; 3000 break; 3001 case eEncodingT3: 3002 Rn = Bits32(opcode, 19, 16); 3003 Rm = Bits32(opcode, 3, 0); 3004 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3005 if (Rn == 15 || BadReg(Rm)) 3006 return false; 3007 break; 3008 case eEncodingA1: 3009 Rn = Bits32(opcode, 19, 16); 3010 Rm = Bits32(opcode, 3, 0); 3011 shift_n = DecodeImmShiftARM(opcode, shift_t); 3012 break; 3013 default: 3014 return false; 3015 } 3016 // Read the register value from register Rn. 3017 uint32_t val1 = ReadCoreReg(Rn, &success); 3018 if (!success) 3019 return false; 3020 3021 // Read the register value from register Rm. 3022 uint32_t val2 = ReadCoreReg(Rm, &success); 3023 if (!success) 3024 return false; 3025 3026 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3027 if (!success) 3028 return false; 3029 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3030 3031 EmulateInstruction::Context context; 3032 context.type = EmulateInstruction::eContextImmediate; 3033 context.SetNoArgs(); 3034 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3035 return false; 3036 3037 return true; 3038 } 3039 3040 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 3041 // shifting in copies of its sign bit, and writes the result to the destination register. It can 3042 // optionally update the condition flags based on the result. 3043 bool 3044 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 3045 { 3046 #if 0 3047 // ARM pseudo code... 3048 if ConditionPassed() then 3049 EncodingSpecificOperations(); 3050 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3051 if d == 15 then // Can only occur for ARM encoding 3052 ALUWritePC(result); // setflags is always FALSE here 3053 else 3054 R[d] = result; 3055 if setflags then 3056 APSR.N = result<31>; 3057 APSR.Z = IsZeroBit(result); 3058 APSR.C = carry; 3059 // APSR.V unchanged 3060 #endif 3061 3062 return EmulateShiftImm (opcode, encoding, SRType_ASR); 3063 } 3064 3065 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 3066 // shifting in copies of its sign bit, and writes the result to the destination register. 3067 // The variable number of bits is read from the bottom byte of a register. It can optionally update 3068 // the condition flags based on the result. 3069 bool 3070 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 3071 { 3072 #if 0 3073 // ARM pseudo code... 3074 if ConditionPassed() then 3075 EncodingSpecificOperations(); 3076 shift_n = UInt(R[m]<7:0>); 3077 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3078 R[d] = result; 3079 if setflags then 3080 APSR.N = result<31>; 3081 APSR.Z = IsZeroBit(result); 3082 APSR.C = carry; 3083 // APSR.V unchanged 3084 #endif 3085 3086 return EmulateShiftReg (opcode, encoding, SRType_ASR); 3087 } 3088 3089 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 3090 // shifting in zeros, and writes the result to the destination register. It can optionally 3091 // update the condition flags based on the result. 3092 bool 3093 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 3094 { 3095 #if 0 3096 // ARM pseudo code... 3097 if ConditionPassed() then 3098 EncodingSpecificOperations(); 3099 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3100 if d == 15 then // Can only occur for ARM encoding 3101 ALUWritePC(result); // setflags is always FALSE here 3102 else 3103 R[d] = result; 3104 if setflags then 3105 APSR.N = result<31>; 3106 APSR.Z = IsZeroBit(result); 3107 APSR.C = carry; 3108 // APSR.V unchanged 3109 #endif 3110 3111 return EmulateShiftImm (opcode, encoding, SRType_LSL); 3112 } 3113 3114 // Logical Shift Left (register) shifts a register value left by a variable number of bits, 3115 // shifting in zeros, and writes the result to the destination register. The variable number 3116 // of bits is read from the bottom byte of a register. It can optionally update the condition 3117 // flags based on the result. 3118 bool 3119 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 3120 { 3121 #if 0 3122 // ARM pseudo code... 3123 if ConditionPassed() then 3124 EncodingSpecificOperations(); 3125 shift_n = UInt(R[m]<7:0>); 3126 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3127 R[d] = result; 3128 if setflags then 3129 APSR.N = result<31>; 3130 APSR.Z = IsZeroBit(result); 3131 APSR.C = carry; 3132 // APSR.V unchanged 3133 #endif 3134 3135 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3136 } 3137 3138 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3139 // shifting in zeros, and writes the result to the destination register. It can optionally 3140 // update the condition flags based on the result. 3141 bool 3142 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3143 { 3144 #if 0 3145 // ARM pseudo code... 3146 if ConditionPassed() then 3147 EncodingSpecificOperations(); 3148 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3149 if d == 15 then // Can only occur for ARM encoding 3150 ALUWritePC(result); // setflags is always FALSE here 3151 else 3152 R[d] = result; 3153 if setflags then 3154 APSR.N = result<31>; 3155 APSR.Z = IsZeroBit(result); 3156 APSR.C = carry; 3157 // APSR.V unchanged 3158 #endif 3159 3160 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3161 } 3162 3163 // Logical Shift Right (register) shifts a register value right by a variable number of bits, 3164 // shifting in zeros, and writes the result to the destination register. The variable number 3165 // of bits is read from the bottom byte of a register. It can optionally update the condition 3166 // flags based on the result. 3167 bool 3168 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3169 { 3170 #if 0 3171 // ARM pseudo code... 3172 if ConditionPassed() then 3173 EncodingSpecificOperations(); 3174 shift_n = UInt(R[m]<7:0>); 3175 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3176 R[d] = result; 3177 if setflags then 3178 APSR.N = result<31>; 3179 APSR.Z = IsZeroBit(result); 3180 APSR.C = carry; 3181 // APSR.V unchanged 3182 #endif 3183 3184 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3185 } 3186 3187 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3188 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3189 // It can optionally update the condition flags based on the result. 3190 bool 3191 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3192 { 3193 #if 0 3194 // ARM pseudo code... 3195 if ConditionPassed() then 3196 EncodingSpecificOperations(); 3197 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3198 if d == 15 then // Can only occur for ARM encoding 3199 ALUWritePC(result); // setflags is always FALSE here 3200 else 3201 R[d] = result; 3202 if setflags then 3203 APSR.N = result<31>; 3204 APSR.Z = IsZeroBit(result); 3205 APSR.C = carry; 3206 // APSR.V unchanged 3207 #endif 3208 3209 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3210 } 3211 3212 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3213 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3214 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3215 // flags based on the result. 3216 bool 3217 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3218 { 3219 #if 0 3220 // ARM pseudo code... 3221 if ConditionPassed() then 3222 EncodingSpecificOperations(); 3223 shift_n = UInt(R[m]<7:0>); 3224 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3225 R[d] = result; 3226 if setflags then 3227 APSR.N = result<31>; 3228 APSR.Z = IsZeroBit(result); 3229 APSR.C = carry; 3230 // APSR.V unchanged 3231 #endif 3232 3233 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3234 } 3235 3236 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3237 // with the carry flag shifted into bit [31]. 3238 // 3239 // RRX can optionally update the condition flags based on the result. 3240 // In that case, bit [0] is shifted into the carry flag. 3241 bool 3242 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3243 { 3244 #if 0 3245 // ARM pseudo code... 3246 if ConditionPassed() then 3247 EncodingSpecificOperations(); 3248 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3249 if d == 15 then // Can only occur for ARM encoding 3250 ALUWritePC(result); // setflags is always FALSE here 3251 else 3252 R[d] = result; 3253 if setflags then 3254 APSR.N = result<31>; 3255 APSR.Z = IsZeroBit(result); 3256 APSR.C = carry; 3257 // APSR.V unchanged 3258 #endif 3259 3260 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3261 } 3262 3263 bool 3264 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3265 { 3266 // assert(shift_type == SRType_ASR 3267 // || shift_type == SRType_LSL 3268 // || shift_type == SRType_LSR 3269 // || shift_type == SRType_ROR 3270 // || shift_type == SRType_RRX); 3271 3272 bool success = false; 3273 3274 if (ConditionPassed(opcode)) 3275 { 3276 uint32_t Rd; // the destination register 3277 uint32_t Rm; // the first operand register 3278 uint32_t imm5; // encoding for the shift amount 3279 uint32_t carry; // the carry bit after the shift operation 3280 bool setflags; 3281 3282 // Special case handling! 3283 // A8.6.139 ROR (immediate) -- Encoding T1 3284 ARMEncoding use_encoding = encoding; 3285 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3286 { 3287 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3288 // have the same decoding of bit fields as the other Thumb2 shift operations. 3289 use_encoding = eEncodingT2; 3290 } 3291 3292 switch (use_encoding) { 3293 case eEncodingT1: 3294 // Due to the above special case handling! 3295 if (shift_type == SRType_ROR) 3296 return false; 3297 3298 Rd = Bits32(opcode, 2, 0); 3299 Rm = Bits32(opcode, 5, 3); 3300 setflags = !InITBlock(); 3301 imm5 = Bits32(opcode, 10, 6); 3302 break; 3303 case eEncodingT2: 3304 // A8.6.141 RRX 3305 // There's no imm form of RRX instructions. 3306 if (shift_type == SRType_RRX) 3307 return false; 3308 3309 Rd = Bits32(opcode, 11, 8); 3310 Rm = Bits32(opcode, 3, 0); 3311 setflags = BitIsSet(opcode, 20); 3312 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3313 if (BadReg(Rd) || BadReg(Rm)) 3314 return false; 3315 break; 3316 case eEncodingA1: 3317 Rd = Bits32(opcode, 15, 12); 3318 Rm = Bits32(opcode, 3, 0); 3319 setflags = BitIsSet(opcode, 20); 3320 imm5 = Bits32(opcode, 11, 7); 3321 break; 3322 default: 3323 return false; 3324 } 3325 3326 // A8.6.139 ROR (immediate) 3327 if (shift_type == SRType_ROR && imm5 == 0) 3328 shift_type = SRType_RRX; 3329 3330 // Get the first operand. 3331 uint32_t value = ReadCoreReg (Rm, &success); 3332 if (!success) 3333 return false; 3334 3335 // Decode the shift amount if not RRX. 3336 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3337 3338 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3339 if (!success) 3340 return false; 3341 3342 // The context specifies that an immediate is to be moved into Rd. 3343 EmulateInstruction::Context context; 3344 context.type = EmulateInstruction::eContextImmediate; 3345 context.SetNoArgs (); 3346 3347 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3348 return false; 3349 } 3350 return true; 3351 } 3352 3353 bool 3354 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3355 { 3356 // assert(shift_type == SRType_ASR 3357 // || shift_type == SRType_LSL 3358 // || shift_type == SRType_LSR 3359 // || shift_type == SRType_ROR); 3360 3361 bool success = false; 3362 3363 if (ConditionPassed(opcode)) 3364 { 3365 uint32_t Rd; // the destination register 3366 uint32_t Rn; // the first operand register 3367 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3368 uint32_t carry; // the carry bit after the shift operation 3369 bool setflags; 3370 switch (encoding) { 3371 case eEncodingT1: 3372 Rd = Bits32(opcode, 2, 0); 3373 Rn = Rd; 3374 Rm = Bits32(opcode, 5, 3); 3375 setflags = !InITBlock(); 3376 break; 3377 case eEncodingT2: 3378 Rd = Bits32(opcode, 11, 8); 3379 Rn = Bits32(opcode, 19, 16); 3380 Rm = Bits32(opcode, 3, 0); 3381 setflags = BitIsSet(opcode, 20); 3382 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3383 return false; 3384 break; 3385 case eEncodingA1: 3386 Rd = Bits32(opcode, 15, 12); 3387 Rn = Bits32(opcode, 3, 0); 3388 Rm = Bits32(opcode, 11, 8); 3389 setflags = BitIsSet(opcode, 20); 3390 if (Rd == 15 || Rn == 15 || Rm == 15) 3391 return false; 3392 break; 3393 default: 3394 return false; 3395 } 3396 3397 // Get the first operand. 3398 uint32_t value = ReadCoreReg (Rn, &success); 3399 if (!success) 3400 return false; 3401 // Get the Rm register content. 3402 uint32_t val = ReadCoreReg (Rm, &success); 3403 if (!success) 3404 return false; 3405 3406 // Get the shift amount. 3407 uint32_t amt = Bits32(val, 7, 0); 3408 3409 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3410 if (!success) 3411 return false; 3412 3413 // The context specifies that an immediate is to be moved into Rd. 3414 EmulateInstruction::Context context; 3415 context.type = EmulateInstruction::eContextImmediate; 3416 context.SetNoArgs (); 3417 3418 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3419 return false; 3420 } 3421 return true; 3422 } 3423 3424 // LDM loads multiple registers from consecutive memory locations, using an 3425 // address from a base register. Optionally the address just above the highest of those locations 3426 // can be written back to the base register. 3427 bool 3428 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3429 { 3430 #if 0 3431 // ARM pseudo code... 3432 if ConditionPassed() 3433 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3434 address = R[n]; 3435 3436 for i = 0 to 14 3437 if registers<i> == '1' then 3438 R[i] = MemA[address, 4]; address = address + 4; 3439 if registers<15> == '1' then 3440 LoadWritePC (MemA[address, 4]); 3441 3442 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3443 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3444 3445 #endif 3446 3447 bool success = false; 3448 if (ConditionPassed(opcode)) 3449 { 3450 uint32_t n; 3451 uint32_t registers = 0; 3452 bool wback; 3453 const uint32_t addr_byte_size = GetAddressByteSize(); 3454 switch (encoding) 3455 { 3456 case eEncodingT1: 3457 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3458 n = Bits32 (opcode, 10, 8); 3459 registers = Bits32 (opcode, 7, 0); 3460 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3461 wback = BitIsClear (registers, n); 3462 // if BitCount(registers) < 1 then UNPREDICTABLE; 3463 if (BitCount(registers) < 1) 3464 return false; 3465 break; 3466 case eEncodingT2: 3467 // if W == '1' && Rn == '1101' then SEE POP; 3468 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3469 n = Bits32 (opcode, 19, 16); 3470 registers = Bits32 (opcode, 15, 0); 3471 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3472 wback = BitIsSet (opcode, 21); 3473 3474 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3475 if ((n == 15) 3476 || (BitCount (registers) < 2) 3477 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3478 return false; 3479 3480 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3481 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3482 return false; 3483 3484 // if wback && registers<n> == '1' then UNPREDICTABLE; 3485 if (wback 3486 && BitIsSet (registers, n)) 3487 return false; 3488 break; 3489 3490 case eEncodingA1: 3491 n = Bits32 (opcode, 19, 16); 3492 registers = Bits32 (opcode, 15, 0); 3493 wback = BitIsSet (opcode, 21); 3494 if ((n == 15) 3495 || (BitCount (registers) < 1)) 3496 return false; 3497 break; 3498 default: 3499 return false; 3500 } 3501 3502 int32_t offset = 0; 3503 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3504 if (!success) 3505 return false; 3506 3507 EmulateInstruction::Context context; 3508 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3509 RegisterInfo dwarf_reg; 3510 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3511 context.SetRegisterPlusOffset (dwarf_reg, offset); 3512 3513 for (int i = 0; i < 14; ++i) 3514 { 3515 if (BitIsSet (registers, i)) 3516 { 3517 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3518 context.SetRegisterPlusOffset (dwarf_reg, offset); 3519 if (wback && (n == 13)) // Pop Instruction 3520 { 3521 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3522 context.SetAddress(base_address + offset); 3523 } 3524 3525 // R[i] = MemA [address, 4]; address = address + 4; 3526 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3527 if (!success) 3528 return false; 3529 3530 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3531 return false; 3532 3533 offset += addr_byte_size; 3534 } 3535 } 3536 3537 if (BitIsSet (registers, 15)) 3538 { 3539 //LoadWritePC (MemA [address, 4]); 3540 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3541 context.SetRegisterPlusOffset (dwarf_reg, offset); 3542 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3543 if (!success) 3544 return false; 3545 // In ARMv5T and above, this is an interworking branch. 3546 if (!LoadWritePC(context, data)) 3547 return false; 3548 } 3549 3550 if (wback && BitIsClear (registers, n)) 3551 { 3552 // R[n] = R[n] + 4 * BitCount (registers) 3553 int32_t offset = addr_byte_size * BitCount (registers); 3554 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3555 context.SetRegisterPlusOffset (dwarf_reg, offset); 3556 3557 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3558 return false; 3559 } 3560 if (wback && BitIsSet (registers, n)) 3561 // R[n] bits(32) UNKNOWN; 3562 return WriteBits32Unknown (n); 3563 } 3564 return true; 3565 } 3566 3567 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3568 // The consecutive memory locations end at this address and the address just below the lowest of those locations 3569 // can optionally be written back to the base register. 3570 bool 3571 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3572 { 3573 #if 0 3574 // ARM pseudo code... 3575 if ConditionPassed() then 3576 EncodingSpecificOperations(); 3577 address = R[n] - 4*BitCount(registers) + 4; 3578 3579 for i = 0 to 14 3580 if registers<i> == '1' then 3581 R[i] = MemA[address,4]; address = address + 4; 3582 3583 if registers<15> == '1' then 3584 LoadWritePC(MemA[address,4]); 3585 3586 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3587 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3588 #endif 3589 3590 bool success = false; 3591 3592 if (ConditionPassed(opcode)) 3593 { 3594 uint32_t n; 3595 uint32_t registers = 0; 3596 bool wback; 3597 const uint32_t addr_byte_size = GetAddressByteSize(); 3598 3599 // EncodingSpecificOperations(); 3600 switch (encoding) 3601 { 3602 case eEncodingA1: 3603 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3604 n = Bits32 (opcode, 19, 16); 3605 registers = Bits32 (opcode, 15, 0); 3606 wback = BitIsSet (opcode, 21); 3607 3608 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3609 if ((n == 15) || (BitCount (registers) < 1)) 3610 return false; 3611 3612 break; 3613 3614 default: 3615 return false; 3616 } 3617 // address = R[n] - 4*BitCount(registers) + 4; 3618 3619 int32_t offset = 0; 3620 addr_t Rn = ReadCoreReg (n, &success); 3621 3622 if (!success) 3623 return false; 3624 3625 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3626 3627 EmulateInstruction::Context context; 3628 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3629 RegisterInfo dwarf_reg; 3630 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3631 context.SetRegisterPlusOffset (dwarf_reg, offset); 3632 3633 // for i = 0 to 14 3634 for (int i = 0; i < 14; ++i) 3635 { 3636 // if registers<i> == '1' then 3637 if (BitIsSet (registers, i)) 3638 { 3639 // R[i] = MemA[address,4]; address = address + 4; 3640 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3641 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3642 if (!success) 3643 return false; 3644 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3645 return false; 3646 offset += addr_byte_size; 3647 } 3648 } 3649 3650 // if registers<15> == '1' then 3651 // LoadWritePC(MemA[address,4]); 3652 if (BitIsSet (registers, 15)) 3653 { 3654 context.SetRegisterPlusOffset (dwarf_reg, offset); 3655 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3656 if (!success) 3657 return false; 3658 // In ARMv5T and above, this is an interworking branch. 3659 if (!LoadWritePC(context, data)) 3660 return false; 3661 } 3662 3663 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3664 if (wback && BitIsClear (registers, n)) 3665 { 3666 if (!success) 3667 return false; 3668 3669 offset = (addr_byte_size * BitCount (registers)) * -1; 3670 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3671 context.SetImmediateSigned (offset); 3672 addr_t addr = Rn + offset; 3673 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3674 return false; 3675 } 3676 3677 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3678 if (wback && BitIsSet (registers, n)) 3679 return WriteBits32Unknown (n); 3680 } 3681 return true; 3682 } 3683 3684 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3685 // consecutive memory locations end just below this address, and the address of the lowest of those locations can 3686 // be optionally written back to the base register. 3687 bool 3688 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3689 { 3690 #if 0 3691 // ARM pseudo code... 3692 if ConditionPassed() then 3693 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3694 address = R[n] - 4*BitCount(registers); 3695 3696 for i = 0 to 14 3697 if registers<i> == '1' then 3698 R[i] = MemA[address,4]; address = address + 4; 3699 if registers<15> == '1' then 3700 LoadWritePC(MemA[address,4]); 3701 3702 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3703 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3704 #endif 3705 3706 bool success = false; 3707 3708 if (ConditionPassed(opcode)) 3709 { 3710 uint32_t n; 3711 uint32_t registers = 0; 3712 bool wback; 3713 const uint32_t addr_byte_size = GetAddressByteSize(); 3714 switch (encoding) 3715 { 3716 case eEncodingT1: 3717 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3718 n = Bits32 (opcode, 19, 16); 3719 registers = Bits32 (opcode, 15, 0); 3720 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3721 wback = BitIsSet (opcode, 21); 3722 3723 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3724 if ((n == 15) 3725 || (BitCount (registers) < 2) 3726 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3727 return false; 3728 3729 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3730 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3731 return false; 3732 3733 // if wback && registers<n> == '1' then UNPREDICTABLE; 3734 if (wback && BitIsSet (registers, n)) 3735 return false; 3736 3737 break; 3738 3739 case eEncodingA1: 3740 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3741 n = Bits32 (opcode, 19, 16); 3742 registers = Bits32 (opcode, 15, 0); 3743 wback = BitIsSet (opcode, 21); 3744 3745 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3746 if ((n == 15) || (BitCount (registers) < 1)) 3747 return false; 3748 3749 break; 3750 3751 default: 3752 return false; 3753 } 3754 3755 // address = R[n] - 4*BitCount(registers); 3756 3757 int32_t offset = 0; 3758 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3759 3760 if (!success) 3761 return false; 3762 3763 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3764 EmulateInstruction::Context context; 3765 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3766 RegisterInfo dwarf_reg; 3767 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3768 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3769 3770 for (int i = 0; i < 14; ++i) 3771 { 3772 if (BitIsSet (registers, i)) 3773 { 3774 // R[i] = MemA[address,4]; address = address + 4; 3775 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3776 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3777 if (!success) 3778 return false; 3779 3780 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3781 return false; 3782 3783 offset += addr_byte_size; 3784 } 3785 } 3786 3787 // if registers<15> == '1' then 3788 // LoadWritePC(MemA[address,4]); 3789 if (BitIsSet (registers, 15)) 3790 { 3791 context.SetRegisterPlusOffset (dwarf_reg, offset); 3792 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3793 if (!success) 3794 return false; 3795 // In ARMv5T and above, this is an interworking branch. 3796 if (!LoadWritePC(context, data)) 3797 return false; 3798 } 3799 3800 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3801 if (wback && BitIsClear (registers, n)) 3802 { 3803 if (!success) 3804 return false; 3805 3806 offset = (addr_byte_size * BitCount (registers)) * -1; 3807 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3808 context.SetImmediateSigned (offset); 3809 addr_t addr = Rn + offset; 3810 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3811 return false; 3812 } 3813 3814 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3815 if (wback && BitIsSet (registers, n)) 3816 return WriteBits32Unknown (n); 3817 } 3818 return true; 3819 } 3820 3821 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3822 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3823 // optinoally be written back to the base register. 3824 bool 3825 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3826 { 3827 #if 0 3828 if ConditionPassed() then 3829 EncodingSpecificOperations(); 3830 address = R[n] + 4; 3831 3832 for i = 0 to 14 3833 if registers<i> == '1' then 3834 R[i] = MemA[address,4]; address = address + 4; 3835 if registers<15> == '1' then 3836 LoadWritePC(MemA[address,4]); 3837 3838 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3839 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3840 #endif 3841 3842 bool success = false; 3843 3844 if (ConditionPassed(opcode)) 3845 { 3846 uint32_t n; 3847 uint32_t registers = 0; 3848 bool wback; 3849 const uint32_t addr_byte_size = GetAddressByteSize(); 3850 switch (encoding) 3851 { 3852 case eEncodingA1: 3853 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3854 n = Bits32 (opcode, 19, 16); 3855 registers = Bits32 (opcode, 15, 0); 3856 wback = BitIsSet (opcode, 21); 3857 3858 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3859 if ((n == 15) || (BitCount (registers) < 1)) 3860 return false; 3861 3862 break; 3863 default: 3864 return false; 3865 } 3866 // address = R[n] + 4; 3867 3868 int32_t offset = 0; 3869 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3870 3871 if (!success) 3872 return false; 3873 3874 addr_t address = Rn + addr_byte_size; 3875 3876 EmulateInstruction::Context context; 3877 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3878 RegisterInfo dwarf_reg; 3879 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3880 context.SetRegisterPlusOffset (dwarf_reg, offset); 3881 3882 for (int i = 0; i < 14; ++i) 3883 { 3884 if (BitIsSet (registers, i)) 3885 { 3886 // R[i] = MemA[address,4]; address = address + 4; 3887 3888 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3889 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3890 if (!success) 3891 return false; 3892 3893 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3894 return false; 3895 3896 offset += addr_byte_size; 3897 } 3898 } 3899 3900 // if registers<15> == '1' then 3901 // LoadWritePC(MemA[address,4]); 3902 if (BitIsSet (registers, 15)) 3903 { 3904 context.SetRegisterPlusOffset (dwarf_reg, offset); 3905 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3906 if (!success) 3907 return false; 3908 // In ARMv5T and above, this is an interworking branch. 3909 if (!LoadWritePC(context, data)) 3910 return false; 3911 } 3912 3913 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3914 if (wback && BitIsClear (registers, n)) 3915 { 3916 if (!success) 3917 return false; 3918 3919 offset = addr_byte_size * BitCount (registers); 3920 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3921 context.SetImmediateSigned (offset); 3922 addr_t addr = Rn + offset; 3923 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3924 return false; 3925 } 3926 3927 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3928 if (wback && BitIsSet (registers, n)) 3929 return WriteBits32Unknown (n); 3930 } 3931 return true; 3932 } 3933 3934 // Load Register (immediate) calculates an address from a base register value and 3935 // an immediate offset, loads a word from memory, and writes to a register. 3936 // LDR (immediate, Thumb) 3937 bool 3938 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3939 { 3940 #if 0 3941 // ARM pseudo code... 3942 if (ConditionPassed()) 3943 { 3944 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3945 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3946 address = if index then offset_addr else R[n]; 3947 data = MemU[address,4]; 3948 if wback then R[n] = offset_addr; 3949 if t == 15 then 3950 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3951 elsif UnalignedSupport() || address<1:0> = '00' then 3952 R[t] = data; 3953 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3954 } 3955 #endif 3956 3957 bool success = false; 3958 3959 if (ConditionPassed(opcode)) 3960 { 3961 uint32_t Rt; // the destination register 3962 uint32_t Rn; // the base register 3963 uint32_t imm32; // the immediate offset used to form the address 3964 addr_t offset_addr; // the offset address 3965 addr_t address; // the calculated address 3966 uint32_t data; // the literal data value from memory load 3967 bool add, index, wback; 3968 switch (encoding) { 3969 case eEncodingT1: 3970 Rt = Bits32(opcode, 2, 0); 3971 Rn = Bits32(opcode, 5, 3); 3972 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3973 // index = TRUE; add = TRUE; wback = FALSE 3974 add = true; 3975 index = true; 3976 wback = false; 3977 3978 break; 3979 3980 case eEncodingT2: 3981 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3982 Rt = Bits32 (opcode, 10, 8); 3983 Rn = 13; 3984 imm32 = Bits32 (opcode, 7, 0) << 2; 3985 3986 // index = TRUE; add = TRUE; wback = FALSE; 3987 index = true; 3988 add = true; 3989 wback = false; 3990 3991 break; 3992 3993 case eEncodingT3: 3994 // if Rn == '1111' then SEE LDR (literal); 3995 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3996 Rt = Bits32 (opcode, 15, 12); 3997 Rn = Bits32 (opcode, 19, 16); 3998 imm32 = Bits32 (opcode, 11, 0); 3999 4000 // index = TRUE; add = TRUE; wback = FALSE; 4001 index = true; 4002 add = true; 4003 wback = false; 4004 4005 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4006 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4007 return false; 4008 4009 break; 4010 4011 case eEncodingT4: 4012 // if Rn == '1111' then SEE LDR (literal); 4013 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4014 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 4015 // if P == '0' && W == '0' then UNDEFINED; 4016 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 4017 return false; 4018 4019 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4020 Rt = Bits32 (opcode, 15, 12); 4021 Rn = Bits32 (opcode, 19, 16); 4022 imm32 = Bits32 (opcode, 7, 0); 4023 4024 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4025 index = BitIsSet (opcode, 10); 4026 add = BitIsSet (opcode, 9); 4027 wback = BitIsSet (opcode, 8); 4028 4029 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 4030 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 4031 return false; 4032 4033 break; 4034 4035 default: 4036 return false; 4037 } 4038 uint32_t base = ReadCoreReg (Rn, &success); 4039 if (!success) 4040 return false; 4041 if (add) 4042 offset_addr = base + imm32; 4043 else 4044 offset_addr = base - imm32; 4045 4046 address = (index ? offset_addr : base); 4047 4048 RegisterInfo base_reg; 4049 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4050 if (wback) 4051 { 4052 EmulateInstruction::Context ctx; 4053 if (Rn == 13) 4054 { 4055 ctx.type = eContextAdjustStackPointer; 4056 ctx.SetImmediateSigned((int32_t) (offset_addr - base)); 4057 } 4058 else if (Rn == GetFramePointerRegisterNumber()) 4059 { 4060 ctx.type = eContextSetFramePointer; 4061 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4062 } 4063 else 4064 { 4065 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4066 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4067 } 4068 4069 4070 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 4071 return false; 4072 } 4073 4074 // Prepare to write to the Rt register. 4075 EmulateInstruction::Context context; 4076 context.type = EmulateInstruction::eContextRegisterLoad; 4077 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4078 4079 // Read memory from the address. 4080 data = MemURead(context, address, 4, 0, &success); 4081 if (!success) 4082 return false; 4083 4084 if (Rt == 15) 4085 { 4086 if (Bits32(address, 1, 0) == 0) 4087 { 4088 if (!LoadWritePC(context, data)) 4089 return false; 4090 } 4091 else 4092 return false; 4093 } 4094 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 4095 { 4096 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 4097 return false; 4098 } 4099 else 4100 WriteBits32Unknown (Rt); 4101 } 4102 return true; 4103 } 4104 4105 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 4106 // from a base register. The consecutive memory locations start at this address, and the address just above the last 4107 // of those locations can optionally be written back to the base register. 4108 bool 4109 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 4110 { 4111 #if 0 4112 if ConditionPassed() then 4113 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4114 address = R[n]; 4115 4116 for i = 0 to 14 4117 if registers<i> == '1' then 4118 if i == n && wback && i != LowestSetBit(registers) then 4119 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4120 else 4121 MemA[address,4] = R[i]; 4122 address = address + 4; 4123 4124 if registers<15> == '1' then // Only possible for encoding A1 4125 MemA[address,4] = PCStoreValue(); 4126 if wback then R[n] = R[n] + 4*BitCount(registers); 4127 #endif 4128 4129 bool success = false; 4130 4131 if (ConditionPassed(opcode)) 4132 { 4133 uint32_t n; 4134 uint32_t registers = 0; 4135 bool wback; 4136 const uint32_t addr_byte_size = GetAddressByteSize(); 4137 4138 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4139 switch (encoding) 4140 { 4141 case eEncodingT1: 4142 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4143 n = Bits32 (opcode, 10, 8); 4144 registers = Bits32 (opcode, 7, 0); 4145 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4146 wback = true; 4147 4148 // if BitCount(registers) < 1 then UNPREDICTABLE; 4149 if (BitCount (registers) < 1) 4150 return false; 4151 4152 break; 4153 4154 case eEncodingT2: 4155 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4156 n = Bits32 (opcode, 19, 16); 4157 registers = Bits32 (opcode, 15, 0); 4158 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4159 wback = BitIsSet (opcode, 21); 4160 4161 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4162 if ((n == 15) || (BitCount (registers) < 2)) 4163 return false; 4164 4165 // if wback && registers<n> == '1' then UNPREDICTABLE; 4166 if (wback && BitIsSet (registers, n)) 4167 return false; 4168 4169 break; 4170 4171 case eEncodingA1: 4172 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4173 n = Bits32 (opcode, 19, 16); 4174 registers = Bits32 (opcode, 15, 0); 4175 wback = BitIsSet (opcode, 21); 4176 4177 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4178 if ((n == 15) || (BitCount (registers) < 1)) 4179 return false; 4180 4181 break; 4182 4183 default: 4184 return false; 4185 } 4186 4187 // address = R[n]; 4188 int32_t offset = 0; 4189 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4190 if (!success) 4191 return false; 4192 4193 EmulateInstruction::Context context; 4194 context.type = EmulateInstruction::eContextRegisterStore; 4195 RegisterInfo base_reg; 4196 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4197 4198 // for i = 0 to 14 4199 uint32_t lowest_set_bit = 14; 4200 for (uint32_t i = 0; i < 14; ++i) 4201 { 4202 // if registers<i> == '1' then 4203 if (BitIsSet (registers, i)) 4204 { 4205 if (i < lowest_set_bit) 4206 lowest_set_bit = i; 4207 // if i == n && wback && i != LowestSetBit(registers) then 4208 if ((i == n) && wback && (i != lowest_set_bit)) 4209 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4210 WriteBits32UnknownToMemory (address + offset); 4211 else 4212 { 4213 // MemA[address,4] = R[i]; 4214 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4215 if (!success) 4216 return false; 4217 4218 RegisterInfo data_reg; 4219 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4220 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4221 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4222 return false; 4223 } 4224 4225 // address = address + 4; 4226 offset += addr_byte_size; 4227 } 4228 } 4229 4230 // if registers<15> == '1' then // Only possible for encoding A1 4231 // MemA[address,4] = PCStoreValue(); 4232 if (BitIsSet (registers, 15)) 4233 { 4234 RegisterInfo pc_reg; 4235 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4236 context.SetRegisterPlusOffset (pc_reg, 8); 4237 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4238 if (!success) 4239 return false; 4240 4241 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4242 return false; 4243 } 4244 4245 // if wback then R[n] = R[n] + 4*BitCount(registers); 4246 if (wback) 4247 { 4248 offset = addr_byte_size * BitCount (registers); 4249 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4250 context.SetImmediateSigned (offset); 4251 addr_t data = address + offset; 4252 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4253 return false; 4254 } 4255 } 4256 return true; 4257 } 4258 4259 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4260 // from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4261 // of those locations can optionally be written back to the base register. 4262 bool 4263 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4264 { 4265 #if 0 4266 if ConditionPassed() then 4267 EncodingSpecificOperations(); 4268 address = R[n] - 4*BitCount(registers) + 4; 4269 4270 for i = 0 to 14 4271 if registers<i> == '1' then 4272 if i == n && wback && i != LowestSetBit(registers) then 4273 MemA[address,4] = bits(32) UNKNOWN; 4274 else 4275 MemA[address,4] = R[i]; 4276 address = address + 4; 4277 4278 if registers<15> == '1' then 4279 MemA[address,4] = PCStoreValue(); 4280 4281 if wback then R[n] = R[n] - 4*BitCount(registers); 4282 #endif 4283 4284 bool success = false; 4285 4286 if (ConditionPassed(opcode)) 4287 { 4288 uint32_t n; 4289 uint32_t registers = 0; 4290 bool wback; 4291 const uint32_t addr_byte_size = GetAddressByteSize(); 4292 4293 // EncodingSpecificOperations(); 4294 switch (encoding) 4295 { 4296 case eEncodingA1: 4297 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4298 n = Bits32 (opcode, 19, 16); 4299 registers = Bits32 (opcode, 15, 0); 4300 wback = BitIsSet (opcode, 21); 4301 4302 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4303 if ((n == 15) || (BitCount (registers) < 1)) 4304 return false; 4305 break; 4306 default: 4307 return false; 4308 } 4309 4310 // address = R[n] - 4*BitCount(registers) + 4; 4311 int32_t offset = 0; 4312 addr_t Rn = ReadCoreReg (n, &success); 4313 if (!success) 4314 return false; 4315 4316 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4317 4318 EmulateInstruction::Context context; 4319 context.type = EmulateInstruction::eContextRegisterStore; 4320 RegisterInfo base_reg; 4321 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4322 4323 // for i = 0 to 14 4324 uint32_t lowest_bit_set = 14; 4325 for (uint32_t i = 0; i < 14; ++i) 4326 { 4327 // if registers<i> == '1' then 4328 if (BitIsSet (registers, i)) 4329 { 4330 if (i < lowest_bit_set) 4331 lowest_bit_set = i; 4332 //if i == n && wback && i != LowestSetBit(registers) then 4333 if ((i == n) && wback && (i != lowest_bit_set)) 4334 // MemA[address,4] = bits(32) UNKNOWN; 4335 WriteBits32UnknownToMemory (address + offset); 4336 else 4337 { 4338 // MemA[address,4] = R[i]; 4339 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4340 if (!success) 4341 return false; 4342 4343 RegisterInfo data_reg; 4344 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4345 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4346 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4347 return false; 4348 } 4349 4350 // address = address + 4; 4351 offset += addr_byte_size; 4352 } 4353 } 4354 4355 // if registers<15> == '1' then 4356 // MemA[address,4] = PCStoreValue(); 4357 if (BitIsSet (registers, 15)) 4358 { 4359 RegisterInfo pc_reg; 4360 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4361 context.SetRegisterPlusOffset (pc_reg, 8); 4362 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4363 if (!success) 4364 return false; 4365 4366 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4367 return false; 4368 } 4369 4370 // if wback then R[n] = R[n] - 4*BitCount(registers); 4371 if (wback) 4372 { 4373 offset = (addr_byte_size * BitCount (registers)) * -1; 4374 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4375 context.SetImmediateSigned (offset); 4376 addr_t data = Rn + offset; 4377 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4378 return false; 4379 } 4380 } 4381 return true; 4382 } 4383 4384 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4385 // from a base register. The consecutive memory locations end just below this address, and the address of the first of 4386 // those locations can optionally be written back to the base register. 4387 bool 4388 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4389 { 4390 #if 0 4391 if ConditionPassed() then 4392 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4393 address = R[n] - 4*BitCount(registers); 4394 4395 for i = 0 to 14 4396 if registers<i> == '1' then 4397 if i == n && wback && i != LowestSetBit(registers) then 4398 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4399 else 4400 MemA[address,4] = R[i]; 4401 address = address + 4; 4402 4403 if registers<15> == '1' then // Only possible for encoding A1 4404 MemA[address,4] = PCStoreValue(); 4405 4406 if wback then R[n] = R[n] - 4*BitCount(registers); 4407 #endif 4408 4409 4410 bool success = false; 4411 4412 if (ConditionPassed(opcode)) 4413 { 4414 uint32_t n; 4415 uint32_t registers = 0; 4416 bool wback; 4417 const uint32_t addr_byte_size = GetAddressByteSize(); 4418 4419 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4420 switch (encoding) 4421 { 4422 case eEncodingT1: 4423 // if W == '1' && Rn == '1101' then SEE PUSH; 4424 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4425 { 4426 // See PUSH 4427 } 4428 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4429 n = Bits32 (opcode, 19, 16); 4430 registers = Bits32 (opcode, 15, 0); 4431 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4432 wback = BitIsSet (opcode, 21); 4433 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4434 if ((n == 15) || BitCount (registers) < 2) 4435 return false; 4436 // if wback && registers<n> == '1' then UNPREDICTABLE; 4437 if (wback && BitIsSet (registers, n)) 4438 return false; 4439 break; 4440 4441 case eEncodingA1: 4442 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE PUSH; 4443 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4444 { 4445 // See Push 4446 } 4447 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4448 n = Bits32 (opcode, 19, 16); 4449 registers = Bits32 (opcode, 15, 0); 4450 wback = BitIsSet (opcode, 21); 4451 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4452 if ((n == 15) || BitCount (registers) < 1) 4453 return false; 4454 break; 4455 4456 default: 4457 return false; 4458 } 4459 4460 // address = R[n] - 4*BitCount(registers); 4461 4462 int32_t offset = 0; 4463 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4464 if (!success) 4465 return false; 4466 4467 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4468 4469 EmulateInstruction::Context context; 4470 context.type = EmulateInstruction::eContextRegisterStore; 4471 RegisterInfo base_reg; 4472 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4473 4474 // for i = 0 to 14 4475 uint32_t lowest_set_bit = 14; 4476 for (uint32_t i = 0; i < 14; ++i) 4477 { 4478 // if registers<i> == '1' then 4479 if (BitIsSet (registers, i)) 4480 { 4481 if (i < lowest_set_bit) 4482 lowest_set_bit = i; 4483 // if i == n && wback && i != LowestSetBit(registers) then 4484 if ((i == n) && wback && (i != lowest_set_bit)) 4485 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4486 WriteBits32UnknownToMemory (address + offset); 4487 else 4488 { 4489 // MemA[address,4] = R[i]; 4490 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4491 if (!success) 4492 return false; 4493 4494 RegisterInfo data_reg; 4495 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4496 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4497 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4498 return false; 4499 } 4500 4501 // address = address + 4; 4502 offset += addr_byte_size; 4503 } 4504 } 4505 4506 // if registers<15> == '1' then // Only possible for encoding A1 4507 // MemA[address,4] = PCStoreValue(); 4508 if (BitIsSet (registers, 15)) 4509 { 4510 RegisterInfo pc_reg; 4511 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4512 context.SetRegisterPlusOffset (pc_reg, 8); 4513 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4514 if (!success) 4515 return false; 4516 4517 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4518 return false; 4519 } 4520 4521 // if wback then R[n] = R[n] - 4*BitCount(registers); 4522 if (wback) 4523 { 4524 offset = (addr_byte_size * BitCount (registers)) * -1; 4525 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4526 context.SetImmediateSigned (offset); 4527 addr_t data = Rn + offset; 4528 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4529 return false; 4530 } 4531 } 4532 return true; 4533 } 4534 4535 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4536 // from a base register. The consecutive memory locations start just above this address, and the address of the last 4537 // of those locations can optionally be written back to the base register. 4538 bool 4539 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4540 { 4541 #if 0 4542 if ConditionPassed() then 4543 EncodingSpecificOperations(); 4544 address = R[n] + 4; 4545 4546 for i = 0 to 14 4547 if registers<i> == '1' then 4548 if i == n && wback && i != LowestSetBit(registers) then 4549 MemA[address,4] = bits(32) UNKNOWN; 4550 else 4551 MemA[address,4] = R[i]; 4552 address = address + 4; 4553 4554 if registers<15> == '1' then 4555 MemA[address,4] = PCStoreValue(); 4556 4557 if wback then R[n] = R[n] + 4*BitCount(registers); 4558 #endif 4559 4560 bool success = false; 4561 4562 if (ConditionPassed(opcode)) 4563 { 4564 uint32_t n; 4565 uint32_t registers = 0; 4566 bool wback; 4567 const uint32_t addr_byte_size = GetAddressByteSize(); 4568 4569 // EncodingSpecificOperations(); 4570 switch (encoding) 4571 { 4572 case eEncodingA1: 4573 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4574 n = Bits32 (opcode, 19, 16); 4575 registers = Bits32 (opcode, 15, 0); 4576 wback = BitIsSet (opcode, 21); 4577 4578 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4579 if ((n == 15) && (BitCount (registers) < 1)) 4580 return false; 4581 break; 4582 default: 4583 return false; 4584 } 4585 // address = R[n] + 4; 4586 4587 int32_t offset = 0; 4588 addr_t Rn = ReadCoreReg (n, &success); 4589 if (!success) 4590 return false; 4591 4592 addr_t address = Rn + addr_byte_size; 4593 4594 EmulateInstruction::Context context; 4595 context.type = EmulateInstruction::eContextRegisterStore; 4596 RegisterInfo base_reg; 4597 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4598 4599 uint32_t lowest_set_bit = 14; 4600 // for i = 0 to 14 4601 for (uint32_t i = 0; i < 14; ++i) 4602 { 4603 // if registers<i> == '1' then 4604 if (BitIsSet (registers, i)) 4605 { 4606 if (i < lowest_set_bit) 4607 lowest_set_bit = i; 4608 // if i == n && wback && i != LowestSetBit(registers) then 4609 if ((i == n) && wback && (i != lowest_set_bit)) 4610 // MemA[address,4] = bits(32) UNKNOWN; 4611 WriteBits32UnknownToMemory (address + offset); 4612 // else 4613 else 4614 { 4615 // MemA[address,4] = R[i]; 4616 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4617 if (!success) 4618 return false; 4619 4620 RegisterInfo data_reg; 4621 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4622 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4623 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4624 return false; 4625 } 4626 4627 // address = address + 4; 4628 offset += addr_byte_size; 4629 } 4630 } 4631 4632 // if registers<15> == '1' then 4633 // MemA[address,4] = PCStoreValue(); 4634 if (BitIsSet (registers, 15)) 4635 { 4636 RegisterInfo pc_reg; 4637 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4638 context.SetRegisterPlusOffset (pc_reg, 8); 4639 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4640 if (!success) 4641 return false; 4642 4643 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4644 return false; 4645 } 4646 4647 // if wback then R[n] = R[n] + 4*BitCount(registers); 4648 if (wback) 4649 { 4650 offset = addr_byte_size * BitCount (registers); 4651 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4652 context.SetImmediateSigned (offset); 4653 addr_t data = Rn + offset; 4654 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4655 return false; 4656 } 4657 } 4658 return true; 4659 } 4660 4661 // STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word 4662 // from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4663 bool 4664 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4665 { 4666 #if 0 4667 if ConditionPassed() then 4668 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4669 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4670 address = if index then offset_addr else R[n]; 4671 if UnalignedSupport() || address<1:0> == '00' then 4672 MemU[address,4] = R[t]; 4673 else // Can only occur before ARMv7 4674 MemU[address,4] = bits(32) UNKNOWN; 4675 if wback then R[n] = offset_addr; 4676 #endif 4677 4678 bool success = false; 4679 4680 if (ConditionPassed(opcode)) 4681 { 4682 const uint32_t addr_byte_size = GetAddressByteSize(); 4683 4684 uint32_t t; 4685 uint32_t n; 4686 uint32_t imm32; 4687 bool index; 4688 bool add; 4689 bool wback; 4690 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4691 switch (encoding) 4692 { 4693 case eEncodingT1: 4694 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4695 t = Bits32 (opcode, 2, 0); 4696 n = Bits32 (opcode, 5, 3); 4697 imm32 = Bits32 (opcode, 10, 6) << 2; 4698 4699 // index = TRUE; add = TRUE; wback = FALSE; 4700 index = true; 4701 add = false; 4702 wback = false; 4703 break; 4704 4705 case eEncodingT2: 4706 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4707 t = Bits32 (opcode, 10, 8); 4708 n = 13; 4709 imm32 = Bits32 (opcode, 7, 0) << 2; 4710 4711 // index = TRUE; add = TRUE; wback = FALSE; 4712 index = true; 4713 add = true; 4714 wback = false; 4715 break; 4716 4717 case eEncodingT3: 4718 // if Rn == '1111' then UNDEFINED; 4719 if (Bits32 (opcode, 19, 16) == 15) 4720 return false; 4721 4722 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4723 t = Bits32 (opcode, 15, 12); 4724 n = Bits32 (opcode, 19, 16); 4725 imm32 = Bits32 (opcode, 11, 0); 4726 4727 // index = TRUE; add = TRUE; wback = FALSE; 4728 index = true; 4729 add = true; 4730 wback = false; 4731 4732 // if t == 15 then UNPREDICTABLE; 4733 if (t == 15) 4734 return false; 4735 break; 4736 4737 case eEncodingT4: 4738 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4739 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4740 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4741 if ((Bits32 (opcode, 19, 16) == 15) 4742 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4743 return false; 4744 4745 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4746 t = Bits32 (opcode, 15, 12); 4747 n = Bits32 (opcode, 19, 16); 4748 imm32 = Bits32 (opcode, 7, 0); 4749 4750 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4751 index = BitIsSet (opcode, 10); 4752 add = BitIsSet (opcode, 9); 4753 wback = BitIsSet (opcode, 8); 4754 4755 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4756 if ((t == 15) || (wback && (n == t))) 4757 return false; 4758 break; 4759 4760 default: 4761 return false; 4762 } 4763 4764 addr_t offset_addr; 4765 addr_t address; 4766 4767 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4768 uint32_t base_address = ReadCoreReg (n, &success); 4769 if (!success) 4770 return false; 4771 4772 if (add) 4773 offset_addr = base_address + imm32; 4774 else 4775 offset_addr = base_address - imm32; 4776 4777 // address = if index then offset_addr else R[n]; 4778 if (index) 4779 address = offset_addr; 4780 else 4781 address = base_address; 4782 4783 EmulateInstruction::Context context; 4784 context.type = eContextRegisterStore; 4785 RegisterInfo base_reg; 4786 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4787 4788 // if UnalignedSupport() || address<1:0> == '00' then 4789 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4790 { 4791 // MemU[address,4] = R[t]; 4792 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4793 if (!success) 4794 return false; 4795 4796 RegisterInfo data_reg; 4797 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4798 int32_t offset = address - base_address; 4799 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4800 if (!MemUWrite (context, address, data, addr_byte_size)) 4801 return false; 4802 } 4803 else 4804 { 4805 // MemU[address,4] = bits(32) UNKNOWN; 4806 WriteBits32UnknownToMemory (address); 4807 } 4808 4809 // if wback then R[n] = offset_addr; 4810 if (wback) 4811 { 4812 context.type = eContextRegisterLoad; 4813 context.SetAddress (offset_addr); 4814 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4815 return false; 4816 } 4817 } 4818 return true; 4819 } 4820 4821 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4822 // word from a register to memory. The offset register value can optionally be shifted. 4823 bool 4824 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4825 { 4826 #if 0 4827 if ConditionPassed() then 4828 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4829 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4830 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4831 address = if index then offset_addr else R[n]; 4832 if t == 15 then // Only possible for encoding A1 4833 data = PCStoreValue(); 4834 else 4835 data = R[t]; 4836 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4837 MemU[address,4] = data; 4838 else // Can only occur before ARMv7 4839 MemU[address,4] = bits(32) UNKNOWN; 4840 if wback then R[n] = offset_addr; 4841 #endif 4842 4843 bool success = false; 4844 4845 if (ConditionPassed(opcode)) 4846 { 4847 const uint32_t addr_byte_size = GetAddressByteSize(); 4848 4849 uint32_t t; 4850 uint32_t n; 4851 uint32_t m; 4852 ARM_ShifterType shift_t; 4853 uint32_t shift_n; 4854 bool index; 4855 bool add; 4856 bool wback; 4857 4858 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4859 switch (encoding) 4860 { 4861 case eEncodingT1: 4862 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4863 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4864 t = Bits32 (opcode, 2, 0); 4865 n = Bits32 (opcode, 5, 3); 4866 m = Bits32 (opcode, 8, 6); 4867 4868 // index = TRUE; add = TRUE; wback = FALSE; 4869 index = true; 4870 add = true; 4871 wback = false; 4872 4873 // (shift_t, shift_n) = (SRType_LSL, 0); 4874 shift_t = SRType_LSL; 4875 shift_n = 0; 4876 break; 4877 4878 case eEncodingT2: 4879 // if Rn == '1111' then UNDEFINED; 4880 if (Bits32 (opcode, 19, 16) == 15) 4881 return false; 4882 4883 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4884 t = Bits32 (opcode, 15, 12); 4885 n = Bits32 (opcode, 19, 16); 4886 m = Bits32 (opcode, 3, 0); 4887 4888 // index = TRUE; add = TRUE; wback = FALSE; 4889 index = true; 4890 add = true; 4891 wback = false; 4892 4893 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4894 shift_t = SRType_LSL; 4895 shift_n = Bits32 (opcode, 5, 4); 4896 4897 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4898 if ((t == 15) || (BadReg (m))) 4899 return false; 4900 break; 4901 4902 case eEncodingA1: 4903 { 4904 // if P == '0' && W == '1' then SEE STRT; 4905 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4906 t = Bits32 (opcode, 15, 12); 4907 n = Bits32 (opcode, 19, 16); 4908 m = Bits32 (opcode, 3, 0); 4909 4910 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4911 index = BitIsSet (opcode, 24); 4912 add = BitIsSet (opcode, 23); 4913 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4914 4915 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4916 uint32_t typ = Bits32 (opcode, 6, 5); 4917 uint32_t imm5 = Bits32 (opcode, 11, 7); 4918 shift_n = DecodeImmShift(typ, imm5, shift_t); 4919 4920 // if m == 15 then UNPREDICTABLE; 4921 if (m == 15) 4922 return false; 4923 4924 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4925 if (wback && ((n == 15) || (n == t))) 4926 return false; 4927 4928 break; 4929 } 4930 default: 4931 return false; 4932 } 4933 4934 addr_t offset_addr; 4935 addr_t address; 4936 int32_t offset = 0; 4937 4938 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4939 if (!success) 4940 return false; 4941 4942 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4943 if (!success) 4944 return false; 4945 4946 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4947 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4948 if (!success) 4949 return false; 4950 4951 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4952 if (add) 4953 offset_addr = base_address + offset; 4954 else 4955 offset_addr = base_address - offset; 4956 4957 // address = if index then offset_addr else R[n]; 4958 if (index) 4959 address = offset_addr; 4960 else 4961 address = base_address; 4962 4963 uint32_t data; 4964 // if t == 15 then // Only possible for encoding A1 4965 if (t == 15) 4966 // data = PCStoreValue(); 4967 data = ReadCoreReg (PC_REG, &success); 4968 else 4969 // data = R[t]; 4970 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4971 4972 if (!success) 4973 return false; 4974 4975 EmulateInstruction::Context context; 4976 context.type = eContextRegisterStore; 4977 4978 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4979 if (UnalignedSupport () 4980 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4981 || CurrentInstrSet() == eModeARM) 4982 { 4983 // MemU[address,4] = data; 4984 4985 RegisterInfo base_reg; 4986 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4987 4988 RegisterInfo data_reg; 4989 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4990 4991 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4992 if (!MemUWrite (context, address, data, addr_byte_size)) 4993 return false; 4994 4995 } 4996 else 4997 // MemU[address,4] = bits(32) UNKNOWN; 4998 WriteBits32UnknownToMemory (address); 4999 5000 // if wback then R[n] = offset_addr; 5001 if (wback) 5002 { 5003 context.type = eContextRegisterLoad; 5004 context.SetAddress (offset_addr); 5005 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5006 return false; 5007 } 5008 5009 } 5010 return true; 5011 } 5012 5013 bool 5014 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 5015 { 5016 #if 0 5017 if ConditionPassed() then 5018 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5019 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5020 address = if index then offset_addr else R[n]; 5021 MemU[address,1] = R[t]<7:0>; 5022 if wback then R[n] = offset_addr; 5023 #endif 5024 5025 5026 bool success = false; 5027 5028 if (ConditionPassed(opcode)) 5029 { 5030 uint32_t t; 5031 uint32_t n; 5032 uint32_t imm32; 5033 bool index; 5034 bool add; 5035 bool wback; 5036 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5037 switch (encoding) 5038 { 5039 case eEncodingT1: 5040 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5041 t = Bits32 (opcode, 2, 0); 5042 n = Bits32 (opcode, 5, 3); 5043 imm32 = Bits32 (opcode, 10, 6); 5044 5045 // index = TRUE; add = TRUE; wback = FALSE; 5046 index = true; 5047 add = true; 5048 wback = false; 5049 break; 5050 5051 case eEncodingT2: 5052 // if Rn == '1111' then UNDEFINED; 5053 if (Bits32 (opcode, 19, 16) == 15) 5054 return false; 5055 5056 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5057 t = Bits32 (opcode, 15, 12); 5058 n = Bits32 (opcode, 19, 16); 5059 imm32 = Bits32 (opcode, 11, 0); 5060 5061 // index = TRUE; add = TRUE; wback = FALSE; 5062 index = true; 5063 add = true; 5064 wback = false; 5065 5066 // if BadReg(t) then UNPREDICTABLE; 5067 if (BadReg (t)) 5068 return false; 5069 break; 5070 5071 case eEncodingT3: 5072 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5073 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5074 if (Bits32 (opcode, 19, 16) == 15) 5075 return false; 5076 5077 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5078 t = Bits32 (opcode, 15, 12); 5079 n = Bits32 (opcode, 19, 16); 5080 imm32 = Bits32 (opcode, 7, 0); 5081 5082 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5083 index = BitIsSet (opcode, 10); 5084 add = BitIsSet (opcode, 9); 5085 wback = BitIsSet (opcode, 8); 5086 5087 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5088 if ((BadReg (t)) || (wback && (n == t))) 5089 return false; 5090 break; 5091 5092 default: 5093 return false; 5094 } 5095 5096 addr_t offset_addr; 5097 addr_t address; 5098 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5099 if (!success) 5100 return false; 5101 5102 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5103 if (add) 5104 offset_addr = base_address + imm32; 5105 else 5106 offset_addr = base_address - imm32; 5107 5108 // address = if index then offset_addr else R[n]; 5109 if (index) 5110 address = offset_addr; 5111 else 5112 address = base_address; 5113 5114 // MemU[address,1] = R[t]<7:0> 5115 RegisterInfo base_reg; 5116 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5117 5118 RegisterInfo data_reg; 5119 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5120 5121 EmulateInstruction::Context context; 5122 context.type = eContextRegisterStore; 5123 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5124 5125 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5126 if (!success) 5127 return false; 5128 5129 data = Bits32 (data, 7, 0); 5130 5131 if (!MemUWrite (context, address, data, 1)) 5132 return false; 5133 5134 // if wback then R[n] = offset_addr; 5135 if (wback) 5136 { 5137 context.type = eContextRegisterLoad; 5138 context.SetAddress (offset_addr); 5139 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5140 return false; 5141 } 5142 5143 } 5144 5145 return true; 5146 } 5147 5148 // STRH (register) calculates an address from a base register value and an offset register value, and stores a 5149 // halfword from a register to memory. The offset register value can be shifted left by 0, 1, 2, or 3 bits. 5150 bool 5151 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5152 { 5153 #if 0 5154 if ConditionPassed() then 5155 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5156 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5157 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5158 address = if index then offset_addr else R[n]; 5159 if UnalignedSupport() || address<0> == '0' then 5160 MemU[address,2] = R[t]<15:0>; 5161 else // Can only occur before ARMv7 5162 MemU[address,2] = bits(16) UNKNOWN; 5163 if wback then R[n] = offset_addr; 5164 #endif 5165 5166 bool success = false; 5167 5168 if (ConditionPassed(opcode)) 5169 { 5170 uint32_t t; 5171 uint32_t n; 5172 uint32_t m; 5173 bool index; 5174 bool add; 5175 bool wback; 5176 ARM_ShifterType shift_t; 5177 uint32_t shift_n; 5178 5179 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5180 switch (encoding) 5181 { 5182 case eEncodingT1: 5183 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5184 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5185 t = Bits32 (opcode, 2, 0); 5186 n = Bits32 (opcode, 5, 3); 5187 m = Bits32 (opcode, 8, 6); 5188 5189 // index = TRUE; add = TRUE; wback = FALSE; 5190 index = true; 5191 add = true; 5192 wback = false; 5193 5194 // (shift_t, shift_n) = (SRType_LSL, 0); 5195 shift_t = SRType_LSL; 5196 shift_n = 0; 5197 5198 break; 5199 5200 case eEncodingT2: 5201 // if Rn == '1111' then UNDEFINED; 5202 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5203 t = Bits32 (opcode, 15, 12); 5204 n = Bits32 (opcode, 19, 16); 5205 m = Bits32 (opcode, 3, 0); 5206 if (n == 15) 5207 return false; 5208 5209 // index = TRUE; add = TRUE; wback = FALSE; 5210 index = true; 5211 add = true; 5212 wback = false; 5213 5214 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5215 shift_t = SRType_LSL; 5216 shift_n = Bits32 (opcode, 5, 4); 5217 5218 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5219 if (BadReg (t) || BadReg (m)) 5220 return false; 5221 5222 break; 5223 5224 case eEncodingA1: 5225 // if P == '0' && W == '1' then SEE STRHT; 5226 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5227 t = Bits32 (opcode, 15, 12); 5228 n = Bits32 (opcode, 19, 16); 5229 m = Bits32 (opcode, 3, 0); 5230 5231 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5232 index = BitIsSet (opcode, 24); 5233 add = BitIsSet (opcode, 23); 5234 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5235 5236 // (shift_t, shift_n) = (SRType_LSL, 0); 5237 shift_t = SRType_LSL; 5238 shift_n = 0; 5239 5240 // if t == 15 || m == 15 then UNPREDICTABLE; 5241 if ((t == 15) || (m == 15)) 5242 return false; 5243 5244 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5245 if (wback && ((n == 15) || (n == t))) 5246 return false; 5247 5248 break; 5249 5250 default: 5251 return false; 5252 } 5253 5254 uint32_t Rm = ReadCoreReg (m, &success); 5255 if (!success) 5256 return false; 5257 5258 uint32_t Rn = ReadCoreReg (n, &success); 5259 if (!success) 5260 return false; 5261 5262 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5263 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5264 if (!success) 5265 return false; 5266 5267 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5268 addr_t offset_addr; 5269 if (add) 5270 offset_addr = Rn + offset; 5271 else 5272 offset_addr = Rn - offset; 5273 5274 // address = if index then offset_addr else R[n]; 5275 addr_t address; 5276 if (index) 5277 address = offset_addr; 5278 else 5279 address = Rn; 5280 5281 EmulateInstruction::Context context; 5282 context.type = eContextRegisterStore; 5283 RegisterInfo base_reg; 5284 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5285 RegisterInfo offset_reg; 5286 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5287 5288 // if UnalignedSupport() || address<0> == '0' then 5289 if (UnalignedSupport() || BitIsClear (address, 0)) 5290 { 5291 // MemU[address,2] = R[t]<15:0>; 5292 uint32_t Rt = ReadCoreReg (t, &success); 5293 if (!success) 5294 return false; 5295 5296 EmulateInstruction::Context context; 5297 context.type = eContextRegisterStore; 5298 RegisterInfo base_reg; 5299 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5300 RegisterInfo offset_reg; 5301 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5302 RegisterInfo data_reg; 5303 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5304 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5305 5306 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5307 return false; 5308 } 5309 else // Can only occur before ARMv7 5310 { 5311 // MemU[address,2] = bits(16) UNKNOWN; 5312 } 5313 5314 // if wback then R[n] = offset_addr; 5315 if (wback) 5316 { 5317 context.type = eContextAdjustBaseRegister; 5318 context.SetAddress (offset_addr); 5319 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5320 return false; 5321 } 5322 } 5323 5324 return true; 5325 } 5326 5327 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5328 // and writes the result to the destination register. It can optionally update the condition flags 5329 // based on the result. 5330 bool 5331 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5332 { 5333 #if 0 5334 // ARM pseudo code... 5335 if ConditionPassed() then 5336 EncodingSpecificOperations(); 5337 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5338 if d == 15 then // Can only occur for ARM encoding 5339 ALUWritePC(result); // setflags is always FALSE here 5340 else 5341 R[d] = result; 5342 if setflags then 5343 APSR.N = result<31>; 5344 APSR.Z = IsZeroBit(result); 5345 APSR.C = carry; 5346 APSR.V = overflow; 5347 #endif 5348 5349 bool success = false; 5350 5351 if (ConditionPassed(opcode)) 5352 { 5353 uint32_t Rd, Rn; 5354 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5355 bool setflags; 5356 switch (encoding) 5357 { 5358 case eEncodingT1: 5359 Rd = Bits32(opcode, 11, 8); 5360 Rn = Bits32(opcode, 19, 16); 5361 setflags = BitIsSet(opcode, 20); 5362 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5363 if (BadReg(Rd) || BadReg(Rn)) 5364 return false; 5365 break; 5366 case eEncodingA1: 5367 Rd = Bits32(opcode, 15, 12); 5368 Rn = Bits32(opcode, 19, 16); 5369 setflags = BitIsSet(opcode, 20); 5370 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5371 5372 if (Rd == 15 && setflags) 5373 return EmulateSUBSPcLrEtc (opcode, encoding); 5374 break; 5375 default: 5376 return false; 5377 } 5378 5379 // Read the first operand. 5380 int32_t val1 = ReadCoreReg(Rn, &success); 5381 if (!success) 5382 return false; 5383 5384 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5385 5386 EmulateInstruction::Context context; 5387 context.type = EmulateInstruction::eContextImmediate; 5388 context.SetNoArgs (); 5389 5390 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5391 return false; 5392 } 5393 return true; 5394 } 5395 5396 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5397 // register value, and writes the result to the destination register. It can optionally update the 5398 // condition flags based on the result. 5399 bool 5400 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5401 { 5402 #if 0 5403 // ARM pseudo code... 5404 if ConditionPassed() then 5405 EncodingSpecificOperations(); 5406 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5407 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5408 if d == 15 then // Can only occur for ARM encoding 5409 ALUWritePC(result); // setflags is always FALSE here 5410 else 5411 R[d] = result; 5412 if setflags then 5413 APSR.N = result<31>; 5414 APSR.Z = IsZeroBit(result); 5415 APSR.C = carry; 5416 APSR.V = overflow; 5417 #endif 5418 5419 bool success = false; 5420 5421 if (ConditionPassed(opcode)) 5422 { 5423 uint32_t Rd, Rn, Rm; 5424 ARM_ShifterType shift_t; 5425 uint32_t shift_n; // the shift applied to the value read from Rm 5426 bool setflags; 5427 switch (encoding) 5428 { 5429 case eEncodingT1: 5430 Rd = Rn = Bits32(opcode, 2, 0); 5431 Rm = Bits32(opcode, 5, 3); 5432 setflags = !InITBlock(); 5433 shift_t = SRType_LSL; 5434 shift_n = 0; 5435 break; 5436 case eEncodingT2: 5437 Rd = Bits32(opcode, 11, 8); 5438 Rn = Bits32(opcode, 19, 16); 5439 Rm = Bits32(opcode, 3, 0); 5440 setflags = BitIsSet(opcode, 20); 5441 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5442 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5443 return false; 5444 break; 5445 case eEncodingA1: 5446 Rd = Bits32(opcode, 15, 12); 5447 Rn = Bits32(opcode, 19, 16); 5448 Rm = Bits32(opcode, 3, 0); 5449 setflags = BitIsSet(opcode, 20); 5450 shift_n = DecodeImmShiftARM(opcode, shift_t); 5451 5452 if (Rd == 15 && setflags) 5453 return EmulateSUBSPcLrEtc (opcode, encoding); 5454 break; 5455 default: 5456 return false; 5457 } 5458 5459 // Read the first operand. 5460 int32_t val1 = ReadCoreReg(Rn, &success); 5461 if (!success) 5462 return false; 5463 5464 // Read the second operand. 5465 int32_t val2 = ReadCoreReg(Rm, &success); 5466 if (!success) 5467 return false; 5468 5469 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5470 if (!success) 5471 return false; 5472 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5473 5474 EmulateInstruction::Context context; 5475 context.type = EmulateInstruction::eContextImmediate; 5476 context.SetNoArgs (); 5477 5478 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5479 return false; 5480 } 5481 return true; 5482 } 5483 5484 // This instruction adds an immediate value to the PC value to form a PC-relative address, 5485 // and writes the result to the destination register. 5486 bool 5487 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5488 { 5489 #if 0 5490 // ARM pseudo code... 5491 if ConditionPassed() then 5492 EncodingSpecificOperations(); 5493 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5494 if d == 15 then // Can only occur for ARM encodings 5495 ALUWritePC(result); 5496 else 5497 R[d] = result; 5498 #endif 5499 5500 bool success = false; 5501 5502 if (ConditionPassed(opcode)) 5503 { 5504 uint32_t Rd; 5505 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5506 bool add; 5507 switch (encoding) 5508 { 5509 case eEncodingT1: 5510 Rd = Bits32(opcode, 10, 8); 5511 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5512 add = true; 5513 break; 5514 case eEncodingT2: 5515 case eEncodingT3: 5516 Rd = Bits32(opcode, 11, 8); 5517 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5518 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5519 if (BadReg(Rd)) 5520 return false; 5521 break; 5522 case eEncodingA1: 5523 case eEncodingA2: 5524 Rd = Bits32(opcode, 15, 12); 5525 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5526 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5527 break; 5528 default: 5529 return false; 5530 } 5531 5532 // Read the PC value. 5533 uint32_t pc = ReadCoreReg(PC_REG, &success); 5534 if (!success) 5535 return false; 5536 5537 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5538 5539 EmulateInstruction::Context context; 5540 context.type = EmulateInstruction::eContextImmediate; 5541 context.SetNoArgs (); 5542 5543 if (!WriteCoreReg(context, result, Rd)) 5544 return false; 5545 } 5546 return true; 5547 } 5548 5549 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5550 // to the destination register. It can optionally update the condition flags based on the result. 5551 bool 5552 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5553 { 5554 #if 0 5555 // ARM pseudo code... 5556 if ConditionPassed() then 5557 EncodingSpecificOperations(); 5558 result = R[n] AND imm32; 5559 if d == 15 then // Can only occur for ARM encoding 5560 ALUWritePC(result); // setflags is always FALSE here 5561 else 5562 R[d] = result; 5563 if setflags then 5564 APSR.N = result<31>; 5565 APSR.Z = IsZeroBit(result); 5566 APSR.C = carry; 5567 // APSR.V unchanged 5568 #endif 5569 5570 bool success = false; 5571 5572 if (ConditionPassed(opcode)) 5573 { 5574 uint32_t Rd, Rn; 5575 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5576 bool setflags; 5577 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5578 switch (encoding) 5579 { 5580 case eEncodingT1: 5581 Rd = Bits32(opcode, 11, 8); 5582 Rn = Bits32(opcode, 19, 16); 5583 setflags = BitIsSet(opcode, 20); 5584 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5585 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5586 if (Rd == 15 && setflags) 5587 return EmulateTSTImm(opcode, eEncodingT1); 5588 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5589 return false; 5590 break; 5591 case eEncodingA1: 5592 Rd = Bits32(opcode, 15, 12); 5593 Rn = Bits32(opcode, 19, 16); 5594 setflags = BitIsSet(opcode, 20); 5595 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5596 5597 if (Rd == 15 && setflags) 5598 return EmulateSUBSPcLrEtc (opcode, encoding); 5599 break; 5600 default: 5601 return false; 5602 } 5603 5604 // Read the first operand. 5605 uint32_t val1 = ReadCoreReg(Rn, &success); 5606 if (!success) 5607 return false; 5608 5609 uint32_t result = val1 & imm32; 5610 5611 EmulateInstruction::Context context; 5612 context.type = EmulateInstruction::eContextImmediate; 5613 context.SetNoArgs (); 5614 5615 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5616 return false; 5617 } 5618 return true; 5619 } 5620 5621 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5622 // and writes the result to the destination register. It can optionally update the condition flags 5623 // based on the result. 5624 bool 5625 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5626 { 5627 #if 0 5628 // ARM pseudo code... 5629 if ConditionPassed() then 5630 EncodingSpecificOperations(); 5631 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5632 result = R[n] AND shifted; 5633 if d == 15 then // Can only occur for ARM encoding 5634 ALUWritePC(result); // setflags is always FALSE here 5635 else 5636 R[d] = result; 5637 if setflags then 5638 APSR.N = result<31>; 5639 APSR.Z = IsZeroBit(result); 5640 APSR.C = carry; 5641 // APSR.V unchanged 5642 #endif 5643 5644 bool success = false; 5645 5646 if (ConditionPassed(opcode)) 5647 { 5648 uint32_t Rd, Rn, Rm; 5649 ARM_ShifterType shift_t; 5650 uint32_t shift_n; // the shift applied to the value read from Rm 5651 bool setflags; 5652 uint32_t carry; 5653 switch (encoding) 5654 { 5655 case eEncodingT1: 5656 Rd = Rn = Bits32(opcode, 2, 0); 5657 Rm = Bits32(opcode, 5, 3); 5658 setflags = !InITBlock(); 5659 shift_t = SRType_LSL; 5660 shift_n = 0; 5661 break; 5662 case eEncodingT2: 5663 Rd = Bits32(opcode, 11, 8); 5664 Rn = Bits32(opcode, 19, 16); 5665 Rm = Bits32(opcode, 3, 0); 5666 setflags = BitIsSet(opcode, 20); 5667 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5668 // if Rd == '1111' && S == '1' then SEE TST (register); 5669 if (Rd == 15 && setflags) 5670 return EmulateTSTReg(opcode, eEncodingT2); 5671 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5672 return false; 5673 break; 5674 case eEncodingA1: 5675 Rd = Bits32(opcode, 15, 12); 5676 Rn = Bits32(opcode, 19, 16); 5677 Rm = Bits32(opcode, 3, 0); 5678 setflags = BitIsSet(opcode, 20); 5679 shift_n = DecodeImmShiftARM(opcode, shift_t); 5680 5681 if (Rd == 15 && setflags) 5682 return EmulateSUBSPcLrEtc (opcode, encoding); 5683 break; 5684 default: 5685 return false; 5686 } 5687 5688 // Read the first operand. 5689 uint32_t val1 = ReadCoreReg(Rn, &success); 5690 if (!success) 5691 return false; 5692 5693 // Read the second operand. 5694 uint32_t val2 = ReadCoreReg(Rm, &success); 5695 if (!success) 5696 return false; 5697 5698 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5699 if (!success) 5700 return false; 5701 uint32_t result = val1 & shifted; 5702 5703 EmulateInstruction::Context context; 5704 context.type = EmulateInstruction::eContextImmediate; 5705 context.SetNoArgs (); 5706 5707 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5708 return false; 5709 } 5710 return true; 5711 } 5712 5713 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5714 // immediate value, and writes the result to the destination register. It can optionally update the 5715 // condition flags based on the result. 5716 bool 5717 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5718 { 5719 #if 0 5720 // ARM pseudo code... 5721 if ConditionPassed() then 5722 EncodingSpecificOperations(); 5723 result = R[n] AND NOT(imm32); 5724 if d == 15 then // Can only occur for ARM encoding 5725 ALUWritePC(result); // setflags is always FALSE here 5726 else 5727 R[d] = result; 5728 if setflags then 5729 APSR.N = result<31>; 5730 APSR.Z = IsZeroBit(result); 5731 APSR.C = carry; 5732 // APSR.V unchanged 5733 #endif 5734 5735 bool success = false; 5736 5737 if (ConditionPassed(opcode)) 5738 { 5739 uint32_t Rd, Rn; 5740 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5741 bool setflags; 5742 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5743 switch (encoding) 5744 { 5745 case eEncodingT1: 5746 Rd = Bits32(opcode, 11, 8); 5747 Rn = Bits32(opcode, 19, 16); 5748 setflags = BitIsSet(opcode, 20); 5749 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5750 if (BadReg(Rd) || BadReg(Rn)) 5751 return false; 5752 break; 5753 case eEncodingA1: 5754 Rd = Bits32(opcode, 15, 12); 5755 Rn = Bits32(opcode, 19, 16); 5756 setflags = BitIsSet(opcode, 20); 5757 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5758 5759 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5760 if (Rd == 15 && setflags) 5761 return EmulateSUBSPcLrEtc (opcode, encoding); 5762 break; 5763 default: 5764 return false; 5765 } 5766 5767 // Read the first operand. 5768 uint32_t val1 = ReadCoreReg(Rn, &success); 5769 if (!success) 5770 return false; 5771 5772 uint32_t result = val1 & ~imm32; 5773 5774 EmulateInstruction::Context context; 5775 context.type = EmulateInstruction::eContextImmediate; 5776 context.SetNoArgs (); 5777 5778 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5779 return false; 5780 } 5781 return true; 5782 } 5783 5784 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5785 // optionally-shifted register value, and writes the result to the destination register. 5786 // It can optionally update the condition flags based on the result. 5787 bool 5788 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5789 { 5790 #if 0 5791 // ARM pseudo code... 5792 if ConditionPassed() then 5793 EncodingSpecificOperations(); 5794 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5795 result = R[n] AND NOT(shifted); 5796 if d == 15 then // Can only occur for ARM encoding 5797 ALUWritePC(result); // setflags is always FALSE here 5798 else 5799 R[d] = result; 5800 if setflags then 5801 APSR.N = result<31>; 5802 APSR.Z = IsZeroBit(result); 5803 APSR.C = carry; 5804 // APSR.V unchanged 5805 #endif 5806 5807 bool success = false; 5808 5809 if (ConditionPassed(opcode)) 5810 { 5811 uint32_t Rd, Rn, Rm; 5812 ARM_ShifterType shift_t; 5813 uint32_t shift_n; // the shift applied to the value read from Rm 5814 bool setflags; 5815 uint32_t carry; 5816 switch (encoding) 5817 { 5818 case eEncodingT1: 5819 Rd = Rn = Bits32(opcode, 2, 0); 5820 Rm = Bits32(opcode, 5, 3); 5821 setflags = !InITBlock(); 5822 shift_t = SRType_LSL; 5823 shift_n = 0; 5824 break; 5825 case eEncodingT2: 5826 Rd = Bits32(opcode, 11, 8); 5827 Rn = Bits32(opcode, 19, 16); 5828 Rm = Bits32(opcode, 3, 0); 5829 setflags = BitIsSet(opcode, 20); 5830 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5831 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5832 return false; 5833 break; 5834 case eEncodingA1: 5835 Rd = Bits32(opcode, 15, 12); 5836 Rn = Bits32(opcode, 19, 16); 5837 Rm = Bits32(opcode, 3, 0); 5838 setflags = BitIsSet(opcode, 20); 5839 shift_n = DecodeImmShiftARM(opcode, shift_t); 5840 5841 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5842 if (Rd == 15 && setflags) 5843 return EmulateSUBSPcLrEtc (opcode, encoding); 5844 break; 5845 default: 5846 return false; 5847 } 5848 5849 // Read the first operand. 5850 uint32_t val1 = ReadCoreReg(Rn, &success); 5851 if (!success) 5852 return false; 5853 5854 // Read the second operand. 5855 uint32_t val2 = ReadCoreReg(Rm, &success); 5856 if (!success) 5857 return false; 5858 5859 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5860 if (!success) 5861 return false; 5862 uint32_t result = val1 & ~shifted; 5863 5864 EmulateInstruction::Context context; 5865 context.type = EmulateInstruction::eContextImmediate; 5866 context.SetNoArgs (); 5867 5868 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5869 return false; 5870 } 5871 return true; 5872 } 5873 5874 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5875 // from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5876 bool 5877 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5878 { 5879 #if 0 5880 if ConditionPassed() then 5881 EncodingSpecificOperations(); 5882 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5883 address = if index then offset_addr else R[n]; 5884 data = MemU[address,4]; 5885 if wback then R[n] = offset_addr; 5886 if t == 15 then 5887 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5888 elsif UnalignedSupport() || address<1:0> = '00' then 5889 R[t] = data; 5890 else // Can only apply before ARMv7 5891 R[t] = ROR(data, 8*UInt(address<1:0>)); 5892 #endif 5893 5894 bool success = false; 5895 5896 if (ConditionPassed(opcode)) 5897 { 5898 const uint32_t addr_byte_size = GetAddressByteSize(); 5899 5900 uint32_t t; 5901 uint32_t n; 5902 uint32_t imm32; 5903 bool index; 5904 bool add; 5905 bool wback; 5906 5907 switch (encoding) 5908 { 5909 case eEncodingA1: 5910 // if Rn == '1111' then SEE LDR (literal); 5911 // if P == '0' && W == '1' then SEE LDRT; 5912 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5913 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5914 t = Bits32 (opcode, 15, 12); 5915 n = Bits32 (opcode, 19, 16); 5916 imm32 = Bits32 (opcode, 11, 0); 5917 5918 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5919 index = BitIsSet (opcode, 24); 5920 add = BitIsSet (opcode, 23); 5921 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5922 5923 // if wback && n == t then UNPREDICTABLE; 5924 if (wback && (n == t)) 5925 return false; 5926 5927 break; 5928 5929 default: 5930 return false; 5931 } 5932 5933 addr_t address; 5934 addr_t offset_addr; 5935 addr_t base_address = ReadCoreReg (n, &success); 5936 if (!success) 5937 return false; 5938 5939 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5940 if (add) 5941 offset_addr = base_address + imm32; 5942 else 5943 offset_addr = base_address - imm32; 5944 5945 // address = if index then offset_addr else R[n]; 5946 if (index) 5947 address = offset_addr; 5948 else 5949 address = base_address; 5950 5951 // data = MemU[address,4]; 5952 5953 RegisterInfo base_reg; 5954 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5955 5956 EmulateInstruction::Context context; 5957 context.type = eContextRegisterLoad; 5958 context.SetRegisterPlusOffset (base_reg, address - base_address); 5959 5960 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5961 if (!success) 5962 return false; 5963 5964 // if wback then R[n] = offset_addr; 5965 if (wback) 5966 { 5967 context.type = eContextAdjustBaseRegister; 5968 context.SetAddress (offset_addr); 5969 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5970 return false; 5971 } 5972 5973 // if t == 15 then 5974 if (t == 15) 5975 { 5976 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5977 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5978 { 5979 // LoadWritePC (data); 5980 context.type = eContextRegisterLoad; 5981 context.SetRegisterPlusOffset (base_reg, address - base_address); 5982 LoadWritePC (context, data); 5983 } 5984 else 5985 return false; 5986 } 5987 // elsif UnalignedSupport() || address<1:0> = '00' then 5988 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5989 { 5990 // R[t] = data; 5991 context.type = eContextRegisterLoad; 5992 context.SetRegisterPlusOffset (base_reg, address - base_address); 5993 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5994 return false; 5995 } 5996 // else // Can only apply before ARMv7 5997 else 5998 { 5999 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6000 data = ROR (data, Bits32 (address, 1, 0), &success); 6001 if (!success) 6002 return false; 6003 context.type = eContextRegisterLoad; 6004 context.SetImmediate (data); 6005 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6006 return false; 6007 } 6008 6009 } 6010 return true; 6011 } 6012 6013 // LDR (register) calculates an address from a base register value and an offset register value, loads a word 6014 // from memory, and writes it to a register. The offset register value can optionally be shifted. 6015 bool 6016 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 6017 { 6018 #if 0 6019 if ConditionPassed() then 6020 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6021 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6022 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6023 address = if index then offset_addr else R[n]; 6024 data = MemU[address,4]; 6025 if wback then R[n] = offset_addr; 6026 if t == 15 then 6027 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6028 elsif UnalignedSupport() || address<1:0> = '00' then 6029 R[t] = data; 6030 else // Can only apply before ARMv7 6031 if CurrentInstrSet() == InstrSet_ARM then 6032 R[t] = ROR(data, 8*UInt(address<1:0>)); 6033 else 6034 R[t] = bits(32) UNKNOWN; 6035 #endif 6036 6037 bool success = false; 6038 6039 if (ConditionPassed(opcode)) 6040 { 6041 const uint32_t addr_byte_size = GetAddressByteSize(); 6042 6043 uint32_t t; 6044 uint32_t n; 6045 uint32_t m; 6046 bool index; 6047 bool add; 6048 bool wback; 6049 ARM_ShifterType shift_t; 6050 uint32_t shift_n; 6051 6052 switch (encoding) 6053 { 6054 case eEncodingT1: 6055 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6056 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6057 t = Bits32 (opcode, 2, 0); 6058 n = Bits32 (opcode, 5, 3); 6059 m = Bits32 (opcode, 8, 6); 6060 6061 // index = TRUE; add = TRUE; wback = FALSE; 6062 index = true; 6063 add = true; 6064 wback = false; 6065 6066 // (shift_t, shift_n) = (SRType_LSL, 0); 6067 shift_t = SRType_LSL; 6068 shift_n = 0; 6069 6070 break; 6071 6072 case eEncodingT2: 6073 // if Rn == '1111' then SEE LDR (literal); 6074 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6075 t = Bits32 (opcode, 15, 12); 6076 n = Bits32 (opcode, 19, 16); 6077 m = Bits32 (opcode, 3, 0); 6078 6079 // index = TRUE; add = TRUE; wback = FALSE; 6080 index = true; 6081 add = true; 6082 wback = false; 6083 6084 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6085 shift_t = SRType_LSL; 6086 shift_n = Bits32 (opcode, 5, 4); 6087 6088 // if BadReg(m) then UNPREDICTABLE; 6089 if (BadReg (m)) 6090 return false; 6091 6092 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6093 if ((t == 15) && InITBlock() && !LastInITBlock()) 6094 return false; 6095 6096 break; 6097 6098 case eEncodingA1: 6099 { 6100 // if P == '0' && W == '1' then SEE LDRT; 6101 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6102 t = Bits32 (opcode, 15, 12); 6103 n = Bits32 (opcode, 19, 16); 6104 m = Bits32 (opcode, 3, 0); 6105 6106 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6107 index = BitIsSet (opcode, 24); 6108 add = BitIsSet (opcode, 23); 6109 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6110 6111 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6112 uint32_t type = Bits32 (opcode, 6, 5); 6113 uint32_t imm5 = Bits32 (opcode, 11, 7); 6114 shift_n = DecodeImmShift (type, imm5, shift_t); 6115 6116 // if m == 15 then UNPREDICTABLE; 6117 if (m == 15) 6118 return false; 6119 6120 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6121 if (wback && ((n == 15) || (n == t))) 6122 return false; 6123 } 6124 break; 6125 6126 6127 default: 6128 return false; 6129 } 6130 6131 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6132 if (!success) 6133 return false; 6134 6135 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6136 if (!success) 6137 return false; 6138 6139 addr_t offset_addr; 6140 addr_t address; 6141 6142 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6143 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6144 if (!success) 6145 return false; 6146 6147 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6148 if (add) 6149 offset_addr = Rn + offset; 6150 else 6151 offset_addr = Rn - offset; 6152 6153 // address = if index then offset_addr else R[n]; 6154 if (index) 6155 address = offset_addr; 6156 else 6157 address = Rn; 6158 6159 // data = MemU[address,4]; 6160 RegisterInfo base_reg; 6161 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6162 6163 EmulateInstruction::Context context; 6164 context.type = eContextRegisterLoad; 6165 context.SetRegisterPlusOffset (base_reg, address - Rn); 6166 6167 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6168 if (!success) 6169 return false; 6170 6171 // if wback then R[n] = offset_addr; 6172 if (wback) 6173 { 6174 context.type = eContextAdjustBaseRegister; 6175 context.SetAddress (offset_addr); 6176 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6177 return false; 6178 } 6179 6180 // if t == 15 then 6181 if (t == 15) 6182 { 6183 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6184 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6185 { 6186 context.type = eContextRegisterLoad; 6187 context.SetRegisterPlusOffset (base_reg, address - Rn); 6188 LoadWritePC (context, data); 6189 } 6190 else 6191 return false; 6192 } 6193 // elsif UnalignedSupport() || address<1:0> = '00' then 6194 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6195 { 6196 // R[t] = data; 6197 context.type = eContextRegisterLoad; 6198 context.SetRegisterPlusOffset (base_reg, address - Rn); 6199 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6200 return false; 6201 } 6202 else // Can only apply before ARMv7 6203 { 6204 // if CurrentInstrSet() == InstrSet_ARM then 6205 if (CurrentInstrSet () == eModeARM) 6206 { 6207 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6208 data = ROR (data, Bits32 (address, 1, 0), &success); 6209 if (!success) 6210 return false; 6211 context.type = eContextRegisterLoad; 6212 context.SetImmediate (data); 6213 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6214 return false; 6215 } 6216 else 6217 { 6218 // R[t] = bits(32) UNKNOWN; 6219 WriteBits32Unknown (t); 6220 } 6221 } 6222 } 6223 return true; 6224 } 6225 6226 // LDRB (immediate, Thumb) 6227 bool 6228 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6229 { 6230 #if 0 6231 if ConditionPassed() then 6232 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6233 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6234 address = if index then offset_addr else R[n]; 6235 R[t] = ZeroExtend(MemU[address,1], 32); 6236 if wback then R[n] = offset_addr; 6237 #endif 6238 6239 bool success = false; 6240 6241 if (ConditionPassed(opcode)) 6242 { 6243 uint32_t t; 6244 uint32_t n; 6245 uint32_t imm32; 6246 bool index; 6247 bool add; 6248 bool wback; 6249 6250 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6251 switch (encoding) 6252 { 6253 case eEncodingT1: 6254 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6255 t = Bits32 (opcode, 2, 0); 6256 n = Bits32 (opcode, 5, 3); 6257 imm32 = Bits32 (opcode, 10, 6); 6258 6259 // index = TRUE; add = TRUE; wback = FALSE; 6260 index = true; 6261 add = true; 6262 wback= false; 6263 6264 break; 6265 6266 case eEncodingT2: 6267 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6268 t = Bits32 (opcode, 15, 12); 6269 n = Bits32 (opcode, 19, 16); 6270 imm32 = Bits32 (opcode, 11, 0); 6271 6272 // index = TRUE; add = TRUE; wback = FALSE; 6273 index = true; 6274 add = true; 6275 wback = false; 6276 6277 // if Rt == '1111' then SEE PLD; 6278 if (t == 15) 6279 return false; // PLD is not implemented yet 6280 6281 // if Rn == '1111' then SEE LDRB (literal); 6282 if (n == 15) 6283 return EmulateLDRBLiteral(opcode, eEncodingT1); 6284 6285 // if t == 13 then UNPREDICTABLE; 6286 if (t == 13) 6287 return false; 6288 6289 break; 6290 6291 case eEncodingT3: 6292 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6293 // if P == '0' && W == '0' then UNDEFINED; 6294 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6295 return false; 6296 6297 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6298 t = Bits32 (opcode, 15, 12); 6299 n = Bits32 (opcode, 19, 16); 6300 imm32 = Bits32 (opcode, 7, 0); 6301 6302 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6303 index = BitIsSet (opcode, 10); 6304 add = BitIsSet (opcode, 9); 6305 wback = BitIsSet (opcode, 8); 6306 6307 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6308 if (t == 15) 6309 return false; // PLD is not implemented yet 6310 6311 // if Rn == '1111' then SEE LDRB (literal); 6312 if (n == 15) 6313 return EmulateLDRBLiteral(opcode, eEncodingT1); 6314 6315 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6316 if (BadReg (t) || (wback && (n == t))) 6317 return false; 6318 6319 break; 6320 6321 default: 6322 return false; 6323 } 6324 6325 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6326 if (!success) 6327 return false; 6328 6329 addr_t address; 6330 addr_t offset_addr; 6331 6332 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6333 if (add) 6334 offset_addr = Rn + imm32; 6335 else 6336 offset_addr = Rn - imm32; 6337 6338 // address = if index then offset_addr else R[n]; 6339 if (index) 6340 address = offset_addr; 6341 else 6342 address = Rn; 6343 6344 // R[t] = ZeroExtend(MemU[address,1], 32); 6345 RegisterInfo base_reg; 6346 RegisterInfo data_reg; 6347 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6348 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6349 6350 EmulateInstruction::Context context; 6351 context.type = eContextRegisterLoad; 6352 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6353 6354 uint64_t data = MemURead (context, address, 1, 0, &success); 6355 if (!success) 6356 return false; 6357 6358 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6359 return false; 6360 6361 // if wback then R[n] = offset_addr; 6362 if (wback) 6363 { 6364 context.type = eContextAdjustBaseRegister; 6365 context.SetAddress (offset_addr); 6366 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6367 return false; 6368 } 6369 } 6370 return true; 6371 } 6372 6373 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6374 // zero-extends it to form a 32-bit word and writes it to a register. 6375 bool 6376 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6377 { 6378 #if 0 6379 if ConditionPassed() then 6380 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6381 base = Align(PC,4); 6382 address = if add then (base + imm32) else (base - imm32); 6383 R[t] = ZeroExtend(MemU[address,1], 32); 6384 #endif 6385 6386 bool success = false; 6387 6388 if (ConditionPassed(opcode)) 6389 { 6390 uint32_t t; 6391 uint32_t imm32; 6392 bool add; 6393 switch (encoding) 6394 { 6395 case eEncodingT1: 6396 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6397 t = Bits32 (opcode, 15, 12); 6398 imm32 = Bits32 (opcode, 11, 0); 6399 add = BitIsSet (opcode, 23); 6400 6401 // if Rt == '1111' then SEE PLD; 6402 if (t == 15) 6403 return false; // PLD is not implemented yet 6404 6405 // if t == 13 then UNPREDICTABLE; 6406 if (t == 13) 6407 return false; 6408 6409 break; 6410 6411 case eEncodingA1: 6412 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6413 t = Bits32 (opcode, 15, 12); 6414 imm32 = Bits32 (opcode, 11, 0); 6415 add = BitIsSet (opcode, 23); 6416 6417 // if t == 15 then UNPREDICTABLE; 6418 if (t == 15) 6419 return false; 6420 break; 6421 6422 default: 6423 return false; 6424 } 6425 6426 // base = Align(PC,4); 6427 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6428 if (!success) 6429 return false; 6430 6431 uint32_t base = AlignPC (pc_val); 6432 6433 addr_t address; 6434 // address = if add then (base + imm32) else (base - imm32); 6435 if (add) 6436 address = base + imm32; 6437 else 6438 address = base - imm32; 6439 6440 // R[t] = ZeroExtend(MemU[address,1], 32); 6441 EmulateInstruction::Context context; 6442 context.type = eContextRelativeBranchImmediate; 6443 context.SetImmediate (address - base); 6444 6445 uint64_t data = MemURead (context, address, 1, 0, &success); 6446 if (!success) 6447 return false; 6448 6449 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6450 return false; 6451 } 6452 return true; 6453 } 6454 6455 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6456 // memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6457 // optionally be shifted. 6458 bool 6459 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6460 { 6461 #if 0 6462 if ConditionPassed() then 6463 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6464 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6465 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6466 address = if index then offset_addr else R[n]; 6467 R[t] = ZeroExtend(MemU[address,1],32); 6468 if wback then R[n] = offset_addr; 6469 #endif 6470 6471 bool success = false; 6472 6473 if (ConditionPassed(opcode)) 6474 { 6475 uint32_t t; 6476 uint32_t n; 6477 uint32_t m; 6478 bool index; 6479 bool add; 6480 bool wback; 6481 ARM_ShifterType shift_t; 6482 uint32_t shift_n; 6483 6484 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6485 switch (encoding) 6486 { 6487 case eEncodingT1: 6488 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6489 t = Bits32 (opcode, 2, 0); 6490 n = Bits32 (opcode, 5, 3); 6491 m = Bits32 (opcode, 8, 6); 6492 6493 // index = TRUE; add = TRUE; wback = FALSE; 6494 index = true; 6495 add = true; 6496 wback = false; 6497 6498 // (shift_t, shift_n) = (SRType_LSL, 0); 6499 shift_t = SRType_LSL; 6500 shift_n = 0; 6501 break; 6502 6503 case eEncodingT2: 6504 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6505 t = Bits32 (opcode, 15, 12); 6506 n = Bits32 (opcode, 19, 16); 6507 m = Bits32 (opcode, 3, 0); 6508 6509 // index = TRUE; add = TRUE; wback = FALSE; 6510 index = true; 6511 add = true; 6512 wback = false; 6513 6514 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6515 shift_t = SRType_LSL; 6516 shift_n = Bits32 (opcode, 5, 4); 6517 6518 // if Rt == '1111' then SEE PLD; 6519 if (t == 15) 6520 return false; // PLD is not implemented yet 6521 6522 // if Rn == '1111' then SEE LDRB (literal); 6523 if (n == 15) 6524 return EmulateLDRBLiteral(opcode, eEncodingT1); 6525 6526 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6527 if ((t == 13) || BadReg (m)) 6528 return false; 6529 break; 6530 6531 case eEncodingA1: 6532 { 6533 // if P == '0' && W == '1' then SEE LDRBT; 6534 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6535 t = Bits32 (opcode, 15, 12); 6536 n = Bits32 (opcode, 19, 16); 6537 m = Bits32 (opcode, 3, 0); 6538 6539 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6540 index = BitIsSet (opcode, 24); 6541 add = BitIsSet (opcode, 23); 6542 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6543 6544 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6545 uint32_t type = Bits32 (opcode, 6, 5); 6546 uint32_t imm5 = Bits32 (opcode, 11, 7); 6547 shift_n = DecodeImmShift (type, imm5, shift_t); 6548 6549 // if t == 15 || m == 15 then UNPREDICTABLE; 6550 if ((t == 15) || (m == 15)) 6551 return false; 6552 6553 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6554 if (wback && ((n == 15) || (n == t))) 6555 return false; 6556 } 6557 break; 6558 6559 default: 6560 return false; 6561 } 6562 6563 addr_t offset_addr; 6564 addr_t address; 6565 6566 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6567 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6568 if (!success) 6569 return false; 6570 6571 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6572 if (!success) 6573 return false; 6574 6575 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6576 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6577 if (!success) 6578 return false; 6579 6580 if (add) 6581 offset_addr = Rn + offset; 6582 else 6583 offset_addr = Rn - offset; 6584 6585 // address = if index then offset_addr else R[n]; 6586 if (index) 6587 address = offset_addr; 6588 else 6589 address = Rn; 6590 6591 // R[t] = ZeroExtend(MemU[address,1],32); 6592 RegisterInfo base_reg; 6593 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6594 6595 EmulateInstruction::Context context; 6596 context.type = eContextRegisterLoad; 6597 context.SetRegisterPlusOffset (base_reg, address - Rn); 6598 6599 uint64_t data = MemURead (context, address, 1, 0, &success); 6600 if (!success) 6601 return false; 6602 6603 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6604 return false; 6605 6606 // if wback then R[n] = offset_addr; 6607 if (wback) 6608 { 6609 context.type = eContextAdjustBaseRegister; 6610 context.SetAddress (offset_addr); 6611 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6612 return false; 6613 } 6614 } 6615 return true; 6616 } 6617 6618 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6619 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6620 // post-indexed, or pre-indexed addressing. 6621 bool 6622 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6623 { 6624 #if 0 6625 if ConditionPassed() then 6626 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6627 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6628 address = if index then offset_addr else R[n]; 6629 data = MemU[address,2]; 6630 if wback then R[n] = offset_addr; 6631 if UnalignedSupport() || address<0> = '0' then 6632 R[t] = ZeroExtend(data, 32); 6633 else // Can only apply before ARMv7 6634 R[t] = bits(32) UNKNOWN; 6635 #endif 6636 6637 6638 bool success = false; 6639 6640 if (ConditionPassed(opcode)) 6641 { 6642 uint32_t t; 6643 uint32_t n; 6644 uint32_t imm32; 6645 bool index; 6646 bool add; 6647 bool wback; 6648 6649 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6650 switch (encoding) 6651 { 6652 case eEncodingT1: 6653 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6654 t = Bits32 (opcode, 2, 0); 6655 n = Bits32 (opcode, 5, 3); 6656 imm32 = Bits32 (opcode, 10, 6) << 1; 6657 6658 // index = TRUE; add = TRUE; wback = FALSE; 6659 index = true; 6660 add = true; 6661 wback = false; 6662 6663 break; 6664 6665 case eEncodingT2: 6666 // if Rt == '1111' then SEE "Unallocated memory hints"; 6667 // if Rn == '1111' then SEE LDRH (literal); 6668 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6669 t = Bits32 (opcode, 15, 12); 6670 n = Bits32 (opcode, 19, 16); 6671 imm32 = Bits32 (opcode, 11, 0); 6672 6673 // index = TRUE; add = TRUE; wback = FALSE; 6674 index = true; 6675 add = true; 6676 wback = false; 6677 6678 // if t == 13 then UNPREDICTABLE; 6679 if (t == 13) 6680 return false; 6681 break; 6682 6683 case eEncodingT3: 6684 // if Rn == '1111' then SEE LDRH (literal); 6685 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6686 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6687 // if P == '0' && W == '0' then UNDEFINED; 6688 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6689 return false; 6690 6691 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6692 t = Bits32 (opcode, 15, 12); 6693 n = Bits32 (opcode, 19, 16); 6694 imm32 = Bits32 (opcode, 7, 0); 6695 6696 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6697 index = BitIsSet (opcode, 10); 6698 add = BitIsSet (opcode, 9); 6699 wback = BitIsSet (opcode, 8); 6700 6701 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6702 if (BadReg (t) || (wback && (n == t))) 6703 return false; 6704 break; 6705 6706 default: 6707 return false; 6708 } 6709 6710 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6711 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6712 if (!success) 6713 return false; 6714 6715 addr_t offset_addr; 6716 addr_t address; 6717 6718 if (add) 6719 offset_addr = Rn + imm32; 6720 else 6721 offset_addr = Rn - imm32; 6722 6723 // address = if index then offset_addr else R[n]; 6724 if (index) 6725 address = offset_addr; 6726 else 6727 address = Rn; 6728 6729 // data = MemU[address,2]; 6730 RegisterInfo base_reg; 6731 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6732 6733 EmulateInstruction::Context context; 6734 context.type = eContextRegisterLoad; 6735 context.SetRegisterPlusOffset (base_reg, address - Rn); 6736 6737 uint64_t data = MemURead (context, address, 2, 0, &success); 6738 if (!success) 6739 return false; 6740 6741 // if wback then R[n] = offset_addr; 6742 if (wback) 6743 { 6744 context.type = eContextAdjustBaseRegister; 6745 context.SetAddress (offset_addr); 6746 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6747 return false; 6748 } 6749 6750 // if UnalignedSupport() || address<0> = '0' then 6751 if (UnalignedSupport () || BitIsClear (address, 0)) 6752 { 6753 // R[t] = ZeroExtend(data, 32); 6754 context.type = eContextRegisterLoad; 6755 context.SetRegisterPlusOffset (base_reg, address - Rn); 6756 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6757 return false; 6758 } 6759 else // Can only apply before ARMv7 6760 { 6761 // R[t] = bits(32) UNKNOWN; 6762 WriteBits32Unknown (t); 6763 } 6764 } 6765 return true; 6766 } 6767 6768 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6769 // zero-extends it to form a 32-bit word, and writes it to a register. 6770 bool 6771 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6772 { 6773 #if 0 6774 if ConditionPassed() then 6775 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6776 base = Align(PC,4); 6777 address = if add then (base + imm32) else (base - imm32); 6778 data = MemU[address,2]; 6779 if UnalignedSupport() || address<0> = '0' then 6780 R[t] = ZeroExtend(data, 32); 6781 else // Can only apply before ARMv7 6782 R[t] = bits(32) UNKNOWN; 6783 #endif 6784 6785 bool success = false; 6786 6787 if (ConditionPassed(opcode)) 6788 { 6789 uint32_t t; 6790 uint32_t imm32; 6791 bool add; 6792 6793 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6794 switch (encoding) 6795 { 6796 case eEncodingT1: 6797 // if Rt == '1111' then SEE "Unallocated memory hints"; 6798 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6799 t = Bits32 (opcode, 15, 12); 6800 imm32 = Bits32 (opcode, 11, 0); 6801 add = BitIsSet (opcode, 23); 6802 6803 // if t == 13 then UNPREDICTABLE; 6804 if (t == 13) 6805 return false; 6806 6807 break; 6808 6809 case eEncodingA1: 6810 { 6811 uint32_t imm4H = Bits32 (opcode, 11, 8); 6812 uint32_t imm4L = Bits32 (opcode, 3, 0); 6813 6814 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6815 t = Bits32 (opcode, 15, 12); 6816 imm32 = (imm4H << 4) | imm4L; 6817 add = BitIsSet (opcode, 23); 6818 6819 // if t == 15 then UNPREDICTABLE; 6820 if (t == 15) 6821 return false; 6822 break; 6823 } 6824 6825 default: 6826 return false; 6827 } 6828 6829 // base = Align(PC,4); 6830 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6831 if (!success) 6832 return false; 6833 6834 addr_t base = AlignPC (pc_value); 6835 addr_t address; 6836 6837 // address = if add then (base + imm32) else (base - imm32); 6838 if (add) 6839 address = base + imm32; 6840 else 6841 address = base - imm32; 6842 6843 // data = MemU[address,2]; 6844 RegisterInfo base_reg; 6845 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6846 6847 EmulateInstruction::Context context; 6848 context.type = eContextRegisterLoad; 6849 context.SetRegisterPlusOffset (base_reg, address - base); 6850 6851 uint64_t data = MemURead (context, address, 2, 0, &success); 6852 if (!success) 6853 return false; 6854 6855 6856 // if UnalignedSupport() || address<0> = '0' then 6857 if (UnalignedSupport () || BitIsClear (address, 0)) 6858 { 6859 // R[t] = ZeroExtend(data, 32); 6860 context.type = eContextRegisterLoad; 6861 context.SetRegisterPlusOffset (base_reg, address - base); 6862 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6863 return false; 6864 6865 } 6866 else // Can only apply before ARMv7 6867 { 6868 // R[t] = bits(32) UNKNOWN; 6869 WriteBits32Unknown (t); 6870 } 6871 } 6872 return true; 6873 } 6874 6875 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6876 // from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6877 // be shifted left by 0, 1, 2, or 3 bits. 6878 bool 6879 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6880 { 6881 #if 0 6882 if ConditionPassed() then 6883 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6884 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6885 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6886 address = if index then offset_addr else R[n]; 6887 data = MemU[address,2]; 6888 if wback then R[n] = offset_addr; 6889 if UnalignedSupport() || address<0> = '0' then 6890 R[t] = ZeroExtend(data, 32); 6891 else // Can only apply before ARMv7 6892 R[t] = bits(32) UNKNOWN; 6893 #endif 6894 6895 bool success = false; 6896 6897 if (ConditionPassed(opcode)) 6898 { 6899 uint32_t t; 6900 uint32_t n; 6901 uint32_t m; 6902 bool index; 6903 bool add; 6904 bool wback; 6905 ARM_ShifterType shift_t; 6906 uint32_t shift_n; 6907 6908 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6909 switch (encoding) 6910 { 6911 case eEncodingT1: 6912 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6913 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6914 t = Bits32 (opcode, 2, 0); 6915 n = Bits32 (opcode, 5, 3); 6916 m = Bits32 (opcode, 8, 6); 6917 6918 // index = TRUE; add = TRUE; wback = FALSE; 6919 index = true; 6920 add = true; 6921 wback = false; 6922 6923 // (shift_t, shift_n) = (SRType_LSL, 0); 6924 shift_t = SRType_LSL; 6925 shift_n = 0; 6926 6927 break; 6928 6929 case eEncodingT2: 6930 // if Rn == '1111' then SEE LDRH (literal); 6931 // if Rt == '1111' then SEE "Unallocated memory hints"; 6932 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6933 t = Bits32 (opcode, 15, 12); 6934 n = Bits32 (opcode, 19, 16); 6935 m = Bits32 (opcode, 3, 0); 6936 6937 // index = TRUE; add = TRUE; wback = FALSE; 6938 index = true; 6939 add = true; 6940 wback = false; 6941 6942 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6943 shift_t = SRType_LSL; 6944 shift_n = Bits32 (opcode, 5, 4); 6945 6946 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6947 if ((t == 13) || BadReg (m)) 6948 return false; 6949 break; 6950 6951 case eEncodingA1: 6952 // if P == '0' && W == '1' then SEE LDRHT; 6953 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6954 t = Bits32 (opcode, 15, 12); 6955 n = Bits32 (opcode, 19, 16); 6956 m = Bits32 (opcode, 3, 0); 6957 6958 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6959 index = BitIsSet (opcode, 24); 6960 add = BitIsSet (opcode, 23); 6961 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6962 6963 // (shift_t, shift_n) = (SRType_LSL, 0); 6964 shift_t = SRType_LSL; 6965 shift_n = 0; 6966 6967 // if t == 15 || m == 15 then UNPREDICTABLE; 6968 if ((t == 15) || (m == 15)) 6969 return false; 6970 6971 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6972 if (wback && ((n == 15) || (n == t))) 6973 return false; 6974 6975 break; 6976 6977 default: 6978 return false; 6979 } 6980 6981 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6982 6983 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6984 if (!success) 6985 return false; 6986 6987 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6988 if (!success) 6989 return false; 6990 6991 addr_t offset_addr; 6992 addr_t address; 6993 6994 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6995 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6996 if (!success) 6997 return false; 6998 6999 if (add) 7000 offset_addr = Rn + offset; 7001 else 7002 offset_addr = Rn - offset; 7003 7004 // address = if index then offset_addr else R[n]; 7005 if (index) 7006 address = offset_addr; 7007 else 7008 address = Rn; 7009 7010 // data = MemU[address,2]; 7011 RegisterInfo base_reg; 7012 RegisterInfo offset_reg; 7013 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7014 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7015 7016 EmulateInstruction::Context context; 7017 context.type = eContextRegisterLoad; 7018 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7019 uint64_t data = MemURead (context, address, 2, 0, &success); 7020 if (!success) 7021 return false; 7022 7023 // if wback then R[n] = offset_addr; 7024 if (wback) 7025 { 7026 context.type = eContextAdjustBaseRegister; 7027 context.SetAddress (offset_addr); 7028 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7029 return false; 7030 } 7031 7032 // if UnalignedSupport() || address<0> = '0' then 7033 if (UnalignedSupport() || BitIsClear (address, 0)) 7034 { 7035 // R[t] = ZeroExtend(data, 32); 7036 context.type = eContextRegisterLoad; 7037 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7038 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7039 return false; 7040 } 7041 else // Can only apply before ARMv7 7042 { 7043 // R[t] = bits(32) UNKNOWN; 7044 WriteBits32Unknown (t); 7045 } 7046 } 7047 return true; 7048 } 7049 7050 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 7051 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 7052 // or pre-indexed addressing. 7053 bool 7054 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 7055 { 7056 #if 0 7057 if ConditionPassed() then 7058 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7059 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7060 address = if index then offset_addr else R[n]; 7061 R[t] = SignExtend(MemU[address,1], 32); 7062 if wback then R[n] = offset_addr; 7063 #endif 7064 7065 bool success = false; 7066 7067 if (ConditionPassed(opcode)) 7068 { 7069 uint32_t t; 7070 uint32_t n; 7071 uint32_t imm32; 7072 bool index; 7073 bool add; 7074 bool wback; 7075 7076 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7077 switch (encoding) 7078 { 7079 case eEncodingT1: 7080 // if Rt == '1111' then SEE PLI; 7081 // if Rn == '1111' then SEE LDRSB (literal); 7082 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7083 t = Bits32 (opcode, 15, 12); 7084 n = Bits32 (opcode, 19, 16); 7085 imm32 = Bits32 (opcode, 11, 0); 7086 7087 // index = TRUE; add = TRUE; wback = FALSE; 7088 index = true; 7089 add = true; 7090 wback = false; 7091 7092 // if t == 13 then UNPREDICTABLE; 7093 if (t == 13) 7094 return false; 7095 7096 break; 7097 7098 case eEncodingT2: 7099 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7100 // if Rn == '1111' then SEE LDRSB (literal); 7101 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7102 // if P == '0' && W == '0' then UNDEFINED; 7103 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7104 return false; 7105 7106 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7107 t = Bits32 (opcode, 15, 12); 7108 n = Bits32 (opcode, 19, 16); 7109 imm32 = Bits32 (opcode, 7, 0); 7110 7111 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7112 index = BitIsSet (opcode, 10); 7113 add = BitIsSet (opcode, 9); 7114 wback = BitIsSet (opcode, 8); 7115 7116 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7117 if (((t == 13) || ((t == 15) 7118 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 7119 || (wback && (n == t))) 7120 return false; 7121 7122 break; 7123 7124 case eEncodingA1: 7125 { 7126 // if Rn == '1111' then SEE LDRSB (literal); 7127 // if P == '0' && W == '1' then SEE LDRSBT; 7128 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7129 t = Bits32 (opcode, 15, 12); 7130 n = Bits32 (opcode, 19, 16); 7131 7132 uint32_t imm4H = Bits32 (opcode, 11, 8); 7133 uint32_t imm4L = Bits32 (opcode, 3, 0); 7134 imm32 = (imm4H << 4) | imm4L; 7135 7136 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7137 index = BitIsSet (opcode, 24); 7138 add = BitIsSet (opcode, 23); 7139 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 7140 7141 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7142 if ((t == 15) || (wback && (n == t))) 7143 return false; 7144 7145 break; 7146 } 7147 7148 default: 7149 return false; 7150 } 7151 7152 uint64_t Rn = ReadCoreReg (n, &success); 7153 if (!success) 7154 return false; 7155 7156 addr_t offset_addr; 7157 addr_t address; 7158 7159 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7160 if (add) 7161 offset_addr = Rn + imm32; 7162 else 7163 offset_addr = Rn - imm32; 7164 7165 // address = if index then offset_addr else R[n]; 7166 if (index) 7167 address = offset_addr; 7168 else 7169 address = Rn; 7170 7171 // R[t] = SignExtend(MemU[address,1], 32); 7172 RegisterInfo base_reg; 7173 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7174 7175 EmulateInstruction::Context context; 7176 context.type = eContextRegisterLoad; 7177 context.SetRegisterPlusOffset (base_reg, address - Rn); 7178 7179 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7180 if (!success) 7181 return false; 7182 7183 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7184 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7185 return false; 7186 7187 // if wback then R[n] = offset_addr; 7188 if (wback) 7189 { 7190 context.type = eContextAdjustBaseRegister; 7191 context.SetAddress (offset_addr); 7192 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7193 return false; 7194 } 7195 } 7196 7197 return true; 7198 } 7199 7200 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7201 // sign-extends it to form a 32-bit word, and writes tit to a register. 7202 bool 7203 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7204 { 7205 #if 0 7206 if ConditionPassed() then 7207 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7208 base = Align(PC,4); 7209 address = if add then (base + imm32) else (base - imm32); 7210 R[t] = SignExtend(MemU[address,1], 32); 7211 #endif 7212 7213 bool success = false; 7214 7215 if (ConditionPassed(opcode)) 7216 { 7217 uint32_t t; 7218 uint32_t imm32; 7219 bool add; 7220 7221 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7222 switch (encoding) 7223 { 7224 case eEncodingT1: 7225 // if Rt == '1111' then SEE PLI; 7226 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7227 t = Bits32 (opcode, 15, 12); 7228 imm32 = Bits32 (opcode, 11, 0); 7229 add = BitIsSet (opcode, 23); 7230 7231 // if t == 13 then UNPREDICTABLE; 7232 if (t == 13) 7233 return false; 7234 7235 break; 7236 7237 case eEncodingA1: 7238 { 7239 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7240 t = Bits32 (opcode, 15, 12); 7241 uint32_t imm4H = Bits32 (opcode, 11, 8); 7242 uint32_t imm4L = Bits32 (opcode, 3, 0); 7243 imm32 = (imm4H << 4) | imm4L; 7244 add = BitIsSet (opcode, 23); 7245 7246 // if t == 15 then UNPREDICTABLE; 7247 if (t == 15) 7248 return false; 7249 7250 break; 7251 } 7252 7253 default: 7254 return false; 7255 } 7256 7257 // base = Align(PC,4); 7258 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7259 if (!success) 7260 return false; 7261 uint64_t base = AlignPC (pc_value); 7262 7263 // address = if add then (base + imm32) else (base - imm32); 7264 addr_t address; 7265 if (add) 7266 address = base + imm32; 7267 else 7268 address = base - imm32; 7269 7270 // R[t] = SignExtend(MemU[address,1], 32); 7271 RegisterInfo base_reg; 7272 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7273 7274 EmulateInstruction::Context context; 7275 context.type = eContextRegisterLoad; 7276 context.SetRegisterPlusOffset (base_reg, address - base); 7277 7278 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7279 if (!success) 7280 return false; 7281 7282 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7283 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7284 return false; 7285 } 7286 return true; 7287 } 7288 7289 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7290 // memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7291 // shifted left by 0, 1, 2, or 3 bits. 7292 bool 7293 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7294 { 7295 #if 0 7296 if ConditionPassed() then 7297 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7298 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7299 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7300 address = if index then offset_addr else R[n]; 7301 R[t] = SignExtend(MemU[address,1], 32); 7302 if wback then R[n] = offset_addr; 7303 #endif 7304 7305 bool success = false; 7306 7307 if (ConditionPassed(opcode)) 7308 { 7309 uint32_t t; 7310 uint32_t n; 7311 uint32_t m; 7312 bool index; 7313 bool add; 7314 bool wback; 7315 ARM_ShifterType shift_t; 7316 uint32_t shift_n; 7317 7318 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7319 switch (encoding) 7320 { 7321 case eEncodingT1: 7322 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7323 t = Bits32 (opcode, 2, 0); 7324 n = Bits32 (opcode, 5, 3); 7325 m = Bits32 (opcode, 8, 6); 7326 7327 // index = TRUE; add = TRUE; wback = FALSE; 7328 index = true; 7329 add = true; 7330 wback = false; 7331 7332 // (shift_t, shift_n) = (SRType_LSL, 0); 7333 shift_t = SRType_LSL; 7334 shift_n = 0; 7335 7336 break; 7337 7338 case eEncodingT2: 7339 // if Rt == '1111' then SEE PLI; 7340 // if Rn == '1111' then SEE LDRSB (literal); 7341 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7342 t = Bits32 (opcode, 15, 12); 7343 n = Bits32 (opcode, 19, 16); 7344 m = Bits32 (opcode, 3, 0); 7345 7346 // index = TRUE; add = TRUE; wback = FALSE; 7347 index = true; 7348 add = true; 7349 wback = false; 7350 7351 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7352 shift_t = SRType_LSL; 7353 shift_n = Bits32 (opcode, 5, 4); 7354 7355 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7356 if ((t == 13) || BadReg (m)) 7357 return false; 7358 break; 7359 7360 case eEncodingA1: 7361 // if P == '0' && W == '1' then SEE LDRSBT; 7362 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7363 t = Bits32 (opcode, 15, 12); 7364 n = Bits32 (opcode, 19, 16); 7365 m = Bits32 (opcode, 3, 0); 7366 7367 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7368 index = BitIsSet (opcode, 24); 7369 add = BitIsSet (opcode, 23); 7370 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7371 7372 // (shift_t, shift_n) = (SRType_LSL, 0); 7373 shift_t = SRType_LSL; 7374 shift_n = 0; 7375 7376 // if t == 15 || m == 15 then UNPREDICTABLE; 7377 if ((t == 15) || (m == 15)) 7378 return false; 7379 7380 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7381 if (wback && ((n == 15) || (n == t))) 7382 return false; 7383 break; 7384 7385 default: 7386 return false; 7387 } 7388 7389 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7390 if (!success) 7391 return false; 7392 7393 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7394 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7395 if (!success) 7396 return false; 7397 7398 addr_t offset_addr; 7399 addr_t address; 7400 7401 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7402 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7403 if (!success) 7404 return false; 7405 7406 if (add) 7407 offset_addr = Rn + offset; 7408 else 7409 offset_addr = Rn - offset; 7410 7411 // address = if index then offset_addr else R[n]; 7412 if (index) 7413 address = offset_addr; 7414 else 7415 address = Rn; 7416 7417 // R[t] = SignExtend(MemU[address,1], 32); 7418 RegisterInfo base_reg; 7419 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7420 RegisterInfo offset_reg; 7421 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7422 7423 EmulateInstruction::Context context; 7424 context.type = eContextRegisterLoad; 7425 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7426 7427 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7428 if (!success) 7429 return false; 7430 7431 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7432 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7433 return false; 7434 7435 // if wback then R[n] = offset_addr; 7436 if (wback) 7437 { 7438 context.type = eContextAdjustBaseRegister; 7439 context.SetAddress (offset_addr); 7440 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7441 return false; 7442 } 7443 } 7444 return true; 7445 } 7446 7447 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7448 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7449 // pre-indexed addressing. 7450 bool 7451 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7452 { 7453 #if 0 7454 if ConditionPassed() then 7455 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7456 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7457 address = if index then offset_addr else R[n]; 7458 data = MemU[address,2]; 7459 if wback then R[n] = offset_addr; 7460 if UnalignedSupport() || address<0> = '0' then 7461 R[t] = SignExtend(data, 32); 7462 else // Can only apply before ARMv7 7463 R[t] = bits(32) UNKNOWN; 7464 #endif 7465 7466 bool success = false; 7467 7468 if (ConditionPassed(opcode)) 7469 { 7470 uint32_t t; 7471 uint32_t n; 7472 uint32_t imm32; 7473 bool index; 7474 bool add; 7475 bool wback; 7476 7477 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7478 switch (encoding) 7479 { 7480 case eEncodingT1: 7481 // if Rn == '1111' then SEE LDRSH (literal); 7482 // if Rt == '1111' then SEE "Unallocated memory hints"; 7483 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7484 t = Bits32 (opcode, 15, 12); 7485 n = Bits32 (opcode, 19, 16); 7486 imm32 = Bits32 (opcode, 11, 0); 7487 7488 // index = TRUE; add = TRUE; wback = FALSE; 7489 index = true; 7490 add = true; 7491 wback = false; 7492 7493 // if t == 13 then UNPREDICTABLE; 7494 if (t == 13) 7495 return false; 7496 7497 break; 7498 7499 case eEncodingT2: 7500 // if Rn == '1111' then SEE LDRSH (literal); 7501 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7502 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7503 // if P == '0' && W == '0' then UNDEFINED; 7504 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7505 return false; 7506 7507 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7508 t = Bits32 (opcode, 15, 12); 7509 n = Bits32 (opcode, 19, 16); 7510 imm32 = Bits32 (opcode, 7, 0); 7511 7512 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7513 index = BitIsSet (opcode, 10); 7514 add = BitIsSet (opcode, 9); 7515 wback = BitIsSet (opcode, 8); 7516 7517 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7518 if (BadReg (t) || (wback && (n == t))) 7519 return false; 7520 7521 break; 7522 7523 case eEncodingA1: 7524 { 7525 // if Rn == '1111' then SEE LDRSH (literal); 7526 // if P == '0' && W == '1' then SEE LDRSHT; 7527 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7528 t = Bits32 (opcode, 15, 12); 7529 n = Bits32 (opcode, 19, 16); 7530 uint32_t imm4H = Bits32 (opcode, 11,8); 7531 uint32_t imm4L = Bits32 (opcode, 3, 0); 7532 imm32 = (imm4H << 4) | imm4L; 7533 7534 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7535 index = BitIsSet (opcode, 24); 7536 add = BitIsSet (opcode, 23); 7537 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7538 7539 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7540 if ((t == 15) || (wback && (n == t))) 7541 return false; 7542 7543 break; 7544 } 7545 7546 default: 7547 return false; 7548 } 7549 7550 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7551 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7552 if (!success) 7553 return false; 7554 7555 addr_t offset_addr; 7556 if (add) 7557 offset_addr = Rn + imm32; 7558 else 7559 offset_addr = Rn - imm32; 7560 7561 // address = if index then offset_addr else R[n]; 7562 addr_t address; 7563 if (index) 7564 address = offset_addr; 7565 else 7566 address = Rn; 7567 7568 // data = MemU[address,2]; 7569 RegisterInfo base_reg; 7570 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7571 7572 EmulateInstruction::Context context; 7573 context.type = eContextRegisterLoad; 7574 context.SetRegisterPlusOffset (base_reg, address - Rn); 7575 7576 uint64_t data = MemURead (context, address, 2, 0, &success); 7577 if (!success) 7578 return false; 7579 7580 // if wback then R[n] = offset_addr; 7581 if (wback) 7582 { 7583 context.type = eContextAdjustBaseRegister; 7584 context.SetAddress (offset_addr); 7585 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7586 return false; 7587 } 7588 7589 // if UnalignedSupport() || address<0> = '0' then 7590 if (UnalignedSupport() || BitIsClear (address, 0)) 7591 { 7592 // R[t] = SignExtend(data, 32); 7593 int64_t signed_data = llvm::SignExtend64<16>(data); 7594 context.type = eContextRegisterLoad; 7595 context.SetRegisterPlusOffset (base_reg, address - Rn); 7596 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7597 return false; 7598 } 7599 else // Can only apply before ARMv7 7600 { 7601 // R[t] = bits(32) UNKNOWN; 7602 WriteBits32Unknown (t); 7603 } 7604 } 7605 return true; 7606 } 7607 7608 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7609 // sign-extends it to from a 32-bit word, and writes it to a register. 7610 bool 7611 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7612 { 7613 #if 0 7614 if ConditionPassed() then 7615 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7616 base = Align(PC,4); 7617 address = if add then (base + imm32) else (base - imm32); 7618 data = MemU[address,2]; 7619 if UnalignedSupport() || address<0> = '0' then 7620 R[t] = SignExtend(data, 32); 7621 else // Can only apply before ARMv7 7622 R[t] = bits(32) UNKNOWN; 7623 #endif 7624 7625 bool success = false; 7626 7627 if (ConditionPassed(opcode)) 7628 { 7629 uint32_t t; 7630 uint32_t imm32; 7631 bool add; 7632 7633 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7634 switch (encoding) 7635 { 7636 case eEncodingT1: 7637 // if Rt == '1111' then SEE "Unallocated memory hints"; 7638 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7639 t = Bits32 (opcode, 15, 12); 7640 imm32 = Bits32 (opcode, 11, 0); 7641 add = BitIsSet (opcode, 23); 7642 7643 // if t == 13 then UNPREDICTABLE; 7644 if (t == 13) 7645 return false; 7646 7647 break; 7648 7649 case eEncodingA1: 7650 { 7651 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7652 t = Bits32 (opcode, 15, 12); 7653 uint32_t imm4H = Bits32 (opcode, 11, 8); 7654 uint32_t imm4L = Bits32 (opcode, 3, 0); 7655 imm32 = (imm4H << 4) | imm4L; 7656 add = BitIsSet (opcode, 23); 7657 7658 // if t == 15 then UNPREDICTABLE; 7659 if (t == 15) 7660 return false; 7661 7662 break; 7663 } 7664 default: 7665 return false; 7666 } 7667 7668 // base = Align(PC,4); 7669 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7670 if (!success) 7671 return false; 7672 7673 uint64_t base = AlignPC (pc_value); 7674 7675 addr_t address; 7676 // address = if add then (base + imm32) else (base - imm32); 7677 if (add) 7678 address = base + imm32; 7679 else 7680 address = base - imm32; 7681 7682 // data = MemU[address,2]; 7683 RegisterInfo base_reg; 7684 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7685 7686 EmulateInstruction::Context context; 7687 context.type = eContextRegisterLoad; 7688 context.SetRegisterPlusOffset (base_reg, imm32); 7689 7690 uint64_t data = MemURead (context, address, 2, 0, &success); 7691 if (!success) 7692 return false; 7693 7694 // if UnalignedSupport() || address<0> = '0' then 7695 if (UnalignedSupport() || BitIsClear (address, 0)) 7696 { 7697 // R[t] = SignExtend(data, 32); 7698 int64_t signed_data = llvm::SignExtend64<16>(data); 7699 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7700 return false; 7701 } 7702 else // Can only apply before ARMv7 7703 { 7704 // R[t] = bits(32) UNKNOWN; 7705 WriteBits32Unknown (t); 7706 } 7707 } 7708 return true; 7709 } 7710 7711 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7712 // from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7713 // shifted left by 0, 1, 2, or 3 bits. 7714 bool 7715 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7716 { 7717 #if 0 7718 if ConditionPassed() then 7719 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7720 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7721 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7722 address = if index then offset_addr else R[n]; 7723 data = MemU[address,2]; 7724 if wback then R[n] = offset_addr; 7725 if UnalignedSupport() || address<0> = '0' then 7726 R[t] = SignExtend(data, 32); 7727 else // Can only apply before ARMv7 7728 R[t] = bits(32) UNKNOWN; 7729 #endif 7730 7731 bool success = false; 7732 7733 if (ConditionPassed(opcode)) 7734 { 7735 uint32_t t; 7736 uint32_t n; 7737 uint32_t m; 7738 bool index; 7739 bool add; 7740 bool wback; 7741 ARM_ShifterType shift_t; 7742 uint32_t shift_n; 7743 7744 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7745 switch (encoding) 7746 { 7747 case eEncodingT1: 7748 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7749 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7750 t = Bits32 (opcode, 2, 0); 7751 n = Bits32 (opcode, 5, 3); 7752 m = Bits32 (opcode, 8, 6); 7753 7754 // index = TRUE; add = TRUE; wback = FALSE; 7755 index = true; 7756 add = true; 7757 wback = false; 7758 7759 // (shift_t, shift_n) = (SRType_LSL, 0); 7760 shift_t = SRType_LSL; 7761 shift_n = 0; 7762 7763 break; 7764 7765 case eEncodingT2: 7766 // if Rn == '1111' then SEE LDRSH (literal); 7767 // if Rt == '1111' then SEE "Unallocated memory hints"; 7768 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7769 t = Bits32 (opcode, 15, 12); 7770 n = Bits32 (opcode, 19, 16); 7771 m = Bits32 (opcode, 3, 0); 7772 7773 // index = TRUE; add = TRUE; wback = FALSE; 7774 index = true; 7775 add = true; 7776 wback = false; 7777 7778 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7779 shift_t = SRType_LSL; 7780 shift_n = Bits32 (opcode, 5, 4); 7781 7782 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7783 if ((t == 13) || BadReg (m)) 7784 return false; 7785 7786 break; 7787 7788 case eEncodingA1: 7789 // if P == '0' && W == '1' then SEE LDRSHT; 7790 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7791 t = Bits32 (opcode, 15, 12); 7792 n = Bits32 (opcode, 19, 16); 7793 m = Bits32 (opcode, 3, 0); 7794 7795 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7796 index = BitIsSet (opcode, 24); 7797 add = BitIsSet (opcode, 23); 7798 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7799 7800 // (shift_t, shift_n) = (SRType_LSL, 0); 7801 shift_t = SRType_LSL; 7802 shift_n = 0; 7803 7804 // if t == 15 || m == 15 then UNPREDICTABLE; 7805 if ((t == 15) || (m == 15)) 7806 return false; 7807 7808 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7809 if (wback && ((n == 15) || (n == t))) 7810 return false; 7811 7812 break; 7813 7814 default: 7815 return false; 7816 } 7817 7818 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7819 if (!success) 7820 return false; 7821 7822 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7823 if (!success) 7824 return false; 7825 7826 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7827 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7828 if (!success) 7829 return false; 7830 7831 addr_t offset_addr; 7832 addr_t address; 7833 7834 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7835 if (add) 7836 offset_addr = Rn + offset; 7837 else 7838 offset_addr = Rn - offset; 7839 7840 // address = if index then offset_addr else R[n]; 7841 if (index) 7842 address = offset_addr; 7843 else 7844 address = Rn; 7845 7846 // data = MemU[address,2]; 7847 RegisterInfo base_reg; 7848 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7849 7850 RegisterInfo offset_reg; 7851 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7852 7853 EmulateInstruction::Context context; 7854 context.type = eContextRegisterLoad; 7855 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7856 7857 uint64_t data = MemURead (context, address, 2, 0, &success); 7858 if (!success) 7859 return false; 7860 7861 // if wback then R[n] = offset_addr; 7862 if (wback) 7863 { 7864 context.type = eContextAdjustBaseRegister; 7865 context.SetAddress (offset_addr); 7866 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7867 return false; 7868 } 7869 7870 // if UnalignedSupport() || address<0> = '0' then 7871 if (UnalignedSupport() || BitIsClear (address, 0)) 7872 { 7873 // R[t] = SignExtend(data, 32); 7874 context.type = eContextRegisterLoad; 7875 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7876 7877 int64_t signed_data = llvm::SignExtend64<16>(data); 7878 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7879 return false; 7880 } 7881 else // Can only apply before ARMv7 7882 { 7883 // R[t] = bits(32) UNKNOWN; 7884 WriteBits32Unknown (t); 7885 } 7886 } 7887 return true; 7888 } 7889 7890 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7891 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7892 bool 7893 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7894 { 7895 #if 0 7896 if ConditionPassed() then 7897 EncodingSpecificOperations(); 7898 rotated = ROR(R[m], rotation); 7899 R[d] = SignExtend(rotated<7:0>, 32); 7900 #endif 7901 7902 bool success = false; 7903 7904 if (ConditionPassed(opcode)) 7905 { 7906 uint32_t d; 7907 uint32_t m; 7908 uint32_t rotation; 7909 7910 // EncodingSpecificOperations(); 7911 switch (encoding) 7912 { 7913 case eEncodingT1: 7914 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7915 d = Bits32 (opcode, 2, 0); 7916 m = Bits32 (opcode, 5, 3); 7917 rotation = 0; 7918 7919 break; 7920 7921 case eEncodingT2: 7922 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7923 d = Bits32 (opcode, 11, 8); 7924 m = Bits32 (opcode, 3, 0); 7925 rotation = Bits32 (opcode, 5, 4) << 3; 7926 7927 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7928 if (BadReg (d) || BadReg (m)) 7929 return false; 7930 7931 break; 7932 7933 case eEncodingA1: 7934 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7935 d = Bits32 (opcode, 15, 12); 7936 m = Bits32 (opcode, 3, 0); 7937 rotation = Bits32 (opcode, 11, 10) << 3; 7938 7939 // if d == 15 || m == 15 then UNPREDICTABLE; 7940 if ((d == 15) || (m == 15)) 7941 return false; 7942 7943 break; 7944 7945 default: 7946 return false; 7947 } 7948 7949 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7950 if (!success) 7951 return false; 7952 7953 // rotated = ROR(R[m], rotation); 7954 uint64_t rotated = ROR (Rm, rotation, &success); 7955 if (!success) 7956 return false; 7957 7958 // R[d] = SignExtend(rotated<7:0>, 32); 7959 int64_t data = llvm::SignExtend64<8>(rotated); 7960 7961 RegisterInfo source_reg; 7962 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7963 7964 EmulateInstruction::Context context; 7965 context.type = eContextRegisterLoad; 7966 context.SetRegister (source_reg); 7967 7968 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7969 return false; 7970 } 7971 return true; 7972 } 7973 7974 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7975 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7976 bool 7977 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7978 { 7979 #if 0 7980 if ConditionPassed() then 7981 EncodingSpecificOperations(); 7982 rotated = ROR(R[m], rotation); 7983 R[d] = SignExtend(rotated<15:0>, 32); 7984 #endif 7985 7986 bool success = false; 7987 7988 if (ConditionPassed(opcode)) 7989 { 7990 uint32_t d; 7991 uint32_t m; 7992 uint32_t rotation; 7993 7994 // EncodingSpecificOperations(); 7995 switch (encoding) 7996 { 7997 case eEncodingT1: 7998 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7999 d = Bits32 (opcode, 2, 0); 8000 m = Bits32 (opcode, 5, 3); 8001 rotation = 0; 8002 8003 break; 8004 8005 case eEncodingT2: 8006 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8007 d = Bits32 (opcode, 11, 8); 8008 m = Bits32 (opcode, 3, 0); 8009 rotation = Bits32 (opcode, 5, 4) << 3; 8010 8011 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8012 if (BadReg (d) || BadReg (m)) 8013 return false; 8014 8015 break; 8016 8017 case eEncodingA1: 8018 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8019 d = Bits32 (opcode, 15, 12); 8020 m = Bits32 (opcode, 3, 0); 8021 rotation = Bits32 (opcode, 11, 10) << 3; 8022 8023 // if d == 15 || m == 15 then UNPREDICTABLE; 8024 if ((d == 15) || (m == 15)) 8025 return false; 8026 8027 break; 8028 8029 default: 8030 return false; 8031 } 8032 8033 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8034 if (!success) 8035 return false; 8036 8037 // rotated = ROR(R[m], rotation); 8038 uint64_t rotated = ROR (Rm, rotation, &success); 8039 if (!success) 8040 return false; 8041 8042 // R[d] = SignExtend(rotated<15:0>, 32); 8043 RegisterInfo source_reg; 8044 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8045 8046 EmulateInstruction::Context context; 8047 context.type = eContextRegisterLoad; 8048 context.SetRegister (source_reg); 8049 8050 int64_t data = llvm::SignExtend64<16> (rotated); 8051 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 8052 return false; 8053 } 8054 8055 return true; 8056 } 8057 8058 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 8059 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 8060 bool 8061 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 8062 { 8063 #if 0 8064 if ConditionPassed() then 8065 EncodingSpecificOperations(); 8066 rotated = ROR(R[m], rotation); 8067 R[d] = ZeroExtend(rotated<7:0>, 32); 8068 #endif 8069 8070 bool success = false; 8071 8072 if (ConditionPassed(opcode)) 8073 { 8074 uint32_t d; 8075 uint32_t m; 8076 uint32_t rotation; 8077 8078 // EncodingSpecificOperations(); 8079 switch (encoding) 8080 { 8081 case eEncodingT1: 8082 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8083 d = Bits32 (opcode, 2, 0); 8084 m = Bits32 (opcode, 5, 3); 8085 rotation = 0; 8086 8087 break; 8088 8089 case eEncodingT2: 8090 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8091 d = Bits32 (opcode, 11, 8); 8092 m = Bits32 (opcode, 3, 0); 8093 rotation = Bits32 (opcode, 5, 4) << 3; 8094 8095 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8096 if (BadReg (d) || BadReg (m)) 8097 return false; 8098 8099 break; 8100 8101 case eEncodingA1: 8102 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8103 d = Bits32 (opcode, 15, 12); 8104 m = Bits32 (opcode, 3, 0); 8105 rotation = Bits32 (opcode, 11, 10) << 3; 8106 8107 // if d == 15 || m == 15 then UNPREDICTABLE; 8108 if ((d == 15) || (m == 15)) 8109 return false; 8110 8111 break; 8112 8113 default: 8114 return false; 8115 } 8116 8117 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8118 if (!success) 8119 return false; 8120 8121 // rotated = ROR(R[m], rotation); 8122 uint64_t rotated = ROR (Rm, rotation, &success); 8123 if (!success) 8124 return false; 8125 8126 // R[d] = ZeroExtend(rotated<7:0>, 32); 8127 RegisterInfo source_reg; 8128 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8129 8130 EmulateInstruction::Context context; 8131 context.type = eContextRegisterLoad; 8132 context.SetRegister (source_reg); 8133 8134 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 8135 return false; 8136 } 8137 return true; 8138 } 8139 8140 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 8141 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 8142 bool 8143 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 8144 { 8145 #if 0 8146 if ConditionPassed() then 8147 EncodingSpecificOperations(); 8148 rotated = ROR(R[m], rotation); 8149 R[d] = ZeroExtend(rotated<15:0>, 32); 8150 #endif 8151 8152 bool success = false; 8153 8154 if (ConditionPassed(opcode)) 8155 { 8156 uint32_t d; 8157 uint32_t m; 8158 uint32_t rotation; 8159 8160 switch (encoding) 8161 { 8162 case eEncodingT1: 8163 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8164 d = Bits32 (opcode, 2, 0); 8165 m = Bits32 (opcode, 5, 3); 8166 rotation = 0; 8167 8168 break; 8169 8170 case eEncodingT2: 8171 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8172 d = Bits32 (opcode, 11, 8); 8173 m = Bits32 (opcode, 3, 0); 8174 rotation = Bits32 (opcode, 5, 4) << 3; 8175 8176 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8177 if (BadReg (d) || BadReg (m)) 8178 return false; 8179 8180 break; 8181 8182 case eEncodingA1: 8183 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8184 d = Bits32 (opcode, 15, 12); 8185 m = Bits32 (opcode, 3, 0); 8186 rotation = Bits32 (opcode, 11, 10) << 3; 8187 8188 // if d == 15 || m == 15 then UNPREDICTABLE; 8189 if ((d == 15) || (m == 15)) 8190 return false; 8191 8192 break; 8193 8194 default: 8195 return false; 8196 } 8197 8198 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8199 if (!success) 8200 return false; 8201 8202 // rotated = ROR(R[m], rotation); 8203 uint64_t rotated = ROR (Rm, rotation, &success); 8204 if (!success) 8205 return false; 8206 8207 // R[d] = ZeroExtend(rotated<15:0>, 32); 8208 RegisterInfo source_reg; 8209 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8210 8211 EmulateInstruction::Context context; 8212 context.type = eContextRegisterLoad; 8213 context.SetRegister (source_reg); 8214 8215 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8216 return false; 8217 } 8218 return true; 8219 } 8220 8221 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8222 // word respectively. 8223 bool 8224 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8225 { 8226 #if 0 8227 if ConditionPassed() then 8228 EncodingSpecificOperations(); 8229 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8230 UNPREDICTABLE; 8231 else 8232 address = if increment then R[n] else R[n]-8; 8233 if wordhigher then address = address+4; 8234 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8235 BranchWritePC(MemA[address,4]); 8236 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8237 #endif 8238 8239 bool success = false; 8240 8241 if (ConditionPassed(opcode)) 8242 { 8243 uint32_t n; 8244 bool wback; 8245 bool increment; 8246 bool wordhigher; 8247 8248 // EncodingSpecificOperations(); 8249 switch (encoding) 8250 { 8251 case eEncodingT1: 8252 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8253 n = Bits32 (opcode, 19, 16); 8254 wback = BitIsSet (opcode, 21); 8255 increment = false; 8256 wordhigher = false; 8257 8258 // if n == 15 then UNPREDICTABLE; 8259 if (n == 15) 8260 return false; 8261 8262 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8263 if (InITBlock() && !LastInITBlock()) 8264 return false; 8265 8266 break; 8267 8268 case eEncodingT2: 8269 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8270 n = Bits32 (opcode, 19, 16); 8271 wback = BitIsSet (opcode, 21); 8272 increment = true; 8273 wordhigher = false; 8274 8275 // if n == 15 then UNPREDICTABLE; 8276 if (n == 15) 8277 return false; 8278 8279 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8280 if (InITBlock() && !LastInITBlock()) 8281 return false; 8282 8283 break; 8284 8285 case eEncodingA1: 8286 // n = UInt(Rn); 8287 n = Bits32 (opcode, 19, 16); 8288 8289 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8290 wback = BitIsSet (opcode, 21); 8291 increment = BitIsSet (opcode, 23); 8292 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8293 8294 // if n == 15 then UNPREDICTABLE; 8295 if (n == 15) 8296 return false; 8297 8298 break; 8299 8300 default: 8301 return false; 8302 } 8303 8304 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8305 if (!CurrentModeIsPrivileged ()) 8306 // UNPREDICTABLE; 8307 return false; 8308 else 8309 { 8310 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8311 if (!success) 8312 return false; 8313 8314 addr_t address; 8315 // address = if increment then R[n] else R[n]-8; 8316 if (increment) 8317 address = Rn; 8318 else 8319 address = Rn - 8; 8320 8321 // if wordhigher then address = address+4; 8322 if (wordhigher) 8323 address = address + 4; 8324 8325 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8326 RegisterInfo base_reg; 8327 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8328 8329 EmulateInstruction::Context context; 8330 context.type = eContextReturnFromException; 8331 context.SetRegisterPlusOffset (base_reg, address - Rn); 8332 8333 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8334 if (!success) 8335 return false; 8336 8337 CPSRWriteByInstr (data, 15, true); 8338 8339 // BranchWritePC(MemA[address,4]); 8340 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8341 if (!success) 8342 return false; 8343 8344 BranchWritePC (context, data2); 8345 8346 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8347 if (wback) 8348 { 8349 context.type = eContextAdjustBaseRegister; 8350 if (increment) 8351 { 8352 context.SetOffset (8); 8353 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8354 return false; 8355 } 8356 else 8357 { 8358 context.SetOffset (-8); 8359 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8360 return false; 8361 } 8362 } // if wback 8363 } 8364 } // if ConditionPassed() 8365 return true; 8366 } 8367 8368 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8369 // and writes the result to the destination register. It can optionally update the condition flags based on 8370 // the result. 8371 bool 8372 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8373 { 8374 #if 0 8375 // ARM pseudo code... 8376 if ConditionPassed() then 8377 EncodingSpecificOperations(); 8378 result = R[n] EOR imm32; 8379 if d == 15 then // Can only occur for ARM encoding 8380 ALUWritePC(result); // setflags is always FALSE here 8381 else 8382 R[d] = result; 8383 if setflags then 8384 APSR.N = result<31>; 8385 APSR.Z = IsZeroBit(result); 8386 APSR.C = carry; 8387 // APSR.V unchanged 8388 #endif 8389 8390 bool success = false; 8391 8392 if (ConditionPassed(opcode)) 8393 { 8394 uint32_t Rd, Rn; 8395 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8396 bool setflags; 8397 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8398 switch (encoding) 8399 { 8400 case eEncodingT1: 8401 Rd = Bits32(opcode, 11, 8); 8402 Rn = Bits32(opcode, 19, 16); 8403 setflags = BitIsSet(opcode, 20); 8404 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8405 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8406 if (Rd == 15 && setflags) 8407 return EmulateTEQImm (opcode, eEncodingT1); 8408 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8409 return false; 8410 break; 8411 case eEncodingA1: 8412 Rd = Bits32(opcode, 15, 12); 8413 Rn = Bits32(opcode, 19, 16); 8414 setflags = BitIsSet(opcode, 20); 8415 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8416 8417 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8418 if (Rd == 15 && setflags) 8419 return EmulateSUBSPcLrEtc (opcode, encoding); 8420 break; 8421 default: 8422 return false; 8423 } 8424 8425 // Read the first operand. 8426 uint32_t val1 = ReadCoreReg(Rn, &success); 8427 if (!success) 8428 return false; 8429 8430 uint32_t result = val1 ^ imm32; 8431 8432 EmulateInstruction::Context context; 8433 context.type = EmulateInstruction::eContextImmediate; 8434 context.SetNoArgs (); 8435 8436 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8437 return false; 8438 } 8439 return true; 8440 } 8441 8442 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8443 // optionally-shifted register value, and writes the result to the destination register. 8444 // It can optionally update the condition flags based on the result. 8445 bool 8446 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8447 { 8448 #if 0 8449 // ARM pseudo code... 8450 if ConditionPassed() then 8451 EncodingSpecificOperations(); 8452 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8453 result = R[n] EOR shifted; 8454 if d == 15 then // Can only occur for ARM encoding 8455 ALUWritePC(result); // setflags is always FALSE here 8456 else 8457 R[d] = result; 8458 if setflags then 8459 APSR.N = result<31>; 8460 APSR.Z = IsZeroBit(result); 8461 APSR.C = carry; 8462 // APSR.V unchanged 8463 #endif 8464 8465 bool success = false; 8466 8467 if (ConditionPassed(opcode)) 8468 { 8469 uint32_t Rd, Rn, Rm; 8470 ARM_ShifterType shift_t; 8471 uint32_t shift_n; // the shift applied to the value read from Rm 8472 bool setflags; 8473 uint32_t carry; 8474 switch (encoding) 8475 { 8476 case eEncodingT1: 8477 Rd = Rn = Bits32(opcode, 2, 0); 8478 Rm = Bits32(opcode, 5, 3); 8479 setflags = !InITBlock(); 8480 shift_t = SRType_LSL; 8481 shift_n = 0; 8482 break; 8483 case eEncodingT2: 8484 Rd = Bits32(opcode, 11, 8); 8485 Rn = Bits32(opcode, 19, 16); 8486 Rm = Bits32(opcode, 3, 0); 8487 setflags = BitIsSet(opcode, 20); 8488 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8489 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8490 if (Rd == 15 && setflags) 8491 return EmulateTEQReg (opcode, eEncodingT1); 8492 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8493 return false; 8494 break; 8495 case eEncodingA1: 8496 Rd = Bits32(opcode, 15, 12); 8497 Rn = Bits32(opcode, 19, 16); 8498 Rm = Bits32(opcode, 3, 0); 8499 setflags = BitIsSet(opcode, 20); 8500 shift_n = DecodeImmShiftARM(opcode, shift_t); 8501 8502 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8503 if (Rd == 15 && setflags) 8504 return EmulateSUBSPcLrEtc (opcode, encoding); 8505 break; 8506 default: 8507 return false; 8508 } 8509 8510 // Read the first operand. 8511 uint32_t val1 = ReadCoreReg(Rn, &success); 8512 if (!success) 8513 return false; 8514 8515 // Read the second operand. 8516 uint32_t val2 = ReadCoreReg(Rm, &success); 8517 if (!success) 8518 return false; 8519 8520 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8521 if (!success) 8522 return false; 8523 uint32_t result = val1 ^ shifted; 8524 8525 EmulateInstruction::Context context; 8526 context.type = EmulateInstruction::eContextImmediate; 8527 context.SetNoArgs (); 8528 8529 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8530 return false; 8531 } 8532 return true; 8533 } 8534 8535 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8536 // writes the result to the destination register. It can optionally update the condition flags based 8537 // on the result. 8538 bool 8539 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8540 { 8541 #if 0 8542 // ARM pseudo code... 8543 if ConditionPassed() then 8544 EncodingSpecificOperations(); 8545 result = R[n] OR imm32; 8546 if d == 15 then // Can only occur for ARM encoding 8547 ALUWritePC(result); // setflags is always FALSE here 8548 else 8549 R[d] = result; 8550 if setflags then 8551 APSR.N = result<31>; 8552 APSR.Z = IsZeroBit(result); 8553 APSR.C = carry; 8554 // APSR.V unchanged 8555 #endif 8556 8557 bool success = false; 8558 8559 if (ConditionPassed(opcode)) 8560 { 8561 uint32_t Rd, Rn; 8562 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8563 bool setflags; 8564 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8565 switch (encoding) 8566 { 8567 case eEncodingT1: 8568 Rd = Bits32(opcode, 11, 8); 8569 Rn = Bits32(opcode, 19, 16); 8570 setflags = BitIsSet(opcode, 20); 8571 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8572 // if Rn == '1111' then SEE MOV (immediate); 8573 if (Rn == 15) 8574 return EmulateMOVRdImm (opcode, eEncodingT2); 8575 if (BadReg(Rd) || Rn == 13) 8576 return false; 8577 break; 8578 case eEncodingA1: 8579 Rd = Bits32(opcode, 15, 12); 8580 Rn = Bits32(opcode, 19, 16); 8581 setflags = BitIsSet(opcode, 20); 8582 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8583 8584 if (Rd == 15 && setflags) 8585 return EmulateSUBSPcLrEtc (opcode, encoding); 8586 break; 8587 default: 8588 return false; 8589 } 8590 8591 // Read the first operand. 8592 uint32_t val1 = ReadCoreReg(Rn, &success); 8593 if (!success) 8594 return false; 8595 8596 uint32_t result = val1 | imm32; 8597 8598 EmulateInstruction::Context context; 8599 context.type = EmulateInstruction::eContextImmediate; 8600 context.SetNoArgs (); 8601 8602 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8603 return false; 8604 } 8605 return true; 8606 } 8607 8608 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8609 // value, and writes the result to the destination register. It can optionally update the condition flags based 8610 // on the result. 8611 bool 8612 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8613 { 8614 #if 0 8615 // ARM pseudo code... 8616 if ConditionPassed() then 8617 EncodingSpecificOperations(); 8618 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8619 result = R[n] OR shifted; 8620 if d == 15 then // Can only occur for ARM encoding 8621 ALUWritePC(result); // setflags is always FALSE here 8622 else 8623 R[d] = result; 8624 if setflags then 8625 APSR.N = result<31>; 8626 APSR.Z = IsZeroBit(result); 8627 APSR.C = carry; 8628 // APSR.V unchanged 8629 #endif 8630 8631 bool success = false; 8632 8633 if (ConditionPassed(opcode)) 8634 { 8635 uint32_t Rd, Rn, Rm; 8636 ARM_ShifterType shift_t; 8637 uint32_t shift_n; // the shift applied to the value read from Rm 8638 bool setflags; 8639 uint32_t carry; 8640 switch (encoding) 8641 { 8642 case eEncodingT1: 8643 Rd = Rn = Bits32(opcode, 2, 0); 8644 Rm = Bits32(opcode, 5, 3); 8645 setflags = !InITBlock(); 8646 shift_t = SRType_LSL; 8647 shift_n = 0; 8648 break; 8649 case eEncodingT2: 8650 Rd = Bits32(opcode, 11, 8); 8651 Rn = Bits32(opcode, 19, 16); 8652 Rm = Bits32(opcode, 3, 0); 8653 setflags = BitIsSet(opcode, 20); 8654 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8655 // if Rn == '1111' then SEE MOV (register); 8656 if (Rn == 15) 8657 return EmulateMOVRdRm (opcode, eEncodingT3); 8658 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8659 return false; 8660 break; 8661 case eEncodingA1: 8662 Rd = Bits32(opcode, 15, 12); 8663 Rn = Bits32(opcode, 19, 16); 8664 Rm = Bits32(opcode, 3, 0); 8665 setflags = BitIsSet(opcode, 20); 8666 shift_n = DecodeImmShiftARM(opcode, shift_t); 8667 8668 if (Rd == 15 && setflags) 8669 return EmulateSUBSPcLrEtc (opcode, encoding); 8670 break; 8671 default: 8672 return false; 8673 } 8674 8675 // Read the first operand. 8676 uint32_t val1 = ReadCoreReg(Rn, &success); 8677 if (!success) 8678 return false; 8679 8680 // Read the second operand. 8681 uint32_t val2 = ReadCoreReg(Rm, &success); 8682 if (!success) 8683 return false; 8684 8685 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8686 if (!success) 8687 return false; 8688 uint32_t result = val1 | shifted; 8689 8690 EmulateInstruction::Context context; 8691 context.type = EmulateInstruction::eContextImmediate; 8692 context.SetNoArgs (); 8693 8694 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8695 return false; 8696 } 8697 return true; 8698 } 8699 8700 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8701 // the destination register. It can optionally update the condition flags based on the result. 8702 bool 8703 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8704 { 8705 #if 0 8706 // ARM pseudo code... 8707 if ConditionPassed() then 8708 EncodingSpecificOperations(); 8709 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8710 if d == 15 then // Can only occur for ARM encoding 8711 ALUWritePC(result); // setflags is always FALSE here 8712 else 8713 R[d] = result; 8714 if setflags then 8715 APSR.N = result<31>; 8716 APSR.Z = IsZeroBit(result); 8717 APSR.C = carry; 8718 APSR.V = overflow; 8719 #endif 8720 8721 bool success = false; 8722 8723 uint32_t Rd; // the destination register 8724 uint32_t Rn; // the first operand 8725 bool setflags; 8726 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8727 switch (encoding) { 8728 case eEncodingT1: 8729 Rd = Bits32(opcode, 2, 0); 8730 Rn = Bits32(opcode, 5, 3); 8731 setflags = !InITBlock(); 8732 imm32 = 0; 8733 break; 8734 case eEncodingT2: 8735 Rd = Bits32(opcode, 11, 8); 8736 Rn = Bits32(opcode, 19, 16); 8737 setflags = BitIsSet(opcode, 20); 8738 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8739 if (BadReg(Rd) || BadReg(Rn)) 8740 return false; 8741 break; 8742 case eEncodingA1: 8743 Rd = Bits32(opcode, 15, 12); 8744 Rn = Bits32(opcode, 19, 16); 8745 setflags = BitIsSet(opcode, 20); 8746 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8747 8748 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8749 if (Rd == 15 && setflags) 8750 return EmulateSUBSPcLrEtc (opcode, encoding); 8751 break; 8752 default: 8753 return false; 8754 } 8755 // Read the register value from the operand register Rn. 8756 uint32_t reg_val = ReadCoreReg(Rn, &success); 8757 if (!success) 8758 return false; 8759 8760 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8761 8762 EmulateInstruction::Context context; 8763 context.type = EmulateInstruction::eContextImmediate; 8764 context.SetNoArgs (); 8765 8766 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8767 return false; 8768 8769 return true; 8770 } 8771 8772 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8773 // result to the destination register. It can optionally update the condition flags based on the result. 8774 bool 8775 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8776 { 8777 #if 0 8778 // ARM pseudo code... 8779 if ConditionPassed() then 8780 EncodingSpecificOperations(); 8781 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8782 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8783 if d == 15 then // Can only occur for ARM encoding 8784 ALUWritePC(result); // setflags is always FALSE here 8785 else 8786 R[d] = result; 8787 if setflags then 8788 APSR.N = result<31>; 8789 APSR.Z = IsZeroBit(result); 8790 APSR.C = carry; 8791 APSR.V = overflow; 8792 #endif 8793 8794 bool success = false; 8795 8796 uint32_t Rd; // the destination register 8797 uint32_t Rn; // the first operand 8798 uint32_t Rm; // the second operand 8799 bool setflags; 8800 ARM_ShifterType shift_t; 8801 uint32_t shift_n; // the shift applied to the value read from Rm 8802 switch (encoding) { 8803 case eEncodingT1: 8804 Rd = Bits32(opcode, 11, 8); 8805 Rn = Bits32(opcode, 19, 16); 8806 Rm = Bits32(opcode, 3, 0); 8807 setflags = BitIsSet(opcode, 20); 8808 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8809 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8810 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8811 return false; 8812 break; 8813 case eEncodingA1: 8814 Rd = Bits32(opcode, 15, 12); 8815 Rn = Bits32(opcode, 19, 16); 8816 Rm = Bits32(opcode, 3, 0); 8817 setflags = BitIsSet(opcode, 20); 8818 shift_n = DecodeImmShiftARM(opcode, shift_t); 8819 8820 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8821 if (Rd == 15 && setflags) 8822 return EmulateSUBSPcLrEtc (opcode, encoding); 8823 break; 8824 default: 8825 return false; 8826 } 8827 // Read the register value from register Rn. 8828 uint32_t val1 = ReadCoreReg(Rn, &success); 8829 if (!success) 8830 return false; 8831 8832 // Read the register value from register Rm. 8833 uint32_t val2 = ReadCoreReg(Rm, &success); 8834 if (!success) 8835 return false; 8836 8837 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8838 if (!success) 8839 return false; 8840 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8841 8842 EmulateInstruction::Context context; 8843 context.type = EmulateInstruction::eContextImmediate; 8844 context.SetNoArgs(); 8845 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8846 return false; 8847 8848 return true; 8849 } 8850 8851 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8852 // an immediate value, and writes the result to the destination register. It can optionally update the condition 8853 // flags based on the result. 8854 bool 8855 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8856 { 8857 #if 0 8858 // ARM pseudo code... 8859 if ConditionPassed() then 8860 EncodingSpecificOperations(); 8861 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8862 if d == 15 then 8863 ALUWritePC(result); // setflags is always FALSE here 8864 else 8865 R[d] = result; 8866 if setflags then 8867 APSR.N = result<31>; 8868 APSR.Z = IsZeroBit(result); 8869 APSR.C = carry; 8870 APSR.V = overflow; 8871 #endif 8872 8873 bool success = false; 8874 8875 uint32_t Rd; // the destination register 8876 uint32_t Rn; // the first operand 8877 bool setflags; 8878 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8879 switch (encoding) { 8880 case eEncodingA1: 8881 Rd = Bits32(opcode, 15, 12); 8882 Rn = Bits32(opcode, 19, 16); 8883 setflags = BitIsSet(opcode, 20); 8884 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8885 8886 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8887 if (Rd == 15 && setflags) 8888 return EmulateSUBSPcLrEtc (opcode, encoding); 8889 break; 8890 default: 8891 return false; 8892 } 8893 // Read the register value from the operand register Rn. 8894 uint32_t reg_val = ReadCoreReg(Rn, &success); 8895 if (!success) 8896 return false; 8897 8898 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8899 8900 EmulateInstruction::Context context; 8901 context.type = EmulateInstruction::eContextImmediate; 8902 context.SetNoArgs (); 8903 8904 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8905 return false; 8906 8907 return true; 8908 } 8909 8910 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8911 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8912 // condition flags based on the result. 8913 bool 8914 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8915 { 8916 #if 0 8917 // ARM pseudo code... 8918 if ConditionPassed() then 8919 EncodingSpecificOperations(); 8920 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8921 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8922 if d == 15 then 8923 ALUWritePC(result); // setflags is always FALSE here 8924 else 8925 R[d] = result; 8926 if setflags then 8927 APSR.N = result<31>; 8928 APSR.Z = IsZeroBit(result); 8929 APSR.C = carry; 8930 APSR.V = overflow; 8931 #endif 8932 8933 bool success = false; 8934 8935 uint32_t Rd; // the destination register 8936 uint32_t Rn; // the first operand 8937 uint32_t Rm; // the second operand 8938 bool setflags; 8939 ARM_ShifterType shift_t; 8940 uint32_t shift_n; // the shift applied to the value read from Rm 8941 switch (encoding) { 8942 case eEncodingA1: 8943 Rd = Bits32(opcode, 15, 12); 8944 Rn = Bits32(opcode, 19, 16); 8945 Rm = Bits32(opcode, 3, 0); 8946 setflags = BitIsSet(opcode, 20); 8947 shift_n = DecodeImmShiftARM(opcode, shift_t); 8948 8949 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8950 if (Rd == 15 && setflags) 8951 return EmulateSUBSPcLrEtc (opcode, encoding); 8952 break; 8953 default: 8954 return false; 8955 } 8956 // Read the register value from register Rn. 8957 uint32_t val1 = ReadCoreReg(Rn, &success); 8958 if (!success) 8959 return false; 8960 8961 // Read the register value from register Rm. 8962 uint32_t val2 = ReadCoreReg(Rm, &success); 8963 if (!success) 8964 return false; 8965 8966 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8967 if (!success) 8968 return false; 8969 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8970 8971 EmulateInstruction::Context context; 8972 context.type = EmulateInstruction::eContextImmediate; 8973 context.SetNoArgs(); 8974 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8975 return false; 8976 8977 return true; 8978 } 8979 8980 // Subtract with Carry (immediate) subtracts an immediate value and the value of 8981 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8982 // It can optionally update the condition flags based on the result. 8983 bool 8984 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 8985 { 8986 #if 0 8987 // ARM pseudo code... 8988 if ConditionPassed() then 8989 EncodingSpecificOperations(); 8990 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8991 if d == 15 then // Can only occur for ARM encoding 8992 ALUWritePC(result); // setflags is always FALSE here 8993 else 8994 R[d] = result; 8995 if setflags then 8996 APSR.N = result<31>; 8997 APSR.Z = IsZeroBit(result); 8998 APSR.C = carry; 8999 APSR.V = overflow; 9000 #endif 9001 9002 bool success = false; 9003 9004 uint32_t Rd; // the destination register 9005 uint32_t Rn; // the first operand 9006 bool setflags; 9007 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 9008 switch (encoding) { 9009 case eEncodingT1: 9010 Rd = Bits32(opcode, 11, 8); 9011 Rn = Bits32(opcode, 19, 16); 9012 setflags = BitIsSet(opcode, 20); 9013 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9014 if (BadReg(Rd) || BadReg(Rn)) 9015 return false; 9016 break; 9017 case eEncodingA1: 9018 Rd = Bits32(opcode, 15, 12); 9019 Rn = Bits32(opcode, 19, 16); 9020 setflags = BitIsSet(opcode, 20); 9021 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9022 9023 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9024 if (Rd == 15 && setflags) 9025 return EmulateSUBSPcLrEtc (opcode, encoding); 9026 break; 9027 default: 9028 return false; 9029 } 9030 // Read the register value from the operand register Rn. 9031 uint32_t reg_val = ReadCoreReg(Rn, &success); 9032 if (!success) 9033 return false; 9034 9035 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9036 9037 EmulateInstruction::Context context; 9038 context.type = EmulateInstruction::eContextImmediate; 9039 context.SetNoArgs (); 9040 9041 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9042 return false; 9043 9044 return true; 9045 } 9046 9047 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 9048 // NOT (Carry flag) from a register value, and writes the result to the destination register. 9049 // It can optionally update the condition flags based on the result. 9050 bool 9051 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 9052 { 9053 #if 0 9054 // ARM pseudo code... 9055 if ConditionPassed() then 9056 EncodingSpecificOperations(); 9057 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9058 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9059 if d == 15 then // Can only occur for ARM encoding 9060 ALUWritePC(result); // setflags is always FALSE here 9061 else 9062 R[d] = result; 9063 if setflags then 9064 APSR.N = result<31>; 9065 APSR.Z = IsZeroBit(result); 9066 APSR.C = carry; 9067 APSR.V = overflow; 9068 #endif 9069 9070 bool success = false; 9071 9072 uint32_t Rd; // the destination register 9073 uint32_t Rn; // the first operand 9074 uint32_t Rm; // the second operand 9075 bool setflags; 9076 ARM_ShifterType shift_t; 9077 uint32_t shift_n; // the shift applied to the value read from Rm 9078 switch (encoding) { 9079 case eEncodingT1: 9080 Rd = Rn = Bits32(opcode, 2, 0); 9081 Rm = Bits32(opcode, 5, 3); 9082 setflags = !InITBlock(); 9083 shift_t = SRType_LSL; 9084 shift_n = 0; 9085 break; 9086 case eEncodingT2: 9087 Rd = Bits32(opcode, 11, 8); 9088 Rn = Bits32(opcode, 19, 16); 9089 Rm = Bits32(opcode, 3, 0); 9090 setflags = BitIsSet(opcode, 20); 9091 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9092 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9093 return false; 9094 break; 9095 case eEncodingA1: 9096 Rd = Bits32(opcode, 15, 12); 9097 Rn = Bits32(opcode, 19, 16); 9098 Rm = Bits32(opcode, 3, 0); 9099 setflags = BitIsSet(opcode, 20); 9100 shift_n = DecodeImmShiftARM(opcode, shift_t); 9101 9102 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9103 if (Rd == 15 && setflags) 9104 return EmulateSUBSPcLrEtc (opcode, encoding); 9105 break; 9106 default: 9107 return false; 9108 } 9109 // Read the register value from register Rn. 9110 uint32_t val1 = ReadCoreReg(Rn, &success); 9111 if (!success) 9112 return false; 9113 9114 // Read the register value from register Rm. 9115 uint32_t val2 = ReadCoreReg(Rm, &success); 9116 if (!success) 9117 return false; 9118 9119 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9120 if (!success) 9121 return false; 9122 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9123 9124 EmulateInstruction::Context context; 9125 context.type = EmulateInstruction::eContextImmediate; 9126 context.SetNoArgs(); 9127 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9128 return false; 9129 9130 return true; 9131 } 9132 9133 // This instruction subtracts an immediate value from a register value, and writes the result 9134 // to the destination register. It can optionally update the condition flags based on the result. 9135 bool 9136 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 9137 { 9138 #if 0 9139 // ARM pseudo code... 9140 if ConditionPassed() then 9141 EncodingSpecificOperations(); 9142 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9143 R[d] = result; 9144 if setflags then 9145 APSR.N = result<31>; 9146 APSR.Z = IsZeroBit(result); 9147 APSR.C = carry; 9148 APSR.V = overflow; 9149 #endif 9150 9151 bool success = false; 9152 9153 uint32_t Rd; // the destination register 9154 uint32_t Rn; // the first operand 9155 bool setflags; 9156 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9157 switch (encoding) { 9158 case eEncodingT1: 9159 Rd = Bits32(opcode, 2, 0); 9160 Rn = Bits32(opcode, 5, 3); 9161 setflags = !InITBlock(); 9162 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9163 break; 9164 case eEncodingT2: 9165 Rd = Rn = Bits32(opcode, 10, 8); 9166 setflags = !InITBlock(); 9167 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9168 break; 9169 case eEncodingT3: 9170 Rd = Bits32(opcode, 11, 8); 9171 Rn = Bits32(opcode, 19, 16); 9172 setflags = BitIsSet(opcode, 20); 9173 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9174 9175 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9176 if (Rd == 15 && setflags) 9177 return EmulateCMPImm (opcode, eEncodingT2); 9178 9179 // if Rn == '1101' then SEE SUB (SP minus immediate); 9180 if (Rn == 13) 9181 return EmulateSUBSPImm (opcode, eEncodingT2); 9182 9183 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9184 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9185 return false; 9186 break; 9187 case eEncodingT4: 9188 Rd = Bits32(opcode, 11, 8); 9189 Rn = Bits32(opcode, 19, 16); 9190 setflags = BitIsSet(opcode, 20); 9191 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9192 9193 // if Rn == '1111' then SEE ADR; 9194 if (Rn == 15) 9195 return EmulateADR (opcode, eEncodingT2); 9196 9197 // if Rn == '1101' then SEE SUB (SP minus immediate); 9198 if (Rn == 13) 9199 return EmulateSUBSPImm (opcode, eEncodingT3); 9200 9201 if (BadReg(Rd)) 9202 return false; 9203 break; 9204 default: 9205 return false; 9206 } 9207 // Read the register value from the operand register Rn. 9208 uint32_t reg_val = ReadCoreReg(Rn, &success); 9209 if (!success) 9210 return false; 9211 9212 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9213 9214 EmulateInstruction::Context context; 9215 context.type = EmulateInstruction::eContextImmediate; 9216 context.SetNoArgs (); 9217 9218 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9219 return false; 9220 9221 return true; 9222 } 9223 9224 // This instruction subtracts an immediate value from a register value, and writes the result 9225 // to the destination register. It can optionally update the condition flags based on the result. 9226 bool 9227 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9228 { 9229 #if 0 9230 // ARM pseudo code... 9231 if ConditionPassed() then 9232 EncodingSpecificOperations(); 9233 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9234 if d == 15 then 9235 ALUWritePC(result); // setflags is always FALSE here 9236 else 9237 R[d] = result; 9238 if setflags then 9239 APSR.N = result<31>; 9240 APSR.Z = IsZeroBit(result); 9241 APSR.C = carry; 9242 APSR.V = overflow; 9243 #endif 9244 9245 bool success = false; 9246 9247 if (ConditionPassed(opcode)) 9248 { 9249 uint32_t Rd; // the destination register 9250 uint32_t Rn; // the first operand 9251 bool setflags; 9252 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9253 switch (encoding) { 9254 case eEncodingA1: 9255 Rd = Bits32(opcode, 15, 12); 9256 Rn = Bits32(opcode, 19, 16); 9257 setflags = BitIsSet(opcode, 20); 9258 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9259 9260 // if Rn == '1111' && S == '0' then SEE ADR; 9261 if (Rn == 15 && !setflags) 9262 return EmulateADR (opcode, eEncodingA2); 9263 9264 // if Rn == '1101' then SEE SUB (SP minus immediate); 9265 if (Rn == 13) 9266 return EmulateSUBSPImm (opcode, eEncodingA1); 9267 9268 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9269 if (Rd == 15 && setflags) 9270 return EmulateSUBSPcLrEtc (opcode, encoding); 9271 break; 9272 default: 9273 return false; 9274 } 9275 // Read the register value from the operand register Rn. 9276 uint32_t reg_val = ReadCoreReg(Rn, &success); 9277 if (!success) 9278 return false; 9279 9280 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9281 9282 EmulateInstruction::Context context; 9283 if (Rd == 13) 9284 context.type = EmulateInstruction::eContextAdjustStackPointer; 9285 else 9286 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9287 9288 RegisterInfo dwarf_reg; 9289 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 9290 int64_t imm32_signed = imm32; 9291 context.SetRegisterPlusOffset (dwarf_reg, -imm32_signed); 9292 9293 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9294 return false; 9295 } 9296 return true; 9297 } 9298 9299 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9300 // immediate value. It updates the condition flags based on the result, and discards the result. 9301 bool 9302 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9303 { 9304 #if 0 9305 // ARM pseudo code... 9306 if ConditionPassed() then 9307 EncodingSpecificOperations(); 9308 result = R[n] EOR imm32; 9309 APSR.N = result<31>; 9310 APSR.Z = IsZeroBit(result); 9311 APSR.C = carry; 9312 // APSR.V unchanged 9313 #endif 9314 9315 bool success = false; 9316 9317 if (ConditionPassed(opcode)) 9318 { 9319 uint32_t Rn; 9320 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9321 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9322 switch (encoding) 9323 { 9324 case eEncodingT1: 9325 Rn = Bits32(opcode, 19, 16); 9326 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9327 if (BadReg(Rn)) 9328 return false; 9329 break; 9330 case eEncodingA1: 9331 Rn = Bits32(opcode, 19, 16); 9332 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9333 break; 9334 default: 9335 return false; 9336 } 9337 9338 // Read the first operand. 9339 uint32_t val1 = ReadCoreReg(Rn, &success); 9340 if (!success) 9341 return false; 9342 9343 uint32_t result = val1 ^ imm32; 9344 9345 EmulateInstruction::Context context; 9346 context.type = EmulateInstruction::eContextImmediate; 9347 context.SetNoArgs (); 9348 9349 if (!WriteFlags(context, result, carry)) 9350 return false; 9351 } 9352 return true; 9353 } 9354 9355 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9356 // optionally-shifted register value. It updates the condition flags based on the result, and discards 9357 // the result. 9358 bool 9359 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9360 { 9361 #if 0 9362 // ARM pseudo code... 9363 if ConditionPassed() then 9364 EncodingSpecificOperations(); 9365 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9366 result = R[n] EOR shifted; 9367 APSR.N = result<31>; 9368 APSR.Z = IsZeroBit(result); 9369 APSR.C = carry; 9370 // APSR.V unchanged 9371 #endif 9372 9373 bool success = false; 9374 9375 if (ConditionPassed(opcode)) 9376 { 9377 uint32_t Rn, Rm; 9378 ARM_ShifterType shift_t; 9379 uint32_t shift_n; // the shift applied to the value read from Rm 9380 uint32_t carry; 9381 switch (encoding) 9382 { 9383 case eEncodingT1: 9384 Rn = Bits32(opcode, 19, 16); 9385 Rm = Bits32(opcode, 3, 0); 9386 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9387 if (BadReg(Rn) || BadReg(Rm)) 9388 return false; 9389 break; 9390 case eEncodingA1: 9391 Rn = Bits32(opcode, 19, 16); 9392 Rm = Bits32(opcode, 3, 0); 9393 shift_n = DecodeImmShiftARM(opcode, shift_t); 9394 break; 9395 default: 9396 return false; 9397 } 9398 9399 // Read the first operand. 9400 uint32_t val1 = ReadCoreReg(Rn, &success); 9401 if (!success) 9402 return false; 9403 9404 // Read the second operand. 9405 uint32_t val2 = ReadCoreReg(Rm, &success); 9406 if (!success) 9407 return false; 9408 9409 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9410 if (!success) 9411 return false; 9412 uint32_t result = val1 ^ shifted; 9413 9414 EmulateInstruction::Context context; 9415 context.type = EmulateInstruction::eContextImmediate; 9416 context.SetNoArgs (); 9417 9418 if (!WriteFlags(context, result, carry)) 9419 return false; 9420 } 9421 return true; 9422 } 9423 9424 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9425 // It updates the condition flags based on the result, and discards the result. 9426 bool 9427 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9428 { 9429 #if 0 9430 // ARM pseudo code... 9431 if ConditionPassed() then 9432 EncodingSpecificOperations(); 9433 result = R[n] AND imm32; 9434 APSR.N = result<31>; 9435 APSR.Z = IsZeroBit(result); 9436 APSR.C = carry; 9437 // APSR.V unchanged 9438 #endif 9439 9440 bool success = false; 9441 9442 if (ConditionPassed(opcode)) 9443 { 9444 uint32_t Rn; 9445 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9446 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9447 switch (encoding) 9448 { 9449 case eEncodingT1: 9450 Rn = Bits32(opcode, 19, 16); 9451 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9452 if (BadReg(Rn)) 9453 return false; 9454 break; 9455 case eEncodingA1: 9456 Rn = Bits32(opcode, 19, 16); 9457 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9458 break; 9459 default: 9460 return false; 9461 } 9462 9463 // Read the first operand. 9464 uint32_t val1 = ReadCoreReg(Rn, &success); 9465 if (!success) 9466 return false; 9467 9468 uint32_t result = val1 & imm32; 9469 9470 EmulateInstruction::Context context; 9471 context.type = EmulateInstruction::eContextImmediate; 9472 context.SetNoArgs (); 9473 9474 if (!WriteFlags(context, result, carry)) 9475 return false; 9476 } 9477 return true; 9478 } 9479 9480 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9481 // It updates the condition flags based on the result, and discards the result. 9482 bool 9483 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9484 { 9485 #if 0 9486 // ARM pseudo code... 9487 if ConditionPassed() then 9488 EncodingSpecificOperations(); 9489 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9490 result = R[n] AND shifted; 9491 APSR.N = result<31>; 9492 APSR.Z = IsZeroBit(result); 9493 APSR.C = carry; 9494 // APSR.V unchanged 9495 #endif 9496 9497 bool success = false; 9498 9499 if (ConditionPassed(opcode)) 9500 { 9501 uint32_t Rn, Rm; 9502 ARM_ShifterType shift_t; 9503 uint32_t shift_n; // the shift applied to the value read from Rm 9504 uint32_t carry; 9505 switch (encoding) 9506 { 9507 case eEncodingT1: 9508 Rn = Bits32(opcode, 2, 0); 9509 Rm = Bits32(opcode, 5, 3); 9510 shift_t = SRType_LSL; 9511 shift_n = 0; 9512 break; 9513 case eEncodingT2: 9514 Rn = Bits32(opcode, 19, 16); 9515 Rm = Bits32(opcode, 3, 0); 9516 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9517 if (BadReg(Rn) || BadReg(Rm)) 9518 return false; 9519 break; 9520 case eEncodingA1: 9521 Rn = Bits32(opcode, 19, 16); 9522 Rm = Bits32(opcode, 3, 0); 9523 shift_n = DecodeImmShiftARM(opcode, shift_t); 9524 break; 9525 default: 9526 return false; 9527 } 9528 9529 // Read the first operand. 9530 uint32_t val1 = ReadCoreReg(Rn, &success); 9531 if (!success) 9532 return false; 9533 9534 // Read the second operand. 9535 uint32_t val2 = ReadCoreReg(Rm, &success); 9536 if (!success) 9537 return false; 9538 9539 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9540 if (!success) 9541 return false; 9542 uint32_t result = val1 & shifted; 9543 9544 EmulateInstruction::Context context; 9545 context.type = EmulateInstruction::eContextImmediate; 9546 context.SetNoArgs (); 9547 9548 if (!WriteFlags(context, result, carry)) 9549 return false; 9550 } 9551 return true; 9552 } 9553 9554 // A8.6.216 SUB (SP minus register) 9555 bool 9556 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9557 { 9558 #if 0 9559 if ConditionPassed() then 9560 EncodingSpecificOperations(); 9561 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9562 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 9563 if d == 15 then // Can only occur for ARM encoding 9564 ALUWritePC(result); // setflags is always FALSE here 9565 else 9566 R[d] = result; 9567 if setflags then 9568 APSR.N = result<31>; 9569 APSR.Z = IsZeroBit(result); 9570 APSR.C = carry; 9571 APSR.V = overflow; 9572 #endif 9573 9574 bool success = false; 9575 9576 if (ConditionPassed(opcode)) 9577 { 9578 uint32_t d; 9579 uint32_t m; 9580 bool setflags; 9581 ARM_ShifterType shift_t; 9582 uint32_t shift_n; 9583 9584 switch (encoding) 9585 { 9586 case eEncodingT1: 9587 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 9588 d = Bits32 (opcode, 11, 8); 9589 m = Bits32 (opcode, 3, 0); 9590 setflags = BitIsSet (opcode, 20); 9591 9592 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9593 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9594 9595 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9596 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9597 return false; 9598 9599 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9600 if ((d == 15) || BadReg (m)) 9601 return false; 9602 break; 9603 9604 case eEncodingA1: 9605 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 9606 d = Bits32 (opcode, 15, 12); 9607 m = Bits32 (opcode, 3, 0); 9608 setflags = BitIsSet (opcode, 20); 9609 9610 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9611 if (d == 15 && setflags) 9612 EmulateSUBSPcLrEtc (opcode, encoding); 9613 9614 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9615 shift_n = DecodeImmShiftARM (opcode, shift_t); 9616 break; 9617 9618 default: 9619 return false; 9620 } 9621 9622 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9623 uint32_t Rm = ReadCoreReg (m, &success); 9624 if (!success) 9625 return false; 9626 9627 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9628 if (!success) 9629 return false; 9630 9631 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 9632 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9633 if (!success) 9634 return false; 9635 9636 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9637 9638 EmulateInstruction::Context context; 9639 context.type = eContextArithmetic; 9640 RegisterInfo sp_reg; 9641 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9642 RegisterInfo dwarf_reg; 9643 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9644 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9645 9646 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9647 return false; 9648 } 9649 return true; 9650 } 9651 9652 9653 // A8.6.7 ADD (register-shifted register) 9654 bool 9655 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9656 { 9657 #if 0 9658 if ConditionPassed() then 9659 EncodingSpecificOperations(); 9660 shift_n = UInt(R[s]<7:0>); 9661 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9662 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 9663 R[d] = result; 9664 if setflags then 9665 APSR.N = result<31>; 9666 APSR.Z = IsZeroBit(result); 9667 APSR.C = carry; 9668 APSR.V = overflow; 9669 #endif 9670 9671 bool success = false; 9672 9673 if (ConditionPassed(opcode)) 9674 { 9675 uint32_t d; 9676 uint32_t n; 9677 uint32_t m; 9678 uint32_t s; 9679 bool setflags; 9680 ARM_ShifterType shift_t; 9681 9682 switch (encoding) 9683 { 9684 case eEncodingA1: 9685 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9686 d = Bits32 (opcode, 15, 12); 9687 n = Bits32 (opcode, 19, 16); 9688 m = Bits32 (opcode, 3, 0); 9689 s = Bits32 (opcode, 11, 8); 9690 9691 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 9692 setflags = BitIsSet (opcode, 20); 9693 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9694 9695 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9696 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9697 return false; 9698 break; 9699 9700 default: 9701 return false; 9702 } 9703 9704 // shift_n = UInt(R[s]<7:0>); 9705 uint32_t Rs = ReadCoreReg (s, &success); 9706 if (!success) 9707 return false; 9708 9709 uint32_t shift_n = Bits32 (Rs, 7, 0); 9710 9711 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9712 uint32_t Rm = ReadCoreReg (m, &success); 9713 if (!success) 9714 return false; 9715 9716 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9717 if (!success) 9718 return false; 9719 9720 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 9721 uint32_t Rn = ReadCoreReg (n, &success); 9722 if (!success) 9723 return false; 9724 9725 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9726 9727 // R[d] = result; 9728 EmulateInstruction::Context context; 9729 context.type = eContextArithmetic; 9730 RegisterInfo reg_n; 9731 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9732 RegisterInfo reg_m; 9733 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9734 9735 context.SetRegisterRegisterOperands (reg_n, reg_m); 9736 9737 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9738 return false; 9739 9740 // if setflags then 9741 // APSR.N = result<31>; 9742 // APSR.Z = IsZeroBit(result); 9743 // APSR.C = carry; 9744 // APSR.V = overflow; 9745 if (setflags) 9746 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9747 } 9748 return true; 9749 } 9750 9751 // A8.6.213 SUB (register) 9752 bool 9753 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9754 { 9755 #if 0 9756 if ConditionPassed() then 9757 EncodingSpecificOperations(); 9758 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9759 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 9760 if d == 15 then // Can only occur for ARM encoding 9761 ALUWritePC(result); // setflags is always FALSE here 9762 else 9763 R[d] = result; 9764 if setflags then 9765 APSR.N = result<31>; 9766 APSR.Z = IsZeroBit(result); 9767 APSR.C = carry; 9768 APSR.V = overflow; 9769 #endif 9770 9771 bool success = false; 9772 9773 if (ConditionPassed(opcode)) 9774 { 9775 uint32_t d; 9776 uint32_t n; 9777 uint32_t m; 9778 bool setflags; 9779 ARM_ShifterType shift_t; 9780 uint32_t shift_n; 9781 9782 switch (encoding) 9783 { 9784 case eEncodingT1: 9785 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9786 d = Bits32 (opcode, 2, 0); 9787 n = Bits32 (opcode, 5, 3); 9788 m = Bits32 (opcode, 8, 6); 9789 setflags = !InITBlock(); 9790 9791 // (shift_t, shift_n) = (SRType_LSL, 0); 9792 shift_t = SRType_LSL; 9793 shift_n = 0; 9794 9795 break; 9796 9797 case eEncodingT2: 9798 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 9799 d = Bits32 (opcode, 11, 8); 9800 n = Bits32 (opcode, 19, 16); 9801 m = Bits32 (opcode, 3, 0); 9802 setflags = BitIsSet (opcode, 20); 9803 9804 // if Rd == "1111" && S == "1" then SEE CMP (register); 9805 if (d == 15 && setflags == 1) 9806 return EmulateCMPImm (opcode, eEncodingT3); 9807 9808 // if Rn == "1101" then SEE SUB (SP minus register); 9809 if (n == 13) 9810 return EmulateSUBSPReg (opcode, eEncodingT1); 9811 9812 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9813 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9814 9815 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9816 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9817 return false; 9818 9819 break; 9820 9821 case eEncodingA1: 9822 // if Rn == '1101' then SEE SUB (SP minus register); 9823 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 9824 d = Bits32 (opcode, 15, 12); 9825 n = Bits32 (opcode, 19, 16); 9826 m = Bits32 (opcode, 3, 0); 9827 setflags = BitIsSet (opcode, 20); 9828 9829 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9830 if ((d == 15) && setflags) 9831 EmulateSUBSPcLrEtc (opcode, encoding); 9832 9833 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9834 shift_n = DecodeImmShiftARM (opcode, shift_t); 9835 9836 break; 9837 9838 default: 9839 return false; 9840 } 9841 9842 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9843 uint32_t Rm = ReadCoreReg (m, &success); 9844 if (!success) 9845 return false; 9846 9847 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9848 if (!success) 9849 return false; 9850 9851 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 9852 uint32_t Rn = ReadCoreReg (n, &success); 9853 if (!success) 9854 return false; 9855 9856 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9857 9858 // if d == 15 then // Can only occur for ARM encoding 9859 // ALUWritePC(result); // setflags is always FALSE here 9860 // else 9861 // R[d] = result; 9862 // if setflags then 9863 // APSR.N = result<31>; 9864 // APSR.Z = IsZeroBit(result); 9865 // APSR.C = carry; 9866 // APSR.V = overflow; 9867 9868 EmulateInstruction::Context context; 9869 context.type = eContextArithmetic; 9870 RegisterInfo reg_n; 9871 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9872 RegisterInfo reg_m; 9873 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9874 context.SetRegisterRegisterOperands (reg_n, reg_m); 9875 9876 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9877 return false; 9878 } 9879 return true; 9880 } 9881 9882 // A8.6.202 STREX 9883 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9884 // word from a register to memory if the executing processor has exclusive access to the memory addressed. 9885 bool 9886 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9887 { 9888 #if 0 9889 if ConditionPassed() then 9890 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9891 address = R[n] + imm32; 9892 if ExclusiveMonitorsPass(address,4) then 9893 MemA[address,4] = R[t]; 9894 R[d] = 0; 9895 else 9896 R[d] = 1; 9897 #endif 9898 9899 bool success = false; 9900 9901 if (ConditionPassed(opcode)) 9902 { 9903 uint32_t d; 9904 uint32_t t; 9905 uint32_t n; 9906 uint32_t imm32; 9907 const uint32_t addr_byte_size = GetAddressByteSize(); 9908 9909 switch (encoding) 9910 { 9911 case eEncodingT1: 9912 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 9913 d = Bits32 (opcode, 11, 8); 9914 t = Bits32 (opcode, 15, 12); 9915 n = Bits32 (opcode, 19, 16); 9916 imm32 = Bits32 (opcode, 7, 0) << 2; 9917 9918 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9919 if (BadReg (d) || BadReg (t) || (n == 15)) 9920 return false; 9921 9922 // if d == n || d == t then UNPREDICTABLE; 9923 if ((d == n) || (d == t)) 9924 return false; 9925 9926 break; 9927 9928 case eEncodingA1: 9929 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9930 d = Bits32 (opcode, 15, 12); 9931 t = Bits32 (opcode, 3, 0); 9932 n = Bits32 (opcode, 19, 16); 9933 imm32 = 0; 9934 9935 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9936 if ((d == 15) || (t == 15) || (n == 15)) 9937 return false; 9938 9939 // if d == n || d == t then UNPREDICTABLE; 9940 if ((d == n) || (d == t)) 9941 return false; 9942 9943 break; 9944 9945 default: 9946 return false; 9947 } 9948 9949 // address = R[n] + imm32; 9950 uint32_t Rn = ReadCoreReg (n, &success); 9951 if (!success) 9952 return false; 9953 9954 addr_t address = Rn + imm32; 9955 9956 RegisterInfo base_reg; 9957 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9958 RegisterInfo data_reg; 9959 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9960 EmulateInstruction::Context context; 9961 context.type = eContextRegisterStore; 9962 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9963 9964 // if ExclusiveMonitorsPass(address,4) then 9965 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9966 // always return true. 9967 if (true) 9968 { 9969 // MemA[address,4] = R[t]; 9970 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9971 if (!success) 9972 return false; 9973 9974 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9975 return false; 9976 9977 // R[d] = 0; 9978 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9979 return false; 9980 } 9981 #if 0 // unreachable because if true 9982 else 9983 { 9984 // R[d] = 1; 9985 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9986 return false; 9987 } 9988 #endif // unreachable because if true 9989 } 9990 return true; 9991 } 9992 9993 // A8.6.197 STRB (immediate, ARM) 9994 bool 9995 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9996 { 9997 #if 0 9998 if ConditionPassed() then 9999 EncodingSpecificOperations(); 10000 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10001 address = if index then offset_addr else R[n]; 10002 MemU[address,1] = R[t]<7:0>; 10003 if wback then R[n] = offset_addr; 10004 #endif 10005 10006 bool success = false; 10007 10008 if (ConditionPassed(opcode)) 10009 { 10010 uint32_t t; 10011 uint32_t n; 10012 uint32_t imm32; 10013 bool index; 10014 bool add; 10015 bool wback; 10016 10017 switch (encoding) 10018 { 10019 case eEncodingA1: 10020 // if P == '0' && W == '1' then SEE STRBT; 10021 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10022 t = Bits32 (opcode, 15, 12); 10023 n = Bits32 (opcode, 19, 16); 10024 imm32 = Bits32 (opcode, 11, 0); 10025 10026 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10027 index = BitIsSet (opcode, 24); 10028 add = BitIsSet (opcode, 23); 10029 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10030 10031 // if t == 15 then UNPREDICTABLE; 10032 if (t == 15) 10033 return false; 10034 10035 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10036 if (wback && ((n == 15) || (n == t))) 10037 return false; 10038 10039 break; 10040 10041 default: 10042 return false; 10043 } 10044 10045 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10046 uint32_t Rn = ReadCoreReg (n, &success); 10047 if (!success) 10048 return false; 10049 10050 addr_t offset_addr; 10051 if (add) 10052 offset_addr = Rn + imm32; 10053 else 10054 offset_addr = Rn - imm32; 10055 10056 // address = if index then offset_addr else R[n]; 10057 addr_t address; 10058 if (index) 10059 address = offset_addr; 10060 else 10061 address = Rn; 10062 10063 // MemU[address,1] = R[t]<7:0>; 10064 uint32_t Rt = ReadCoreReg (t, &success); 10065 if (!success) 10066 return false; 10067 10068 RegisterInfo base_reg; 10069 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10070 RegisterInfo data_reg; 10071 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10072 EmulateInstruction::Context context; 10073 context.type = eContextRegisterStore; 10074 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10075 10076 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 10077 return false; 10078 10079 // if wback then R[n] = offset_addr; 10080 if (wback) 10081 { 10082 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10083 return false; 10084 } 10085 } 10086 return true; 10087 } 10088 10089 // A8.6.194 STR (immediate, ARM) 10090 bool 10091 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 10092 { 10093 #if 0 10094 if ConditionPassed() then 10095 EncodingSpecificOperations(); 10096 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10097 address = if index then offset_addr else R[n]; 10098 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10099 if wback then R[n] = offset_addr; 10100 #endif 10101 10102 bool success = false; 10103 10104 if (ConditionPassed(opcode)) 10105 { 10106 uint32_t t; 10107 uint32_t n; 10108 uint32_t imm32; 10109 bool index; 10110 bool add; 10111 bool wback; 10112 10113 const uint32_t addr_byte_size = GetAddressByteSize(); 10114 10115 switch (encoding) 10116 { 10117 case eEncodingA1: 10118 // if P == '0' && W == '1' then SEE STRT; 10119 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH; 10120 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10121 t = Bits32 (opcode, 15, 12); 10122 n = Bits32 (opcode, 19, 16); 10123 imm32 = Bits32 (opcode, 11, 0); 10124 10125 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10126 index = BitIsSet (opcode, 24); 10127 add = BitIsSet (opcode, 23); 10128 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10129 10130 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10131 if (wback && ((n == 15) || (n == t))) 10132 return false; 10133 10134 break; 10135 10136 default: 10137 return false; 10138 } 10139 10140 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10141 uint32_t Rn = ReadCoreReg (n, &success); 10142 if (!success) 10143 return false; 10144 10145 addr_t offset_addr; 10146 if (add) 10147 offset_addr = Rn + imm32; 10148 else 10149 offset_addr = Rn - imm32; 10150 10151 // address = if index then offset_addr else R[n]; 10152 addr_t address; 10153 if (index) 10154 address = offset_addr; 10155 else 10156 address = Rn; 10157 10158 RegisterInfo base_reg; 10159 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10160 RegisterInfo data_reg; 10161 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10162 EmulateInstruction::Context context; 10163 context.type = eContextRegisterStore; 10164 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10165 10166 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10167 uint32_t Rt = ReadCoreReg (t, &success); 10168 if (!success) 10169 return false; 10170 10171 if (t == 15) 10172 { 10173 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10174 if (!success) 10175 return false; 10176 10177 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10178 return false; 10179 } 10180 else 10181 { 10182 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10183 return false; 10184 } 10185 10186 // if wback then R[n] = offset_addr; 10187 if (wback) 10188 { 10189 context.type = eContextAdjustBaseRegister; 10190 context.SetImmediate (offset_addr); 10191 10192 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10193 return false; 10194 } 10195 } 10196 return true; 10197 } 10198 10199 // A8.6.66 LDRD (immediate) 10200 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10201 // words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10202 bool 10203 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10204 { 10205 #if 0 10206 if ConditionPassed() then 10207 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10208 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10209 address = if index then offset_addr else R[n]; 10210 R[t] = MemA[address,4]; 10211 R[t2] = MemA[address+4,4]; 10212 if wback then R[n] = offset_addr; 10213 #endif 10214 10215 bool success = false; 10216 10217 if (ConditionPassed(opcode)) 10218 { 10219 uint32_t t; 10220 uint32_t t2; 10221 uint32_t n; 10222 uint32_t imm32; 10223 bool index; 10224 bool add; 10225 bool wback; 10226 10227 switch (encoding) 10228 { 10229 case eEncodingT1: 10230 //if P == '0' && W == '0' then SEE 'Related encodings'; 10231 //if Rn == '1111' then SEE LDRD (literal); 10232 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 10233 t = Bits32 (opcode, 15, 12); 10234 t2 = Bits32 (opcode, 11, 8); 10235 n = Bits32 (opcode, 19, 16); 10236 imm32 = Bits32 (opcode, 7, 0) << 2; 10237 10238 //index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10239 index = BitIsSet (opcode, 24); 10240 add = BitIsSet (opcode, 23); 10241 wback = BitIsSet (opcode, 21); 10242 10243 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10244 if (wback && ((n == t) || (n == t2))) 10245 return false; 10246 10247 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10248 if (BadReg (t) || BadReg (t2) || (t == t2)) 10249 return false; 10250 10251 break; 10252 10253 case eEncodingA1: 10254 //if Rn == '1111' then SEE LDRD (literal); 10255 //if Rt<0> == '1' then UNPREDICTABLE; 10256 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10257 t = Bits32 (opcode, 15, 12); 10258 if (BitIsSet (t, 0)) 10259 return false; 10260 t2 = t + 1; 10261 n = Bits32 (opcode, 19, 16); 10262 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10263 10264 //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10265 index = BitIsSet (opcode, 24); 10266 add = BitIsSet (opcode, 23); 10267 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10268 10269 //if P == '0' && W == '1' then UNPREDICTABLE; 10270 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10271 return false; 10272 10273 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10274 if (wback && ((n == t) || (n == t2))) 10275 return false; 10276 10277 //if t2 == 15 then UNPREDICTABLE; 10278 if (t2 == 15) 10279 return false; 10280 10281 break; 10282 10283 default: 10284 return false; 10285 } 10286 10287 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10288 uint32_t Rn = ReadCoreReg (n, &success); 10289 if (!success) 10290 return false; 10291 10292 addr_t offset_addr; 10293 if (add) 10294 offset_addr = Rn + imm32; 10295 else 10296 offset_addr = Rn - imm32; 10297 10298 //address = if index then offset_addr else R[n]; 10299 addr_t address; 10300 if (index) 10301 address = offset_addr; 10302 else 10303 address = Rn; 10304 10305 //R[t] = MemA[address,4]; 10306 RegisterInfo base_reg; 10307 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10308 10309 EmulateInstruction::Context context; 10310 if (n == 13) 10311 context.type = eContextPopRegisterOffStack; 10312 else 10313 context.type = eContextRegisterLoad; 10314 context.SetAddress(address); 10315 10316 const uint32_t addr_byte_size = GetAddressByteSize(); 10317 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10318 if (!success) 10319 return false; 10320 10321 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10322 return false; 10323 10324 //R[t2] = MemA[address+4,4]; 10325 context.SetAddress(address + 4); 10326 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10327 if (!success) 10328 return false; 10329 10330 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10331 return false; 10332 10333 //if wback then R[n] = offset_addr; 10334 if (wback) 10335 { 10336 context.type = eContextAdjustBaseRegister; 10337 context.SetAddress (offset_addr); 10338 10339 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10340 return false; 10341 } 10342 } 10343 return true; 10344 } 10345 10346 // A8.6.68 LDRD (register) 10347 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10348 // words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10349 bool 10350 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10351 { 10352 #if 0 10353 if ConditionPassed() then 10354 EncodingSpecificOperations(); 10355 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10356 address = if index then offset_addr else R[n]; 10357 R[t] = MemA[address,4]; 10358 R[t2] = MemA[address+4,4]; 10359 if wback then R[n] = offset_addr; 10360 #endif 10361 10362 bool success = false; 10363 10364 if (ConditionPassed(opcode)) 10365 { 10366 uint32_t t; 10367 uint32_t t2; 10368 uint32_t n; 10369 uint32_t m; 10370 bool index; 10371 bool add; 10372 bool wback; 10373 10374 switch (encoding) 10375 { 10376 case eEncodingA1: 10377 // if Rt<0> == '1' then UNPREDICTABLE; 10378 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10379 t = Bits32 (opcode, 15, 12); 10380 if (BitIsSet (t, 0)) 10381 return false; 10382 t2 = t + 1; 10383 n = Bits32 (opcode, 19, 16); 10384 m = Bits32 (opcode, 3, 0); 10385 10386 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10387 index = BitIsSet (opcode, 24); 10388 add = BitIsSet (opcode, 23); 10389 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10390 10391 // if P == '0' && W == '1' then UNPREDICTABLE; 10392 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10393 return false; 10394 10395 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10396 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10397 return false; 10398 10399 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10400 if (wback && ((n == 15) || (n == t) || (n == t2))) 10401 return false; 10402 10403 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10404 if ((ArchVersion() < 6) && wback && (m == n)) 10405 return false; 10406 break; 10407 10408 default: 10409 return false; 10410 } 10411 10412 uint32_t Rn = ReadCoreReg (n, &success); 10413 if (!success) 10414 return false; 10415 RegisterInfo base_reg; 10416 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10417 10418 uint32_t Rm = ReadCoreReg (m, &success); 10419 if (!success) 10420 return false; 10421 RegisterInfo offset_reg; 10422 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10423 10424 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10425 addr_t offset_addr; 10426 if (add) 10427 offset_addr = Rn + Rm; 10428 else 10429 offset_addr = Rn - Rm; 10430 10431 // address = if index then offset_addr else R[n]; 10432 addr_t address; 10433 if (index) 10434 address = offset_addr; 10435 else 10436 address = Rn; 10437 10438 EmulateInstruction::Context context; 10439 if (n == 13) 10440 context.type = eContextPopRegisterOffStack; 10441 else 10442 context.type = eContextRegisterLoad; 10443 context.SetAddress(address); 10444 10445 // R[t] = MemA[address,4]; 10446 const uint32_t addr_byte_size = GetAddressByteSize(); 10447 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10448 if (!success) 10449 return false; 10450 10451 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10452 return false; 10453 10454 // R[t2] = MemA[address+4,4]; 10455 10456 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10457 if (!success) 10458 return false; 10459 10460 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10461 return false; 10462 10463 // if wback then R[n] = offset_addr; 10464 if (wback) 10465 { 10466 context.type = eContextAdjustBaseRegister; 10467 context.SetAddress (offset_addr); 10468 10469 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10470 return false; 10471 } 10472 } 10473 return true; 10474 } 10475 10476 // A8.6.200 STRD (immediate) 10477 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10478 // stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10479 bool 10480 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10481 { 10482 #if 0 10483 if ConditionPassed() then 10484 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10485 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10486 address = if index then offset_addr else R[n]; 10487 MemA[address,4] = R[t]; 10488 MemA[address+4,4] = R[t2]; 10489 if wback then R[n] = offset_addr; 10490 #endif 10491 10492 bool success = false; 10493 10494 if (ConditionPassed(opcode)) 10495 { 10496 uint32_t t; 10497 uint32_t t2; 10498 uint32_t n; 10499 uint32_t imm32; 10500 bool index; 10501 bool add; 10502 bool wback; 10503 10504 switch (encoding) 10505 { 10506 case eEncodingT1: 10507 // if P == '0' && W == '0' then SEE 'Related encodings'; 10508 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 10509 t = Bits32 (opcode, 15, 12); 10510 t2 = Bits32 (opcode, 11, 8); 10511 n = Bits32 (opcode, 19, 16); 10512 imm32 = Bits32 (opcode, 7, 0) << 2; 10513 10514 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10515 index = BitIsSet (opcode, 24); 10516 add = BitIsSet (opcode, 23); 10517 wback = BitIsSet (opcode, 21); 10518 10519 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10520 if (wback && ((n == t) || (n == t2))) 10521 return false; 10522 10523 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10524 if ((n == 15) || BadReg (t) || BadReg (t2)) 10525 return false; 10526 10527 break; 10528 10529 case eEncodingA1: 10530 // if Rt<0> == '1' then UNPREDICTABLE; 10531 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10532 t = Bits32 (opcode, 15, 12); 10533 if (BitIsSet (t, 0)) 10534 return false; 10535 10536 t2 = t + 1; 10537 n = Bits32 (opcode, 19, 16); 10538 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10539 10540 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10541 index = BitIsSet (opcode, 24); 10542 add = BitIsSet (opcode, 23); 10543 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10544 10545 // if P == '0' && W == '1' then UNPREDICTABLE; 10546 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10547 return false; 10548 10549 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10550 if (wback && ((n == 15) || (n == t) || (n == t2))) 10551 return false; 10552 10553 // if t2 == 15 then UNPREDICTABLE; 10554 if (t2 == 15) 10555 return false; 10556 10557 break; 10558 10559 default: 10560 return false; 10561 } 10562 10563 RegisterInfo base_reg; 10564 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10565 10566 uint32_t Rn = ReadCoreReg (n, &success); 10567 if (!success) 10568 return false; 10569 10570 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10571 addr_t offset_addr; 10572 if (add) 10573 offset_addr = Rn + imm32; 10574 else 10575 offset_addr = Rn - imm32; 10576 10577 //address = if index then offset_addr else R[n]; 10578 addr_t address; 10579 if (index) 10580 address = offset_addr; 10581 else 10582 address = Rn; 10583 10584 //MemA[address,4] = R[t]; 10585 RegisterInfo data_reg; 10586 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10587 10588 uint32_t data = ReadCoreReg (t, &success); 10589 if (!success) 10590 return false; 10591 10592 EmulateInstruction::Context context; 10593 if (n == 13) 10594 context.type = eContextPushRegisterOnStack; 10595 else 10596 context.type = eContextRegisterStore; 10597 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10598 10599 const uint32_t addr_byte_size = GetAddressByteSize(); 10600 10601 if (!MemAWrite (context, address, data, addr_byte_size)) 10602 return false; 10603 10604 //MemA[address+4,4] = R[t2]; 10605 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10606 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10607 10608 data = ReadCoreReg (t2, &success); 10609 if (!success) 10610 return false; 10611 10612 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10613 return false; 10614 10615 //if wback then R[n] = offset_addr; 10616 if (wback) 10617 { 10618 context.type = eContextAdjustBaseRegister; 10619 context.SetAddress (offset_addr); 10620 10621 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10622 return false; 10623 } 10624 } 10625 return true; 10626 } 10627 10628 10629 // A8.6.201 STRD (register) 10630 bool 10631 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10632 { 10633 #if 0 10634 if ConditionPassed() then 10635 EncodingSpecificOperations(); 10636 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10637 address = if index then offset_addr else R[n]; 10638 MemA[address,4] = R[t]; 10639 MemA[address+4,4] = R[t2]; 10640 if wback then R[n] = offset_addr; 10641 #endif 10642 10643 bool success = false; 10644 10645 if (ConditionPassed(opcode)) 10646 { 10647 uint32_t t; 10648 uint32_t t2; 10649 uint32_t n; 10650 uint32_t m; 10651 bool index; 10652 bool add; 10653 bool wback; 10654 10655 switch (encoding) 10656 { 10657 case eEncodingA1: 10658 // if Rt<0> == '1' then UNPREDICTABLE; 10659 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10660 t = Bits32 (opcode, 15, 12); 10661 if (BitIsSet (t, 0)) 10662 return false; 10663 10664 t2 = t+1; 10665 n = Bits32 (opcode, 19, 16); 10666 m = Bits32 (opcode, 3, 0); 10667 10668 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10669 index = BitIsSet (opcode, 24); 10670 add = BitIsSet (opcode, 23); 10671 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10672 10673 // if P == '0' && W == '1' then UNPREDICTABLE; 10674 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10675 return false; 10676 10677 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10678 if ((t2 == 15) || (m == 15)) 10679 return false; 10680 10681 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10682 if (wback && ((n == 15) || (n == t) || (n == t2))) 10683 return false; 10684 10685 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10686 if ((ArchVersion() < 6) && wback && (m == n)) 10687 return false; 10688 10689 break; 10690 10691 default: 10692 return false; 10693 } 10694 10695 RegisterInfo base_reg; 10696 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10697 RegisterInfo offset_reg; 10698 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10699 RegisterInfo data_reg; 10700 10701 uint32_t Rn = ReadCoreReg (n, &success); 10702 if (!success) 10703 return false; 10704 10705 uint32_t Rm = ReadCoreReg (m, &success); 10706 if (!success) 10707 return false; 10708 10709 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10710 addr_t offset_addr; 10711 if (add) 10712 offset_addr = Rn + Rm; 10713 else 10714 offset_addr = Rn - Rm; 10715 10716 // address = if index then offset_addr else R[n]; 10717 addr_t address; 10718 if (index) 10719 address = offset_addr; 10720 else 10721 address = Rn; 10722 // MemA[address,4] = R[t]; 10723 uint32_t Rt = ReadCoreReg (t, &success); 10724 if (!success) 10725 return false; 10726 10727 EmulateInstruction::Context context; 10728 if (t == 13) 10729 context.type = eContextPushRegisterOnStack; 10730 else 10731 context.type = eContextRegisterStore; 10732 10733 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10734 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10735 10736 const uint32_t addr_byte_size = GetAddressByteSize(); 10737 10738 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10739 return false; 10740 10741 // MemA[address+4,4] = R[t2]; 10742 uint32_t Rt2 = ReadCoreReg (t2, &success); 10743 if (!success) 10744 return false; 10745 10746 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10747 10748 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10749 10750 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10751 return false; 10752 10753 // if wback then R[n] = offset_addr; 10754 if (wback) 10755 { 10756 context.type = eContextAdjustBaseRegister; 10757 context.SetAddress (offset_addr); 10758 10759 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10760 return false; 10761 10762 } 10763 } 10764 return true; 10765 } 10766 10767 // A8.6.319 VLDM 10768 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10769 // an ARM core register. 10770 bool 10771 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10772 { 10773 #if 0 10774 if ConditionPassed() then 10775 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10776 address = if add then R[n] else R[n]-imm32; 10777 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10778 for r = 0 to regs-1 10779 if single_regs then 10780 S[d+r] = MemA[address,4]; address = address+4; 10781 else 10782 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10783 // Combine the word-aligned words in the correct order for current endianness. 10784 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10785 #endif 10786 10787 bool success = false; 10788 10789 if (ConditionPassed(opcode)) 10790 { 10791 bool single_regs; 10792 bool add; 10793 bool wback; 10794 uint32_t d; 10795 uint32_t n; 10796 uint32_t imm32; 10797 uint32_t regs; 10798 10799 switch (encoding) 10800 { 10801 case eEncodingT1: 10802 case eEncodingA1: 10803 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10804 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 10805 // if P == '1' && W == '0' then SEE VLDR; 10806 // if P == U && W == '1' then UNDEFINED; 10807 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10808 return false; 10809 10810 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10811 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 10812 single_regs = false; 10813 add = BitIsSet (opcode, 23); 10814 wback = BitIsSet (opcode, 21); 10815 10816 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 10817 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10818 n = Bits32 (opcode, 19, 16); 10819 imm32 = Bits32 (opcode, 7, 0) << 2; 10820 10821 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 10822 regs = Bits32 (opcode, 7, 0) / 2; 10823 10824 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10825 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10826 return false; 10827 10828 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10829 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10830 return false; 10831 10832 break; 10833 10834 case eEncodingT2: 10835 case eEncodingA2: 10836 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10837 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 10838 // if P == '1' && W == '0' then SEE VLDR; 10839 // if P == U && W == '1' then UNDEFINED; 10840 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10841 return false; 10842 10843 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10844 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); 10845 single_regs = true; 10846 add = BitIsSet (opcode, 23); 10847 wback = BitIsSet (opcode, 21); 10848 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10849 n = Bits32 (opcode, 19, 16); 10850 10851 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 10852 imm32 = Bits32 (opcode, 7, 0) << 2; 10853 regs = Bits32 (opcode, 7, 0); 10854 10855 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10856 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10857 return false; 10858 10859 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10860 if ((regs == 0) || ((d + regs) > 32)) 10861 return false; 10862 break; 10863 10864 default: 10865 return false; 10866 } 10867 10868 RegisterInfo base_reg; 10869 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10870 10871 uint32_t Rn = ReadCoreReg (n, &success); 10872 if (!success) 10873 return false; 10874 10875 // address = if add then R[n] else R[n]-imm32; 10876 addr_t address; 10877 if (add) 10878 address = Rn; 10879 else 10880 address = Rn - imm32; 10881 10882 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10883 EmulateInstruction::Context context; 10884 10885 if (wback) 10886 { 10887 uint32_t value; 10888 if (add) 10889 value = Rn + imm32; 10890 else 10891 value = Rn - imm32; 10892 10893 context.type = eContextAdjustBaseRegister; 10894 context.SetImmediateSigned (value - Rn); 10895 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10896 return false; 10897 10898 } 10899 10900 const uint32_t addr_byte_size = GetAddressByteSize(); 10901 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10902 10903 context.type = eContextRegisterLoad; 10904 10905 // for r = 0 to regs-1 10906 for (uint32_t r = 0; r < regs; ++r) 10907 { 10908 if (single_regs) 10909 { 10910 // S[d+r] = MemA[address,4]; address = address+4; 10911 context.SetRegisterPlusOffset (base_reg, address - Rn); 10912 10913 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10914 if (!success) 10915 return false; 10916 10917 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10918 return false; 10919 10920 address = address + 4; 10921 } 10922 else 10923 { 10924 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10925 context.SetRegisterPlusOffset (base_reg, address - Rn); 10926 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10927 if (!success) 10928 return false; 10929 10930 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10931 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10932 if (!success) 10933 return false; 10934 10935 address = address + 8; 10936 // // Combine the word-aligned words in the correct order for current endianness. 10937 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10938 uint64_t data; 10939 if (GetByteOrder() == eByteOrderBig) 10940 { 10941 data = word1; 10942 data = (data << 32) | word2; 10943 } 10944 else 10945 { 10946 data = word2; 10947 data = (data << 32) | word1; 10948 } 10949 10950 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10951 return false; 10952 } 10953 } 10954 } 10955 return true; 10956 } 10957 10958 // A8.6.399 VSTM 10959 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10960 // ARM core register. 10961 bool 10962 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10963 { 10964 #if 0 10965 if ConditionPassed() then 10966 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10967 address = if add then R[n] else R[n]-imm32; 10968 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10969 for r = 0 to regs-1 10970 if single_regs then 10971 MemA[address,4] = S[d+r]; address = address+4; 10972 else 10973 // Store as two word-aligned words in the correct order for current endianness. 10974 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10975 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10976 address = address+8; 10977 #endif 10978 10979 bool success = false; 10980 10981 if (ConditionPassed (opcode)) 10982 { 10983 bool single_regs; 10984 bool add; 10985 bool wback; 10986 uint32_t d; 10987 uint32_t n; 10988 uint32_t imm32; 10989 uint32_t regs; 10990 10991 switch (encoding) 10992 { 10993 case eEncodingT1: 10994 case eEncodingA1: 10995 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10996 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 10997 // if P == '1' && W == '0' then SEE VSTR; 10998 // if P == U && W == '1' then UNDEFINED; 10999 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 11000 return false; 11001 11002 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 11003 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11004 single_regs = false; 11005 add = BitIsSet (opcode, 23); 11006 wback = BitIsSet (opcode, 21); 11007 11008 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11009 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11010 n = Bits32 (opcode, 19, 16); 11011 imm32 = Bits32 (opcode, 7, 0) << 2; 11012 11013 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11014 regs = Bits32 (opcode, 7, 0) / 2; 11015 11016 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 11017 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11018 return false; 11019 11020 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11021 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11022 return false; 11023 11024 break; 11025 11026 case eEncodingT2: 11027 case eEncodingA2: 11028 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11029 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11030 // if P == '1' && W == '0' then SEE VSTR; 11031 // if P == U && W == '1' then UNDEFINED; 11032 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 11033 return false; 11034 11035 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 11036 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); 11037 single_regs = true; 11038 add = BitIsSet (opcode, 23); 11039 wback = BitIsSet (opcode, 21); 11040 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11041 n = Bits32 (opcode, 19, 16); 11042 11043 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11044 imm32 = Bits32 (opcode, 7, 0) << 2; 11045 regs = Bits32 (opcode, 7, 0); 11046 11047 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 11048 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 11049 return false; 11050 11051 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11052 if ((regs == 0) || ((d + regs) > 32)) 11053 return false; 11054 11055 break; 11056 11057 default: 11058 return false; 11059 } 11060 11061 RegisterInfo base_reg; 11062 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11063 11064 uint32_t Rn = ReadCoreReg (n, &success); 11065 if (!success) 11066 return false; 11067 11068 // address = if add then R[n] else R[n]-imm32; 11069 addr_t address; 11070 if (add) 11071 address = Rn; 11072 else 11073 address = Rn - imm32; 11074 11075 EmulateInstruction::Context context; 11076 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11077 if (wback) 11078 { 11079 uint32_t value; 11080 if (add) 11081 value = Rn + imm32; 11082 else 11083 value = Rn - imm32; 11084 11085 context.type = eContextAdjustBaseRegister; 11086 context.SetRegisterPlusOffset (base_reg, value - Rn); 11087 11088 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11089 return false; 11090 } 11091 11092 const uint32_t addr_byte_size = GetAddressByteSize(); 11093 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11094 11095 context.type = eContextRegisterStore; 11096 // for r = 0 to regs-1 11097 for (uint32_t r = 0; r < regs; ++r) 11098 { 11099 11100 if (single_regs) 11101 { 11102 // MemA[address,4] = S[d+r]; address = address+4; 11103 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 11104 if (!success) 11105 return false; 11106 11107 RegisterInfo data_reg; 11108 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11109 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11110 if (!MemAWrite (context, address, data, addr_byte_size)) 11111 return false; 11112 11113 address = address + 4; 11114 } 11115 else 11116 { 11117 // // Store as two word-aligned words in the correct order for current endianness. 11118 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11119 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11120 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 11121 if (!success) 11122 return false; 11123 11124 RegisterInfo data_reg; 11125 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11126 11127 if (GetByteOrder() == eByteOrderBig) 11128 { 11129 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11130 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11131 return false; 11132 11133 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11134 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 11135 return false; 11136 } 11137 else 11138 { 11139 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11140 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11141 return false; 11142 11143 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11144 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11145 return false; 11146 } 11147 // address = address+8; 11148 address = address + 8; 11149 } 11150 } 11151 } 11152 return true; 11153 } 11154 11155 // A8.6.320 11156 // This instruction loads a single extension register from memory, using an address from an ARM core register, with 11157 // an optional offset. 11158 bool 11159 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 11160 { 11161 #if 0 11162 if ConditionPassed() then 11163 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11164 base = if n == 15 then Align(PC,4) else R[n]; 11165 address = if add then (base + imm32) else (base - imm32); 11166 if single_reg then 11167 S[d] = MemA[address,4]; 11168 else 11169 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11170 // Combine the word-aligned words in the correct order for current endianness. 11171 D[d] = if BigEndian() then word1:word2 else word2:word1; 11172 #endif 11173 11174 bool success = false; 11175 11176 if (ConditionPassed (opcode)) 11177 { 11178 bool single_reg; 11179 bool add; 11180 uint32_t imm32; 11181 uint32_t d; 11182 uint32_t n; 11183 11184 switch (encoding) 11185 { 11186 case eEncodingT1: 11187 case eEncodingA1: 11188 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11189 single_reg = false; 11190 add = BitIsSet (opcode, 23); 11191 imm32 = Bits32 (opcode, 7, 0) << 2; 11192 11193 // d = UInt(D:Vd); n = UInt(Rn); 11194 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11195 n = Bits32 (opcode, 19, 16); 11196 11197 break; 11198 11199 case eEncodingT2: 11200 case eEncodingA2: 11201 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11202 single_reg = true; 11203 add = BitIsSet (opcode, 23); 11204 imm32 = Bits32 (opcode, 7, 0) << 2; 11205 11206 // d = UInt(Vd:D); n = UInt(Rn); 11207 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11208 n = Bits32 (opcode, 19, 16); 11209 11210 break; 11211 11212 default: 11213 return false; 11214 } 11215 RegisterInfo base_reg; 11216 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11217 11218 uint32_t Rn = ReadCoreReg (n, &success); 11219 if (!success) 11220 return false; 11221 11222 // base = if n == 15 then Align(PC,4) else R[n]; 11223 uint32_t base; 11224 if (n == 15) 11225 base = AlignPC (Rn); 11226 else 11227 base = Rn; 11228 11229 // address = if add then (base + imm32) else (base - imm32); 11230 addr_t address; 11231 if (add) 11232 address = base + imm32; 11233 else 11234 address = base - imm32; 11235 11236 const uint32_t addr_byte_size = GetAddressByteSize(); 11237 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11238 11239 EmulateInstruction::Context context; 11240 context.type = eContextRegisterLoad; 11241 context.SetRegisterPlusOffset (base_reg, address - base); 11242 11243 if (single_reg) 11244 { 11245 // S[d] = MemA[address,4]; 11246 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11247 if (!success) 11248 return false; 11249 11250 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11251 return false; 11252 } 11253 else 11254 { 11255 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11256 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11257 if (!success) 11258 return false; 11259 11260 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11261 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11262 if (!success) 11263 return false; 11264 // // Combine the word-aligned words in the correct order for current endianness. 11265 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11266 uint64_t data64; 11267 if (GetByteOrder() == eByteOrderBig) 11268 { 11269 data64 = word1; 11270 data64 = (data64 << 32) | word2; 11271 } 11272 else 11273 { 11274 data64 = word2; 11275 data64 = (data64 << 32) | word1; 11276 } 11277 11278 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11279 return false; 11280 } 11281 } 11282 return true; 11283 } 11284 11285 // A8.6.400 VSTR 11286 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11287 // optional offset. 11288 bool 11289 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11290 { 11291 #if 0 11292 if ConditionPassed() then 11293 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11294 address = if add then (R[n] + imm32) else (R[n] - imm32); 11295 if single_reg then 11296 MemA[address,4] = S[d]; 11297 else 11298 // Store as two word-aligned words in the correct order for current endianness. 11299 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11300 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11301 #endif 11302 11303 bool success = false; 11304 11305 if (ConditionPassed (opcode)) 11306 { 11307 bool single_reg; 11308 bool add; 11309 uint32_t imm32; 11310 uint32_t d; 11311 uint32_t n; 11312 11313 switch (encoding) 11314 { 11315 case eEncodingT1: 11316 case eEncodingA1: 11317 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11318 single_reg = false; 11319 add = BitIsSet (opcode, 23); 11320 imm32 = Bits32 (opcode, 7, 0) << 2; 11321 11322 // d = UInt(D:Vd); n = UInt(Rn); 11323 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11324 n = Bits32 (opcode, 19, 16); 11325 11326 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11327 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11328 return false; 11329 11330 break; 11331 11332 case eEncodingT2: 11333 case eEncodingA2: 11334 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11335 single_reg = true; 11336 add = BitIsSet (opcode, 23); 11337 imm32 = Bits32 (opcode, 7, 0) << 2; 11338 11339 // d = UInt(Vd:D); n = UInt(Rn); 11340 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11341 n = Bits32 (opcode, 19, 16); 11342 11343 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11344 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11345 return false; 11346 11347 break; 11348 11349 default: 11350 return false; 11351 } 11352 11353 RegisterInfo base_reg; 11354 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11355 11356 uint32_t Rn = ReadCoreReg (n, &success); 11357 if (!success) 11358 return false; 11359 11360 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11361 addr_t address; 11362 if (add) 11363 address = Rn + imm32; 11364 else 11365 address = Rn - imm32; 11366 11367 const uint32_t addr_byte_size = GetAddressByteSize(); 11368 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11369 11370 RegisterInfo data_reg; 11371 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11372 EmulateInstruction::Context context; 11373 context.type = eContextRegisterStore; 11374 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11375 11376 if (single_reg) 11377 { 11378 // MemA[address,4] = S[d]; 11379 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11380 if (!success) 11381 return false; 11382 11383 if (!MemAWrite (context, address, data, addr_byte_size)) 11384 return false; 11385 } 11386 else 11387 { 11388 // // Store as two word-aligned words in the correct order for current endianness. 11389 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11390 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11391 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11392 if (!success) 11393 return false; 11394 11395 if (GetByteOrder() == eByteOrderBig) 11396 { 11397 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11398 return false; 11399 11400 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11401 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11402 return false; 11403 } 11404 else 11405 { 11406 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11407 return false; 11408 11409 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11410 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11411 return false; 11412 } 11413 } 11414 } 11415 return true; 11416 } 11417 11418 // A8.6.307 VLDI1 (multiple single elements) 11419 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11420 // element of each register is loaded. 11421 bool 11422 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11423 { 11424 #if 0 11425 if ConditionPassed() then 11426 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11427 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11428 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11429 for r = 0 to regs-1 11430 for e = 0 to elements-1 11431 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11432 address = address + ebytes; 11433 #endif 11434 11435 bool success = false; 11436 11437 if (ConditionPassed (opcode)) 11438 { 11439 uint32_t regs; 11440 uint32_t alignment; 11441 uint32_t ebytes; 11442 uint32_t esize; 11443 uint32_t elements; 11444 uint32_t d; 11445 uint32_t n; 11446 uint32_t m; 11447 bool wback; 11448 bool register_index; 11449 11450 switch (encoding) 11451 { 11452 case eEncodingT1: 11453 case eEncodingA1: 11454 { 11455 // case type of 11456 // when '0111' 11457 // regs = 1; if align<1> == '1' then UNDEFINED; 11458 // when '1010' 11459 // regs = 2; if align == '11' then UNDEFINED; 11460 // when '0110' 11461 // regs = 3; if align<1> == '1' then UNDEFINED; 11462 // when '0010' 11463 // regs = 4; 11464 // otherwise 11465 // SEE 'Related encodings'; 11466 uint32_t type = Bits32 (opcode, 11, 8); 11467 uint32_t align = Bits32 (opcode, 5, 4); 11468 if (type == 7) // '0111' 11469 { 11470 regs = 1; 11471 if (BitIsSet (align, 1)) 11472 return false; 11473 } 11474 else if (type == 10) // '1010' 11475 { 11476 regs = 2; 11477 if (align == 3) 11478 return false; 11479 11480 } 11481 else if (type == 6) // '0110' 11482 { 11483 regs = 3; 11484 if (BitIsSet (align, 1)) 11485 return false; 11486 } 11487 else if (type == 2) // '0010' 11488 { 11489 regs = 4; 11490 } 11491 else 11492 return false; 11493 11494 // alignment = if align == '00' then 1 else 4 << UInt(align); 11495 if (align == 0) 11496 alignment = 1; 11497 else 11498 alignment = 4 << align; 11499 11500 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11501 ebytes = 1 << Bits32 (opcode, 7, 6); 11502 esize = 8 * ebytes; 11503 elements = 8 / ebytes; 11504 11505 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11506 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11507 n = Bits32 (opcode, 19, 15); 11508 m = Bits32 (opcode, 3, 0); 11509 11510 // wback = (m != 15); register_index = (m != 15 && m != 13); 11511 wback = (m != 15); 11512 register_index = ((m != 15) && (m != 13)); 11513 11514 // if d+regs > 32 then UNPREDICTABLE; 11515 if ((d + regs) > 32) 11516 return false; 11517 } 11518 break; 11519 11520 default: 11521 return false; 11522 } 11523 11524 RegisterInfo base_reg; 11525 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11526 11527 uint32_t Rn = ReadCoreReg (n, &success); 11528 if (!success) 11529 return false; 11530 11531 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11532 addr_t address = Rn; 11533 if ((address % alignment) != 0) 11534 return false; 11535 11536 EmulateInstruction::Context context; 11537 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11538 if (wback) 11539 { 11540 uint32_t Rm = ReadCoreReg (m, &success); 11541 if (!success) 11542 return false; 11543 11544 uint32_t offset; 11545 if (register_index) 11546 offset = Rm; 11547 else 11548 offset = 8 * regs; 11549 11550 uint32_t value = Rn + offset; 11551 context.type = eContextAdjustBaseRegister; 11552 context.SetRegisterPlusOffset (base_reg, offset); 11553 11554 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11555 return false; 11556 11557 } 11558 11559 // for r = 0 to regs-1 11560 for (uint32_t r = 0; r < regs; ++r) 11561 { 11562 // for e = 0 to elements-1 11563 uint64_t assembled_data = 0; 11564 for (uint32_t e = 0; e < elements; ++e) 11565 { 11566 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11567 context.type = eContextRegisterLoad; 11568 context.SetRegisterPlusOffset (base_reg, address - Rn); 11569 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11570 if (!success) 11571 return false; 11572 11573 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11574 11575 // address = address + ebytes; 11576 address = address + ebytes; 11577 } 11578 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11579 return false; 11580 } 11581 } 11582 return true; 11583 } 11584 11585 // A8.6.308 VLD1 (single element to one lane) 11586 // 11587 bool 11588 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11589 { 11590 #if 0 11591 if ConditionPassed() then 11592 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11593 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11594 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11595 Elem[D[d],index,esize] = MemU[address,ebytes]; 11596 #endif 11597 11598 bool success = false; 11599 11600 if (ConditionPassed (opcode)) 11601 { 11602 uint32_t ebytes; 11603 uint32_t esize; 11604 uint32_t index; 11605 uint32_t alignment; 11606 uint32_t d; 11607 uint32_t n; 11608 uint32_t m; 11609 bool wback; 11610 bool register_index; 11611 11612 switch (encoding) 11613 { 11614 case eEncodingT1: 11615 case eEncodingA1: 11616 { 11617 uint32_t size = Bits32 (opcode, 11, 10); 11618 uint32_t index_align = Bits32 (opcode, 7, 4); 11619 // if size == '11' then SEE VLD1 (single element to all lanes); 11620 if (size == 3) 11621 return EmulateVLD1SingleAll (opcode, encoding); 11622 // case size of 11623 if (size == 0) // when '00' 11624 { 11625 // if index_align<0> != '0' then UNDEFINED; 11626 if (BitIsClear (index_align, 0)) 11627 return false; 11628 11629 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11630 ebytes = 1; 11631 esize = 8; 11632 index = Bits32 (index_align, 3, 1); 11633 alignment = 1; 11634 } 11635 else if (size == 1) // when '01' 11636 { 11637 // if index_align<1> != '0' then UNDEFINED; 11638 if (BitIsClear (index_align, 1)) 11639 return false; 11640 11641 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11642 ebytes = 2; 11643 esize = 16; 11644 index = Bits32 (index_align, 3, 2); 11645 11646 // alignment = if index_align<0> == '0' then 1 else 2; 11647 if (BitIsClear (index_align, 0)) 11648 alignment = 1; 11649 else 11650 alignment = 2; 11651 } 11652 else if (size == 2) // when '10' 11653 { 11654 // if index_align<2> != '0' then UNDEFINED; 11655 if (BitIsClear (index_align, 2)) 11656 return false; 11657 11658 // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED; 11659 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11660 return false; 11661 11662 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11663 ebytes = 4; 11664 esize = 32; 11665 index = Bit32 (index_align, 3); 11666 11667 // alignment = if index_align<1:0> == '00' then 1 else 4; 11668 if (Bits32 (index_align, 1, 0) == 0) 11669 alignment = 1; 11670 else 11671 alignment = 4; 11672 } 11673 else 11674 { 11675 return false; 11676 } 11677 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11678 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11679 n = Bits32 (opcode, 19, 16); 11680 m = Bits32 (opcode, 3, 0); 11681 11682 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11683 wback = (m != 15); 11684 register_index = ((m != 15) && (m != 13)); 11685 11686 if (n == 15) 11687 return false; 11688 11689 } 11690 break; 11691 11692 default: 11693 return false; 11694 } 11695 11696 RegisterInfo base_reg; 11697 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11698 11699 uint32_t Rn = ReadCoreReg (n, &success); 11700 if (!success) 11701 return false; 11702 11703 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11704 addr_t address = Rn; 11705 if ((address % alignment) != 0) 11706 return false; 11707 11708 EmulateInstruction::Context context; 11709 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11710 if (wback) 11711 { 11712 uint32_t Rm = ReadCoreReg (m, &success); 11713 if (!success) 11714 return false; 11715 11716 uint32_t offset; 11717 if (register_index) 11718 offset = Rm; 11719 else 11720 offset = ebytes; 11721 11722 uint32_t value = Rn + offset; 11723 11724 context.type = eContextAdjustBaseRegister; 11725 context.SetRegisterPlusOffset (base_reg, offset); 11726 11727 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11728 return false; 11729 } 11730 11731 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11732 uint32_t element = MemURead (context, address, esize, 0, &success); 11733 if (!success) 11734 return false; 11735 11736 element = element << (index * esize); 11737 11738 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11739 if (!success) 11740 return false; 11741 11742 uint64_t all_ones = -1; 11743 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11744 // at element & to the right of element. 11745 if (index > 0) 11746 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11747 // now mask should be 0's where element goes & 1's 11748 // everywhere else. 11749 11750 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11751 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11752 11753 context.type = eContextRegisterLoad; 11754 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11755 return false; 11756 } 11757 return true; 11758 } 11759 11760 // A8.6.391 VST1 (multiple single elements) 11761 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without 11762 // interleaving. Every element of each register is stored. 11763 bool 11764 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11765 { 11766 #if 0 11767 if ConditionPassed() then 11768 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11769 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11770 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11771 for r = 0 to regs-1 11772 for e = 0 to elements-1 11773 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11774 address = address + ebytes; 11775 #endif 11776 11777 bool success = false; 11778 11779 if (ConditionPassed (opcode)) 11780 { 11781 uint32_t regs; 11782 uint32_t alignment; 11783 uint32_t ebytes; 11784 uint32_t esize; 11785 uint32_t elements; 11786 uint32_t d; 11787 uint32_t n; 11788 uint32_t m; 11789 bool wback; 11790 bool register_index; 11791 11792 switch (encoding) 11793 { 11794 case eEncodingT1: 11795 case eEncodingA1: 11796 { 11797 uint32_t type = Bits32 (opcode, 11, 8); 11798 uint32_t align = Bits32 (opcode, 5, 4); 11799 11800 // case type of 11801 if (type == 7) // when '0111' 11802 { 11803 // regs = 1; if align<1> == '1' then UNDEFINED; 11804 regs = 1; 11805 if (BitIsSet (align, 1)) 11806 return false; 11807 } 11808 else if (type == 10) // when '1010' 11809 { 11810 // regs = 2; if align == '11' then UNDEFINED; 11811 regs = 2; 11812 if (align == 3) 11813 return false; 11814 } 11815 else if (type == 6) // when '0110' 11816 { 11817 // regs = 3; if align<1> == '1' then UNDEFINED; 11818 regs = 3; 11819 if (BitIsSet (align, 1)) 11820 return false; 11821 } 11822 else if (type == 2) // when '0010' 11823 // regs = 4; 11824 regs = 4; 11825 else // otherwise 11826 // SEE 'Related encodings'; 11827 return false; 11828 11829 // alignment = if align == '00' then 1 else 4 << UInt(align); 11830 if (align == 0) 11831 alignment = 1; 11832 else 11833 alignment = 4 << align; 11834 11835 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11836 ebytes = 1 << Bits32 (opcode,7, 6); 11837 esize = 8 * ebytes; 11838 elements = 8 / ebytes; 11839 11840 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11841 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11842 n = Bits32 (opcode, 19, 16); 11843 m = Bits32 (opcode, 3, 0); 11844 11845 // wback = (m != 15); register_index = (m != 15 && m != 13); 11846 wback = (m != 15); 11847 register_index = ((m != 15) && (m != 13)); 11848 11849 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11850 if ((d + regs) > 32) 11851 return false; 11852 11853 if (n == 15) 11854 return false; 11855 11856 } 11857 break; 11858 11859 default: 11860 return false; 11861 } 11862 11863 RegisterInfo base_reg; 11864 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11865 11866 uint32_t Rn = ReadCoreReg (n, &success); 11867 if (!success) 11868 return false; 11869 11870 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11871 addr_t address = Rn; 11872 if ((address % alignment) != 0) 11873 return false; 11874 11875 EmulateInstruction::Context context; 11876 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11877 if (wback) 11878 { 11879 uint32_t Rm = ReadCoreReg (m, &success); 11880 if (!success) 11881 return false; 11882 11883 uint32_t offset; 11884 if (register_index) 11885 offset = Rm; 11886 else 11887 offset = 8 * regs; 11888 11889 context.type = eContextAdjustBaseRegister; 11890 context.SetRegisterPlusOffset (base_reg, offset); 11891 11892 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11893 return false; 11894 } 11895 11896 RegisterInfo data_reg; 11897 context.type = eContextRegisterStore; 11898 // for r = 0 to regs-1 11899 for (uint32_t r = 0; r < regs; ++r) 11900 { 11901 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11902 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11903 if (!success) 11904 return false; 11905 11906 // for e = 0 to elements-1 11907 for (uint32_t e = 0; e < elements; ++e) 11908 { 11909 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11910 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11911 11912 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11913 if (!MemUWrite (context, address, word, ebytes)) 11914 return false; 11915 11916 // address = address + ebytes; 11917 address = address + ebytes; 11918 } 11919 } 11920 } 11921 return true; 11922 } 11923 11924 // A8.6.392 VST1 (single element from one lane) 11925 // This instruction stores one element to memory from one element of a register. 11926 bool 11927 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11928 { 11929 #if 0 11930 if ConditionPassed() then 11931 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11932 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11933 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11934 MemU[address,ebytes] = Elem[D[d],index,esize]; 11935 #endif 11936 11937 bool success = false; 11938 11939 if (ConditionPassed (opcode)) 11940 { 11941 uint32_t ebytes; 11942 uint32_t esize; 11943 uint32_t index; 11944 uint32_t alignment; 11945 uint32_t d; 11946 uint32_t n; 11947 uint32_t m; 11948 bool wback; 11949 bool register_index; 11950 11951 switch (encoding) 11952 { 11953 case eEncodingT1: 11954 case eEncodingA1: 11955 { 11956 uint32_t size = Bits32 (opcode, 11, 10); 11957 uint32_t index_align = Bits32 (opcode, 7, 4); 11958 11959 // if size == '11' then UNDEFINED; 11960 if (size == 3) 11961 return false; 11962 11963 // case size of 11964 if (size == 0) // when '00' 11965 { 11966 // if index_align<0> != '0' then UNDEFINED; 11967 if (BitIsClear (index_align, 0)) 11968 return false; 11969 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11970 ebytes = 1; 11971 esize = 8; 11972 index = Bits32 (index_align, 3, 1); 11973 alignment = 1; 11974 } 11975 else if (size == 1) // when '01' 11976 { 11977 // if index_align<1> != '0' then UNDEFINED; 11978 if (BitIsClear (index_align, 1)) 11979 return false; 11980 11981 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11982 ebytes = 2; 11983 esize = 16; 11984 index = Bits32 (index_align, 3, 2); 11985 11986 // alignment = if index_align<0> == '0' then 1 else 2; 11987 if (BitIsClear (index_align, 0)) 11988 alignment = 1; 11989 else 11990 alignment = 2; 11991 } 11992 else if (size == 2) // when '10' 11993 { 11994 // if index_align<2> != '0' then UNDEFINED; 11995 if (BitIsClear (index_align, 2)) 11996 return false; 11997 11998 // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED; 11999 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 12000 return false; 12001 12002 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12003 ebytes = 4; 12004 esize = 32; 12005 index = Bit32 (index_align, 3); 12006 12007 // alignment = if index_align<1:0> == '00' then 1 else 4; 12008 if (Bits32 (index_align, 1, 0) == 0) 12009 alignment = 1; 12010 else 12011 alignment = 4; 12012 } 12013 else 12014 { 12015 return false; 12016 } 12017 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12018 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 12019 n = Bits32 (opcode, 19, 16); 12020 m = Bits32 (opcode, 3, 0); 12021 12022 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 12023 wback = (m != 15); 12024 register_index = ((m != 15) && (m != 13)); 12025 12026 if (n == 15) 12027 return false; 12028 } 12029 break; 12030 12031 default: 12032 return false; 12033 } 12034 12035 RegisterInfo base_reg; 12036 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12037 12038 uint32_t Rn = ReadCoreReg (n, &success); 12039 if (!success) 12040 return false; 12041 12042 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12043 addr_t address = Rn; 12044 if ((address % alignment) != 0) 12045 return false; 12046 12047 EmulateInstruction::Context context; 12048 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12049 if (wback) 12050 { 12051 uint32_t Rm = ReadCoreReg (m, &success); 12052 if (!success) 12053 return false; 12054 12055 uint32_t offset; 12056 if (register_index) 12057 offset = Rm; 12058 else 12059 offset = ebytes; 12060 12061 context.type = eContextAdjustBaseRegister; 12062 context.SetRegisterPlusOffset (base_reg, offset); 12063 12064 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12065 return false; 12066 } 12067 12068 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12069 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12070 if (!success) 12071 return false; 12072 12073 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 12074 12075 RegisterInfo data_reg; 12076 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12077 context.type = eContextRegisterStore; 12078 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 12079 12080 if (!MemUWrite (context, address, word, ebytes)) 12081 return false; 12082 } 12083 return true; 12084 } 12085 12086 // A8.6.309 VLD1 (single element to all lanes) 12087 // This instruction loads one element from memory into every element of one or two vectors. 12088 bool 12089 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 12090 { 12091 #if 0 12092 if ConditionPassed() then 12093 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12094 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12095 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12096 replicated_element = Replicate(MemU[address,ebytes], elements); 12097 for r = 0 to regs-1 12098 D[d+r] = replicated_element; 12099 #endif 12100 12101 bool success = false; 12102 12103 if (ConditionPassed (opcode)) 12104 { 12105 uint32_t ebytes; 12106 uint32_t elements; 12107 uint32_t regs; 12108 uint32_t alignment; 12109 uint32_t d; 12110 uint32_t n; 12111 uint32_t m; 12112 bool wback; 12113 bool register_index; 12114 12115 switch (encoding) 12116 { 12117 case eEncodingT1: 12118 case eEncodingA1: 12119 { 12120 //if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12121 uint32_t size = Bits32 (opcode, 7, 6); 12122 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 12123 return false; 12124 12125 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' then 1 else 2; 12126 ebytes = 1 << size; 12127 elements = 8 / ebytes; 12128 if (BitIsClear (opcode, 5)) 12129 regs = 1; 12130 else 12131 regs = 2; 12132 12133 //alignment = if a == '0' then 1 else ebytes; 12134 if (BitIsClear (opcode, 4)) 12135 alignment = 1; 12136 else 12137 alignment = ebytes; 12138 12139 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12140 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 12141 n = Bits32 (opcode, 19, 16); 12142 m = Bits32 (opcode, 3, 0); 12143 12144 //wback = (m != 15); register_index = (m != 15 && m != 13); 12145 wback = (m != 15); 12146 register_index = ((m != 15) && (m != 13)); 12147 12148 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12149 if ((d + regs) > 32) 12150 return false; 12151 12152 if (n == 15) 12153 return false; 12154 } 12155 break; 12156 12157 default: 12158 return false; 12159 } 12160 12161 RegisterInfo base_reg; 12162 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12163 12164 uint32_t Rn = ReadCoreReg (n, &success); 12165 if (!success) 12166 return false; 12167 12168 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12169 addr_t address = Rn; 12170 if ((address % alignment) != 0) 12171 return false; 12172 12173 EmulateInstruction::Context context; 12174 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12175 if (wback) 12176 { 12177 uint32_t Rm = ReadCoreReg (m, &success); 12178 if (!success) 12179 return false; 12180 12181 uint32_t offset; 12182 if (register_index) 12183 offset = Rm; 12184 else 12185 offset = ebytes; 12186 12187 context.type = eContextAdjustBaseRegister; 12188 context.SetRegisterPlusOffset (base_reg, offset); 12189 12190 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12191 return false; 12192 } 12193 12194 // replicated_element = Replicate(MemU[address,ebytes], elements); 12195 12196 context.type = eContextRegisterLoad; 12197 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12198 if (!success) 12199 return false; 12200 12201 uint64_t replicated_element = 0; 12202 uint32_t esize = ebytes * 8; 12203 for (uint32_t e = 0; e < elements; ++e) 12204 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12205 12206 // for r = 0 to regs-1 12207 for (uint32_t r = 0; r < regs; ++r) 12208 { 12209 // D[d+r] = replicated_element; 12210 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12211 return false; 12212 } 12213 } 12214 return true; 12215 } 12216 12217 // B6.2.13 SUBS PC, LR and related instructions 12218 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12219 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12220 bool 12221 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12222 { 12223 #if 0 12224 if ConditionPassed() then 12225 EncodingSpecificOperations(); 12226 if CurrentInstrSet() == InstrSet_ThumbEE then 12227 UNPREDICTABLE; 12228 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12229 case opcode of 12230 when '0000' result = R[n] AND operand2; // AND 12231 when '0001' result = R[n] EOR operand2; // EOR 12232 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12233 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12234 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12235 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12236 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12237 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12238 when '1100' result = R[n] OR operand2; // ORR 12239 when '1101' result = operand2; // MOV 12240 when '1110' result = R[n] AND NOT(operand2); // BIC 12241 when '1111' result = NOT(operand2); // MVN 12242 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12243 BranchWritePC(result); 12244 #endif 12245 12246 bool success = false; 12247 12248 if (ConditionPassed (opcode)) 12249 { 12250 uint32_t n; 12251 uint32_t m; 12252 uint32_t imm32; 12253 bool register_form; 12254 ARM_ShifterType shift_t; 12255 uint32_t shift_n; 12256 uint32_t code; 12257 12258 switch (encoding) 12259 { 12260 case eEncodingT1: 12261 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12262 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; // = SUB 12263 n = 14; 12264 imm32 = Bits32 (opcode, 7, 0); 12265 register_form = false; 12266 code = 2; 12267 12268 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12269 if (InITBlock() && !LastInITBlock()) 12270 return false; 12271 12272 break; 12273 12274 case eEncodingA1: 12275 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12276 n = Bits32 (opcode, 19, 16); 12277 imm32 = ARMExpandImm (opcode); 12278 register_form = false; 12279 code = Bits32 (opcode, 24, 21); 12280 12281 break; 12282 12283 case eEncodingA2: 12284 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12285 n = Bits32 (opcode, 19, 16); 12286 m = Bits32 (opcode, 3, 0); 12287 register_form = true; 12288 12289 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12290 shift_n = DecodeImmShiftARM (opcode, shift_t); 12291 12292 break; 12293 12294 default: 12295 return false; 12296 } 12297 12298 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12299 uint32_t operand2; 12300 if (register_form) 12301 { 12302 uint32_t Rm = ReadCoreReg (m, &success); 12303 if (!success) 12304 return false; 12305 12306 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12307 if (!success) 12308 return false; 12309 } 12310 else 12311 { 12312 operand2 = imm32; 12313 } 12314 12315 uint32_t Rn = ReadCoreReg (n, &success); 12316 if (!success) 12317 return false; 12318 12319 AddWithCarryResult result; 12320 12321 // case opcode of 12322 switch (code) 12323 { 12324 case 0: // when '0000' 12325 // result = R[n] AND operand2; // AND 12326 result.result = Rn & operand2; 12327 break; 12328 12329 case 1: // when '0001' 12330 // result = R[n] EOR operand2; // EOR 12331 result.result = Rn ^ operand2; 12332 break; 12333 12334 case 2: // when '0010' 12335 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12336 result = AddWithCarry (Rn, ~(operand2), 1); 12337 break; 12338 12339 case 3: // when '0011' 12340 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12341 result = AddWithCarry (~(Rn), operand2, 1); 12342 break; 12343 12344 case 4: // when '0100' 12345 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12346 result = AddWithCarry (Rn, operand2, 0); 12347 break; 12348 12349 case 5: // when '0101' 12350 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12351 result = AddWithCarry (Rn, operand2, APSR_C); 12352 break; 12353 12354 case 6: // when '0110' 12355 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12356 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12357 break; 12358 12359 case 7: // when '0111' 12360 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12361 result = AddWithCarry (~(Rn), operand2, APSR_C); 12362 break; 12363 12364 case 10: // when '1100' 12365 // result = R[n] OR operand2; // ORR 12366 result.result = Rn | operand2; 12367 break; 12368 12369 case 11: // when '1101' 12370 // result = operand2; // MOV 12371 result.result = operand2; 12372 break; 12373 12374 case 12: // when '1110' 12375 // result = R[n] AND NOT(operand2); // BIC 12376 result.result = Rn & ~(operand2); 12377 break; 12378 12379 case 15: // when '1111' 12380 // result = NOT(operand2); // MVN 12381 result.result = ~(operand2); 12382 break; 12383 12384 default: 12385 return false; 12386 } 12387 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12388 12389 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12390 // the best. 12391 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12392 if (!success) 12393 return false; 12394 12395 CPSRWriteByInstr (spsr, 15, true); 12396 12397 // BranchWritePC(result); 12398 EmulateInstruction::Context context; 12399 context.type = eContextAdjustPC; 12400 context.SetImmediate (result.result); 12401 12402 BranchWritePC (context, result.result); 12403 } 12404 return true; 12405 } 12406 12407 EmulateInstructionARM::ARMOpcode* 12408 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12409 { 12410 static ARMOpcode 12411 g_arm_opcodes[] = 12412 { 12413 //---------------------------------------------------------------------- 12414 // Prologue instructions 12415 //---------------------------------------------------------------------- 12416 12417 // push register(s) 12418 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12419 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12420 12421 // set r7 to point to a stack offset 12422 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12423 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12424 // copy the stack pointer to ip 12425 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12426 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12427 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12428 12429 // adjust the stack pointer 12430 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12431 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12432 12433 // push one register 12434 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12435 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12436 12437 // vector push consecutive extension register(s) 12438 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12439 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12440 12441 //---------------------------------------------------------------------- 12442 // Epilogue instructions 12443 //---------------------------------------------------------------------- 12444 12445 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12446 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12447 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12448 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12449 12450 //---------------------------------------------------------------------- 12451 // Supervisor Call (previously Software Interrupt) 12452 //---------------------------------------------------------------------- 12453 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12454 12455 //---------------------------------------------------------------------- 12456 // Branch instructions 12457 //---------------------------------------------------------------------- 12458 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>". 12459 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12460 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12461 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12462 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12463 // for example, "bx lr" 12464 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12465 // bxj 12466 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12467 12468 //---------------------------------------------------------------------- 12469 // Data-processing instructions 12470 //---------------------------------------------------------------------- 12471 // adc (immediate) 12472 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12473 // adc (register) 12474 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12475 // add (immediate) 12476 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12477 // add (register) 12478 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12479 // add (register-shifted register) 12480 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12481 // adr 12482 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12483 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12484 // and (immediate) 12485 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12486 // and (register) 12487 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12488 // bic (immediate) 12489 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12490 // bic (register) 12491 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12492 // eor (immediate) 12493 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12494 // eor (register) 12495 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12496 // orr (immediate) 12497 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12498 // orr (register) 12499 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12500 // rsb (immediate) 12501 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12502 // rsb (register) 12503 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12504 // rsc (immediate) 12505 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12506 // rsc (register) 12507 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12508 // sbc (immediate) 12509 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12510 // sbc (register) 12511 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12512 // sub (immediate, ARM) 12513 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12514 // sub (sp minus immediate) 12515 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12516 // sub (register) 12517 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12518 // teq (immediate) 12519 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12520 // teq (register) 12521 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12522 // tst (immediate) 12523 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12524 // tst (register) 12525 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12526 12527 // mov (immediate) 12528 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12529 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12530 // mov (register) 12531 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12532 // mvn (immediate) 12533 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12534 // mvn (register) 12535 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12536 // cmn (immediate) 12537 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12538 // cmn (register) 12539 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12540 // cmp (immediate) 12541 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12542 // cmp (register) 12543 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12544 // asr (immediate) 12545 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12546 // asr (register) 12547 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12548 // lsl (immediate) 12549 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12550 // lsl (register) 12551 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12552 // lsr (immediate) 12553 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12554 // lsr (register) 12555 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12556 // rrx is a special case encoding of ror (immediate) 12557 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12558 // ror (immediate) 12559 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12560 // ror (register) 12561 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12562 // mul 12563 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12564 12565 // subs pc, lr and related instructions 12566 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12567 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12568 12569 //---------------------------------------------------------------------- 12570 // Load instructions 12571 //---------------------------------------------------------------------- 12572 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12573 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12574 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12575 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12576 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12577 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12578 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12579 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12580 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12581 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12582 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12583 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12584 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12585 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12586 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12587 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12588 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12589 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12590 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12591 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12592 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12593 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12594 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12595 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12596 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12597 12598 //---------------------------------------------------------------------- 12599 // Store instructions 12600 //---------------------------------------------------------------------- 12601 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12602 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12603 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12604 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12605 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12606 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12607 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12608 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12609 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12610 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12611 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12612 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12613 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12614 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12615 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12616 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12617 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12618 12619 //---------------------------------------------------------------------- 12620 // Other instructions 12621 //---------------------------------------------------------------------- 12622 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12623 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12624 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12625 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12626 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12627 12628 }; 12629 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 12630 12631 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12632 { 12633 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12634 (g_arm_opcodes[i].variants & arm_isa) != 0) 12635 return &g_arm_opcodes[i]; 12636 } 12637 return NULL; 12638 } 12639 12640 12641 EmulateInstructionARM::ARMOpcode* 12642 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12643 { 12644 12645 static ARMOpcode 12646 g_thumb_opcodes[] = 12647 { 12648 //---------------------------------------------------------------------- 12649 // Prologue instructions 12650 //---------------------------------------------------------------------- 12651 12652 // push register(s) 12653 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12654 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12655 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12656 12657 // set r7 to point to a stack offset 12658 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12659 // copy the stack pointer to r7 12660 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12661 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12662 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12663 12664 // PC-relative load into register (see also EmulateADDSPRm) 12665 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12666 12667 // adjust the stack pointer 12668 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12669 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12670 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12671 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12672 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12673 12674 // vector push consecutive extension register(s) 12675 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12676 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12677 12678 //---------------------------------------------------------------------- 12679 // Epilogue instructions 12680 //---------------------------------------------------------------------- 12681 12682 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12683 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12684 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12685 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12686 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12687 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12688 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12689 12690 //---------------------------------------------------------------------- 12691 // Supervisor Call (previously Software Interrupt) 12692 //---------------------------------------------------------------------- 12693 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12694 12695 //---------------------------------------------------------------------- 12696 // If Then makes up to four following instructions conditional. 12697 //---------------------------------------------------------------------- 12698 // The next 5 opcode _must_ come before the if then instruction 12699 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12700 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12701 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12702 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12703 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12704 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12705 12706 //---------------------------------------------------------------------- 12707 // Branch instructions 12708 //---------------------------------------------------------------------- 12709 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12710 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12711 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12712 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12713 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12714 // J1 == J2 == 1 12715 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12716 // J1 == J2 == 1 12717 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12718 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12719 // for example, "bx lr" 12720 { 0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12721 // bxj 12722 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12723 // compare and branch 12724 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12725 // table branch byte 12726 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12727 // table branch halfword 12728 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12729 12730 //---------------------------------------------------------------------- 12731 // Data-processing instructions 12732 //---------------------------------------------------------------------- 12733 // adc (immediate) 12734 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12735 // adc (register) 12736 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12737 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12738 // add (register) 12739 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12740 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12741 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12742 // adr 12743 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12744 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12745 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12746 // and (immediate) 12747 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12748 // and (register) 12749 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12750 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12751 // bic (immediate) 12752 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12753 // bic (register) 12754 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12755 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12756 // eor (immediate) 12757 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12758 // eor (register) 12759 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12760 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12761 // orr (immediate) 12762 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12763 // orr (register) 12764 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12765 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12766 // rsb (immediate) 12767 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12768 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12769 // rsb (register) 12770 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12771 // sbc (immediate) 12772 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12773 // sbc (register) 12774 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12775 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12776 // add (immediate, Thumb) 12777 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12778 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12779 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12780 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12781 // sub (immediate, Thumb) 12782 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12783 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12784 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12785 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12786 // sub (sp minus immediate) 12787 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12788 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12789 // sub (register) 12790 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12791 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12792 // teq (immediate) 12793 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12794 // teq (register) 12795 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12796 // tst (immediate) 12797 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12798 // tst (register) 12799 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12800 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12801 12802 12803 // move from high register to high register 12804 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12805 // move from low register to low register 12806 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12807 // mov{s}<c>.w <Rd>, <Rm> 12808 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12809 // move immediate 12810 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12811 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12812 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12813 // mvn (immediate) 12814 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12815 // mvn (register) 12816 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12817 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12818 // cmn (immediate) 12819 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12820 // cmn (register) 12821 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12822 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12823 // cmp (immediate) 12824 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12825 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12826 // cmp (register) (Rn and Rm both from r0-r7) 12827 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12828 // cmp (register) (Rn and Rm not both from r0-r7) 12829 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12830 { 0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 12831 // asr (immediate) 12832 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12833 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12834 // asr (register) 12835 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12836 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12837 // lsl (immediate) 12838 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12839 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12840 // lsl (register) 12841 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12842 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12843 // lsr (immediate) 12844 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12845 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12846 // lsr (register) 12847 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12848 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12849 // rrx is a special case encoding of ror (immediate) 12850 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12851 // ror (immediate) 12852 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12853 // ror (register) 12854 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12855 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12856 // mul 12857 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12858 // mul 12859 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12860 12861 // subs pc, lr and related instructions 12862 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12863 12864 //---------------------------------------------------------------------- 12865 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12866 // otherwise the wrong instructions will be selected. 12867 //---------------------------------------------------------------------- 12868 12869 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12870 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12871 12872 //---------------------------------------------------------------------- 12873 // Load instructions 12874 //---------------------------------------------------------------------- 12875 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12876 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12877 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12878 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12879 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12880 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12881 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12882 // Thumb2 PC-relative load into register 12883 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12884 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12885 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12886 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12887 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12888 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12889 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12890 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12891 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12892 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12893 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12894 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12895 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12896 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12897 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12898 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12899 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12900 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12901 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12902 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12903 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12904 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12905 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12906 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12907 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12908 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12909 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12910 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12911 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12912 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12913 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12914 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12915 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12916 12917 //---------------------------------------------------------------------- 12918 // Store instructions 12919 //---------------------------------------------------------------------- 12920 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12921 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12922 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12923 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12924 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12925 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12926 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12927 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12928 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12929 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12930 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12931 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12932 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12933 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12934 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12935 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12936 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12937 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12938 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12939 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12940 { 0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12941 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12942 12943 //---------------------------------------------------------------------- 12944 // Other instructions 12945 //---------------------------------------------------------------------- 12946 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12947 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12948 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12949 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12950 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12951 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12952 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12953 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12954 }; 12955 12956 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 12957 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12958 { 12959 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12960 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12961 return &g_thumb_opcodes[i]; 12962 } 12963 return NULL; 12964 } 12965 12966 bool 12967 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12968 { 12969 m_arch = arch; 12970 m_arm_isa = 0; 12971 const char *arch_cstr = arch.GetArchitectureName (); 12972 if (arch_cstr) 12973 { 12974 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12975 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12976 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12977 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12978 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12979 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12980 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12981 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12982 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12983 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12984 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12985 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12986 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12987 } 12988 return m_arm_isa != 0; 12989 } 12990 12991 bool 12992 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12993 { 12994 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12995 { 12996 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12997 m_opcode_mode = eModeThumb; 12998 else 12999 { 13000 AddressClass addr_class = inst_addr.GetAddressClass(); 13001 13002 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 13003 m_opcode_mode = eModeARM; 13004 else if (addr_class == eAddressClassCodeAlternateISA) 13005 m_opcode_mode = eModeThumb; 13006 else 13007 return false; 13008 } 13009 if (m_opcode_mode == eModeThumb) 13010 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13011 else 13012 m_opcode_cpsr = CPSR_MODE_USR; 13013 return true; 13014 } 13015 return false; 13016 } 13017 13018 bool 13019 EmulateInstructionARM::ReadInstruction () 13020 { 13021 bool success = false; 13022 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13023 if (success) 13024 { 13025 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 13026 if (success) 13027 { 13028 Context read_inst_context; 13029 read_inst_context.type = eContextReadOpcode; 13030 read_inst_context.SetNoArgs (); 13031 13032 if (m_opcode_cpsr & MASK_CPSR_T) 13033 { 13034 m_opcode_mode = eModeThumb; 13035 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13036 13037 if (success) 13038 { 13039 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 13040 { 13041 m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder()); 13042 } 13043 else 13044 { 13045 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder()); 13046 } 13047 } 13048 } 13049 else 13050 { 13051 m_opcode_mode = eModeARM; 13052 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder()); 13053 } 13054 } 13055 } 13056 if (!success) 13057 { 13058 m_opcode_mode = eModeInvalid; 13059 m_addr = LLDB_INVALID_ADDRESS; 13060 } 13061 return success; 13062 } 13063 13064 uint32_t 13065 EmulateInstructionARM::ArchVersion () 13066 { 13067 return m_arm_isa; 13068 } 13069 13070 bool 13071 EmulateInstructionARM::ConditionPassed (const uint32_t opcode) 13072 { 13073 // If we are ignoring conditions, then always return true. 13074 // this allows us to iterate over disassembly code and still 13075 // emulate an instruction even if we don't have all the right 13076 // bits set in the CPSR register... 13077 if (m_ignore_conditions) 13078 return true; 13079 13080 const uint32_t cond = CurrentCond (opcode); 13081 if (cond == UINT32_MAX) 13082 return false; 13083 13084 bool result = false; 13085 switch (UnsignedBits(cond, 3, 1)) 13086 { 13087 case 0: 13088 if (m_opcode_cpsr == 0) 13089 result = true; 13090 else 13091 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13092 break; 13093 case 1: 13094 if (m_opcode_cpsr == 0) 13095 result = true; 13096 else 13097 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13098 break; 13099 case 2: 13100 if (m_opcode_cpsr == 0) 13101 result = true; 13102 else 13103 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13104 break; 13105 case 3: 13106 if (m_opcode_cpsr == 0) 13107 result = true; 13108 else 13109 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13110 break; 13111 case 4: 13112 if (m_opcode_cpsr == 0) 13113 result = true; 13114 else 13115 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13116 break; 13117 case 5: 13118 if (m_opcode_cpsr == 0) 13119 result = true; 13120 else 13121 { 13122 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13123 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13124 result = n == v; 13125 } 13126 break; 13127 case 6: 13128 if (m_opcode_cpsr == 0) 13129 result = true; 13130 else 13131 { 13132 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13133 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13134 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13135 } 13136 break; 13137 case 7: 13138 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13139 // opcodes different meanings, but always means execution happens. 13140 return true; 13141 } 13142 13143 if (cond & 1) 13144 result = !result; 13145 return result; 13146 } 13147 13148 uint32_t 13149 EmulateInstructionARM::CurrentCond (const uint32_t opcode) 13150 { 13151 switch (m_opcode_mode) 13152 { 13153 case eModeInvalid: 13154 break; 13155 13156 case eModeARM: 13157 return UnsignedBits(opcode, 31, 28); 13158 13159 case eModeThumb: 13160 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13161 // 'cond' field of the encoding. 13162 { 13163 const uint32_t byte_size = m_opcode.GetByteSize(); 13164 if (byte_size == 2) 13165 { 13166 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 13167 return Bits32(opcode, 11, 8); 13168 } 13169 else if (byte_size == 4) 13170 { 13171 if (Bits32(opcode, 31, 27) == 0x1e && 13172 Bits32(opcode, 15, 14) == 0x02 && 13173 Bits32(opcode, 12, 12) == 0x00 && 13174 Bits32(opcode, 25, 22) <= 0x0d) 13175 { 13176 return Bits32(opcode, 25, 22); 13177 } 13178 } 13179 else 13180 // We have an invalid thumb instruction, let's bail out. 13181 break; 13182 13183 return m_it_session.GetCond(); 13184 } 13185 } 13186 return UINT32_MAX; // Return invalid value 13187 } 13188 13189 bool 13190 EmulateInstructionARM::InITBlock() 13191 { 13192 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13193 } 13194 13195 bool 13196 EmulateInstructionARM::LastInITBlock() 13197 { 13198 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13199 } 13200 13201 bool 13202 EmulateInstructionARM::BadMode (uint32_t mode) 13203 { 13204 13205 switch (mode) 13206 { 13207 case 16: return false; // '10000' 13208 case 17: return false; // '10001' 13209 case 18: return false; // '10010' 13210 case 19: return false; // '10011' 13211 case 22: return false; // '10110' 13212 case 23: return false; // '10111' 13213 case 27: return false; // '11011' 13214 case 31: return false; // '11111' 13215 default: return true; 13216 } 13217 return true; 13218 } 13219 13220 bool 13221 EmulateInstructionARM::CurrentModeIsPrivileged () 13222 { 13223 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13224 13225 if (BadMode (mode)) 13226 return false; 13227 13228 if (mode == 16) 13229 return false; 13230 13231 return true; 13232 } 13233 13234 void 13235 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13236 { 13237 bool privileged = CurrentModeIsPrivileged(); 13238 13239 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13240 13241 if (BitIsSet (bytemask, 3)) 13242 { 13243 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13244 if (affect_execstate) 13245 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13246 } 13247 13248 if (BitIsSet (bytemask, 2)) 13249 { 13250 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13251 } 13252 13253 if (BitIsSet (bytemask, 1)) 13254 { 13255 if (affect_execstate) 13256 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13257 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13258 if (privileged) 13259 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13260 } 13261 13262 if (BitIsSet (bytemask, 0)) 13263 { 13264 if (privileged) 13265 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13266 if (affect_execstate) 13267 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13268 if (privileged) 13269 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13270 } 13271 13272 m_opcode_cpsr = tmp_cpsr; 13273 } 13274 13275 13276 bool 13277 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13278 { 13279 addr_t target; 13280 13281 // Check the current instruction set. 13282 if (CurrentInstrSet() == eModeARM) 13283 target = addr & 0xfffffffc; 13284 else 13285 target = addr & 0xfffffffe; 13286 13287 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13288 return false; 13289 13290 return true; 13291 } 13292 13293 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13294 bool 13295 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13296 { 13297 addr_t target; 13298 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13299 // we want to record it and issue a WriteRegister callback so the clients 13300 // can track the mode changes accordingly. 13301 bool cpsr_changed = false; 13302 13303 if (BitIsSet(addr, 0)) 13304 { 13305 if (CurrentInstrSet() != eModeThumb) 13306 { 13307 SelectInstrSet(eModeThumb); 13308 cpsr_changed = true; 13309 } 13310 target = addr & 0xfffffffe; 13311 context.SetISA (eModeThumb); 13312 } 13313 else if (BitIsClear(addr, 1)) 13314 { 13315 if (CurrentInstrSet() != eModeARM) 13316 { 13317 SelectInstrSet(eModeARM); 13318 cpsr_changed = true; 13319 } 13320 target = addr & 0xfffffffc; 13321 context.SetISA (eModeARM); 13322 } 13323 else 13324 return false; // address<1:0> == '10' => UNPREDICTABLE 13325 13326 if (cpsr_changed) 13327 { 13328 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13329 return false; 13330 } 13331 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13332 return false; 13333 13334 return true; 13335 } 13336 13337 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13338 bool 13339 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13340 { 13341 if (ArchVersion() >= ARMv5T) 13342 return BXWritePC(context, addr); 13343 else 13344 return BranchWritePC((const Context)context, addr); 13345 } 13346 13347 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13348 bool 13349 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13350 { 13351 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13352 return BXWritePC(context, addr); 13353 else 13354 return BranchWritePC((const Context)context, addr); 13355 } 13356 13357 EmulateInstructionARM::Mode 13358 EmulateInstructionARM::CurrentInstrSet () 13359 { 13360 return m_opcode_mode; 13361 } 13362 13363 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13364 // ReadInstruction() is performed. This function has a side effect of updating 13365 // the m_new_inst_cpsr member variable if necessary. 13366 bool 13367 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13368 { 13369 m_new_inst_cpsr = m_opcode_cpsr; 13370 switch (arm_or_thumb) 13371 { 13372 default: 13373 return false; 13374 case eModeARM: 13375 // Clear the T bit. 13376 m_new_inst_cpsr &= ~MASK_CPSR_T; 13377 break; 13378 case eModeThumb: 13379 // Set the T bit. 13380 m_new_inst_cpsr |= MASK_CPSR_T; 13381 break; 13382 } 13383 return true; 13384 } 13385 13386 // This function returns TRUE if the processor currently provides support for 13387 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13388 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13389 bool 13390 EmulateInstructionARM::UnalignedSupport() 13391 { 13392 return (ArchVersion() >= ARMv7); 13393 } 13394 13395 // The main addition and subtraction instructions can produce status information 13396 // about both unsigned carry and signed overflow conditions. This status 13397 // information can be used to synthesize multi-word additions and subtractions. 13398 EmulateInstructionARM::AddWithCarryResult 13399 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13400 { 13401 uint32_t result; 13402 uint8_t carry_out; 13403 uint8_t overflow; 13404 13405 uint64_t unsigned_sum = x + y + carry_in; 13406 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13407 13408 result = UnsignedBits(unsigned_sum, 31, 0); 13409 // carry_out = (result == unsigned_sum ? 0 : 1); 13410 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13411 13412 if (carry_in) 13413 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13414 else 13415 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13416 13417 AddWithCarryResult res = { result, carry_out, overflow }; 13418 return res; 13419 } 13420 13421 uint32_t 13422 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13423 { 13424 lldb::RegisterKind reg_kind; 13425 uint32_t reg_num; 13426 switch (num) 13427 { 13428 case SP_REG: 13429 reg_kind = eRegisterKindGeneric; 13430 reg_num = LLDB_REGNUM_GENERIC_SP; 13431 break; 13432 case LR_REG: 13433 reg_kind = eRegisterKindGeneric; 13434 reg_num = LLDB_REGNUM_GENERIC_RA; 13435 break; 13436 case PC_REG: 13437 reg_kind = eRegisterKindGeneric; 13438 reg_num = LLDB_REGNUM_GENERIC_PC; 13439 break; 13440 default: 13441 if (num < SP_REG) 13442 { 13443 reg_kind = eRegisterKindDWARF; 13444 reg_num = dwarf_r0 + num; 13445 } 13446 else 13447 { 13448 //assert(0 && "Invalid register number"); 13449 *success = false; 13450 return UINT32_MAX; 13451 } 13452 break; 13453 } 13454 13455 // Read our register. 13456 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13457 13458 // When executing an ARM instruction , PC reads as the address of the current 13459 // instruction plus 8. 13460 // When executing a Thumb instruction , PC reads as the address of the current 13461 // instruction plus 4. 13462 if (num == 15) 13463 { 13464 if (CurrentInstrSet() == eModeARM) 13465 val += 8; 13466 else 13467 val += 4; 13468 } 13469 13470 return val; 13471 } 13472 13473 // Write the result to the ARM core register Rd, and optionally update the 13474 // condition flags based on the result. 13475 // 13476 // This helper method tries to encapsulate the following pseudocode from the 13477 // ARM Architecture Reference Manual: 13478 // 13479 // if d == 15 then // Can only occur for encoding A1 13480 // ALUWritePC(result); // setflags is always FALSE here 13481 // else 13482 // R[d] = result; 13483 // if setflags then 13484 // APSR.N = result<31>; 13485 // APSR.Z = IsZeroBit(result); 13486 // APSR.C = carry; 13487 // // APSR.V unchanged 13488 // 13489 // In the above case, the API client does not pass in the overflow arg, which 13490 // defaults to ~0u. 13491 bool 13492 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13493 const uint32_t result, 13494 const uint32_t Rd, 13495 bool setflags, 13496 const uint32_t carry, 13497 const uint32_t overflow) 13498 { 13499 if (Rd == 15) 13500 { 13501 if (!ALUWritePC (context, result)) 13502 return false; 13503 } 13504 else 13505 { 13506 lldb::RegisterKind reg_kind; 13507 uint32_t reg_num; 13508 switch (Rd) 13509 { 13510 case SP_REG: 13511 reg_kind = eRegisterKindGeneric; 13512 reg_num = LLDB_REGNUM_GENERIC_SP; 13513 break; 13514 case LR_REG: 13515 reg_kind = eRegisterKindGeneric; 13516 reg_num = LLDB_REGNUM_GENERIC_RA; 13517 break; 13518 default: 13519 reg_kind = eRegisterKindDWARF; 13520 reg_num = dwarf_r0 + Rd; 13521 } 13522 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13523 return false; 13524 if (setflags) 13525 return WriteFlags (context, result, carry, overflow); 13526 } 13527 return true; 13528 } 13529 13530 // This helper method tries to encapsulate the following pseudocode from the 13531 // ARM Architecture Reference Manual: 13532 // 13533 // APSR.N = result<31>; 13534 // APSR.Z = IsZeroBit(result); 13535 // APSR.C = carry; 13536 // APSR.V = overflow 13537 // 13538 // Default arguments can be specified for carry and overflow parameters, which means 13539 // not to update the respective flags. 13540 bool 13541 EmulateInstructionARM::WriteFlags (Context &context, 13542 const uint32_t result, 13543 const uint32_t carry, 13544 const uint32_t overflow) 13545 { 13546 m_new_inst_cpsr = m_opcode_cpsr; 13547 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13548 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13549 if (carry != ~0u) 13550 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13551 if (overflow != ~0u) 13552 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13553 if (m_new_inst_cpsr != m_opcode_cpsr) 13554 { 13555 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13556 return false; 13557 } 13558 return true; 13559 } 13560 13561 bool 13562 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13563 { 13564 // Advance the ITSTATE bits to their values for the next instruction. 13565 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13566 m_it_session.ITAdvance(); 13567 13568 ARMOpcode *opcode_data = NULL; 13569 13570 if (m_opcode_mode == eModeThumb) 13571 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13572 else if (m_opcode_mode == eModeARM) 13573 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13574 13575 if (opcode_data == NULL) 13576 return false; 13577 13578 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13579 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13580 13581 bool success = false; 13582 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13583 { 13584 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13585 dwarf_cpsr, 13586 0, 13587 &success); 13588 } 13589 13590 // Only return false if we are unable to read the CPSR if we care about conditions 13591 if (success == false && m_ignore_conditions == false) 13592 return false; 13593 13594 uint32_t orig_pc_value = 0; 13595 if (auto_advance_pc) 13596 { 13597 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13598 if (!success) 13599 return false; 13600 } 13601 13602 // Call the Emulate... function. 13603 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13604 if (!success) 13605 return false; 13606 13607 if (auto_advance_pc) 13608 { 13609 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13610 if (!success) 13611 return false; 13612 13613 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13614 { 13615 if (opcode_data->size == eSize32) 13616 after_pc_value += 4; 13617 else if (opcode_data->size == eSize16) 13618 after_pc_value += 2; 13619 13620 EmulateInstruction::Context context; 13621 context.type = eContextAdvancePC; 13622 context.SetNoArgs(); 13623 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13624 return false; 13625 13626 } 13627 } 13628 return true; 13629 } 13630 13631 bool 13632 EmulateInstructionARM::IsInstructionConditional() 13633 { 13634 const uint32_t cond = CurrentCond (m_opcode.GetOpcode32()); 13635 return cond != 0xe && cond != 0xf && cond != UINT32_MAX; 13636 } 13637 13638 bool 13639 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13640 { 13641 if (!test_data) 13642 { 13643 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13644 return false; 13645 } 13646 13647 static ConstString opcode_key ("opcode"); 13648 static ConstString before_key ("before_state"); 13649 static ConstString after_key ("after_state"); 13650 13651 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13652 13653 uint32_t test_opcode; 13654 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13655 { 13656 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13657 return false; 13658 } 13659 test_opcode = value_sp->GetUInt64Value (); 13660 13661 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13662 { 13663 m_opcode_mode = eModeARM; 13664 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13665 } 13666 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13667 { 13668 m_opcode_mode = eModeThumb; 13669 if (test_opcode < 0x10000) 13670 m_opcode.SetOpcode16 (test_opcode, GetByteOrder()); 13671 else 13672 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13673 13674 } 13675 else 13676 { 13677 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13678 return false; 13679 } 13680 13681 EmulationStateARM before_state; 13682 EmulationStateARM after_state; 13683 13684 value_sp = test_data->GetValueForKey (before_key); 13685 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13686 { 13687 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13688 return false; 13689 } 13690 13691 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13692 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13693 { 13694 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13695 return false; 13696 } 13697 13698 value_sp = test_data->GetValueForKey (after_key); 13699 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13700 { 13701 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13702 return false; 13703 } 13704 13705 state_dictionary = value_sp->GetAsDictionary (); 13706 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13707 { 13708 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13709 return false; 13710 } 13711 13712 SetBaton ((void *) &before_state); 13713 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13714 &EmulationStateARM::WritePseudoMemory, 13715 &EmulationStateARM::ReadPseudoRegister, 13716 &EmulationStateARM::WritePseudoRegister); 13717 13718 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13719 if (!success) 13720 { 13721 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13722 return false; 13723 } 13724 13725 success = before_state.CompareState (after_state); 13726 if (!success) 13727 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13728 13729 return success; 13730 } 13731 // 13732 // 13733 //const char * 13734 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13735 //{ 13736 // if (reg_kind == eRegisterKindGeneric) 13737 // { 13738 // switch (reg_num) 13739 // { 13740 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 13741 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 13742 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 13743 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 13744 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13745 // default: return NULL; 13746 // } 13747 // } 13748 // else if (reg_kind == eRegisterKindDWARF) 13749 // { 13750 // return GetARMDWARFRegisterName (reg_num); 13751 // } 13752 // return NULL; 13753 //} 13754 // 13755 bool 13756 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13757 { 13758 unwind_plan.Clear(); 13759 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13760 13761 UnwindPlan::RowSP row(new UnwindPlan::Row); 13762 13763 // Our previous Call Frame Address is the stack pointer 13764 row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0); 13765 13766 unwind_plan.AppendRow (row); 13767 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13768 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 13769 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 13770 unwind_plan.SetReturnAddressRegister (dwarf_lr); 13771 return true; 13772 } 13773