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 if (n == 13) 4785 context.type = eContextPushRegisterOnStack; 4786 else 4787 context.type = eContextRegisterStore; 4788 4789 RegisterInfo base_reg; 4790 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4791 4792 // if UnalignedSupport() || address<1:0> == '00' then 4793 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4794 { 4795 // MemU[address,4] = R[t]; 4796 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4797 if (!success) 4798 return false; 4799 4800 RegisterInfo data_reg; 4801 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4802 int32_t offset = address - base_address; 4803 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4804 if (!MemUWrite (context, address, data, addr_byte_size)) 4805 return false; 4806 } 4807 else 4808 { 4809 // MemU[address,4] = bits(32) UNKNOWN; 4810 WriteBits32UnknownToMemory (address); 4811 } 4812 4813 // if wback then R[n] = offset_addr; 4814 if (wback) 4815 { 4816 if (n == 13) 4817 context.type = eContextAdjustStackPointer; 4818 else 4819 context.type = eContextAdjustBaseRegister; 4820 context.SetAddress (offset_addr); 4821 4822 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4823 return false; 4824 } 4825 } 4826 return true; 4827 } 4828 4829 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4830 // word from a register to memory. The offset register value can optionally be shifted. 4831 bool 4832 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4833 { 4834 #if 0 4835 if ConditionPassed() then 4836 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4837 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4838 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4839 address = if index then offset_addr else R[n]; 4840 if t == 15 then // Only possible for encoding A1 4841 data = PCStoreValue(); 4842 else 4843 data = R[t]; 4844 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4845 MemU[address,4] = data; 4846 else // Can only occur before ARMv7 4847 MemU[address,4] = bits(32) UNKNOWN; 4848 if wback then R[n] = offset_addr; 4849 #endif 4850 4851 bool success = false; 4852 4853 if (ConditionPassed(opcode)) 4854 { 4855 const uint32_t addr_byte_size = GetAddressByteSize(); 4856 4857 uint32_t t; 4858 uint32_t n; 4859 uint32_t m; 4860 ARM_ShifterType shift_t; 4861 uint32_t shift_n; 4862 bool index; 4863 bool add; 4864 bool wback; 4865 4866 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4867 switch (encoding) 4868 { 4869 case eEncodingT1: 4870 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4871 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4872 t = Bits32 (opcode, 2, 0); 4873 n = Bits32 (opcode, 5, 3); 4874 m = Bits32 (opcode, 8, 6); 4875 4876 // index = TRUE; add = TRUE; wback = FALSE; 4877 index = true; 4878 add = true; 4879 wback = false; 4880 4881 // (shift_t, shift_n) = (SRType_LSL, 0); 4882 shift_t = SRType_LSL; 4883 shift_n = 0; 4884 break; 4885 4886 case eEncodingT2: 4887 // if Rn == '1111' then UNDEFINED; 4888 if (Bits32 (opcode, 19, 16) == 15) 4889 return false; 4890 4891 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4892 t = Bits32 (opcode, 15, 12); 4893 n = Bits32 (opcode, 19, 16); 4894 m = Bits32 (opcode, 3, 0); 4895 4896 // index = TRUE; add = TRUE; wback = FALSE; 4897 index = true; 4898 add = true; 4899 wback = false; 4900 4901 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4902 shift_t = SRType_LSL; 4903 shift_n = Bits32 (opcode, 5, 4); 4904 4905 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4906 if ((t == 15) || (BadReg (m))) 4907 return false; 4908 break; 4909 4910 case eEncodingA1: 4911 { 4912 // if P == '0' && W == '1' then SEE STRT; 4913 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4914 t = Bits32 (opcode, 15, 12); 4915 n = Bits32 (opcode, 19, 16); 4916 m = Bits32 (opcode, 3, 0); 4917 4918 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4919 index = BitIsSet (opcode, 24); 4920 add = BitIsSet (opcode, 23); 4921 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4922 4923 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4924 uint32_t typ = Bits32 (opcode, 6, 5); 4925 uint32_t imm5 = Bits32 (opcode, 11, 7); 4926 shift_n = DecodeImmShift(typ, imm5, shift_t); 4927 4928 // if m == 15 then UNPREDICTABLE; 4929 if (m == 15) 4930 return false; 4931 4932 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4933 if (wback && ((n == 15) || (n == t))) 4934 return false; 4935 4936 break; 4937 } 4938 default: 4939 return false; 4940 } 4941 4942 addr_t offset_addr; 4943 addr_t address; 4944 int32_t offset = 0; 4945 4946 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4947 if (!success) 4948 return false; 4949 4950 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4951 if (!success) 4952 return false; 4953 4954 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4955 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4956 if (!success) 4957 return false; 4958 4959 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4960 if (add) 4961 offset_addr = base_address + offset; 4962 else 4963 offset_addr = base_address - offset; 4964 4965 // address = if index then offset_addr else R[n]; 4966 if (index) 4967 address = offset_addr; 4968 else 4969 address = base_address; 4970 4971 uint32_t data; 4972 // if t == 15 then // Only possible for encoding A1 4973 if (t == 15) 4974 // data = PCStoreValue(); 4975 data = ReadCoreReg (PC_REG, &success); 4976 else 4977 // data = R[t]; 4978 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4979 4980 if (!success) 4981 return false; 4982 4983 EmulateInstruction::Context context; 4984 context.type = eContextRegisterStore; 4985 4986 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4987 if (UnalignedSupport () 4988 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4989 || CurrentInstrSet() == eModeARM) 4990 { 4991 // MemU[address,4] = data; 4992 4993 RegisterInfo base_reg; 4994 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4995 4996 RegisterInfo data_reg; 4997 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4998 4999 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5000 if (!MemUWrite (context, address, data, addr_byte_size)) 5001 return false; 5002 5003 } 5004 else 5005 // MemU[address,4] = bits(32) UNKNOWN; 5006 WriteBits32UnknownToMemory (address); 5007 5008 // if wback then R[n] = offset_addr; 5009 if (wback) 5010 { 5011 context.type = eContextRegisterLoad; 5012 context.SetAddress (offset_addr); 5013 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5014 return false; 5015 } 5016 5017 } 5018 return true; 5019 } 5020 5021 bool 5022 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 5023 { 5024 #if 0 5025 if ConditionPassed() then 5026 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5027 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5028 address = if index then offset_addr else R[n]; 5029 MemU[address,1] = R[t]<7:0>; 5030 if wback then R[n] = offset_addr; 5031 #endif 5032 5033 5034 bool success = false; 5035 5036 if (ConditionPassed(opcode)) 5037 { 5038 uint32_t t; 5039 uint32_t n; 5040 uint32_t imm32; 5041 bool index; 5042 bool add; 5043 bool wback; 5044 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5045 switch (encoding) 5046 { 5047 case eEncodingT1: 5048 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5049 t = Bits32 (opcode, 2, 0); 5050 n = Bits32 (opcode, 5, 3); 5051 imm32 = Bits32 (opcode, 10, 6); 5052 5053 // index = TRUE; add = TRUE; wback = FALSE; 5054 index = true; 5055 add = true; 5056 wback = false; 5057 break; 5058 5059 case eEncodingT2: 5060 // if Rn == '1111' then UNDEFINED; 5061 if (Bits32 (opcode, 19, 16) == 15) 5062 return false; 5063 5064 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5065 t = Bits32 (opcode, 15, 12); 5066 n = Bits32 (opcode, 19, 16); 5067 imm32 = Bits32 (opcode, 11, 0); 5068 5069 // index = TRUE; add = TRUE; wback = FALSE; 5070 index = true; 5071 add = true; 5072 wback = false; 5073 5074 // if BadReg(t) then UNPREDICTABLE; 5075 if (BadReg (t)) 5076 return false; 5077 break; 5078 5079 case eEncodingT3: 5080 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5081 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5082 if (Bits32 (opcode, 19, 16) == 15) 5083 return false; 5084 5085 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5086 t = Bits32 (opcode, 15, 12); 5087 n = Bits32 (opcode, 19, 16); 5088 imm32 = Bits32 (opcode, 7, 0); 5089 5090 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5091 index = BitIsSet (opcode, 10); 5092 add = BitIsSet (opcode, 9); 5093 wback = BitIsSet (opcode, 8); 5094 5095 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5096 if ((BadReg (t)) || (wback && (n == t))) 5097 return false; 5098 break; 5099 5100 default: 5101 return false; 5102 } 5103 5104 addr_t offset_addr; 5105 addr_t address; 5106 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5107 if (!success) 5108 return false; 5109 5110 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5111 if (add) 5112 offset_addr = base_address + imm32; 5113 else 5114 offset_addr = base_address - imm32; 5115 5116 // address = if index then offset_addr else R[n]; 5117 if (index) 5118 address = offset_addr; 5119 else 5120 address = base_address; 5121 5122 // MemU[address,1] = R[t]<7:0> 5123 RegisterInfo base_reg; 5124 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5125 5126 RegisterInfo data_reg; 5127 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5128 5129 EmulateInstruction::Context context; 5130 context.type = eContextRegisterStore; 5131 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5132 5133 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5134 if (!success) 5135 return false; 5136 5137 data = Bits32 (data, 7, 0); 5138 5139 if (!MemUWrite (context, address, data, 1)) 5140 return false; 5141 5142 // if wback then R[n] = offset_addr; 5143 if (wback) 5144 { 5145 context.type = eContextRegisterLoad; 5146 context.SetAddress (offset_addr); 5147 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5148 return false; 5149 } 5150 5151 } 5152 5153 return true; 5154 } 5155 5156 // STRH (register) calculates an address from a base register value and an offset register value, and stores a 5157 // halfword from a register to memory. The offset register value can be shifted left by 0, 1, 2, or 3 bits. 5158 bool 5159 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5160 { 5161 #if 0 5162 if ConditionPassed() then 5163 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5164 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5165 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5166 address = if index then offset_addr else R[n]; 5167 if UnalignedSupport() || address<0> == '0' then 5168 MemU[address,2] = R[t]<15:0>; 5169 else // Can only occur before ARMv7 5170 MemU[address,2] = bits(16) UNKNOWN; 5171 if wback then R[n] = offset_addr; 5172 #endif 5173 5174 bool success = false; 5175 5176 if (ConditionPassed(opcode)) 5177 { 5178 uint32_t t; 5179 uint32_t n; 5180 uint32_t m; 5181 bool index; 5182 bool add; 5183 bool wback; 5184 ARM_ShifterType shift_t; 5185 uint32_t shift_n; 5186 5187 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5188 switch (encoding) 5189 { 5190 case eEncodingT1: 5191 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5192 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5193 t = Bits32 (opcode, 2, 0); 5194 n = Bits32 (opcode, 5, 3); 5195 m = Bits32 (opcode, 8, 6); 5196 5197 // index = TRUE; add = TRUE; wback = FALSE; 5198 index = true; 5199 add = true; 5200 wback = false; 5201 5202 // (shift_t, shift_n) = (SRType_LSL, 0); 5203 shift_t = SRType_LSL; 5204 shift_n = 0; 5205 5206 break; 5207 5208 case eEncodingT2: 5209 // if Rn == '1111' then UNDEFINED; 5210 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5211 t = Bits32 (opcode, 15, 12); 5212 n = Bits32 (opcode, 19, 16); 5213 m = Bits32 (opcode, 3, 0); 5214 if (n == 15) 5215 return false; 5216 5217 // index = TRUE; add = TRUE; wback = FALSE; 5218 index = true; 5219 add = true; 5220 wback = false; 5221 5222 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5223 shift_t = SRType_LSL; 5224 shift_n = Bits32 (opcode, 5, 4); 5225 5226 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5227 if (BadReg (t) || BadReg (m)) 5228 return false; 5229 5230 break; 5231 5232 case eEncodingA1: 5233 // if P == '0' && W == '1' then SEE STRHT; 5234 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5235 t = Bits32 (opcode, 15, 12); 5236 n = Bits32 (opcode, 19, 16); 5237 m = Bits32 (opcode, 3, 0); 5238 5239 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5240 index = BitIsSet (opcode, 24); 5241 add = BitIsSet (opcode, 23); 5242 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5243 5244 // (shift_t, shift_n) = (SRType_LSL, 0); 5245 shift_t = SRType_LSL; 5246 shift_n = 0; 5247 5248 // if t == 15 || m == 15 then UNPREDICTABLE; 5249 if ((t == 15) || (m == 15)) 5250 return false; 5251 5252 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5253 if (wback && ((n == 15) || (n == t))) 5254 return false; 5255 5256 break; 5257 5258 default: 5259 return false; 5260 } 5261 5262 uint32_t Rm = ReadCoreReg (m, &success); 5263 if (!success) 5264 return false; 5265 5266 uint32_t Rn = ReadCoreReg (n, &success); 5267 if (!success) 5268 return false; 5269 5270 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5271 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5272 if (!success) 5273 return false; 5274 5275 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5276 addr_t offset_addr; 5277 if (add) 5278 offset_addr = Rn + offset; 5279 else 5280 offset_addr = Rn - offset; 5281 5282 // address = if index then offset_addr else R[n]; 5283 addr_t address; 5284 if (index) 5285 address = offset_addr; 5286 else 5287 address = Rn; 5288 5289 EmulateInstruction::Context context; 5290 context.type = eContextRegisterStore; 5291 RegisterInfo base_reg; 5292 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5293 RegisterInfo offset_reg; 5294 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5295 5296 // if UnalignedSupport() || address<0> == '0' then 5297 if (UnalignedSupport() || BitIsClear (address, 0)) 5298 { 5299 // MemU[address,2] = R[t]<15:0>; 5300 uint32_t Rt = ReadCoreReg (t, &success); 5301 if (!success) 5302 return false; 5303 5304 EmulateInstruction::Context context; 5305 context.type = eContextRegisterStore; 5306 RegisterInfo base_reg; 5307 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5308 RegisterInfo offset_reg; 5309 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5310 RegisterInfo data_reg; 5311 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5312 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5313 5314 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5315 return false; 5316 } 5317 else // Can only occur before ARMv7 5318 { 5319 // MemU[address,2] = bits(16) UNKNOWN; 5320 } 5321 5322 // if wback then R[n] = offset_addr; 5323 if (wback) 5324 { 5325 context.type = eContextAdjustBaseRegister; 5326 context.SetAddress (offset_addr); 5327 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5328 return false; 5329 } 5330 } 5331 5332 return true; 5333 } 5334 5335 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5336 // and writes the result to the destination register. It can optionally update the condition flags 5337 // based on the result. 5338 bool 5339 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5340 { 5341 #if 0 5342 // ARM pseudo code... 5343 if ConditionPassed() then 5344 EncodingSpecificOperations(); 5345 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5346 if d == 15 then // Can only occur for ARM encoding 5347 ALUWritePC(result); // setflags is always FALSE here 5348 else 5349 R[d] = result; 5350 if setflags then 5351 APSR.N = result<31>; 5352 APSR.Z = IsZeroBit(result); 5353 APSR.C = carry; 5354 APSR.V = overflow; 5355 #endif 5356 5357 bool success = false; 5358 5359 if (ConditionPassed(opcode)) 5360 { 5361 uint32_t Rd, Rn; 5362 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5363 bool setflags; 5364 switch (encoding) 5365 { 5366 case eEncodingT1: 5367 Rd = Bits32(opcode, 11, 8); 5368 Rn = Bits32(opcode, 19, 16); 5369 setflags = BitIsSet(opcode, 20); 5370 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5371 if (BadReg(Rd) || BadReg(Rn)) 5372 return false; 5373 break; 5374 case eEncodingA1: 5375 Rd = Bits32(opcode, 15, 12); 5376 Rn = Bits32(opcode, 19, 16); 5377 setflags = BitIsSet(opcode, 20); 5378 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5379 5380 if (Rd == 15 && setflags) 5381 return EmulateSUBSPcLrEtc (opcode, encoding); 5382 break; 5383 default: 5384 return false; 5385 } 5386 5387 // Read the first operand. 5388 int32_t val1 = ReadCoreReg(Rn, &success); 5389 if (!success) 5390 return false; 5391 5392 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5393 5394 EmulateInstruction::Context context; 5395 context.type = EmulateInstruction::eContextImmediate; 5396 context.SetNoArgs (); 5397 5398 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5399 return false; 5400 } 5401 return true; 5402 } 5403 5404 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5405 // register value, and writes the result to the destination register. It can optionally update the 5406 // condition flags based on the result. 5407 bool 5408 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5409 { 5410 #if 0 5411 // ARM pseudo code... 5412 if ConditionPassed() then 5413 EncodingSpecificOperations(); 5414 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5415 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5416 if d == 15 then // Can only occur for ARM encoding 5417 ALUWritePC(result); // setflags is always FALSE here 5418 else 5419 R[d] = result; 5420 if setflags then 5421 APSR.N = result<31>; 5422 APSR.Z = IsZeroBit(result); 5423 APSR.C = carry; 5424 APSR.V = overflow; 5425 #endif 5426 5427 bool success = false; 5428 5429 if (ConditionPassed(opcode)) 5430 { 5431 uint32_t Rd, Rn, Rm; 5432 ARM_ShifterType shift_t; 5433 uint32_t shift_n; // the shift applied to the value read from Rm 5434 bool setflags; 5435 switch (encoding) 5436 { 5437 case eEncodingT1: 5438 Rd = Rn = Bits32(opcode, 2, 0); 5439 Rm = Bits32(opcode, 5, 3); 5440 setflags = !InITBlock(); 5441 shift_t = SRType_LSL; 5442 shift_n = 0; 5443 break; 5444 case eEncodingT2: 5445 Rd = Bits32(opcode, 11, 8); 5446 Rn = Bits32(opcode, 19, 16); 5447 Rm = Bits32(opcode, 3, 0); 5448 setflags = BitIsSet(opcode, 20); 5449 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5450 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5451 return false; 5452 break; 5453 case eEncodingA1: 5454 Rd = Bits32(opcode, 15, 12); 5455 Rn = Bits32(opcode, 19, 16); 5456 Rm = Bits32(opcode, 3, 0); 5457 setflags = BitIsSet(opcode, 20); 5458 shift_n = DecodeImmShiftARM(opcode, shift_t); 5459 5460 if (Rd == 15 && setflags) 5461 return EmulateSUBSPcLrEtc (opcode, encoding); 5462 break; 5463 default: 5464 return false; 5465 } 5466 5467 // Read the first operand. 5468 int32_t val1 = ReadCoreReg(Rn, &success); 5469 if (!success) 5470 return false; 5471 5472 // Read the second operand. 5473 int32_t val2 = ReadCoreReg(Rm, &success); 5474 if (!success) 5475 return false; 5476 5477 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5478 if (!success) 5479 return false; 5480 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5481 5482 EmulateInstruction::Context context; 5483 context.type = EmulateInstruction::eContextImmediate; 5484 context.SetNoArgs (); 5485 5486 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5487 return false; 5488 } 5489 return true; 5490 } 5491 5492 // This instruction adds an immediate value to the PC value to form a PC-relative address, 5493 // and writes the result to the destination register. 5494 bool 5495 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5496 { 5497 #if 0 5498 // ARM pseudo code... 5499 if ConditionPassed() then 5500 EncodingSpecificOperations(); 5501 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5502 if d == 15 then // Can only occur for ARM encodings 5503 ALUWritePC(result); 5504 else 5505 R[d] = result; 5506 #endif 5507 5508 bool success = false; 5509 5510 if (ConditionPassed(opcode)) 5511 { 5512 uint32_t Rd; 5513 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5514 bool add; 5515 switch (encoding) 5516 { 5517 case eEncodingT1: 5518 Rd = Bits32(opcode, 10, 8); 5519 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5520 add = true; 5521 break; 5522 case eEncodingT2: 5523 case eEncodingT3: 5524 Rd = Bits32(opcode, 11, 8); 5525 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5526 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5527 if (BadReg(Rd)) 5528 return false; 5529 break; 5530 case eEncodingA1: 5531 case eEncodingA2: 5532 Rd = Bits32(opcode, 15, 12); 5533 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5534 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5535 break; 5536 default: 5537 return false; 5538 } 5539 5540 // Read the PC value. 5541 uint32_t pc = ReadCoreReg(PC_REG, &success); 5542 if (!success) 5543 return false; 5544 5545 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5546 5547 EmulateInstruction::Context context; 5548 context.type = EmulateInstruction::eContextImmediate; 5549 context.SetNoArgs (); 5550 5551 if (!WriteCoreReg(context, result, Rd)) 5552 return false; 5553 } 5554 return true; 5555 } 5556 5557 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5558 // to the destination register. It can optionally update the condition flags based on the result. 5559 bool 5560 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5561 { 5562 #if 0 5563 // ARM pseudo code... 5564 if ConditionPassed() then 5565 EncodingSpecificOperations(); 5566 result = R[n] AND imm32; 5567 if d == 15 then // Can only occur for ARM encoding 5568 ALUWritePC(result); // setflags is always FALSE here 5569 else 5570 R[d] = result; 5571 if setflags then 5572 APSR.N = result<31>; 5573 APSR.Z = IsZeroBit(result); 5574 APSR.C = carry; 5575 // APSR.V unchanged 5576 #endif 5577 5578 bool success = false; 5579 5580 if (ConditionPassed(opcode)) 5581 { 5582 uint32_t Rd, Rn; 5583 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5584 bool setflags; 5585 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5586 switch (encoding) 5587 { 5588 case eEncodingT1: 5589 Rd = Bits32(opcode, 11, 8); 5590 Rn = Bits32(opcode, 19, 16); 5591 setflags = BitIsSet(opcode, 20); 5592 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5593 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5594 if (Rd == 15 && setflags) 5595 return EmulateTSTImm(opcode, eEncodingT1); 5596 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5597 return false; 5598 break; 5599 case eEncodingA1: 5600 Rd = Bits32(opcode, 15, 12); 5601 Rn = Bits32(opcode, 19, 16); 5602 setflags = BitIsSet(opcode, 20); 5603 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5604 5605 if (Rd == 15 && setflags) 5606 return EmulateSUBSPcLrEtc (opcode, encoding); 5607 break; 5608 default: 5609 return false; 5610 } 5611 5612 // Read the first operand. 5613 uint32_t val1 = ReadCoreReg(Rn, &success); 5614 if (!success) 5615 return false; 5616 5617 uint32_t result = val1 & imm32; 5618 5619 EmulateInstruction::Context context; 5620 context.type = EmulateInstruction::eContextImmediate; 5621 context.SetNoArgs (); 5622 5623 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5624 return false; 5625 } 5626 return true; 5627 } 5628 5629 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5630 // and writes the result to the destination register. It can optionally update the condition flags 5631 // based on the result. 5632 bool 5633 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5634 { 5635 #if 0 5636 // ARM pseudo code... 5637 if ConditionPassed() then 5638 EncodingSpecificOperations(); 5639 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5640 result = R[n] AND shifted; 5641 if d == 15 then // Can only occur for ARM encoding 5642 ALUWritePC(result); // setflags is always FALSE here 5643 else 5644 R[d] = result; 5645 if setflags then 5646 APSR.N = result<31>; 5647 APSR.Z = IsZeroBit(result); 5648 APSR.C = carry; 5649 // APSR.V unchanged 5650 #endif 5651 5652 bool success = false; 5653 5654 if (ConditionPassed(opcode)) 5655 { 5656 uint32_t Rd, Rn, Rm; 5657 ARM_ShifterType shift_t; 5658 uint32_t shift_n; // the shift applied to the value read from Rm 5659 bool setflags; 5660 uint32_t carry; 5661 switch (encoding) 5662 { 5663 case eEncodingT1: 5664 Rd = Rn = Bits32(opcode, 2, 0); 5665 Rm = Bits32(opcode, 5, 3); 5666 setflags = !InITBlock(); 5667 shift_t = SRType_LSL; 5668 shift_n = 0; 5669 break; 5670 case eEncodingT2: 5671 Rd = Bits32(opcode, 11, 8); 5672 Rn = Bits32(opcode, 19, 16); 5673 Rm = Bits32(opcode, 3, 0); 5674 setflags = BitIsSet(opcode, 20); 5675 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5676 // if Rd == '1111' && S == '1' then SEE TST (register); 5677 if (Rd == 15 && setflags) 5678 return EmulateTSTReg(opcode, eEncodingT2); 5679 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5680 return false; 5681 break; 5682 case eEncodingA1: 5683 Rd = Bits32(opcode, 15, 12); 5684 Rn = Bits32(opcode, 19, 16); 5685 Rm = Bits32(opcode, 3, 0); 5686 setflags = BitIsSet(opcode, 20); 5687 shift_n = DecodeImmShiftARM(opcode, shift_t); 5688 5689 if (Rd == 15 && setflags) 5690 return EmulateSUBSPcLrEtc (opcode, encoding); 5691 break; 5692 default: 5693 return false; 5694 } 5695 5696 // Read the first operand. 5697 uint32_t val1 = ReadCoreReg(Rn, &success); 5698 if (!success) 5699 return false; 5700 5701 // Read the second operand. 5702 uint32_t val2 = ReadCoreReg(Rm, &success); 5703 if (!success) 5704 return false; 5705 5706 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5707 if (!success) 5708 return false; 5709 uint32_t result = val1 & shifted; 5710 5711 EmulateInstruction::Context context; 5712 context.type = EmulateInstruction::eContextImmediate; 5713 context.SetNoArgs (); 5714 5715 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5716 return false; 5717 } 5718 return true; 5719 } 5720 5721 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5722 // immediate value, and writes the result to the destination register. It can optionally update the 5723 // condition flags based on the result. 5724 bool 5725 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5726 { 5727 #if 0 5728 // ARM pseudo code... 5729 if ConditionPassed() then 5730 EncodingSpecificOperations(); 5731 result = R[n] AND NOT(imm32); 5732 if d == 15 then // Can only occur for ARM encoding 5733 ALUWritePC(result); // setflags is always FALSE here 5734 else 5735 R[d] = result; 5736 if setflags then 5737 APSR.N = result<31>; 5738 APSR.Z = IsZeroBit(result); 5739 APSR.C = carry; 5740 // APSR.V unchanged 5741 #endif 5742 5743 bool success = false; 5744 5745 if (ConditionPassed(opcode)) 5746 { 5747 uint32_t Rd, Rn; 5748 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5749 bool setflags; 5750 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5751 switch (encoding) 5752 { 5753 case eEncodingT1: 5754 Rd = Bits32(opcode, 11, 8); 5755 Rn = Bits32(opcode, 19, 16); 5756 setflags = BitIsSet(opcode, 20); 5757 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5758 if (BadReg(Rd) || BadReg(Rn)) 5759 return false; 5760 break; 5761 case eEncodingA1: 5762 Rd = Bits32(opcode, 15, 12); 5763 Rn = Bits32(opcode, 19, 16); 5764 setflags = BitIsSet(opcode, 20); 5765 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5766 5767 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5768 if (Rd == 15 && setflags) 5769 return EmulateSUBSPcLrEtc (opcode, encoding); 5770 break; 5771 default: 5772 return false; 5773 } 5774 5775 // Read the first operand. 5776 uint32_t val1 = ReadCoreReg(Rn, &success); 5777 if (!success) 5778 return false; 5779 5780 uint32_t result = val1 & ~imm32; 5781 5782 EmulateInstruction::Context context; 5783 context.type = EmulateInstruction::eContextImmediate; 5784 context.SetNoArgs (); 5785 5786 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5787 return false; 5788 } 5789 return true; 5790 } 5791 5792 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5793 // optionally-shifted register value, and writes the result to the destination register. 5794 // It can optionally update the condition flags based on the result. 5795 bool 5796 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5797 { 5798 #if 0 5799 // ARM pseudo code... 5800 if ConditionPassed() then 5801 EncodingSpecificOperations(); 5802 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5803 result = R[n] AND NOT(shifted); 5804 if d == 15 then // Can only occur for ARM encoding 5805 ALUWritePC(result); // setflags is always FALSE here 5806 else 5807 R[d] = result; 5808 if setflags then 5809 APSR.N = result<31>; 5810 APSR.Z = IsZeroBit(result); 5811 APSR.C = carry; 5812 // APSR.V unchanged 5813 #endif 5814 5815 bool success = false; 5816 5817 if (ConditionPassed(opcode)) 5818 { 5819 uint32_t Rd, Rn, Rm; 5820 ARM_ShifterType shift_t; 5821 uint32_t shift_n; // the shift applied to the value read from Rm 5822 bool setflags; 5823 uint32_t carry; 5824 switch (encoding) 5825 { 5826 case eEncodingT1: 5827 Rd = Rn = Bits32(opcode, 2, 0); 5828 Rm = Bits32(opcode, 5, 3); 5829 setflags = !InITBlock(); 5830 shift_t = SRType_LSL; 5831 shift_n = 0; 5832 break; 5833 case eEncodingT2: 5834 Rd = Bits32(opcode, 11, 8); 5835 Rn = Bits32(opcode, 19, 16); 5836 Rm = Bits32(opcode, 3, 0); 5837 setflags = BitIsSet(opcode, 20); 5838 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5839 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5840 return false; 5841 break; 5842 case eEncodingA1: 5843 Rd = Bits32(opcode, 15, 12); 5844 Rn = Bits32(opcode, 19, 16); 5845 Rm = Bits32(opcode, 3, 0); 5846 setflags = BitIsSet(opcode, 20); 5847 shift_n = DecodeImmShiftARM(opcode, shift_t); 5848 5849 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5850 if (Rd == 15 && setflags) 5851 return EmulateSUBSPcLrEtc (opcode, encoding); 5852 break; 5853 default: 5854 return false; 5855 } 5856 5857 // Read the first operand. 5858 uint32_t val1 = ReadCoreReg(Rn, &success); 5859 if (!success) 5860 return false; 5861 5862 // Read the second operand. 5863 uint32_t val2 = ReadCoreReg(Rm, &success); 5864 if (!success) 5865 return false; 5866 5867 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5868 if (!success) 5869 return false; 5870 uint32_t result = val1 & ~shifted; 5871 5872 EmulateInstruction::Context context; 5873 context.type = EmulateInstruction::eContextImmediate; 5874 context.SetNoArgs (); 5875 5876 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5877 return false; 5878 } 5879 return true; 5880 } 5881 5882 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5883 // from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5884 bool 5885 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5886 { 5887 #if 0 5888 if ConditionPassed() then 5889 EncodingSpecificOperations(); 5890 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5891 address = if index then offset_addr else R[n]; 5892 data = MemU[address,4]; 5893 if wback then R[n] = offset_addr; 5894 if t == 15 then 5895 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5896 elsif UnalignedSupport() || address<1:0> = '00' then 5897 R[t] = data; 5898 else // Can only apply before ARMv7 5899 R[t] = ROR(data, 8*UInt(address<1:0>)); 5900 #endif 5901 5902 bool success = false; 5903 5904 if (ConditionPassed(opcode)) 5905 { 5906 const uint32_t addr_byte_size = GetAddressByteSize(); 5907 5908 uint32_t t; 5909 uint32_t n; 5910 uint32_t imm32; 5911 bool index; 5912 bool add; 5913 bool wback; 5914 5915 switch (encoding) 5916 { 5917 case eEncodingA1: 5918 // if Rn == '1111' then SEE LDR (literal); 5919 // if P == '0' && W == '1' then SEE LDRT; 5920 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5921 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5922 t = Bits32 (opcode, 15, 12); 5923 n = Bits32 (opcode, 19, 16); 5924 imm32 = Bits32 (opcode, 11, 0); 5925 5926 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5927 index = BitIsSet (opcode, 24); 5928 add = BitIsSet (opcode, 23); 5929 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5930 5931 // if wback && n == t then UNPREDICTABLE; 5932 if (wback && (n == t)) 5933 return false; 5934 5935 break; 5936 5937 default: 5938 return false; 5939 } 5940 5941 addr_t address; 5942 addr_t offset_addr; 5943 addr_t base_address = ReadCoreReg (n, &success); 5944 if (!success) 5945 return false; 5946 5947 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5948 if (add) 5949 offset_addr = base_address + imm32; 5950 else 5951 offset_addr = base_address - imm32; 5952 5953 // address = if index then offset_addr else R[n]; 5954 if (index) 5955 address = offset_addr; 5956 else 5957 address = base_address; 5958 5959 // data = MemU[address,4]; 5960 5961 RegisterInfo base_reg; 5962 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5963 5964 EmulateInstruction::Context context; 5965 context.type = eContextRegisterLoad; 5966 context.SetRegisterPlusOffset (base_reg, address - base_address); 5967 5968 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5969 if (!success) 5970 return false; 5971 5972 // if wback then R[n] = offset_addr; 5973 if (wback) 5974 { 5975 context.type = eContextAdjustBaseRegister; 5976 context.SetAddress (offset_addr); 5977 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5978 return false; 5979 } 5980 5981 // if t == 15 then 5982 if (t == 15) 5983 { 5984 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5985 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5986 { 5987 // LoadWritePC (data); 5988 context.type = eContextRegisterLoad; 5989 context.SetRegisterPlusOffset (base_reg, address - base_address); 5990 LoadWritePC (context, data); 5991 } 5992 else 5993 return false; 5994 } 5995 // elsif UnalignedSupport() || address<1:0> = '00' then 5996 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5997 { 5998 // R[t] = data; 5999 context.type = eContextRegisterLoad; 6000 context.SetRegisterPlusOffset (base_reg, address - base_address); 6001 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6002 return false; 6003 } 6004 // else // Can only apply before ARMv7 6005 else 6006 { 6007 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6008 data = ROR (data, Bits32 (address, 1, 0), &success); 6009 if (!success) 6010 return false; 6011 context.type = eContextRegisterLoad; 6012 context.SetImmediate (data); 6013 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6014 return false; 6015 } 6016 6017 } 6018 return true; 6019 } 6020 6021 // LDR (register) calculates an address from a base register value and an offset register value, loads a word 6022 // from memory, and writes it to a register. The offset register value can optionally be shifted. 6023 bool 6024 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 6025 { 6026 #if 0 6027 if ConditionPassed() then 6028 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6029 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6030 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6031 address = if index then offset_addr else R[n]; 6032 data = MemU[address,4]; 6033 if wback then R[n] = offset_addr; 6034 if t == 15 then 6035 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6036 elsif UnalignedSupport() || address<1:0> = '00' then 6037 R[t] = data; 6038 else // Can only apply before ARMv7 6039 if CurrentInstrSet() == InstrSet_ARM then 6040 R[t] = ROR(data, 8*UInt(address<1:0>)); 6041 else 6042 R[t] = bits(32) UNKNOWN; 6043 #endif 6044 6045 bool success = false; 6046 6047 if (ConditionPassed(opcode)) 6048 { 6049 const uint32_t addr_byte_size = GetAddressByteSize(); 6050 6051 uint32_t t; 6052 uint32_t n; 6053 uint32_t m; 6054 bool index; 6055 bool add; 6056 bool wback; 6057 ARM_ShifterType shift_t; 6058 uint32_t shift_n; 6059 6060 switch (encoding) 6061 { 6062 case eEncodingT1: 6063 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6064 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6065 t = Bits32 (opcode, 2, 0); 6066 n = Bits32 (opcode, 5, 3); 6067 m = Bits32 (opcode, 8, 6); 6068 6069 // index = TRUE; add = TRUE; wback = FALSE; 6070 index = true; 6071 add = true; 6072 wback = false; 6073 6074 // (shift_t, shift_n) = (SRType_LSL, 0); 6075 shift_t = SRType_LSL; 6076 shift_n = 0; 6077 6078 break; 6079 6080 case eEncodingT2: 6081 // if Rn == '1111' then SEE LDR (literal); 6082 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6083 t = Bits32 (opcode, 15, 12); 6084 n = Bits32 (opcode, 19, 16); 6085 m = Bits32 (opcode, 3, 0); 6086 6087 // index = TRUE; add = TRUE; wback = FALSE; 6088 index = true; 6089 add = true; 6090 wback = false; 6091 6092 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6093 shift_t = SRType_LSL; 6094 shift_n = Bits32 (opcode, 5, 4); 6095 6096 // if BadReg(m) then UNPREDICTABLE; 6097 if (BadReg (m)) 6098 return false; 6099 6100 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6101 if ((t == 15) && InITBlock() && !LastInITBlock()) 6102 return false; 6103 6104 break; 6105 6106 case eEncodingA1: 6107 { 6108 // if P == '0' && W == '1' then SEE LDRT; 6109 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6110 t = Bits32 (opcode, 15, 12); 6111 n = Bits32 (opcode, 19, 16); 6112 m = Bits32 (opcode, 3, 0); 6113 6114 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6115 index = BitIsSet (opcode, 24); 6116 add = BitIsSet (opcode, 23); 6117 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6118 6119 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6120 uint32_t type = Bits32 (opcode, 6, 5); 6121 uint32_t imm5 = Bits32 (opcode, 11, 7); 6122 shift_n = DecodeImmShift (type, imm5, shift_t); 6123 6124 // if m == 15 then UNPREDICTABLE; 6125 if (m == 15) 6126 return false; 6127 6128 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6129 if (wback && ((n == 15) || (n == t))) 6130 return false; 6131 } 6132 break; 6133 6134 6135 default: 6136 return false; 6137 } 6138 6139 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6140 if (!success) 6141 return false; 6142 6143 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6144 if (!success) 6145 return false; 6146 6147 addr_t offset_addr; 6148 addr_t address; 6149 6150 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6151 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6152 if (!success) 6153 return false; 6154 6155 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6156 if (add) 6157 offset_addr = Rn + offset; 6158 else 6159 offset_addr = Rn - offset; 6160 6161 // address = if index then offset_addr else R[n]; 6162 if (index) 6163 address = offset_addr; 6164 else 6165 address = Rn; 6166 6167 // data = MemU[address,4]; 6168 RegisterInfo base_reg; 6169 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6170 6171 EmulateInstruction::Context context; 6172 context.type = eContextRegisterLoad; 6173 context.SetRegisterPlusOffset (base_reg, address - Rn); 6174 6175 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6176 if (!success) 6177 return false; 6178 6179 // if wback then R[n] = offset_addr; 6180 if (wback) 6181 { 6182 context.type = eContextAdjustBaseRegister; 6183 context.SetAddress (offset_addr); 6184 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6185 return false; 6186 } 6187 6188 // if t == 15 then 6189 if (t == 15) 6190 { 6191 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6192 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6193 { 6194 context.type = eContextRegisterLoad; 6195 context.SetRegisterPlusOffset (base_reg, address - Rn); 6196 LoadWritePC (context, data); 6197 } 6198 else 6199 return false; 6200 } 6201 // elsif UnalignedSupport() || address<1:0> = '00' then 6202 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6203 { 6204 // R[t] = data; 6205 context.type = eContextRegisterLoad; 6206 context.SetRegisterPlusOffset (base_reg, address - Rn); 6207 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6208 return false; 6209 } 6210 else // Can only apply before ARMv7 6211 { 6212 // if CurrentInstrSet() == InstrSet_ARM then 6213 if (CurrentInstrSet () == eModeARM) 6214 { 6215 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6216 data = ROR (data, Bits32 (address, 1, 0), &success); 6217 if (!success) 6218 return false; 6219 context.type = eContextRegisterLoad; 6220 context.SetImmediate (data); 6221 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6222 return false; 6223 } 6224 else 6225 { 6226 // R[t] = bits(32) UNKNOWN; 6227 WriteBits32Unknown (t); 6228 } 6229 } 6230 } 6231 return true; 6232 } 6233 6234 // LDRB (immediate, Thumb) 6235 bool 6236 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6237 { 6238 #if 0 6239 if ConditionPassed() then 6240 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6241 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6242 address = if index then offset_addr else R[n]; 6243 R[t] = ZeroExtend(MemU[address,1], 32); 6244 if wback then R[n] = offset_addr; 6245 #endif 6246 6247 bool success = false; 6248 6249 if (ConditionPassed(opcode)) 6250 { 6251 uint32_t t; 6252 uint32_t n; 6253 uint32_t imm32; 6254 bool index; 6255 bool add; 6256 bool wback; 6257 6258 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6259 switch (encoding) 6260 { 6261 case eEncodingT1: 6262 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6263 t = Bits32 (opcode, 2, 0); 6264 n = Bits32 (opcode, 5, 3); 6265 imm32 = Bits32 (opcode, 10, 6); 6266 6267 // index = TRUE; add = TRUE; wback = FALSE; 6268 index = true; 6269 add = true; 6270 wback= false; 6271 6272 break; 6273 6274 case eEncodingT2: 6275 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6276 t = Bits32 (opcode, 15, 12); 6277 n = Bits32 (opcode, 19, 16); 6278 imm32 = Bits32 (opcode, 11, 0); 6279 6280 // index = TRUE; add = TRUE; wback = FALSE; 6281 index = true; 6282 add = true; 6283 wback = false; 6284 6285 // if Rt == '1111' then SEE PLD; 6286 if (t == 15) 6287 return false; // PLD is not implemented yet 6288 6289 // if Rn == '1111' then SEE LDRB (literal); 6290 if (n == 15) 6291 return EmulateLDRBLiteral(opcode, eEncodingT1); 6292 6293 // if t == 13 then UNPREDICTABLE; 6294 if (t == 13) 6295 return false; 6296 6297 break; 6298 6299 case eEncodingT3: 6300 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6301 // if P == '0' && W == '0' then UNDEFINED; 6302 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6303 return false; 6304 6305 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6306 t = Bits32 (opcode, 15, 12); 6307 n = Bits32 (opcode, 19, 16); 6308 imm32 = Bits32 (opcode, 7, 0); 6309 6310 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6311 index = BitIsSet (opcode, 10); 6312 add = BitIsSet (opcode, 9); 6313 wback = BitIsSet (opcode, 8); 6314 6315 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6316 if (t == 15) 6317 return false; // PLD is not implemented yet 6318 6319 // if Rn == '1111' then SEE LDRB (literal); 6320 if (n == 15) 6321 return EmulateLDRBLiteral(opcode, eEncodingT1); 6322 6323 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6324 if (BadReg (t) || (wback && (n == t))) 6325 return false; 6326 6327 break; 6328 6329 default: 6330 return false; 6331 } 6332 6333 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6334 if (!success) 6335 return false; 6336 6337 addr_t address; 6338 addr_t offset_addr; 6339 6340 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6341 if (add) 6342 offset_addr = Rn + imm32; 6343 else 6344 offset_addr = Rn - imm32; 6345 6346 // address = if index then offset_addr else R[n]; 6347 if (index) 6348 address = offset_addr; 6349 else 6350 address = Rn; 6351 6352 // R[t] = ZeroExtend(MemU[address,1], 32); 6353 RegisterInfo base_reg; 6354 RegisterInfo data_reg; 6355 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6356 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6357 6358 EmulateInstruction::Context context; 6359 context.type = eContextRegisterLoad; 6360 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6361 6362 uint64_t data = MemURead (context, address, 1, 0, &success); 6363 if (!success) 6364 return false; 6365 6366 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6367 return false; 6368 6369 // if wback then R[n] = offset_addr; 6370 if (wback) 6371 { 6372 context.type = eContextAdjustBaseRegister; 6373 context.SetAddress (offset_addr); 6374 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6375 return false; 6376 } 6377 } 6378 return true; 6379 } 6380 6381 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6382 // zero-extends it to form a 32-bit word and writes it to a register. 6383 bool 6384 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6385 { 6386 #if 0 6387 if ConditionPassed() then 6388 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6389 base = Align(PC,4); 6390 address = if add then (base + imm32) else (base - imm32); 6391 R[t] = ZeroExtend(MemU[address,1], 32); 6392 #endif 6393 6394 bool success = false; 6395 6396 if (ConditionPassed(opcode)) 6397 { 6398 uint32_t t; 6399 uint32_t imm32; 6400 bool add; 6401 switch (encoding) 6402 { 6403 case eEncodingT1: 6404 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6405 t = Bits32 (opcode, 15, 12); 6406 imm32 = Bits32 (opcode, 11, 0); 6407 add = BitIsSet (opcode, 23); 6408 6409 // if Rt == '1111' then SEE PLD; 6410 if (t == 15) 6411 return false; // PLD is not implemented yet 6412 6413 // if t == 13 then UNPREDICTABLE; 6414 if (t == 13) 6415 return false; 6416 6417 break; 6418 6419 case eEncodingA1: 6420 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6421 t = Bits32 (opcode, 15, 12); 6422 imm32 = Bits32 (opcode, 11, 0); 6423 add = BitIsSet (opcode, 23); 6424 6425 // if t == 15 then UNPREDICTABLE; 6426 if (t == 15) 6427 return false; 6428 break; 6429 6430 default: 6431 return false; 6432 } 6433 6434 // base = Align(PC,4); 6435 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6436 if (!success) 6437 return false; 6438 6439 uint32_t base = AlignPC (pc_val); 6440 6441 addr_t address; 6442 // address = if add then (base + imm32) else (base - imm32); 6443 if (add) 6444 address = base + imm32; 6445 else 6446 address = base - imm32; 6447 6448 // R[t] = ZeroExtend(MemU[address,1], 32); 6449 EmulateInstruction::Context context; 6450 context.type = eContextRelativeBranchImmediate; 6451 context.SetImmediate (address - base); 6452 6453 uint64_t data = MemURead (context, address, 1, 0, &success); 6454 if (!success) 6455 return false; 6456 6457 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6458 return false; 6459 } 6460 return true; 6461 } 6462 6463 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6464 // memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6465 // optionally be shifted. 6466 bool 6467 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6468 { 6469 #if 0 6470 if ConditionPassed() then 6471 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6472 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6473 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6474 address = if index then offset_addr else R[n]; 6475 R[t] = ZeroExtend(MemU[address,1],32); 6476 if wback then R[n] = offset_addr; 6477 #endif 6478 6479 bool success = false; 6480 6481 if (ConditionPassed(opcode)) 6482 { 6483 uint32_t t; 6484 uint32_t n; 6485 uint32_t m; 6486 bool index; 6487 bool add; 6488 bool wback; 6489 ARM_ShifterType shift_t; 6490 uint32_t shift_n; 6491 6492 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6493 switch (encoding) 6494 { 6495 case eEncodingT1: 6496 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6497 t = Bits32 (opcode, 2, 0); 6498 n = Bits32 (opcode, 5, 3); 6499 m = Bits32 (opcode, 8, 6); 6500 6501 // index = TRUE; add = TRUE; wback = FALSE; 6502 index = true; 6503 add = true; 6504 wback = false; 6505 6506 // (shift_t, shift_n) = (SRType_LSL, 0); 6507 shift_t = SRType_LSL; 6508 shift_n = 0; 6509 break; 6510 6511 case eEncodingT2: 6512 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6513 t = Bits32 (opcode, 15, 12); 6514 n = Bits32 (opcode, 19, 16); 6515 m = Bits32 (opcode, 3, 0); 6516 6517 // index = TRUE; add = TRUE; wback = FALSE; 6518 index = true; 6519 add = true; 6520 wback = false; 6521 6522 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6523 shift_t = SRType_LSL; 6524 shift_n = Bits32 (opcode, 5, 4); 6525 6526 // if Rt == '1111' then SEE PLD; 6527 if (t == 15) 6528 return false; // PLD is not implemented yet 6529 6530 // if Rn == '1111' then SEE LDRB (literal); 6531 if (n == 15) 6532 return EmulateLDRBLiteral(opcode, eEncodingT1); 6533 6534 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6535 if ((t == 13) || BadReg (m)) 6536 return false; 6537 break; 6538 6539 case eEncodingA1: 6540 { 6541 // if P == '0' && W == '1' then SEE LDRBT; 6542 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6543 t = Bits32 (opcode, 15, 12); 6544 n = Bits32 (opcode, 19, 16); 6545 m = Bits32 (opcode, 3, 0); 6546 6547 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6548 index = BitIsSet (opcode, 24); 6549 add = BitIsSet (opcode, 23); 6550 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6551 6552 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6553 uint32_t type = Bits32 (opcode, 6, 5); 6554 uint32_t imm5 = Bits32 (opcode, 11, 7); 6555 shift_n = DecodeImmShift (type, imm5, shift_t); 6556 6557 // if t == 15 || m == 15 then UNPREDICTABLE; 6558 if ((t == 15) || (m == 15)) 6559 return false; 6560 6561 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6562 if (wback && ((n == 15) || (n == t))) 6563 return false; 6564 } 6565 break; 6566 6567 default: 6568 return false; 6569 } 6570 6571 addr_t offset_addr; 6572 addr_t address; 6573 6574 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6575 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6576 if (!success) 6577 return false; 6578 6579 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6580 if (!success) 6581 return false; 6582 6583 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6584 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6585 if (!success) 6586 return false; 6587 6588 if (add) 6589 offset_addr = Rn + offset; 6590 else 6591 offset_addr = Rn - offset; 6592 6593 // address = if index then offset_addr else R[n]; 6594 if (index) 6595 address = offset_addr; 6596 else 6597 address = Rn; 6598 6599 // R[t] = ZeroExtend(MemU[address,1],32); 6600 RegisterInfo base_reg; 6601 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6602 6603 EmulateInstruction::Context context; 6604 context.type = eContextRegisterLoad; 6605 context.SetRegisterPlusOffset (base_reg, address - Rn); 6606 6607 uint64_t data = MemURead (context, address, 1, 0, &success); 6608 if (!success) 6609 return false; 6610 6611 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6612 return false; 6613 6614 // if wback then R[n] = offset_addr; 6615 if (wback) 6616 { 6617 context.type = eContextAdjustBaseRegister; 6618 context.SetAddress (offset_addr); 6619 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6620 return false; 6621 } 6622 } 6623 return true; 6624 } 6625 6626 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6627 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6628 // post-indexed, or pre-indexed addressing. 6629 bool 6630 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6631 { 6632 #if 0 6633 if ConditionPassed() then 6634 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6635 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6636 address = if index then offset_addr else R[n]; 6637 data = MemU[address,2]; 6638 if wback then R[n] = offset_addr; 6639 if UnalignedSupport() || address<0> = '0' then 6640 R[t] = ZeroExtend(data, 32); 6641 else // Can only apply before ARMv7 6642 R[t] = bits(32) UNKNOWN; 6643 #endif 6644 6645 6646 bool success = false; 6647 6648 if (ConditionPassed(opcode)) 6649 { 6650 uint32_t t; 6651 uint32_t n; 6652 uint32_t imm32; 6653 bool index; 6654 bool add; 6655 bool wback; 6656 6657 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6658 switch (encoding) 6659 { 6660 case eEncodingT1: 6661 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6662 t = Bits32 (opcode, 2, 0); 6663 n = Bits32 (opcode, 5, 3); 6664 imm32 = Bits32 (opcode, 10, 6) << 1; 6665 6666 // index = TRUE; add = TRUE; wback = FALSE; 6667 index = true; 6668 add = true; 6669 wback = false; 6670 6671 break; 6672 6673 case eEncodingT2: 6674 // if Rt == '1111' then SEE "Unallocated memory hints"; 6675 // if Rn == '1111' then SEE LDRH (literal); 6676 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6677 t = Bits32 (opcode, 15, 12); 6678 n = Bits32 (opcode, 19, 16); 6679 imm32 = Bits32 (opcode, 11, 0); 6680 6681 // index = TRUE; add = TRUE; wback = FALSE; 6682 index = true; 6683 add = true; 6684 wback = false; 6685 6686 // if t == 13 then UNPREDICTABLE; 6687 if (t == 13) 6688 return false; 6689 break; 6690 6691 case eEncodingT3: 6692 // if Rn == '1111' then SEE LDRH (literal); 6693 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6694 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6695 // if P == '0' && W == '0' then UNDEFINED; 6696 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6697 return false; 6698 6699 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6700 t = Bits32 (opcode, 15, 12); 6701 n = Bits32 (opcode, 19, 16); 6702 imm32 = Bits32 (opcode, 7, 0); 6703 6704 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6705 index = BitIsSet (opcode, 10); 6706 add = BitIsSet (opcode, 9); 6707 wback = BitIsSet (opcode, 8); 6708 6709 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6710 if (BadReg (t) || (wback && (n == t))) 6711 return false; 6712 break; 6713 6714 default: 6715 return false; 6716 } 6717 6718 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6719 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6720 if (!success) 6721 return false; 6722 6723 addr_t offset_addr; 6724 addr_t address; 6725 6726 if (add) 6727 offset_addr = Rn + imm32; 6728 else 6729 offset_addr = Rn - imm32; 6730 6731 // address = if index then offset_addr else R[n]; 6732 if (index) 6733 address = offset_addr; 6734 else 6735 address = Rn; 6736 6737 // data = MemU[address,2]; 6738 RegisterInfo base_reg; 6739 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6740 6741 EmulateInstruction::Context context; 6742 context.type = eContextRegisterLoad; 6743 context.SetRegisterPlusOffset (base_reg, address - Rn); 6744 6745 uint64_t data = MemURead (context, address, 2, 0, &success); 6746 if (!success) 6747 return false; 6748 6749 // if wback then R[n] = offset_addr; 6750 if (wback) 6751 { 6752 context.type = eContextAdjustBaseRegister; 6753 context.SetAddress (offset_addr); 6754 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6755 return false; 6756 } 6757 6758 // if UnalignedSupport() || address<0> = '0' then 6759 if (UnalignedSupport () || BitIsClear (address, 0)) 6760 { 6761 // R[t] = ZeroExtend(data, 32); 6762 context.type = eContextRegisterLoad; 6763 context.SetRegisterPlusOffset (base_reg, address - Rn); 6764 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6765 return false; 6766 } 6767 else // Can only apply before ARMv7 6768 { 6769 // R[t] = bits(32) UNKNOWN; 6770 WriteBits32Unknown (t); 6771 } 6772 } 6773 return true; 6774 } 6775 6776 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6777 // zero-extends it to form a 32-bit word, and writes it to a register. 6778 bool 6779 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6780 { 6781 #if 0 6782 if ConditionPassed() then 6783 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6784 base = Align(PC,4); 6785 address = if add then (base + imm32) else (base - imm32); 6786 data = MemU[address,2]; 6787 if UnalignedSupport() || address<0> = '0' then 6788 R[t] = ZeroExtend(data, 32); 6789 else // Can only apply before ARMv7 6790 R[t] = bits(32) UNKNOWN; 6791 #endif 6792 6793 bool success = false; 6794 6795 if (ConditionPassed(opcode)) 6796 { 6797 uint32_t t; 6798 uint32_t imm32; 6799 bool add; 6800 6801 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6802 switch (encoding) 6803 { 6804 case eEncodingT1: 6805 // if Rt == '1111' then SEE "Unallocated memory hints"; 6806 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6807 t = Bits32 (opcode, 15, 12); 6808 imm32 = Bits32 (opcode, 11, 0); 6809 add = BitIsSet (opcode, 23); 6810 6811 // if t == 13 then UNPREDICTABLE; 6812 if (t == 13) 6813 return false; 6814 6815 break; 6816 6817 case eEncodingA1: 6818 { 6819 uint32_t imm4H = Bits32 (opcode, 11, 8); 6820 uint32_t imm4L = Bits32 (opcode, 3, 0); 6821 6822 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6823 t = Bits32 (opcode, 15, 12); 6824 imm32 = (imm4H << 4) | imm4L; 6825 add = BitIsSet (opcode, 23); 6826 6827 // if t == 15 then UNPREDICTABLE; 6828 if (t == 15) 6829 return false; 6830 break; 6831 } 6832 6833 default: 6834 return false; 6835 } 6836 6837 // base = Align(PC,4); 6838 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6839 if (!success) 6840 return false; 6841 6842 addr_t base = AlignPC (pc_value); 6843 addr_t address; 6844 6845 // address = if add then (base + imm32) else (base - imm32); 6846 if (add) 6847 address = base + imm32; 6848 else 6849 address = base - imm32; 6850 6851 // data = MemU[address,2]; 6852 RegisterInfo base_reg; 6853 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6854 6855 EmulateInstruction::Context context; 6856 context.type = eContextRegisterLoad; 6857 context.SetRegisterPlusOffset (base_reg, address - base); 6858 6859 uint64_t data = MemURead (context, address, 2, 0, &success); 6860 if (!success) 6861 return false; 6862 6863 6864 // if UnalignedSupport() || address<0> = '0' then 6865 if (UnalignedSupport () || BitIsClear (address, 0)) 6866 { 6867 // R[t] = ZeroExtend(data, 32); 6868 context.type = eContextRegisterLoad; 6869 context.SetRegisterPlusOffset (base_reg, address - base); 6870 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6871 return false; 6872 6873 } 6874 else // Can only apply before ARMv7 6875 { 6876 // R[t] = bits(32) UNKNOWN; 6877 WriteBits32Unknown (t); 6878 } 6879 } 6880 return true; 6881 } 6882 6883 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6884 // from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6885 // be shifted left by 0, 1, 2, or 3 bits. 6886 bool 6887 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6888 { 6889 #if 0 6890 if ConditionPassed() then 6891 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6892 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6893 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6894 address = if index then offset_addr else R[n]; 6895 data = MemU[address,2]; 6896 if wback then R[n] = offset_addr; 6897 if UnalignedSupport() || address<0> = '0' then 6898 R[t] = ZeroExtend(data, 32); 6899 else // Can only apply before ARMv7 6900 R[t] = bits(32) UNKNOWN; 6901 #endif 6902 6903 bool success = false; 6904 6905 if (ConditionPassed(opcode)) 6906 { 6907 uint32_t t; 6908 uint32_t n; 6909 uint32_t m; 6910 bool index; 6911 bool add; 6912 bool wback; 6913 ARM_ShifterType shift_t; 6914 uint32_t shift_n; 6915 6916 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6917 switch (encoding) 6918 { 6919 case eEncodingT1: 6920 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6921 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6922 t = Bits32 (opcode, 2, 0); 6923 n = Bits32 (opcode, 5, 3); 6924 m = Bits32 (opcode, 8, 6); 6925 6926 // index = TRUE; add = TRUE; wback = FALSE; 6927 index = true; 6928 add = true; 6929 wback = false; 6930 6931 // (shift_t, shift_n) = (SRType_LSL, 0); 6932 shift_t = SRType_LSL; 6933 shift_n = 0; 6934 6935 break; 6936 6937 case eEncodingT2: 6938 // if Rn == '1111' then SEE LDRH (literal); 6939 // if Rt == '1111' then SEE "Unallocated memory hints"; 6940 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6941 t = Bits32 (opcode, 15, 12); 6942 n = Bits32 (opcode, 19, 16); 6943 m = Bits32 (opcode, 3, 0); 6944 6945 // index = TRUE; add = TRUE; wback = FALSE; 6946 index = true; 6947 add = true; 6948 wback = false; 6949 6950 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6951 shift_t = SRType_LSL; 6952 shift_n = Bits32 (opcode, 5, 4); 6953 6954 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6955 if ((t == 13) || BadReg (m)) 6956 return false; 6957 break; 6958 6959 case eEncodingA1: 6960 // if P == '0' && W == '1' then SEE LDRHT; 6961 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6962 t = Bits32 (opcode, 15, 12); 6963 n = Bits32 (opcode, 19, 16); 6964 m = Bits32 (opcode, 3, 0); 6965 6966 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6967 index = BitIsSet (opcode, 24); 6968 add = BitIsSet (opcode, 23); 6969 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6970 6971 // (shift_t, shift_n) = (SRType_LSL, 0); 6972 shift_t = SRType_LSL; 6973 shift_n = 0; 6974 6975 // if t == 15 || m == 15 then UNPREDICTABLE; 6976 if ((t == 15) || (m == 15)) 6977 return false; 6978 6979 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6980 if (wback && ((n == 15) || (n == t))) 6981 return false; 6982 6983 break; 6984 6985 default: 6986 return false; 6987 } 6988 6989 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6990 6991 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6992 if (!success) 6993 return false; 6994 6995 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6996 if (!success) 6997 return false; 6998 6999 addr_t offset_addr; 7000 addr_t address; 7001 7002 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7003 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7004 if (!success) 7005 return false; 7006 7007 if (add) 7008 offset_addr = Rn + offset; 7009 else 7010 offset_addr = Rn - offset; 7011 7012 // address = if index then offset_addr else R[n]; 7013 if (index) 7014 address = offset_addr; 7015 else 7016 address = Rn; 7017 7018 // data = MemU[address,2]; 7019 RegisterInfo base_reg; 7020 RegisterInfo offset_reg; 7021 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7022 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7023 7024 EmulateInstruction::Context context; 7025 context.type = eContextRegisterLoad; 7026 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7027 uint64_t data = MemURead (context, address, 2, 0, &success); 7028 if (!success) 7029 return false; 7030 7031 // if wback then R[n] = offset_addr; 7032 if (wback) 7033 { 7034 context.type = eContextAdjustBaseRegister; 7035 context.SetAddress (offset_addr); 7036 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7037 return false; 7038 } 7039 7040 // if UnalignedSupport() || address<0> = '0' then 7041 if (UnalignedSupport() || BitIsClear (address, 0)) 7042 { 7043 // R[t] = ZeroExtend(data, 32); 7044 context.type = eContextRegisterLoad; 7045 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7046 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7047 return false; 7048 } 7049 else // Can only apply before ARMv7 7050 { 7051 // R[t] = bits(32) UNKNOWN; 7052 WriteBits32Unknown (t); 7053 } 7054 } 7055 return true; 7056 } 7057 7058 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 7059 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 7060 // or pre-indexed addressing. 7061 bool 7062 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 7063 { 7064 #if 0 7065 if ConditionPassed() then 7066 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7067 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7068 address = if index then offset_addr else R[n]; 7069 R[t] = SignExtend(MemU[address,1], 32); 7070 if wback then R[n] = offset_addr; 7071 #endif 7072 7073 bool success = false; 7074 7075 if (ConditionPassed(opcode)) 7076 { 7077 uint32_t t; 7078 uint32_t n; 7079 uint32_t imm32; 7080 bool index; 7081 bool add; 7082 bool wback; 7083 7084 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7085 switch (encoding) 7086 { 7087 case eEncodingT1: 7088 // if Rt == '1111' then SEE PLI; 7089 // if Rn == '1111' then SEE LDRSB (literal); 7090 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7091 t = Bits32 (opcode, 15, 12); 7092 n = Bits32 (opcode, 19, 16); 7093 imm32 = Bits32 (opcode, 11, 0); 7094 7095 // index = TRUE; add = TRUE; wback = FALSE; 7096 index = true; 7097 add = true; 7098 wback = false; 7099 7100 // if t == 13 then UNPREDICTABLE; 7101 if (t == 13) 7102 return false; 7103 7104 break; 7105 7106 case eEncodingT2: 7107 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7108 // if Rn == '1111' then SEE LDRSB (literal); 7109 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7110 // if P == '0' && W == '0' then UNDEFINED; 7111 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7112 return false; 7113 7114 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7115 t = Bits32 (opcode, 15, 12); 7116 n = Bits32 (opcode, 19, 16); 7117 imm32 = Bits32 (opcode, 7, 0); 7118 7119 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7120 index = BitIsSet (opcode, 10); 7121 add = BitIsSet (opcode, 9); 7122 wback = BitIsSet (opcode, 8); 7123 7124 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7125 if (((t == 13) || ((t == 15) 7126 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 7127 || (wback && (n == t))) 7128 return false; 7129 7130 break; 7131 7132 case eEncodingA1: 7133 { 7134 // if Rn == '1111' then SEE LDRSB (literal); 7135 // if P == '0' && W == '1' then SEE LDRSBT; 7136 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7137 t = Bits32 (opcode, 15, 12); 7138 n = Bits32 (opcode, 19, 16); 7139 7140 uint32_t imm4H = Bits32 (opcode, 11, 8); 7141 uint32_t imm4L = Bits32 (opcode, 3, 0); 7142 imm32 = (imm4H << 4) | imm4L; 7143 7144 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7145 index = BitIsSet (opcode, 24); 7146 add = BitIsSet (opcode, 23); 7147 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 7148 7149 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7150 if ((t == 15) || (wback && (n == t))) 7151 return false; 7152 7153 break; 7154 } 7155 7156 default: 7157 return false; 7158 } 7159 7160 uint64_t Rn = ReadCoreReg (n, &success); 7161 if (!success) 7162 return false; 7163 7164 addr_t offset_addr; 7165 addr_t address; 7166 7167 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7168 if (add) 7169 offset_addr = Rn + imm32; 7170 else 7171 offset_addr = Rn - imm32; 7172 7173 // address = if index then offset_addr else R[n]; 7174 if (index) 7175 address = offset_addr; 7176 else 7177 address = Rn; 7178 7179 // R[t] = SignExtend(MemU[address,1], 32); 7180 RegisterInfo base_reg; 7181 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7182 7183 EmulateInstruction::Context context; 7184 context.type = eContextRegisterLoad; 7185 context.SetRegisterPlusOffset (base_reg, address - Rn); 7186 7187 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7188 if (!success) 7189 return false; 7190 7191 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7192 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7193 return false; 7194 7195 // if wback then R[n] = offset_addr; 7196 if (wback) 7197 { 7198 context.type = eContextAdjustBaseRegister; 7199 context.SetAddress (offset_addr); 7200 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7201 return false; 7202 } 7203 } 7204 7205 return true; 7206 } 7207 7208 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7209 // sign-extends it to form a 32-bit word, and writes tit to a register. 7210 bool 7211 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7212 { 7213 #if 0 7214 if ConditionPassed() then 7215 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7216 base = Align(PC,4); 7217 address = if add then (base + imm32) else (base - imm32); 7218 R[t] = SignExtend(MemU[address,1], 32); 7219 #endif 7220 7221 bool success = false; 7222 7223 if (ConditionPassed(opcode)) 7224 { 7225 uint32_t t; 7226 uint32_t imm32; 7227 bool add; 7228 7229 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7230 switch (encoding) 7231 { 7232 case eEncodingT1: 7233 // if Rt == '1111' then SEE PLI; 7234 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7235 t = Bits32 (opcode, 15, 12); 7236 imm32 = Bits32 (opcode, 11, 0); 7237 add = BitIsSet (opcode, 23); 7238 7239 // if t == 13 then UNPREDICTABLE; 7240 if (t == 13) 7241 return false; 7242 7243 break; 7244 7245 case eEncodingA1: 7246 { 7247 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7248 t = Bits32 (opcode, 15, 12); 7249 uint32_t imm4H = Bits32 (opcode, 11, 8); 7250 uint32_t imm4L = Bits32 (opcode, 3, 0); 7251 imm32 = (imm4H << 4) | imm4L; 7252 add = BitIsSet (opcode, 23); 7253 7254 // if t == 15 then UNPREDICTABLE; 7255 if (t == 15) 7256 return false; 7257 7258 break; 7259 } 7260 7261 default: 7262 return false; 7263 } 7264 7265 // base = Align(PC,4); 7266 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7267 if (!success) 7268 return false; 7269 uint64_t base = AlignPC (pc_value); 7270 7271 // address = if add then (base + imm32) else (base - imm32); 7272 addr_t address; 7273 if (add) 7274 address = base + imm32; 7275 else 7276 address = base - imm32; 7277 7278 // R[t] = SignExtend(MemU[address,1], 32); 7279 RegisterInfo base_reg; 7280 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7281 7282 EmulateInstruction::Context context; 7283 context.type = eContextRegisterLoad; 7284 context.SetRegisterPlusOffset (base_reg, address - base); 7285 7286 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7287 if (!success) 7288 return false; 7289 7290 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7291 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7292 return false; 7293 } 7294 return true; 7295 } 7296 7297 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7298 // memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7299 // shifted left by 0, 1, 2, or 3 bits. 7300 bool 7301 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7302 { 7303 #if 0 7304 if ConditionPassed() then 7305 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7306 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7307 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7308 address = if index then offset_addr else R[n]; 7309 R[t] = SignExtend(MemU[address,1], 32); 7310 if wback then R[n] = offset_addr; 7311 #endif 7312 7313 bool success = false; 7314 7315 if (ConditionPassed(opcode)) 7316 { 7317 uint32_t t; 7318 uint32_t n; 7319 uint32_t m; 7320 bool index; 7321 bool add; 7322 bool wback; 7323 ARM_ShifterType shift_t; 7324 uint32_t shift_n; 7325 7326 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7327 switch (encoding) 7328 { 7329 case eEncodingT1: 7330 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7331 t = Bits32 (opcode, 2, 0); 7332 n = Bits32 (opcode, 5, 3); 7333 m = Bits32 (opcode, 8, 6); 7334 7335 // index = TRUE; add = TRUE; wback = FALSE; 7336 index = true; 7337 add = true; 7338 wback = false; 7339 7340 // (shift_t, shift_n) = (SRType_LSL, 0); 7341 shift_t = SRType_LSL; 7342 shift_n = 0; 7343 7344 break; 7345 7346 case eEncodingT2: 7347 // if Rt == '1111' then SEE PLI; 7348 // if Rn == '1111' then SEE LDRSB (literal); 7349 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7350 t = Bits32 (opcode, 15, 12); 7351 n = Bits32 (opcode, 19, 16); 7352 m = Bits32 (opcode, 3, 0); 7353 7354 // index = TRUE; add = TRUE; wback = FALSE; 7355 index = true; 7356 add = true; 7357 wback = false; 7358 7359 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7360 shift_t = SRType_LSL; 7361 shift_n = Bits32 (opcode, 5, 4); 7362 7363 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7364 if ((t == 13) || BadReg (m)) 7365 return false; 7366 break; 7367 7368 case eEncodingA1: 7369 // if P == '0' && W == '1' then SEE LDRSBT; 7370 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7371 t = Bits32 (opcode, 15, 12); 7372 n = Bits32 (opcode, 19, 16); 7373 m = Bits32 (opcode, 3, 0); 7374 7375 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7376 index = BitIsSet (opcode, 24); 7377 add = BitIsSet (opcode, 23); 7378 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7379 7380 // (shift_t, shift_n) = (SRType_LSL, 0); 7381 shift_t = SRType_LSL; 7382 shift_n = 0; 7383 7384 // if t == 15 || m == 15 then UNPREDICTABLE; 7385 if ((t == 15) || (m == 15)) 7386 return false; 7387 7388 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7389 if (wback && ((n == 15) || (n == t))) 7390 return false; 7391 break; 7392 7393 default: 7394 return false; 7395 } 7396 7397 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7398 if (!success) 7399 return false; 7400 7401 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7402 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7403 if (!success) 7404 return false; 7405 7406 addr_t offset_addr; 7407 addr_t address; 7408 7409 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7410 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7411 if (!success) 7412 return false; 7413 7414 if (add) 7415 offset_addr = Rn + offset; 7416 else 7417 offset_addr = Rn - offset; 7418 7419 // address = if index then offset_addr else R[n]; 7420 if (index) 7421 address = offset_addr; 7422 else 7423 address = Rn; 7424 7425 // R[t] = SignExtend(MemU[address,1], 32); 7426 RegisterInfo base_reg; 7427 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7428 RegisterInfo offset_reg; 7429 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7430 7431 EmulateInstruction::Context context; 7432 context.type = eContextRegisterLoad; 7433 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7434 7435 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7436 if (!success) 7437 return false; 7438 7439 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7440 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7441 return false; 7442 7443 // if wback then R[n] = offset_addr; 7444 if (wback) 7445 { 7446 context.type = eContextAdjustBaseRegister; 7447 context.SetAddress (offset_addr); 7448 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7449 return false; 7450 } 7451 } 7452 return true; 7453 } 7454 7455 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7456 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7457 // pre-indexed addressing. 7458 bool 7459 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7460 { 7461 #if 0 7462 if ConditionPassed() then 7463 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7464 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7465 address = if index then offset_addr else R[n]; 7466 data = MemU[address,2]; 7467 if wback then R[n] = offset_addr; 7468 if UnalignedSupport() || address<0> = '0' then 7469 R[t] = SignExtend(data, 32); 7470 else // Can only apply before ARMv7 7471 R[t] = bits(32) UNKNOWN; 7472 #endif 7473 7474 bool success = false; 7475 7476 if (ConditionPassed(opcode)) 7477 { 7478 uint32_t t; 7479 uint32_t n; 7480 uint32_t imm32; 7481 bool index; 7482 bool add; 7483 bool wback; 7484 7485 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7486 switch (encoding) 7487 { 7488 case eEncodingT1: 7489 // if Rn == '1111' then SEE LDRSH (literal); 7490 // if Rt == '1111' then SEE "Unallocated memory hints"; 7491 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7492 t = Bits32 (opcode, 15, 12); 7493 n = Bits32 (opcode, 19, 16); 7494 imm32 = Bits32 (opcode, 11, 0); 7495 7496 // index = TRUE; add = TRUE; wback = FALSE; 7497 index = true; 7498 add = true; 7499 wback = false; 7500 7501 // if t == 13 then UNPREDICTABLE; 7502 if (t == 13) 7503 return false; 7504 7505 break; 7506 7507 case eEncodingT2: 7508 // if Rn == '1111' then SEE LDRSH (literal); 7509 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7510 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7511 // if P == '0' && W == '0' then UNDEFINED; 7512 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7513 return false; 7514 7515 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7516 t = Bits32 (opcode, 15, 12); 7517 n = Bits32 (opcode, 19, 16); 7518 imm32 = Bits32 (opcode, 7, 0); 7519 7520 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7521 index = BitIsSet (opcode, 10); 7522 add = BitIsSet (opcode, 9); 7523 wback = BitIsSet (opcode, 8); 7524 7525 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7526 if (BadReg (t) || (wback && (n == t))) 7527 return false; 7528 7529 break; 7530 7531 case eEncodingA1: 7532 { 7533 // if Rn == '1111' then SEE LDRSH (literal); 7534 // if P == '0' && W == '1' then SEE LDRSHT; 7535 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7536 t = Bits32 (opcode, 15, 12); 7537 n = Bits32 (opcode, 19, 16); 7538 uint32_t imm4H = Bits32 (opcode, 11,8); 7539 uint32_t imm4L = Bits32 (opcode, 3, 0); 7540 imm32 = (imm4H << 4) | imm4L; 7541 7542 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7543 index = BitIsSet (opcode, 24); 7544 add = BitIsSet (opcode, 23); 7545 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7546 7547 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7548 if ((t == 15) || (wback && (n == t))) 7549 return false; 7550 7551 break; 7552 } 7553 7554 default: 7555 return false; 7556 } 7557 7558 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7559 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7560 if (!success) 7561 return false; 7562 7563 addr_t offset_addr; 7564 if (add) 7565 offset_addr = Rn + imm32; 7566 else 7567 offset_addr = Rn - imm32; 7568 7569 // address = if index then offset_addr else R[n]; 7570 addr_t address; 7571 if (index) 7572 address = offset_addr; 7573 else 7574 address = Rn; 7575 7576 // data = MemU[address,2]; 7577 RegisterInfo base_reg; 7578 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7579 7580 EmulateInstruction::Context context; 7581 context.type = eContextRegisterLoad; 7582 context.SetRegisterPlusOffset (base_reg, address - Rn); 7583 7584 uint64_t data = MemURead (context, address, 2, 0, &success); 7585 if (!success) 7586 return false; 7587 7588 // if wback then R[n] = offset_addr; 7589 if (wback) 7590 { 7591 context.type = eContextAdjustBaseRegister; 7592 context.SetAddress (offset_addr); 7593 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7594 return false; 7595 } 7596 7597 // if UnalignedSupport() || address<0> = '0' then 7598 if (UnalignedSupport() || BitIsClear (address, 0)) 7599 { 7600 // R[t] = SignExtend(data, 32); 7601 int64_t signed_data = llvm::SignExtend64<16>(data); 7602 context.type = eContextRegisterLoad; 7603 context.SetRegisterPlusOffset (base_reg, address - Rn); 7604 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7605 return false; 7606 } 7607 else // Can only apply before ARMv7 7608 { 7609 // R[t] = bits(32) UNKNOWN; 7610 WriteBits32Unknown (t); 7611 } 7612 } 7613 return true; 7614 } 7615 7616 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7617 // sign-extends it to from a 32-bit word, and writes it to a register. 7618 bool 7619 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7620 { 7621 #if 0 7622 if ConditionPassed() then 7623 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7624 base = Align(PC,4); 7625 address = if add then (base + imm32) else (base - imm32); 7626 data = MemU[address,2]; 7627 if UnalignedSupport() || address<0> = '0' then 7628 R[t] = SignExtend(data, 32); 7629 else // Can only apply before ARMv7 7630 R[t] = bits(32) UNKNOWN; 7631 #endif 7632 7633 bool success = false; 7634 7635 if (ConditionPassed(opcode)) 7636 { 7637 uint32_t t; 7638 uint32_t imm32; 7639 bool add; 7640 7641 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7642 switch (encoding) 7643 { 7644 case eEncodingT1: 7645 // if Rt == '1111' then SEE "Unallocated memory hints"; 7646 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7647 t = Bits32 (opcode, 15, 12); 7648 imm32 = Bits32 (opcode, 11, 0); 7649 add = BitIsSet (opcode, 23); 7650 7651 // if t == 13 then UNPREDICTABLE; 7652 if (t == 13) 7653 return false; 7654 7655 break; 7656 7657 case eEncodingA1: 7658 { 7659 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7660 t = Bits32 (opcode, 15, 12); 7661 uint32_t imm4H = Bits32 (opcode, 11, 8); 7662 uint32_t imm4L = Bits32 (opcode, 3, 0); 7663 imm32 = (imm4H << 4) | imm4L; 7664 add = BitIsSet (opcode, 23); 7665 7666 // if t == 15 then UNPREDICTABLE; 7667 if (t == 15) 7668 return false; 7669 7670 break; 7671 } 7672 default: 7673 return false; 7674 } 7675 7676 // base = Align(PC,4); 7677 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7678 if (!success) 7679 return false; 7680 7681 uint64_t base = AlignPC (pc_value); 7682 7683 addr_t address; 7684 // address = if add then (base + imm32) else (base - imm32); 7685 if (add) 7686 address = base + imm32; 7687 else 7688 address = base - imm32; 7689 7690 // data = MemU[address,2]; 7691 RegisterInfo base_reg; 7692 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7693 7694 EmulateInstruction::Context context; 7695 context.type = eContextRegisterLoad; 7696 context.SetRegisterPlusOffset (base_reg, imm32); 7697 7698 uint64_t data = MemURead (context, address, 2, 0, &success); 7699 if (!success) 7700 return false; 7701 7702 // if UnalignedSupport() || address<0> = '0' then 7703 if (UnalignedSupport() || BitIsClear (address, 0)) 7704 { 7705 // R[t] = SignExtend(data, 32); 7706 int64_t signed_data = llvm::SignExtend64<16>(data); 7707 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7708 return false; 7709 } 7710 else // Can only apply before ARMv7 7711 { 7712 // R[t] = bits(32) UNKNOWN; 7713 WriteBits32Unknown (t); 7714 } 7715 } 7716 return true; 7717 } 7718 7719 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7720 // from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7721 // shifted left by 0, 1, 2, or 3 bits. 7722 bool 7723 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7724 { 7725 #if 0 7726 if ConditionPassed() then 7727 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7728 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7729 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7730 address = if index then offset_addr else R[n]; 7731 data = MemU[address,2]; 7732 if wback then R[n] = offset_addr; 7733 if UnalignedSupport() || address<0> = '0' then 7734 R[t] = SignExtend(data, 32); 7735 else // Can only apply before ARMv7 7736 R[t] = bits(32) UNKNOWN; 7737 #endif 7738 7739 bool success = false; 7740 7741 if (ConditionPassed(opcode)) 7742 { 7743 uint32_t t; 7744 uint32_t n; 7745 uint32_t m; 7746 bool index; 7747 bool add; 7748 bool wback; 7749 ARM_ShifterType shift_t; 7750 uint32_t shift_n; 7751 7752 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7753 switch (encoding) 7754 { 7755 case eEncodingT1: 7756 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7757 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7758 t = Bits32 (opcode, 2, 0); 7759 n = Bits32 (opcode, 5, 3); 7760 m = Bits32 (opcode, 8, 6); 7761 7762 // index = TRUE; add = TRUE; wback = FALSE; 7763 index = true; 7764 add = true; 7765 wback = false; 7766 7767 // (shift_t, shift_n) = (SRType_LSL, 0); 7768 shift_t = SRType_LSL; 7769 shift_n = 0; 7770 7771 break; 7772 7773 case eEncodingT2: 7774 // if Rn == '1111' then SEE LDRSH (literal); 7775 // if Rt == '1111' then SEE "Unallocated memory hints"; 7776 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7777 t = Bits32 (opcode, 15, 12); 7778 n = Bits32 (opcode, 19, 16); 7779 m = Bits32 (opcode, 3, 0); 7780 7781 // index = TRUE; add = TRUE; wback = FALSE; 7782 index = true; 7783 add = true; 7784 wback = false; 7785 7786 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7787 shift_t = SRType_LSL; 7788 shift_n = Bits32 (opcode, 5, 4); 7789 7790 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7791 if ((t == 13) || BadReg (m)) 7792 return false; 7793 7794 break; 7795 7796 case eEncodingA1: 7797 // if P == '0' && W == '1' then SEE LDRSHT; 7798 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7799 t = Bits32 (opcode, 15, 12); 7800 n = Bits32 (opcode, 19, 16); 7801 m = Bits32 (opcode, 3, 0); 7802 7803 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7804 index = BitIsSet (opcode, 24); 7805 add = BitIsSet (opcode, 23); 7806 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7807 7808 // (shift_t, shift_n) = (SRType_LSL, 0); 7809 shift_t = SRType_LSL; 7810 shift_n = 0; 7811 7812 // if t == 15 || m == 15 then UNPREDICTABLE; 7813 if ((t == 15) || (m == 15)) 7814 return false; 7815 7816 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7817 if (wback && ((n == 15) || (n == t))) 7818 return false; 7819 7820 break; 7821 7822 default: 7823 return false; 7824 } 7825 7826 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7827 if (!success) 7828 return false; 7829 7830 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7831 if (!success) 7832 return false; 7833 7834 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7835 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7836 if (!success) 7837 return false; 7838 7839 addr_t offset_addr; 7840 addr_t address; 7841 7842 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7843 if (add) 7844 offset_addr = Rn + offset; 7845 else 7846 offset_addr = Rn - offset; 7847 7848 // address = if index then offset_addr else R[n]; 7849 if (index) 7850 address = offset_addr; 7851 else 7852 address = Rn; 7853 7854 // data = MemU[address,2]; 7855 RegisterInfo base_reg; 7856 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7857 7858 RegisterInfo offset_reg; 7859 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7860 7861 EmulateInstruction::Context context; 7862 context.type = eContextRegisterLoad; 7863 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7864 7865 uint64_t data = MemURead (context, address, 2, 0, &success); 7866 if (!success) 7867 return false; 7868 7869 // if wback then R[n] = offset_addr; 7870 if (wback) 7871 { 7872 context.type = eContextAdjustBaseRegister; 7873 context.SetAddress (offset_addr); 7874 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7875 return false; 7876 } 7877 7878 // if UnalignedSupport() || address<0> = '0' then 7879 if (UnalignedSupport() || BitIsClear (address, 0)) 7880 { 7881 // R[t] = SignExtend(data, 32); 7882 context.type = eContextRegisterLoad; 7883 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7884 7885 int64_t signed_data = llvm::SignExtend64<16>(data); 7886 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7887 return false; 7888 } 7889 else // Can only apply before ARMv7 7890 { 7891 // R[t] = bits(32) UNKNOWN; 7892 WriteBits32Unknown (t); 7893 } 7894 } 7895 return true; 7896 } 7897 7898 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7899 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7900 bool 7901 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7902 { 7903 #if 0 7904 if ConditionPassed() then 7905 EncodingSpecificOperations(); 7906 rotated = ROR(R[m], rotation); 7907 R[d] = SignExtend(rotated<7:0>, 32); 7908 #endif 7909 7910 bool success = false; 7911 7912 if (ConditionPassed(opcode)) 7913 { 7914 uint32_t d; 7915 uint32_t m; 7916 uint32_t rotation; 7917 7918 // EncodingSpecificOperations(); 7919 switch (encoding) 7920 { 7921 case eEncodingT1: 7922 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7923 d = Bits32 (opcode, 2, 0); 7924 m = Bits32 (opcode, 5, 3); 7925 rotation = 0; 7926 7927 break; 7928 7929 case eEncodingT2: 7930 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7931 d = Bits32 (opcode, 11, 8); 7932 m = Bits32 (opcode, 3, 0); 7933 rotation = Bits32 (opcode, 5, 4) << 3; 7934 7935 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7936 if (BadReg (d) || BadReg (m)) 7937 return false; 7938 7939 break; 7940 7941 case eEncodingA1: 7942 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7943 d = Bits32 (opcode, 15, 12); 7944 m = Bits32 (opcode, 3, 0); 7945 rotation = Bits32 (opcode, 11, 10) << 3; 7946 7947 // if d == 15 || m == 15 then UNPREDICTABLE; 7948 if ((d == 15) || (m == 15)) 7949 return false; 7950 7951 break; 7952 7953 default: 7954 return false; 7955 } 7956 7957 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7958 if (!success) 7959 return false; 7960 7961 // rotated = ROR(R[m], rotation); 7962 uint64_t rotated = ROR (Rm, rotation, &success); 7963 if (!success) 7964 return false; 7965 7966 // R[d] = SignExtend(rotated<7:0>, 32); 7967 int64_t data = llvm::SignExtend64<8>(rotated); 7968 7969 RegisterInfo source_reg; 7970 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7971 7972 EmulateInstruction::Context context; 7973 context.type = eContextRegisterLoad; 7974 context.SetRegister (source_reg); 7975 7976 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7977 return false; 7978 } 7979 return true; 7980 } 7981 7982 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7983 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7984 bool 7985 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7986 { 7987 #if 0 7988 if ConditionPassed() then 7989 EncodingSpecificOperations(); 7990 rotated = ROR(R[m], rotation); 7991 R[d] = SignExtend(rotated<15:0>, 32); 7992 #endif 7993 7994 bool success = false; 7995 7996 if (ConditionPassed(opcode)) 7997 { 7998 uint32_t d; 7999 uint32_t m; 8000 uint32_t rotation; 8001 8002 // EncodingSpecificOperations(); 8003 switch (encoding) 8004 { 8005 case eEncodingT1: 8006 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8007 d = Bits32 (opcode, 2, 0); 8008 m = Bits32 (opcode, 5, 3); 8009 rotation = 0; 8010 8011 break; 8012 8013 case eEncodingT2: 8014 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8015 d = Bits32 (opcode, 11, 8); 8016 m = Bits32 (opcode, 3, 0); 8017 rotation = Bits32 (opcode, 5, 4) << 3; 8018 8019 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8020 if (BadReg (d) || BadReg (m)) 8021 return false; 8022 8023 break; 8024 8025 case eEncodingA1: 8026 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8027 d = Bits32 (opcode, 15, 12); 8028 m = Bits32 (opcode, 3, 0); 8029 rotation = Bits32 (opcode, 11, 10) << 3; 8030 8031 // if d == 15 || m == 15 then UNPREDICTABLE; 8032 if ((d == 15) || (m == 15)) 8033 return false; 8034 8035 break; 8036 8037 default: 8038 return false; 8039 } 8040 8041 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8042 if (!success) 8043 return false; 8044 8045 // rotated = ROR(R[m], rotation); 8046 uint64_t rotated = ROR (Rm, rotation, &success); 8047 if (!success) 8048 return false; 8049 8050 // R[d] = SignExtend(rotated<15:0>, 32); 8051 RegisterInfo source_reg; 8052 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8053 8054 EmulateInstruction::Context context; 8055 context.type = eContextRegisterLoad; 8056 context.SetRegister (source_reg); 8057 8058 int64_t data = llvm::SignExtend64<16> (rotated); 8059 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 8060 return false; 8061 } 8062 8063 return true; 8064 } 8065 8066 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 8067 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 8068 bool 8069 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 8070 { 8071 #if 0 8072 if ConditionPassed() then 8073 EncodingSpecificOperations(); 8074 rotated = ROR(R[m], rotation); 8075 R[d] = ZeroExtend(rotated<7:0>, 32); 8076 #endif 8077 8078 bool success = false; 8079 8080 if (ConditionPassed(opcode)) 8081 { 8082 uint32_t d; 8083 uint32_t m; 8084 uint32_t rotation; 8085 8086 // EncodingSpecificOperations(); 8087 switch (encoding) 8088 { 8089 case eEncodingT1: 8090 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8091 d = Bits32 (opcode, 2, 0); 8092 m = Bits32 (opcode, 5, 3); 8093 rotation = 0; 8094 8095 break; 8096 8097 case eEncodingT2: 8098 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8099 d = Bits32 (opcode, 11, 8); 8100 m = Bits32 (opcode, 3, 0); 8101 rotation = Bits32 (opcode, 5, 4) << 3; 8102 8103 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8104 if (BadReg (d) || BadReg (m)) 8105 return false; 8106 8107 break; 8108 8109 case eEncodingA1: 8110 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8111 d = Bits32 (opcode, 15, 12); 8112 m = Bits32 (opcode, 3, 0); 8113 rotation = Bits32 (opcode, 11, 10) << 3; 8114 8115 // if d == 15 || m == 15 then UNPREDICTABLE; 8116 if ((d == 15) || (m == 15)) 8117 return false; 8118 8119 break; 8120 8121 default: 8122 return false; 8123 } 8124 8125 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8126 if (!success) 8127 return false; 8128 8129 // rotated = ROR(R[m], rotation); 8130 uint64_t rotated = ROR (Rm, rotation, &success); 8131 if (!success) 8132 return false; 8133 8134 // R[d] = ZeroExtend(rotated<7:0>, 32); 8135 RegisterInfo source_reg; 8136 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8137 8138 EmulateInstruction::Context context; 8139 context.type = eContextRegisterLoad; 8140 context.SetRegister (source_reg); 8141 8142 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 8143 return false; 8144 } 8145 return true; 8146 } 8147 8148 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 8149 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 8150 bool 8151 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 8152 { 8153 #if 0 8154 if ConditionPassed() then 8155 EncodingSpecificOperations(); 8156 rotated = ROR(R[m], rotation); 8157 R[d] = ZeroExtend(rotated<15:0>, 32); 8158 #endif 8159 8160 bool success = false; 8161 8162 if (ConditionPassed(opcode)) 8163 { 8164 uint32_t d; 8165 uint32_t m; 8166 uint32_t rotation; 8167 8168 switch (encoding) 8169 { 8170 case eEncodingT1: 8171 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8172 d = Bits32 (opcode, 2, 0); 8173 m = Bits32 (opcode, 5, 3); 8174 rotation = 0; 8175 8176 break; 8177 8178 case eEncodingT2: 8179 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8180 d = Bits32 (opcode, 11, 8); 8181 m = Bits32 (opcode, 3, 0); 8182 rotation = Bits32 (opcode, 5, 4) << 3; 8183 8184 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8185 if (BadReg (d) || BadReg (m)) 8186 return false; 8187 8188 break; 8189 8190 case eEncodingA1: 8191 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8192 d = Bits32 (opcode, 15, 12); 8193 m = Bits32 (opcode, 3, 0); 8194 rotation = Bits32 (opcode, 11, 10) << 3; 8195 8196 // if d == 15 || m == 15 then UNPREDICTABLE; 8197 if ((d == 15) || (m == 15)) 8198 return false; 8199 8200 break; 8201 8202 default: 8203 return false; 8204 } 8205 8206 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8207 if (!success) 8208 return false; 8209 8210 // rotated = ROR(R[m], rotation); 8211 uint64_t rotated = ROR (Rm, rotation, &success); 8212 if (!success) 8213 return false; 8214 8215 // R[d] = ZeroExtend(rotated<15:0>, 32); 8216 RegisterInfo source_reg; 8217 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8218 8219 EmulateInstruction::Context context; 8220 context.type = eContextRegisterLoad; 8221 context.SetRegister (source_reg); 8222 8223 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8224 return false; 8225 } 8226 return true; 8227 } 8228 8229 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8230 // word respectively. 8231 bool 8232 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8233 { 8234 #if 0 8235 if ConditionPassed() then 8236 EncodingSpecificOperations(); 8237 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8238 UNPREDICTABLE; 8239 else 8240 address = if increment then R[n] else R[n]-8; 8241 if wordhigher then address = address+4; 8242 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8243 BranchWritePC(MemA[address,4]); 8244 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8245 #endif 8246 8247 bool success = false; 8248 8249 if (ConditionPassed(opcode)) 8250 { 8251 uint32_t n; 8252 bool wback; 8253 bool increment; 8254 bool wordhigher; 8255 8256 // EncodingSpecificOperations(); 8257 switch (encoding) 8258 { 8259 case eEncodingT1: 8260 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8261 n = Bits32 (opcode, 19, 16); 8262 wback = BitIsSet (opcode, 21); 8263 increment = false; 8264 wordhigher = false; 8265 8266 // if n == 15 then UNPREDICTABLE; 8267 if (n == 15) 8268 return false; 8269 8270 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8271 if (InITBlock() && !LastInITBlock()) 8272 return false; 8273 8274 break; 8275 8276 case eEncodingT2: 8277 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8278 n = Bits32 (opcode, 19, 16); 8279 wback = BitIsSet (opcode, 21); 8280 increment = true; 8281 wordhigher = false; 8282 8283 // if n == 15 then UNPREDICTABLE; 8284 if (n == 15) 8285 return false; 8286 8287 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8288 if (InITBlock() && !LastInITBlock()) 8289 return false; 8290 8291 break; 8292 8293 case eEncodingA1: 8294 // n = UInt(Rn); 8295 n = Bits32 (opcode, 19, 16); 8296 8297 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8298 wback = BitIsSet (opcode, 21); 8299 increment = BitIsSet (opcode, 23); 8300 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8301 8302 // if n == 15 then UNPREDICTABLE; 8303 if (n == 15) 8304 return false; 8305 8306 break; 8307 8308 default: 8309 return false; 8310 } 8311 8312 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8313 if (!CurrentModeIsPrivileged ()) 8314 // UNPREDICTABLE; 8315 return false; 8316 else 8317 { 8318 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8319 if (!success) 8320 return false; 8321 8322 addr_t address; 8323 // address = if increment then R[n] else R[n]-8; 8324 if (increment) 8325 address = Rn; 8326 else 8327 address = Rn - 8; 8328 8329 // if wordhigher then address = address+4; 8330 if (wordhigher) 8331 address = address + 4; 8332 8333 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8334 RegisterInfo base_reg; 8335 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8336 8337 EmulateInstruction::Context context; 8338 context.type = eContextReturnFromException; 8339 context.SetRegisterPlusOffset (base_reg, address - Rn); 8340 8341 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8342 if (!success) 8343 return false; 8344 8345 CPSRWriteByInstr (data, 15, true); 8346 8347 // BranchWritePC(MemA[address,4]); 8348 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8349 if (!success) 8350 return false; 8351 8352 BranchWritePC (context, data2); 8353 8354 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8355 if (wback) 8356 { 8357 context.type = eContextAdjustBaseRegister; 8358 if (increment) 8359 { 8360 context.SetOffset (8); 8361 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8362 return false; 8363 } 8364 else 8365 { 8366 context.SetOffset (-8); 8367 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8368 return false; 8369 } 8370 } // if wback 8371 } 8372 } // if ConditionPassed() 8373 return true; 8374 } 8375 8376 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8377 // and writes the result to the destination register. It can optionally update the condition flags based on 8378 // the result. 8379 bool 8380 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8381 { 8382 #if 0 8383 // ARM pseudo code... 8384 if ConditionPassed() then 8385 EncodingSpecificOperations(); 8386 result = R[n] EOR imm32; 8387 if d == 15 then // Can only occur for ARM encoding 8388 ALUWritePC(result); // setflags is always FALSE here 8389 else 8390 R[d] = result; 8391 if setflags then 8392 APSR.N = result<31>; 8393 APSR.Z = IsZeroBit(result); 8394 APSR.C = carry; 8395 // APSR.V unchanged 8396 #endif 8397 8398 bool success = false; 8399 8400 if (ConditionPassed(opcode)) 8401 { 8402 uint32_t Rd, Rn; 8403 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8404 bool setflags; 8405 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8406 switch (encoding) 8407 { 8408 case eEncodingT1: 8409 Rd = Bits32(opcode, 11, 8); 8410 Rn = Bits32(opcode, 19, 16); 8411 setflags = BitIsSet(opcode, 20); 8412 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8413 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8414 if (Rd == 15 && setflags) 8415 return EmulateTEQImm (opcode, eEncodingT1); 8416 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8417 return false; 8418 break; 8419 case eEncodingA1: 8420 Rd = Bits32(opcode, 15, 12); 8421 Rn = Bits32(opcode, 19, 16); 8422 setflags = BitIsSet(opcode, 20); 8423 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8424 8425 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8426 if (Rd == 15 && setflags) 8427 return EmulateSUBSPcLrEtc (opcode, encoding); 8428 break; 8429 default: 8430 return false; 8431 } 8432 8433 // Read the first operand. 8434 uint32_t val1 = ReadCoreReg(Rn, &success); 8435 if (!success) 8436 return false; 8437 8438 uint32_t result = val1 ^ imm32; 8439 8440 EmulateInstruction::Context context; 8441 context.type = EmulateInstruction::eContextImmediate; 8442 context.SetNoArgs (); 8443 8444 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8445 return false; 8446 } 8447 return true; 8448 } 8449 8450 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8451 // optionally-shifted register value, and writes the result to the destination register. 8452 // It can optionally update the condition flags based on the result. 8453 bool 8454 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8455 { 8456 #if 0 8457 // ARM pseudo code... 8458 if ConditionPassed() then 8459 EncodingSpecificOperations(); 8460 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8461 result = R[n] EOR shifted; 8462 if d == 15 then // Can only occur for ARM encoding 8463 ALUWritePC(result); // setflags is always FALSE here 8464 else 8465 R[d] = result; 8466 if setflags then 8467 APSR.N = result<31>; 8468 APSR.Z = IsZeroBit(result); 8469 APSR.C = carry; 8470 // APSR.V unchanged 8471 #endif 8472 8473 bool success = false; 8474 8475 if (ConditionPassed(opcode)) 8476 { 8477 uint32_t Rd, Rn, Rm; 8478 ARM_ShifterType shift_t; 8479 uint32_t shift_n; // the shift applied to the value read from Rm 8480 bool setflags; 8481 uint32_t carry; 8482 switch (encoding) 8483 { 8484 case eEncodingT1: 8485 Rd = Rn = Bits32(opcode, 2, 0); 8486 Rm = Bits32(opcode, 5, 3); 8487 setflags = !InITBlock(); 8488 shift_t = SRType_LSL; 8489 shift_n = 0; 8490 break; 8491 case eEncodingT2: 8492 Rd = Bits32(opcode, 11, 8); 8493 Rn = Bits32(opcode, 19, 16); 8494 Rm = Bits32(opcode, 3, 0); 8495 setflags = BitIsSet(opcode, 20); 8496 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8497 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8498 if (Rd == 15 && setflags) 8499 return EmulateTEQReg (opcode, eEncodingT1); 8500 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8501 return false; 8502 break; 8503 case eEncodingA1: 8504 Rd = Bits32(opcode, 15, 12); 8505 Rn = Bits32(opcode, 19, 16); 8506 Rm = Bits32(opcode, 3, 0); 8507 setflags = BitIsSet(opcode, 20); 8508 shift_n = DecodeImmShiftARM(opcode, shift_t); 8509 8510 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8511 if (Rd == 15 && setflags) 8512 return EmulateSUBSPcLrEtc (opcode, encoding); 8513 break; 8514 default: 8515 return false; 8516 } 8517 8518 // Read the first operand. 8519 uint32_t val1 = ReadCoreReg(Rn, &success); 8520 if (!success) 8521 return false; 8522 8523 // Read the second operand. 8524 uint32_t val2 = ReadCoreReg(Rm, &success); 8525 if (!success) 8526 return false; 8527 8528 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8529 if (!success) 8530 return false; 8531 uint32_t result = val1 ^ shifted; 8532 8533 EmulateInstruction::Context context; 8534 context.type = EmulateInstruction::eContextImmediate; 8535 context.SetNoArgs (); 8536 8537 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8538 return false; 8539 } 8540 return true; 8541 } 8542 8543 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8544 // writes the result to the destination register. It can optionally update the condition flags based 8545 // on the result. 8546 bool 8547 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8548 { 8549 #if 0 8550 // ARM pseudo code... 8551 if ConditionPassed() then 8552 EncodingSpecificOperations(); 8553 result = R[n] OR imm32; 8554 if d == 15 then // Can only occur for ARM encoding 8555 ALUWritePC(result); // setflags is always FALSE here 8556 else 8557 R[d] = result; 8558 if setflags then 8559 APSR.N = result<31>; 8560 APSR.Z = IsZeroBit(result); 8561 APSR.C = carry; 8562 // APSR.V unchanged 8563 #endif 8564 8565 bool success = false; 8566 8567 if (ConditionPassed(opcode)) 8568 { 8569 uint32_t Rd, Rn; 8570 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8571 bool setflags; 8572 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8573 switch (encoding) 8574 { 8575 case eEncodingT1: 8576 Rd = Bits32(opcode, 11, 8); 8577 Rn = Bits32(opcode, 19, 16); 8578 setflags = BitIsSet(opcode, 20); 8579 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8580 // if Rn == '1111' then SEE MOV (immediate); 8581 if (Rn == 15) 8582 return EmulateMOVRdImm (opcode, eEncodingT2); 8583 if (BadReg(Rd) || Rn == 13) 8584 return false; 8585 break; 8586 case eEncodingA1: 8587 Rd = Bits32(opcode, 15, 12); 8588 Rn = Bits32(opcode, 19, 16); 8589 setflags = BitIsSet(opcode, 20); 8590 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8591 8592 if (Rd == 15 && setflags) 8593 return EmulateSUBSPcLrEtc (opcode, encoding); 8594 break; 8595 default: 8596 return false; 8597 } 8598 8599 // Read the first operand. 8600 uint32_t val1 = ReadCoreReg(Rn, &success); 8601 if (!success) 8602 return false; 8603 8604 uint32_t result = val1 | imm32; 8605 8606 EmulateInstruction::Context context; 8607 context.type = EmulateInstruction::eContextImmediate; 8608 context.SetNoArgs (); 8609 8610 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8611 return false; 8612 } 8613 return true; 8614 } 8615 8616 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8617 // value, and writes the result to the destination register. It can optionally update the condition flags based 8618 // on the result. 8619 bool 8620 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8621 { 8622 #if 0 8623 // ARM pseudo code... 8624 if ConditionPassed() then 8625 EncodingSpecificOperations(); 8626 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8627 result = R[n] OR shifted; 8628 if d == 15 then // Can only occur for ARM encoding 8629 ALUWritePC(result); // setflags is always FALSE here 8630 else 8631 R[d] = result; 8632 if setflags then 8633 APSR.N = result<31>; 8634 APSR.Z = IsZeroBit(result); 8635 APSR.C = carry; 8636 // APSR.V unchanged 8637 #endif 8638 8639 bool success = false; 8640 8641 if (ConditionPassed(opcode)) 8642 { 8643 uint32_t Rd, Rn, Rm; 8644 ARM_ShifterType shift_t; 8645 uint32_t shift_n; // the shift applied to the value read from Rm 8646 bool setflags; 8647 uint32_t carry; 8648 switch (encoding) 8649 { 8650 case eEncodingT1: 8651 Rd = Rn = Bits32(opcode, 2, 0); 8652 Rm = Bits32(opcode, 5, 3); 8653 setflags = !InITBlock(); 8654 shift_t = SRType_LSL; 8655 shift_n = 0; 8656 break; 8657 case eEncodingT2: 8658 Rd = Bits32(opcode, 11, 8); 8659 Rn = Bits32(opcode, 19, 16); 8660 Rm = Bits32(opcode, 3, 0); 8661 setflags = BitIsSet(opcode, 20); 8662 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8663 // if Rn == '1111' then SEE MOV (register); 8664 if (Rn == 15) 8665 return EmulateMOVRdRm (opcode, eEncodingT3); 8666 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8667 return false; 8668 break; 8669 case eEncodingA1: 8670 Rd = Bits32(opcode, 15, 12); 8671 Rn = Bits32(opcode, 19, 16); 8672 Rm = Bits32(opcode, 3, 0); 8673 setflags = BitIsSet(opcode, 20); 8674 shift_n = DecodeImmShiftARM(opcode, shift_t); 8675 8676 if (Rd == 15 && setflags) 8677 return EmulateSUBSPcLrEtc (opcode, encoding); 8678 break; 8679 default: 8680 return false; 8681 } 8682 8683 // Read the first operand. 8684 uint32_t val1 = ReadCoreReg(Rn, &success); 8685 if (!success) 8686 return false; 8687 8688 // Read the second operand. 8689 uint32_t val2 = ReadCoreReg(Rm, &success); 8690 if (!success) 8691 return false; 8692 8693 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8694 if (!success) 8695 return false; 8696 uint32_t result = val1 | shifted; 8697 8698 EmulateInstruction::Context context; 8699 context.type = EmulateInstruction::eContextImmediate; 8700 context.SetNoArgs (); 8701 8702 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8703 return false; 8704 } 8705 return true; 8706 } 8707 8708 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8709 // the destination register. It can optionally update the condition flags based on the result. 8710 bool 8711 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8712 { 8713 #if 0 8714 // ARM pseudo code... 8715 if ConditionPassed() then 8716 EncodingSpecificOperations(); 8717 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8718 if d == 15 then // Can only occur for ARM encoding 8719 ALUWritePC(result); // setflags is always FALSE here 8720 else 8721 R[d] = result; 8722 if setflags then 8723 APSR.N = result<31>; 8724 APSR.Z = IsZeroBit(result); 8725 APSR.C = carry; 8726 APSR.V = overflow; 8727 #endif 8728 8729 bool success = false; 8730 8731 uint32_t Rd; // the destination register 8732 uint32_t Rn; // the first operand 8733 bool setflags; 8734 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8735 switch (encoding) { 8736 case eEncodingT1: 8737 Rd = Bits32(opcode, 2, 0); 8738 Rn = Bits32(opcode, 5, 3); 8739 setflags = !InITBlock(); 8740 imm32 = 0; 8741 break; 8742 case eEncodingT2: 8743 Rd = Bits32(opcode, 11, 8); 8744 Rn = Bits32(opcode, 19, 16); 8745 setflags = BitIsSet(opcode, 20); 8746 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8747 if (BadReg(Rd) || BadReg(Rn)) 8748 return false; 8749 break; 8750 case eEncodingA1: 8751 Rd = Bits32(opcode, 15, 12); 8752 Rn = Bits32(opcode, 19, 16); 8753 setflags = BitIsSet(opcode, 20); 8754 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8755 8756 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8757 if (Rd == 15 && setflags) 8758 return EmulateSUBSPcLrEtc (opcode, encoding); 8759 break; 8760 default: 8761 return false; 8762 } 8763 // Read the register value from the operand register Rn. 8764 uint32_t reg_val = ReadCoreReg(Rn, &success); 8765 if (!success) 8766 return false; 8767 8768 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8769 8770 EmulateInstruction::Context context; 8771 context.type = EmulateInstruction::eContextImmediate; 8772 context.SetNoArgs (); 8773 8774 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8775 return false; 8776 8777 return true; 8778 } 8779 8780 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8781 // result to the destination register. It can optionally update the condition flags based on the result. 8782 bool 8783 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8784 { 8785 #if 0 8786 // ARM pseudo code... 8787 if ConditionPassed() then 8788 EncodingSpecificOperations(); 8789 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8790 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8791 if d == 15 then // Can only occur for ARM encoding 8792 ALUWritePC(result); // setflags is always FALSE here 8793 else 8794 R[d] = result; 8795 if setflags then 8796 APSR.N = result<31>; 8797 APSR.Z = IsZeroBit(result); 8798 APSR.C = carry; 8799 APSR.V = overflow; 8800 #endif 8801 8802 bool success = false; 8803 8804 uint32_t Rd; // the destination register 8805 uint32_t Rn; // the first operand 8806 uint32_t Rm; // the second operand 8807 bool setflags; 8808 ARM_ShifterType shift_t; 8809 uint32_t shift_n; // the shift applied to the value read from Rm 8810 switch (encoding) { 8811 case eEncodingT1: 8812 Rd = Bits32(opcode, 11, 8); 8813 Rn = Bits32(opcode, 19, 16); 8814 Rm = Bits32(opcode, 3, 0); 8815 setflags = BitIsSet(opcode, 20); 8816 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8817 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8818 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8819 return false; 8820 break; 8821 case eEncodingA1: 8822 Rd = Bits32(opcode, 15, 12); 8823 Rn = Bits32(opcode, 19, 16); 8824 Rm = Bits32(opcode, 3, 0); 8825 setflags = BitIsSet(opcode, 20); 8826 shift_n = DecodeImmShiftARM(opcode, shift_t); 8827 8828 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8829 if (Rd == 15 && setflags) 8830 return EmulateSUBSPcLrEtc (opcode, encoding); 8831 break; 8832 default: 8833 return false; 8834 } 8835 // Read the register value from register Rn. 8836 uint32_t val1 = ReadCoreReg(Rn, &success); 8837 if (!success) 8838 return false; 8839 8840 // Read the register value from register Rm. 8841 uint32_t val2 = ReadCoreReg(Rm, &success); 8842 if (!success) 8843 return false; 8844 8845 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8846 if (!success) 8847 return false; 8848 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8849 8850 EmulateInstruction::Context context; 8851 context.type = EmulateInstruction::eContextImmediate; 8852 context.SetNoArgs(); 8853 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8854 return false; 8855 8856 return true; 8857 } 8858 8859 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8860 // an immediate value, and writes the result to the destination register. It can optionally update the condition 8861 // flags based on the result. 8862 bool 8863 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8864 { 8865 #if 0 8866 // ARM pseudo code... 8867 if ConditionPassed() then 8868 EncodingSpecificOperations(); 8869 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8870 if d == 15 then 8871 ALUWritePC(result); // setflags is always FALSE here 8872 else 8873 R[d] = result; 8874 if setflags then 8875 APSR.N = result<31>; 8876 APSR.Z = IsZeroBit(result); 8877 APSR.C = carry; 8878 APSR.V = overflow; 8879 #endif 8880 8881 bool success = false; 8882 8883 uint32_t Rd; // the destination register 8884 uint32_t Rn; // the first operand 8885 bool setflags; 8886 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8887 switch (encoding) { 8888 case eEncodingA1: 8889 Rd = Bits32(opcode, 15, 12); 8890 Rn = Bits32(opcode, 19, 16); 8891 setflags = BitIsSet(opcode, 20); 8892 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8893 8894 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8895 if (Rd == 15 && setflags) 8896 return EmulateSUBSPcLrEtc (opcode, encoding); 8897 break; 8898 default: 8899 return false; 8900 } 8901 // Read the register value from the operand register Rn. 8902 uint32_t reg_val = ReadCoreReg(Rn, &success); 8903 if (!success) 8904 return false; 8905 8906 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8907 8908 EmulateInstruction::Context context; 8909 context.type = EmulateInstruction::eContextImmediate; 8910 context.SetNoArgs (); 8911 8912 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8913 return false; 8914 8915 return true; 8916 } 8917 8918 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8919 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8920 // condition flags based on the result. 8921 bool 8922 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8923 { 8924 #if 0 8925 // ARM pseudo code... 8926 if ConditionPassed() then 8927 EncodingSpecificOperations(); 8928 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8929 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8930 if d == 15 then 8931 ALUWritePC(result); // setflags is always FALSE here 8932 else 8933 R[d] = result; 8934 if setflags then 8935 APSR.N = result<31>; 8936 APSR.Z = IsZeroBit(result); 8937 APSR.C = carry; 8938 APSR.V = overflow; 8939 #endif 8940 8941 bool success = false; 8942 8943 uint32_t Rd; // the destination register 8944 uint32_t Rn; // the first operand 8945 uint32_t Rm; // the second operand 8946 bool setflags; 8947 ARM_ShifterType shift_t; 8948 uint32_t shift_n; // the shift applied to the value read from Rm 8949 switch (encoding) { 8950 case eEncodingA1: 8951 Rd = Bits32(opcode, 15, 12); 8952 Rn = Bits32(opcode, 19, 16); 8953 Rm = Bits32(opcode, 3, 0); 8954 setflags = BitIsSet(opcode, 20); 8955 shift_n = DecodeImmShiftARM(opcode, shift_t); 8956 8957 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8958 if (Rd == 15 && setflags) 8959 return EmulateSUBSPcLrEtc (opcode, encoding); 8960 break; 8961 default: 8962 return false; 8963 } 8964 // Read the register value from register Rn. 8965 uint32_t val1 = ReadCoreReg(Rn, &success); 8966 if (!success) 8967 return false; 8968 8969 // Read the register value from register Rm. 8970 uint32_t val2 = ReadCoreReg(Rm, &success); 8971 if (!success) 8972 return false; 8973 8974 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8975 if (!success) 8976 return false; 8977 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8978 8979 EmulateInstruction::Context context; 8980 context.type = EmulateInstruction::eContextImmediate; 8981 context.SetNoArgs(); 8982 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8983 return false; 8984 8985 return true; 8986 } 8987 8988 // Subtract with Carry (immediate) subtracts an immediate value and the value of 8989 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8990 // It can optionally update the condition flags based on the result. 8991 bool 8992 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 8993 { 8994 #if 0 8995 // ARM pseudo code... 8996 if ConditionPassed() then 8997 EncodingSpecificOperations(); 8998 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8999 if d == 15 then // Can only occur for ARM encoding 9000 ALUWritePC(result); // setflags is always FALSE here 9001 else 9002 R[d] = result; 9003 if setflags then 9004 APSR.N = result<31>; 9005 APSR.Z = IsZeroBit(result); 9006 APSR.C = carry; 9007 APSR.V = overflow; 9008 #endif 9009 9010 bool success = false; 9011 9012 uint32_t Rd; // the destination register 9013 uint32_t Rn; // the first operand 9014 bool setflags; 9015 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 9016 switch (encoding) { 9017 case eEncodingT1: 9018 Rd = Bits32(opcode, 11, 8); 9019 Rn = Bits32(opcode, 19, 16); 9020 setflags = BitIsSet(opcode, 20); 9021 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9022 if (BadReg(Rd) || BadReg(Rn)) 9023 return false; 9024 break; 9025 case eEncodingA1: 9026 Rd = Bits32(opcode, 15, 12); 9027 Rn = Bits32(opcode, 19, 16); 9028 setflags = BitIsSet(opcode, 20); 9029 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9030 9031 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9032 if (Rd == 15 && setflags) 9033 return EmulateSUBSPcLrEtc (opcode, encoding); 9034 break; 9035 default: 9036 return false; 9037 } 9038 // Read the register value from the operand register Rn. 9039 uint32_t reg_val = ReadCoreReg(Rn, &success); 9040 if (!success) 9041 return false; 9042 9043 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9044 9045 EmulateInstruction::Context context; 9046 context.type = EmulateInstruction::eContextImmediate; 9047 context.SetNoArgs (); 9048 9049 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9050 return false; 9051 9052 return true; 9053 } 9054 9055 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 9056 // NOT (Carry flag) from a register value, and writes the result to the destination register. 9057 // It can optionally update the condition flags based on the result. 9058 bool 9059 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 9060 { 9061 #if 0 9062 // ARM pseudo code... 9063 if ConditionPassed() then 9064 EncodingSpecificOperations(); 9065 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9066 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9067 if d == 15 then // Can only occur for ARM encoding 9068 ALUWritePC(result); // setflags is always FALSE here 9069 else 9070 R[d] = result; 9071 if setflags then 9072 APSR.N = result<31>; 9073 APSR.Z = IsZeroBit(result); 9074 APSR.C = carry; 9075 APSR.V = overflow; 9076 #endif 9077 9078 bool success = false; 9079 9080 uint32_t Rd; // the destination register 9081 uint32_t Rn; // the first operand 9082 uint32_t Rm; // the second operand 9083 bool setflags; 9084 ARM_ShifterType shift_t; 9085 uint32_t shift_n; // the shift applied to the value read from Rm 9086 switch (encoding) { 9087 case eEncodingT1: 9088 Rd = Rn = Bits32(opcode, 2, 0); 9089 Rm = Bits32(opcode, 5, 3); 9090 setflags = !InITBlock(); 9091 shift_t = SRType_LSL; 9092 shift_n = 0; 9093 break; 9094 case eEncodingT2: 9095 Rd = Bits32(opcode, 11, 8); 9096 Rn = Bits32(opcode, 19, 16); 9097 Rm = Bits32(opcode, 3, 0); 9098 setflags = BitIsSet(opcode, 20); 9099 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9100 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9101 return false; 9102 break; 9103 case eEncodingA1: 9104 Rd = Bits32(opcode, 15, 12); 9105 Rn = Bits32(opcode, 19, 16); 9106 Rm = Bits32(opcode, 3, 0); 9107 setflags = BitIsSet(opcode, 20); 9108 shift_n = DecodeImmShiftARM(opcode, shift_t); 9109 9110 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9111 if (Rd == 15 && setflags) 9112 return EmulateSUBSPcLrEtc (opcode, encoding); 9113 break; 9114 default: 9115 return false; 9116 } 9117 // Read the register value from register Rn. 9118 uint32_t val1 = ReadCoreReg(Rn, &success); 9119 if (!success) 9120 return false; 9121 9122 // Read the register value from register Rm. 9123 uint32_t val2 = ReadCoreReg(Rm, &success); 9124 if (!success) 9125 return false; 9126 9127 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9128 if (!success) 9129 return false; 9130 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9131 9132 EmulateInstruction::Context context; 9133 context.type = EmulateInstruction::eContextImmediate; 9134 context.SetNoArgs(); 9135 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9136 return false; 9137 9138 return true; 9139 } 9140 9141 // This instruction subtracts an immediate value from a register value, and writes the result 9142 // to the destination register. It can optionally update the condition flags based on the result. 9143 bool 9144 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 9145 { 9146 #if 0 9147 // ARM pseudo code... 9148 if ConditionPassed() then 9149 EncodingSpecificOperations(); 9150 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9151 R[d] = result; 9152 if setflags then 9153 APSR.N = result<31>; 9154 APSR.Z = IsZeroBit(result); 9155 APSR.C = carry; 9156 APSR.V = overflow; 9157 #endif 9158 9159 bool success = false; 9160 9161 uint32_t Rd; // the destination register 9162 uint32_t Rn; // the first operand 9163 bool setflags; 9164 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9165 switch (encoding) { 9166 case eEncodingT1: 9167 Rd = Bits32(opcode, 2, 0); 9168 Rn = Bits32(opcode, 5, 3); 9169 setflags = !InITBlock(); 9170 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9171 break; 9172 case eEncodingT2: 9173 Rd = Rn = Bits32(opcode, 10, 8); 9174 setflags = !InITBlock(); 9175 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9176 break; 9177 case eEncodingT3: 9178 Rd = Bits32(opcode, 11, 8); 9179 Rn = Bits32(opcode, 19, 16); 9180 setflags = BitIsSet(opcode, 20); 9181 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9182 9183 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9184 if (Rd == 15 && setflags) 9185 return EmulateCMPImm (opcode, eEncodingT2); 9186 9187 // if Rn == '1101' then SEE SUB (SP minus immediate); 9188 if (Rn == 13) 9189 return EmulateSUBSPImm (opcode, eEncodingT2); 9190 9191 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9192 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9193 return false; 9194 break; 9195 case eEncodingT4: 9196 Rd = Bits32(opcode, 11, 8); 9197 Rn = Bits32(opcode, 19, 16); 9198 setflags = BitIsSet(opcode, 20); 9199 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9200 9201 // if Rn == '1111' then SEE ADR; 9202 if (Rn == 15) 9203 return EmulateADR (opcode, eEncodingT2); 9204 9205 // if Rn == '1101' then SEE SUB (SP minus immediate); 9206 if (Rn == 13) 9207 return EmulateSUBSPImm (opcode, eEncodingT3); 9208 9209 if (BadReg(Rd)) 9210 return false; 9211 break; 9212 default: 9213 return false; 9214 } 9215 // Read the register value from the operand register Rn. 9216 uint32_t reg_val = ReadCoreReg(Rn, &success); 9217 if (!success) 9218 return false; 9219 9220 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9221 9222 EmulateInstruction::Context context; 9223 context.type = EmulateInstruction::eContextImmediate; 9224 context.SetNoArgs (); 9225 9226 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9227 return false; 9228 9229 return true; 9230 } 9231 9232 // This instruction subtracts an immediate value from a register value, and writes the result 9233 // to the destination register. It can optionally update the condition flags based on the result. 9234 bool 9235 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9236 { 9237 #if 0 9238 // ARM pseudo code... 9239 if ConditionPassed() then 9240 EncodingSpecificOperations(); 9241 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9242 if d == 15 then 9243 ALUWritePC(result); // setflags is always FALSE here 9244 else 9245 R[d] = result; 9246 if setflags then 9247 APSR.N = result<31>; 9248 APSR.Z = IsZeroBit(result); 9249 APSR.C = carry; 9250 APSR.V = overflow; 9251 #endif 9252 9253 bool success = false; 9254 9255 if (ConditionPassed(opcode)) 9256 { 9257 uint32_t Rd; // the destination register 9258 uint32_t Rn; // the first operand 9259 bool setflags; 9260 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9261 switch (encoding) { 9262 case eEncodingA1: 9263 Rd = Bits32(opcode, 15, 12); 9264 Rn = Bits32(opcode, 19, 16); 9265 setflags = BitIsSet(opcode, 20); 9266 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9267 9268 // if Rn == '1111' && S == '0' then SEE ADR; 9269 if (Rn == 15 && !setflags) 9270 return EmulateADR (opcode, eEncodingA2); 9271 9272 // if Rn == '1101' then SEE SUB (SP minus immediate); 9273 if (Rn == 13) 9274 return EmulateSUBSPImm (opcode, eEncodingA1); 9275 9276 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9277 if (Rd == 15 && setflags) 9278 return EmulateSUBSPcLrEtc (opcode, encoding); 9279 break; 9280 default: 9281 return false; 9282 } 9283 // Read the register value from the operand register Rn. 9284 uint32_t reg_val = ReadCoreReg(Rn, &success); 9285 if (!success) 9286 return false; 9287 9288 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9289 9290 EmulateInstruction::Context context; 9291 if (Rd == 13) 9292 context.type = EmulateInstruction::eContextAdjustStackPointer; 9293 else 9294 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9295 9296 RegisterInfo dwarf_reg; 9297 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 9298 int64_t imm32_signed = imm32; 9299 context.SetRegisterPlusOffset (dwarf_reg, -imm32_signed); 9300 9301 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9302 return false; 9303 } 9304 return true; 9305 } 9306 9307 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9308 // immediate value. It updates the condition flags based on the result, and discards the result. 9309 bool 9310 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9311 { 9312 #if 0 9313 // ARM pseudo code... 9314 if ConditionPassed() then 9315 EncodingSpecificOperations(); 9316 result = R[n] EOR imm32; 9317 APSR.N = result<31>; 9318 APSR.Z = IsZeroBit(result); 9319 APSR.C = carry; 9320 // APSR.V unchanged 9321 #endif 9322 9323 bool success = false; 9324 9325 if (ConditionPassed(opcode)) 9326 { 9327 uint32_t Rn; 9328 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9329 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9330 switch (encoding) 9331 { 9332 case eEncodingT1: 9333 Rn = Bits32(opcode, 19, 16); 9334 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9335 if (BadReg(Rn)) 9336 return false; 9337 break; 9338 case eEncodingA1: 9339 Rn = Bits32(opcode, 19, 16); 9340 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9341 break; 9342 default: 9343 return false; 9344 } 9345 9346 // Read the first operand. 9347 uint32_t val1 = ReadCoreReg(Rn, &success); 9348 if (!success) 9349 return false; 9350 9351 uint32_t result = val1 ^ imm32; 9352 9353 EmulateInstruction::Context context; 9354 context.type = EmulateInstruction::eContextImmediate; 9355 context.SetNoArgs (); 9356 9357 if (!WriteFlags(context, result, carry)) 9358 return false; 9359 } 9360 return true; 9361 } 9362 9363 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9364 // optionally-shifted register value. It updates the condition flags based on the result, and discards 9365 // the result. 9366 bool 9367 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9368 { 9369 #if 0 9370 // ARM pseudo code... 9371 if ConditionPassed() then 9372 EncodingSpecificOperations(); 9373 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9374 result = R[n] EOR shifted; 9375 APSR.N = result<31>; 9376 APSR.Z = IsZeroBit(result); 9377 APSR.C = carry; 9378 // APSR.V unchanged 9379 #endif 9380 9381 bool success = false; 9382 9383 if (ConditionPassed(opcode)) 9384 { 9385 uint32_t Rn, Rm; 9386 ARM_ShifterType shift_t; 9387 uint32_t shift_n; // the shift applied to the value read from Rm 9388 uint32_t carry; 9389 switch (encoding) 9390 { 9391 case eEncodingT1: 9392 Rn = Bits32(opcode, 19, 16); 9393 Rm = Bits32(opcode, 3, 0); 9394 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9395 if (BadReg(Rn) || BadReg(Rm)) 9396 return false; 9397 break; 9398 case eEncodingA1: 9399 Rn = Bits32(opcode, 19, 16); 9400 Rm = Bits32(opcode, 3, 0); 9401 shift_n = DecodeImmShiftARM(opcode, shift_t); 9402 break; 9403 default: 9404 return false; 9405 } 9406 9407 // Read the first operand. 9408 uint32_t val1 = ReadCoreReg(Rn, &success); 9409 if (!success) 9410 return false; 9411 9412 // Read the second operand. 9413 uint32_t val2 = ReadCoreReg(Rm, &success); 9414 if (!success) 9415 return false; 9416 9417 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9418 if (!success) 9419 return false; 9420 uint32_t result = val1 ^ shifted; 9421 9422 EmulateInstruction::Context context; 9423 context.type = EmulateInstruction::eContextImmediate; 9424 context.SetNoArgs (); 9425 9426 if (!WriteFlags(context, result, carry)) 9427 return false; 9428 } 9429 return true; 9430 } 9431 9432 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9433 // It updates the condition flags based on the result, and discards the result. 9434 bool 9435 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9436 { 9437 #if 0 9438 // ARM pseudo code... 9439 if ConditionPassed() then 9440 EncodingSpecificOperations(); 9441 result = R[n] AND imm32; 9442 APSR.N = result<31>; 9443 APSR.Z = IsZeroBit(result); 9444 APSR.C = carry; 9445 // APSR.V unchanged 9446 #endif 9447 9448 bool success = false; 9449 9450 if (ConditionPassed(opcode)) 9451 { 9452 uint32_t Rn; 9453 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9454 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9455 switch (encoding) 9456 { 9457 case eEncodingT1: 9458 Rn = Bits32(opcode, 19, 16); 9459 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9460 if (BadReg(Rn)) 9461 return false; 9462 break; 9463 case eEncodingA1: 9464 Rn = Bits32(opcode, 19, 16); 9465 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9466 break; 9467 default: 9468 return false; 9469 } 9470 9471 // Read the first operand. 9472 uint32_t val1 = ReadCoreReg(Rn, &success); 9473 if (!success) 9474 return false; 9475 9476 uint32_t result = val1 & imm32; 9477 9478 EmulateInstruction::Context context; 9479 context.type = EmulateInstruction::eContextImmediate; 9480 context.SetNoArgs (); 9481 9482 if (!WriteFlags(context, result, carry)) 9483 return false; 9484 } 9485 return true; 9486 } 9487 9488 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9489 // It updates the condition flags based on the result, and discards the result. 9490 bool 9491 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9492 { 9493 #if 0 9494 // ARM pseudo code... 9495 if ConditionPassed() then 9496 EncodingSpecificOperations(); 9497 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9498 result = R[n] AND shifted; 9499 APSR.N = result<31>; 9500 APSR.Z = IsZeroBit(result); 9501 APSR.C = carry; 9502 // APSR.V unchanged 9503 #endif 9504 9505 bool success = false; 9506 9507 if (ConditionPassed(opcode)) 9508 { 9509 uint32_t Rn, Rm; 9510 ARM_ShifterType shift_t; 9511 uint32_t shift_n; // the shift applied to the value read from Rm 9512 uint32_t carry; 9513 switch (encoding) 9514 { 9515 case eEncodingT1: 9516 Rn = Bits32(opcode, 2, 0); 9517 Rm = Bits32(opcode, 5, 3); 9518 shift_t = SRType_LSL; 9519 shift_n = 0; 9520 break; 9521 case eEncodingT2: 9522 Rn = Bits32(opcode, 19, 16); 9523 Rm = Bits32(opcode, 3, 0); 9524 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9525 if (BadReg(Rn) || BadReg(Rm)) 9526 return false; 9527 break; 9528 case eEncodingA1: 9529 Rn = Bits32(opcode, 19, 16); 9530 Rm = Bits32(opcode, 3, 0); 9531 shift_n = DecodeImmShiftARM(opcode, shift_t); 9532 break; 9533 default: 9534 return false; 9535 } 9536 9537 // Read the first operand. 9538 uint32_t val1 = ReadCoreReg(Rn, &success); 9539 if (!success) 9540 return false; 9541 9542 // Read the second operand. 9543 uint32_t val2 = ReadCoreReg(Rm, &success); 9544 if (!success) 9545 return false; 9546 9547 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9548 if (!success) 9549 return false; 9550 uint32_t result = val1 & shifted; 9551 9552 EmulateInstruction::Context context; 9553 context.type = EmulateInstruction::eContextImmediate; 9554 context.SetNoArgs (); 9555 9556 if (!WriteFlags(context, result, carry)) 9557 return false; 9558 } 9559 return true; 9560 } 9561 9562 // A8.6.216 SUB (SP minus register) 9563 bool 9564 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9565 { 9566 #if 0 9567 if ConditionPassed() then 9568 EncodingSpecificOperations(); 9569 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9570 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 9571 if d == 15 then // Can only occur for ARM encoding 9572 ALUWritePC(result); // setflags is always FALSE here 9573 else 9574 R[d] = result; 9575 if setflags then 9576 APSR.N = result<31>; 9577 APSR.Z = IsZeroBit(result); 9578 APSR.C = carry; 9579 APSR.V = overflow; 9580 #endif 9581 9582 bool success = false; 9583 9584 if (ConditionPassed(opcode)) 9585 { 9586 uint32_t d; 9587 uint32_t m; 9588 bool setflags; 9589 ARM_ShifterType shift_t; 9590 uint32_t shift_n; 9591 9592 switch (encoding) 9593 { 9594 case eEncodingT1: 9595 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 9596 d = Bits32 (opcode, 11, 8); 9597 m = Bits32 (opcode, 3, 0); 9598 setflags = BitIsSet (opcode, 20); 9599 9600 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9601 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9602 9603 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9604 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9605 return false; 9606 9607 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9608 if ((d == 15) || BadReg (m)) 9609 return false; 9610 break; 9611 9612 case eEncodingA1: 9613 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 9614 d = Bits32 (opcode, 15, 12); 9615 m = Bits32 (opcode, 3, 0); 9616 setflags = BitIsSet (opcode, 20); 9617 9618 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9619 if (d == 15 && setflags) 9620 EmulateSUBSPcLrEtc (opcode, encoding); 9621 9622 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9623 shift_n = DecodeImmShiftARM (opcode, shift_t); 9624 break; 9625 9626 default: 9627 return false; 9628 } 9629 9630 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9631 uint32_t Rm = ReadCoreReg (m, &success); 9632 if (!success) 9633 return false; 9634 9635 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9636 if (!success) 9637 return false; 9638 9639 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 9640 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9641 if (!success) 9642 return false; 9643 9644 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9645 9646 EmulateInstruction::Context context; 9647 context.type = eContextArithmetic; 9648 RegisterInfo sp_reg; 9649 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9650 RegisterInfo dwarf_reg; 9651 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9652 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9653 9654 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9655 return false; 9656 } 9657 return true; 9658 } 9659 9660 9661 // A8.6.7 ADD (register-shifted register) 9662 bool 9663 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9664 { 9665 #if 0 9666 if ConditionPassed() then 9667 EncodingSpecificOperations(); 9668 shift_n = UInt(R[s]<7:0>); 9669 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9670 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 9671 R[d] = result; 9672 if setflags then 9673 APSR.N = result<31>; 9674 APSR.Z = IsZeroBit(result); 9675 APSR.C = carry; 9676 APSR.V = overflow; 9677 #endif 9678 9679 bool success = false; 9680 9681 if (ConditionPassed(opcode)) 9682 { 9683 uint32_t d; 9684 uint32_t n; 9685 uint32_t m; 9686 uint32_t s; 9687 bool setflags; 9688 ARM_ShifterType shift_t; 9689 9690 switch (encoding) 9691 { 9692 case eEncodingA1: 9693 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9694 d = Bits32 (opcode, 15, 12); 9695 n = Bits32 (opcode, 19, 16); 9696 m = Bits32 (opcode, 3, 0); 9697 s = Bits32 (opcode, 11, 8); 9698 9699 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 9700 setflags = BitIsSet (opcode, 20); 9701 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9702 9703 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9704 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9705 return false; 9706 break; 9707 9708 default: 9709 return false; 9710 } 9711 9712 // shift_n = UInt(R[s]<7:0>); 9713 uint32_t Rs = ReadCoreReg (s, &success); 9714 if (!success) 9715 return false; 9716 9717 uint32_t shift_n = Bits32 (Rs, 7, 0); 9718 9719 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9720 uint32_t Rm = ReadCoreReg (m, &success); 9721 if (!success) 9722 return false; 9723 9724 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9725 if (!success) 9726 return false; 9727 9728 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 9729 uint32_t Rn = ReadCoreReg (n, &success); 9730 if (!success) 9731 return false; 9732 9733 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9734 9735 // R[d] = result; 9736 EmulateInstruction::Context context; 9737 context.type = eContextArithmetic; 9738 RegisterInfo reg_n; 9739 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9740 RegisterInfo reg_m; 9741 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9742 9743 context.SetRegisterRegisterOperands (reg_n, reg_m); 9744 9745 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9746 return false; 9747 9748 // if setflags then 9749 // APSR.N = result<31>; 9750 // APSR.Z = IsZeroBit(result); 9751 // APSR.C = carry; 9752 // APSR.V = overflow; 9753 if (setflags) 9754 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9755 } 9756 return true; 9757 } 9758 9759 // A8.6.213 SUB (register) 9760 bool 9761 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9762 { 9763 #if 0 9764 if ConditionPassed() then 9765 EncodingSpecificOperations(); 9766 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9767 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 9768 if d == 15 then // Can only occur for ARM encoding 9769 ALUWritePC(result); // setflags is always FALSE here 9770 else 9771 R[d] = result; 9772 if setflags then 9773 APSR.N = result<31>; 9774 APSR.Z = IsZeroBit(result); 9775 APSR.C = carry; 9776 APSR.V = overflow; 9777 #endif 9778 9779 bool success = false; 9780 9781 if (ConditionPassed(opcode)) 9782 { 9783 uint32_t d; 9784 uint32_t n; 9785 uint32_t m; 9786 bool setflags; 9787 ARM_ShifterType shift_t; 9788 uint32_t shift_n; 9789 9790 switch (encoding) 9791 { 9792 case eEncodingT1: 9793 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9794 d = Bits32 (opcode, 2, 0); 9795 n = Bits32 (opcode, 5, 3); 9796 m = Bits32 (opcode, 8, 6); 9797 setflags = !InITBlock(); 9798 9799 // (shift_t, shift_n) = (SRType_LSL, 0); 9800 shift_t = SRType_LSL; 9801 shift_n = 0; 9802 9803 break; 9804 9805 case eEncodingT2: 9806 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 9807 d = Bits32 (opcode, 11, 8); 9808 n = Bits32 (opcode, 19, 16); 9809 m = Bits32 (opcode, 3, 0); 9810 setflags = BitIsSet (opcode, 20); 9811 9812 // if Rd == "1111" && S == "1" then SEE CMP (register); 9813 if (d == 15 && setflags == 1) 9814 return EmulateCMPImm (opcode, eEncodingT3); 9815 9816 // if Rn == "1101" then SEE SUB (SP minus register); 9817 if (n == 13) 9818 return EmulateSUBSPReg (opcode, eEncodingT1); 9819 9820 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9821 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9822 9823 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9824 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9825 return false; 9826 9827 break; 9828 9829 case eEncodingA1: 9830 // if Rn == '1101' then SEE SUB (SP minus register); 9831 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 9832 d = Bits32 (opcode, 15, 12); 9833 n = Bits32 (opcode, 19, 16); 9834 m = Bits32 (opcode, 3, 0); 9835 setflags = BitIsSet (opcode, 20); 9836 9837 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9838 if ((d == 15) && setflags) 9839 EmulateSUBSPcLrEtc (opcode, encoding); 9840 9841 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9842 shift_n = DecodeImmShiftARM (opcode, shift_t); 9843 9844 break; 9845 9846 default: 9847 return false; 9848 } 9849 9850 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9851 uint32_t Rm = ReadCoreReg (m, &success); 9852 if (!success) 9853 return false; 9854 9855 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9856 if (!success) 9857 return false; 9858 9859 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 9860 uint32_t Rn = ReadCoreReg (n, &success); 9861 if (!success) 9862 return false; 9863 9864 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9865 9866 // if d == 15 then // Can only occur for ARM encoding 9867 // ALUWritePC(result); // setflags is always FALSE here 9868 // else 9869 // R[d] = result; 9870 // if setflags then 9871 // APSR.N = result<31>; 9872 // APSR.Z = IsZeroBit(result); 9873 // APSR.C = carry; 9874 // APSR.V = overflow; 9875 9876 EmulateInstruction::Context context; 9877 context.type = eContextArithmetic; 9878 RegisterInfo reg_n; 9879 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9880 RegisterInfo reg_m; 9881 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9882 context.SetRegisterRegisterOperands (reg_n, reg_m); 9883 9884 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9885 return false; 9886 } 9887 return true; 9888 } 9889 9890 // A8.6.202 STREX 9891 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9892 // word from a register to memory if the executing processor has exclusive access to the memory addressed. 9893 bool 9894 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9895 { 9896 #if 0 9897 if ConditionPassed() then 9898 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9899 address = R[n] + imm32; 9900 if ExclusiveMonitorsPass(address,4) then 9901 MemA[address,4] = R[t]; 9902 R[d] = 0; 9903 else 9904 R[d] = 1; 9905 #endif 9906 9907 bool success = false; 9908 9909 if (ConditionPassed(opcode)) 9910 { 9911 uint32_t d; 9912 uint32_t t; 9913 uint32_t n; 9914 uint32_t imm32; 9915 const uint32_t addr_byte_size = GetAddressByteSize(); 9916 9917 switch (encoding) 9918 { 9919 case eEncodingT1: 9920 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 9921 d = Bits32 (opcode, 11, 8); 9922 t = Bits32 (opcode, 15, 12); 9923 n = Bits32 (opcode, 19, 16); 9924 imm32 = Bits32 (opcode, 7, 0) << 2; 9925 9926 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9927 if (BadReg (d) || BadReg (t) || (n == 15)) 9928 return false; 9929 9930 // if d == n || d == t then UNPREDICTABLE; 9931 if ((d == n) || (d == t)) 9932 return false; 9933 9934 break; 9935 9936 case eEncodingA1: 9937 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9938 d = Bits32 (opcode, 15, 12); 9939 t = Bits32 (opcode, 3, 0); 9940 n = Bits32 (opcode, 19, 16); 9941 imm32 = 0; 9942 9943 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9944 if ((d == 15) || (t == 15) || (n == 15)) 9945 return false; 9946 9947 // if d == n || d == t then UNPREDICTABLE; 9948 if ((d == n) || (d == t)) 9949 return false; 9950 9951 break; 9952 9953 default: 9954 return false; 9955 } 9956 9957 // address = R[n] + imm32; 9958 uint32_t Rn = ReadCoreReg (n, &success); 9959 if (!success) 9960 return false; 9961 9962 addr_t address = Rn + imm32; 9963 9964 RegisterInfo base_reg; 9965 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9966 RegisterInfo data_reg; 9967 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9968 EmulateInstruction::Context context; 9969 context.type = eContextRegisterStore; 9970 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9971 9972 // if ExclusiveMonitorsPass(address,4) then 9973 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9974 // always return true. 9975 if (true) 9976 { 9977 // MemA[address,4] = R[t]; 9978 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9979 if (!success) 9980 return false; 9981 9982 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9983 return false; 9984 9985 // R[d] = 0; 9986 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9987 return false; 9988 } 9989 #if 0 // unreachable because if true 9990 else 9991 { 9992 // R[d] = 1; 9993 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9994 return false; 9995 } 9996 #endif // unreachable because if true 9997 } 9998 return true; 9999 } 10000 10001 // A8.6.197 STRB (immediate, ARM) 10002 bool 10003 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 10004 { 10005 #if 0 10006 if ConditionPassed() then 10007 EncodingSpecificOperations(); 10008 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10009 address = if index then offset_addr else R[n]; 10010 MemU[address,1] = R[t]<7:0>; 10011 if wback then R[n] = offset_addr; 10012 #endif 10013 10014 bool success = false; 10015 10016 if (ConditionPassed(opcode)) 10017 { 10018 uint32_t t; 10019 uint32_t n; 10020 uint32_t imm32; 10021 bool index; 10022 bool add; 10023 bool wback; 10024 10025 switch (encoding) 10026 { 10027 case eEncodingA1: 10028 // if P == '0' && W == '1' then SEE STRBT; 10029 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10030 t = Bits32 (opcode, 15, 12); 10031 n = Bits32 (opcode, 19, 16); 10032 imm32 = Bits32 (opcode, 11, 0); 10033 10034 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10035 index = BitIsSet (opcode, 24); 10036 add = BitIsSet (opcode, 23); 10037 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10038 10039 // if t == 15 then UNPREDICTABLE; 10040 if (t == 15) 10041 return false; 10042 10043 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10044 if (wback && ((n == 15) || (n == t))) 10045 return false; 10046 10047 break; 10048 10049 default: 10050 return false; 10051 } 10052 10053 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10054 uint32_t Rn = ReadCoreReg (n, &success); 10055 if (!success) 10056 return false; 10057 10058 addr_t offset_addr; 10059 if (add) 10060 offset_addr = Rn + imm32; 10061 else 10062 offset_addr = Rn - imm32; 10063 10064 // address = if index then offset_addr else R[n]; 10065 addr_t address; 10066 if (index) 10067 address = offset_addr; 10068 else 10069 address = Rn; 10070 10071 // MemU[address,1] = R[t]<7:0>; 10072 uint32_t Rt = ReadCoreReg (t, &success); 10073 if (!success) 10074 return false; 10075 10076 RegisterInfo base_reg; 10077 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10078 RegisterInfo data_reg; 10079 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10080 EmulateInstruction::Context context; 10081 context.type = eContextRegisterStore; 10082 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10083 10084 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 10085 return false; 10086 10087 // if wback then R[n] = offset_addr; 10088 if (wback) 10089 { 10090 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10091 return false; 10092 } 10093 } 10094 return true; 10095 } 10096 10097 // A8.6.194 STR (immediate, ARM) 10098 bool 10099 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 10100 { 10101 #if 0 10102 if ConditionPassed() then 10103 EncodingSpecificOperations(); 10104 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10105 address = if index then offset_addr else R[n]; 10106 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10107 if wback then R[n] = offset_addr; 10108 #endif 10109 10110 bool success = false; 10111 10112 if (ConditionPassed(opcode)) 10113 { 10114 uint32_t t; 10115 uint32_t n; 10116 uint32_t imm32; 10117 bool index; 10118 bool add; 10119 bool wback; 10120 10121 const uint32_t addr_byte_size = GetAddressByteSize(); 10122 10123 switch (encoding) 10124 { 10125 case eEncodingA1: 10126 // if P == '0' && W == '1' then SEE STRT; 10127 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH; 10128 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10129 t = Bits32 (opcode, 15, 12); 10130 n = Bits32 (opcode, 19, 16); 10131 imm32 = Bits32 (opcode, 11, 0); 10132 10133 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10134 index = BitIsSet (opcode, 24); 10135 add = BitIsSet (opcode, 23); 10136 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10137 10138 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10139 if (wback && ((n == 15) || (n == t))) 10140 return false; 10141 10142 break; 10143 10144 default: 10145 return false; 10146 } 10147 10148 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10149 uint32_t Rn = ReadCoreReg (n, &success); 10150 if (!success) 10151 return false; 10152 10153 addr_t offset_addr; 10154 if (add) 10155 offset_addr = Rn + imm32; 10156 else 10157 offset_addr = Rn - imm32; 10158 10159 // address = if index then offset_addr else R[n]; 10160 addr_t address; 10161 if (index) 10162 address = offset_addr; 10163 else 10164 address = Rn; 10165 10166 RegisterInfo base_reg; 10167 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10168 RegisterInfo data_reg; 10169 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10170 EmulateInstruction::Context context; 10171 context.type = eContextRegisterStore; 10172 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10173 10174 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10175 uint32_t Rt = ReadCoreReg (t, &success); 10176 if (!success) 10177 return false; 10178 10179 if (t == 15) 10180 { 10181 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10182 if (!success) 10183 return false; 10184 10185 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10186 return false; 10187 } 10188 else 10189 { 10190 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10191 return false; 10192 } 10193 10194 // if wback then R[n] = offset_addr; 10195 if (wback) 10196 { 10197 context.type = eContextAdjustBaseRegister; 10198 context.SetImmediate (offset_addr); 10199 10200 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10201 return false; 10202 } 10203 } 10204 return true; 10205 } 10206 10207 // A8.6.66 LDRD (immediate) 10208 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10209 // words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10210 bool 10211 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10212 { 10213 #if 0 10214 if ConditionPassed() then 10215 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10216 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10217 address = if index then offset_addr else R[n]; 10218 R[t] = MemA[address,4]; 10219 R[t2] = MemA[address+4,4]; 10220 if wback then R[n] = offset_addr; 10221 #endif 10222 10223 bool success = false; 10224 10225 if (ConditionPassed(opcode)) 10226 { 10227 uint32_t t; 10228 uint32_t t2; 10229 uint32_t n; 10230 uint32_t imm32; 10231 bool index; 10232 bool add; 10233 bool wback; 10234 10235 switch (encoding) 10236 { 10237 case eEncodingT1: 10238 //if P == '0' && W == '0' then SEE 'Related encodings'; 10239 //if Rn == '1111' then SEE LDRD (literal); 10240 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 10241 t = Bits32 (opcode, 15, 12); 10242 t2 = Bits32 (opcode, 11, 8); 10243 n = Bits32 (opcode, 19, 16); 10244 imm32 = Bits32 (opcode, 7, 0) << 2; 10245 10246 //index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10247 index = BitIsSet (opcode, 24); 10248 add = BitIsSet (opcode, 23); 10249 wback = BitIsSet (opcode, 21); 10250 10251 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10252 if (wback && ((n == t) || (n == t2))) 10253 return false; 10254 10255 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10256 if (BadReg (t) || BadReg (t2) || (t == t2)) 10257 return false; 10258 10259 break; 10260 10261 case eEncodingA1: 10262 //if Rn == '1111' then SEE LDRD (literal); 10263 //if Rt<0> == '1' then UNPREDICTABLE; 10264 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10265 t = Bits32 (opcode, 15, 12); 10266 if (BitIsSet (t, 0)) 10267 return false; 10268 t2 = t + 1; 10269 n = Bits32 (opcode, 19, 16); 10270 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10271 10272 //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10273 index = BitIsSet (opcode, 24); 10274 add = BitIsSet (opcode, 23); 10275 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10276 10277 //if P == '0' && W == '1' then UNPREDICTABLE; 10278 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10279 return false; 10280 10281 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10282 if (wback && ((n == t) || (n == t2))) 10283 return false; 10284 10285 //if t2 == 15 then UNPREDICTABLE; 10286 if (t2 == 15) 10287 return false; 10288 10289 break; 10290 10291 default: 10292 return false; 10293 } 10294 10295 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10296 uint32_t Rn = ReadCoreReg (n, &success); 10297 if (!success) 10298 return false; 10299 10300 addr_t offset_addr; 10301 if (add) 10302 offset_addr = Rn + imm32; 10303 else 10304 offset_addr = Rn - imm32; 10305 10306 //address = if index then offset_addr else R[n]; 10307 addr_t address; 10308 if (index) 10309 address = offset_addr; 10310 else 10311 address = Rn; 10312 10313 //R[t] = MemA[address,4]; 10314 RegisterInfo base_reg; 10315 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10316 10317 EmulateInstruction::Context context; 10318 if (n == 13) 10319 context.type = eContextPopRegisterOffStack; 10320 else 10321 context.type = eContextRegisterLoad; 10322 context.SetAddress(address); 10323 10324 const uint32_t addr_byte_size = GetAddressByteSize(); 10325 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10326 if (!success) 10327 return false; 10328 10329 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10330 return false; 10331 10332 //R[t2] = MemA[address+4,4]; 10333 context.SetAddress(address + 4); 10334 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10335 if (!success) 10336 return false; 10337 10338 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10339 return false; 10340 10341 //if wback then R[n] = offset_addr; 10342 if (wback) 10343 { 10344 context.type = eContextAdjustBaseRegister; 10345 context.SetAddress (offset_addr); 10346 10347 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10348 return false; 10349 } 10350 } 10351 return true; 10352 } 10353 10354 // A8.6.68 LDRD (register) 10355 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10356 // words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10357 bool 10358 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10359 { 10360 #if 0 10361 if ConditionPassed() then 10362 EncodingSpecificOperations(); 10363 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10364 address = if index then offset_addr else R[n]; 10365 R[t] = MemA[address,4]; 10366 R[t2] = MemA[address+4,4]; 10367 if wback then R[n] = offset_addr; 10368 #endif 10369 10370 bool success = false; 10371 10372 if (ConditionPassed(opcode)) 10373 { 10374 uint32_t t; 10375 uint32_t t2; 10376 uint32_t n; 10377 uint32_t m; 10378 bool index; 10379 bool add; 10380 bool wback; 10381 10382 switch (encoding) 10383 { 10384 case eEncodingA1: 10385 // if Rt<0> == '1' then UNPREDICTABLE; 10386 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10387 t = Bits32 (opcode, 15, 12); 10388 if (BitIsSet (t, 0)) 10389 return false; 10390 t2 = t + 1; 10391 n = Bits32 (opcode, 19, 16); 10392 m = Bits32 (opcode, 3, 0); 10393 10394 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10395 index = BitIsSet (opcode, 24); 10396 add = BitIsSet (opcode, 23); 10397 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10398 10399 // if P == '0' && W == '1' then UNPREDICTABLE; 10400 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10401 return false; 10402 10403 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10404 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10405 return false; 10406 10407 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10408 if (wback && ((n == 15) || (n == t) || (n == t2))) 10409 return false; 10410 10411 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10412 if ((ArchVersion() < 6) && wback && (m == n)) 10413 return false; 10414 break; 10415 10416 default: 10417 return false; 10418 } 10419 10420 uint32_t Rn = ReadCoreReg (n, &success); 10421 if (!success) 10422 return false; 10423 RegisterInfo base_reg; 10424 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10425 10426 uint32_t Rm = ReadCoreReg (m, &success); 10427 if (!success) 10428 return false; 10429 RegisterInfo offset_reg; 10430 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10431 10432 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10433 addr_t offset_addr; 10434 if (add) 10435 offset_addr = Rn + Rm; 10436 else 10437 offset_addr = Rn - Rm; 10438 10439 // address = if index then offset_addr else R[n]; 10440 addr_t address; 10441 if (index) 10442 address = offset_addr; 10443 else 10444 address = Rn; 10445 10446 EmulateInstruction::Context context; 10447 if (n == 13) 10448 context.type = eContextPopRegisterOffStack; 10449 else 10450 context.type = eContextRegisterLoad; 10451 context.SetAddress(address); 10452 10453 // R[t] = MemA[address,4]; 10454 const uint32_t addr_byte_size = GetAddressByteSize(); 10455 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10456 if (!success) 10457 return false; 10458 10459 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10460 return false; 10461 10462 // R[t2] = MemA[address+4,4]; 10463 10464 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10465 if (!success) 10466 return false; 10467 10468 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10469 return false; 10470 10471 // if wback then R[n] = offset_addr; 10472 if (wback) 10473 { 10474 context.type = eContextAdjustBaseRegister; 10475 context.SetAddress (offset_addr); 10476 10477 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10478 return false; 10479 } 10480 } 10481 return true; 10482 } 10483 10484 // A8.6.200 STRD (immediate) 10485 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10486 // stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10487 bool 10488 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10489 { 10490 #if 0 10491 if ConditionPassed() then 10492 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10493 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10494 address = if index then offset_addr else R[n]; 10495 MemA[address,4] = R[t]; 10496 MemA[address+4,4] = R[t2]; 10497 if wback then R[n] = offset_addr; 10498 #endif 10499 10500 bool success = false; 10501 10502 if (ConditionPassed(opcode)) 10503 { 10504 uint32_t t; 10505 uint32_t t2; 10506 uint32_t n; 10507 uint32_t imm32; 10508 bool index; 10509 bool add; 10510 bool wback; 10511 10512 switch (encoding) 10513 { 10514 case eEncodingT1: 10515 // if P == '0' && W == '0' then SEE 'Related encodings'; 10516 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 10517 t = Bits32 (opcode, 15, 12); 10518 t2 = Bits32 (opcode, 11, 8); 10519 n = Bits32 (opcode, 19, 16); 10520 imm32 = Bits32 (opcode, 7, 0) << 2; 10521 10522 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10523 index = BitIsSet (opcode, 24); 10524 add = BitIsSet (opcode, 23); 10525 wback = BitIsSet (opcode, 21); 10526 10527 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10528 if (wback && ((n == t) || (n == t2))) 10529 return false; 10530 10531 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10532 if ((n == 15) || BadReg (t) || BadReg (t2)) 10533 return false; 10534 10535 break; 10536 10537 case eEncodingA1: 10538 // if Rt<0> == '1' then UNPREDICTABLE; 10539 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10540 t = Bits32 (opcode, 15, 12); 10541 if (BitIsSet (t, 0)) 10542 return false; 10543 10544 t2 = t + 1; 10545 n = Bits32 (opcode, 19, 16); 10546 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10547 10548 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10549 index = BitIsSet (opcode, 24); 10550 add = BitIsSet (opcode, 23); 10551 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10552 10553 // if P == '0' && W == '1' then UNPREDICTABLE; 10554 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10555 return false; 10556 10557 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10558 if (wback && ((n == 15) || (n == t) || (n == t2))) 10559 return false; 10560 10561 // if t2 == 15 then UNPREDICTABLE; 10562 if (t2 == 15) 10563 return false; 10564 10565 break; 10566 10567 default: 10568 return false; 10569 } 10570 10571 RegisterInfo base_reg; 10572 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10573 10574 uint32_t Rn = ReadCoreReg (n, &success); 10575 if (!success) 10576 return false; 10577 10578 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10579 addr_t offset_addr; 10580 if (add) 10581 offset_addr = Rn + imm32; 10582 else 10583 offset_addr = Rn - imm32; 10584 10585 //address = if index then offset_addr else R[n]; 10586 addr_t address; 10587 if (index) 10588 address = offset_addr; 10589 else 10590 address = Rn; 10591 10592 //MemA[address,4] = R[t]; 10593 RegisterInfo data_reg; 10594 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10595 10596 uint32_t data = ReadCoreReg (t, &success); 10597 if (!success) 10598 return false; 10599 10600 EmulateInstruction::Context context; 10601 if (n == 13) 10602 context.type = eContextPushRegisterOnStack; 10603 else 10604 context.type = eContextRegisterStore; 10605 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10606 10607 const uint32_t addr_byte_size = GetAddressByteSize(); 10608 10609 if (!MemAWrite (context, address, data, addr_byte_size)) 10610 return false; 10611 10612 //MemA[address+4,4] = R[t2]; 10613 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10614 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10615 10616 data = ReadCoreReg (t2, &success); 10617 if (!success) 10618 return false; 10619 10620 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10621 return false; 10622 10623 //if wback then R[n] = offset_addr; 10624 if (wback) 10625 { 10626 if (n == 13) 10627 context.type = eContextAdjustStackPointer; 10628 else 10629 context.type = eContextAdjustBaseRegister; 10630 context.SetAddress (offset_addr); 10631 10632 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10633 return false; 10634 } 10635 } 10636 return true; 10637 } 10638 10639 10640 // A8.6.201 STRD (register) 10641 bool 10642 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10643 { 10644 #if 0 10645 if ConditionPassed() then 10646 EncodingSpecificOperations(); 10647 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10648 address = if index then offset_addr else R[n]; 10649 MemA[address,4] = R[t]; 10650 MemA[address+4,4] = R[t2]; 10651 if wback then R[n] = offset_addr; 10652 #endif 10653 10654 bool success = false; 10655 10656 if (ConditionPassed(opcode)) 10657 { 10658 uint32_t t; 10659 uint32_t t2; 10660 uint32_t n; 10661 uint32_t m; 10662 bool index; 10663 bool add; 10664 bool wback; 10665 10666 switch (encoding) 10667 { 10668 case eEncodingA1: 10669 // if Rt<0> == '1' then UNPREDICTABLE; 10670 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10671 t = Bits32 (opcode, 15, 12); 10672 if (BitIsSet (t, 0)) 10673 return false; 10674 10675 t2 = t+1; 10676 n = Bits32 (opcode, 19, 16); 10677 m = Bits32 (opcode, 3, 0); 10678 10679 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10680 index = BitIsSet (opcode, 24); 10681 add = BitIsSet (opcode, 23); 10682 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10683 10684 // if P == '0' && W == '1' then UNPREDICTABLE; 10685 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10686 return false; 10687 10688 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10689 if ((t2 == 15) || (m == 15)) 10690 return false; 10691 10692 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10693 if (wback && ((n == 15) || (n == t) || (n == t2))) 10694 return false; 10695 10696 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10697 if ((ArchVersion() < 6) && wback && (m == n)) 10698 return false; 10699 10700 break; 10701 10702 default: 10703 return false; 10704 } 10705 10706 RegisterInfo base_reg; 10707 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10708 RegisterInfo offset_reg; 10709 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10710 RegisterInfo data_reg; 10711 10712 uint32_t Rn = ReadCoreReg (n, &success); 10713 if (!success) 10714 return false; 10715 10716 uint32_t Rm = ReadCoreReg (m, &success); 10717 if (!success) 10718 return false; 10719 10720 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10721 addr_t offset_addr; 10722 if (add) 10723 offset_addr = Rn + Rm; 10724 else 10725 offset_addr = Rn - Rm; 10726 10727 // address = if index then offset_addr else R[n]; 10728 addr_t address; 10729 if (index) 10730 address = offset_addr; 10731 else 10732 address = Rn; 10733 // MemA[address,4] = R[t]; 10734 uint32_t Rt = ReadCoreReg (t, &success); 10735 if (!success) 10736 return false; 10737 10738 EmulateInstruction::Context context; 10739 if (t == 13) 10740 context.type = eContextPushRegisterOnStack; 10741 else 10742 context.type = eContextRegisterStore; 10743 10744 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10745 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10746 10747 const uint32_t addr_byte_size = GetAddressByteSize(); 10748 10749 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10750 return false; 10751 10752 // MemA[address+4,4] = R[t2]; 10753 uint32_t Rt2 = ReadCoreReg (t2, &success); 10754 if (!success) 10755 return false; 10756 10757 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10758 10759 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10760 10761 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10762 return false; 10763 10764 // if wback then R[n] = offset_addr; 10765 if (wback) 10766 { 10767 context.type = eContextAdjustBaseRegister; 10768 context.SetAddress (offset_addr); 10769 10770 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10771 return false; 10772 10773 } 10774 } 10775 return true; 10776 } 10777 10778 // A8.6.319 VLDM 10779 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10780 // an ARM core register. 10781 bool 10782 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10783 { 10784 #if 0 10785 if ConditionPassed() then 10786 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10787 address = if add then R[n] else R[n]-imm32; 10788 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10789 for r = 0 to regs-1 10790 if single_regs then 10791 S[d+r] = MemA[address,4]; address = address+4; 10792 else 10793 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10794 // Combine the word-aligned words in the correct order for current endianness. 10795 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10796 #endif 10797 10798 bool success = false; 10799 10800 if (ConditionPassed(opcode)) 10801 { 10802 bool single_regs; 10803 bool add; 10804 bool wback; 10805 uint32_t d; 10806 uint32_t n; 10807 uint32_t imm32; 10808 uint32_t regs; 10809 10810 switch (encoding) 10811 { 10812 case eEncodingT1: 10813 case eEncodingA1: 10814 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10815 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 10816 // if P == '1' && W == '0' then SEE VLDR; 10817 // if P == U && W == '1' then UNDEFINED; 10818 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10819 return false; 10820 10821 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10822 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 10823 single_regs = false; 10824 add = BitIsSet (opcode, 23); 10825 wback = BitIsSet (opcode, 21); 10826 10827 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 10828 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10829 n = Bits32 (opcode, 19, 16); 10830 imm32 = Bits32 (opcode, 7, 0) << 2; 10831 10832 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 10833 regs = Bits32 (opcode, 7, 0) / 2; 10834 10835 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10836 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10837 return false; 10838 10839 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10840 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10841 return false; 10842 10843 break; 10844 10845 case eEncodingT2: 10846 case eEncodingA2: 10847 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10848 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 10849 // if P == '1' && W == '0' then SEE VLDR; 10850 // if P == U && W == '1' then UNDEFINED; 10851 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10852 return false; 10853 10854 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10855 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); 10856 single_regs = true; 10857 add = BitIsSet (opcode, 23); 10858 wback = BitIsSet (opcode, 21); 10859 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10860 n = Bits32 (opcode, 19, 16); 10861 10862 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 10863 imm32 = Bits32 (opcode, 7, 0) << 2; 10864 regs = Bits32 (opcode, 7, 0); 10865 10866 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10867 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10868 return false; 10869 10870 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10871 if ((regs == 0) || ((d + regs) > 32)) 10872 return false; 10873 break; 10874 10875 default: 10876 return false; 10877 } 10878 10879 RegisterInfo base_reg; 10880 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10881 10882 uint32_t Rn = ReadCoreReg (n, &success); 10883 if (!success) 10884 return false; 10885 10886 // address = if add then R[n] else R[n]-imm32; 10887 addr_t address; 10888 if (add) 10889 address = Rn; 10890 else 10891 address = Rn - imm32; 10892 10893 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10894 EmulateInstruction::Context context; 10895 10896 if (wback) 10897 { 10898 uint32_t value; 10899 if (add) 10900 value = Rn + imm32; 10901 else 10902 value = Rn - imm32; 10903 10904 context.type = eContextAdjustBaseRegister; 10905 context.SetImmediateSigned (value - Rn); 10906 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10907 return false; 10908 10909 } 10910 10911 const uint32_t addr_byte_size = GetAddressByteSize(); 10912 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10913 10914 context.type = eContextRegisterLoad; 10915 10916 // for r = 0 to regs-1 10917 for (uint32_t r = 0; r < regs; ++r) 10918 { 10919 if (single_regs) 10920 { 10921 // S[d+r] = MemA[address,4]; address = address+4; 10922 context.SetRegisterPlusOffset (base_reg, address - Rn); 10923 10924 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10925 if (!success) 10926 return false; 10927 10928 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10929 return false; 10930 10931 address = address + 4; 10932 } 10933 else 10934 { 10935 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10936 context.SetRegisterPlusOffset (base_reg, address - Rn); 10937 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10938 if (!success) 10939 return false; 10940 10941 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10942 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10943 if (!success) 10944 return false; 10945 10946 address = address + 8; 10947 // // Combine the word-aligned words in the correct order for current endianness. 10948 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10949 uint64_t data; 10950 if (GetByteOrder() == eByteOrderBig) 10951 { 10952 data = word1; 10953 data = (data << 32) | word2; 10954 } 10955 else 10956 { 10957 data = word2; 10958 data = (data << 32) | word1; 10959 } 10960 10961 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10962 return false; 10963 } 10964 } 10965 } 10966 return true; 10967 } 10968 10969 // A8.6.399 VSTM 10970 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10971 // ARM core register. 10972 bool 10973 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10974 { 10975 #if 0 10976 if ConditionPassed() then 10977 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10978 address = if add then R[n] else R[n]-imm32; 10979 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10980 for r = 0 to regs-1 10981 if single_regs then 10982 MemA[address,4] = S[d+r]; address = address+4; 10983 else 10984 // Store as two word-aligned words in the correct order for current endianness. 10985 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10986 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10987 address = address+8; 10988 #endif 10989 10990 bool success = false; 10991 10992 if (ConditionPassed (opcode)) 10993 { 10994 bool single_regs; 10995 bool add; 10996 bool wback; 10997 uint32_t d; 10998 uint32_t n; 10999 uint32_t imm32; 11000 uint32_t regs; 11001 11002 switch (encoding) 11003 { 11004 case eEncodingT1: 11005 case eEncodingA1: 11006 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11007 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11008 // if P == '1' && W == '0' then SEE VSTR; 11009 // if P == U && W == '1' then UNDEFINED; 11010 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 11011 return false; 11012 11013 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 11014 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11015 single_regs = false; 11016 add = BitIsSet (opcode, 23); 11017 wback = BitIsSet (opcode, 21); 11018 11019 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11020 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11021 n = Bits32 (opcode, 19, 16); 11022 imm32 = Bits32 (opcode, 7, 0) << 2; 11023 11024 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11025 regs = Bits32 (opcode, 7, 0) / 2; 11026 11027 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 11028 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11029 return false; 11030 11031 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11032 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11033 return false; 11034 11035 break; 11036 11037 case eEncodingT2: 11038 case eEncodingA2: 11039 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11040 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11041 // if P == '1' && W == '0' then SEE VSTR; 11042 // if P == U && W == '1' then UNDEFINED; 11043 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 11044 return false; 11045 11046 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 11047 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); 11048 single_regs = true; 11049 add = BitIsSet (opcode, 23); 11050 wback = BitIsSet (opcode, 21); 11051 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11052 n = Bits32 (opcode, 19, 16); 11053 11054 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11055 imm32 = Bits32 (opcode, 7, 0) << 2; 11056 regs = Bits32 (opcode, 7, 0); 11057 11058 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 11059 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 11060 return false; 11061 11062 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11063 if ((regs == 0) || ((d + regs) > 32)) 11064 return false; 11065 11066 break; 11067 11068 default: 11069 return false; 11070 } 11071 11072 RegisterInfo base_reg; 11073 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11074 11075 uint32_t Rn = ReadCoreReg (n, &success); 11076 if (!success) 11077 return false; 11078 11079 // address = if add then R[n] else R[n]-imm32; 11080 addr_t address; 11081 if (add) 11082 address = Rn; 11083 else 11084 address = Rn - imm32; 11085 11086 EmulateInstruction::Context context; 11087 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11088 if (wback) 11089 { 11090 uint32_t value; 11091 if (add) 11092 value = Rn + imm32; 11093 else 11094 value = Rn - imm32; 11095 11096 context.type = eContextAdjustBaseRegister; 11097 context.SetRegisterPlusOffset (base_reg, value - Rn); 11098 11099 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11100 return false; 11101 } 11102 11103 const uint32_t addr_byte_size = GetAddressByteSize(); 11104 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11105 11106 context.type = eContextRegisterStore; 11107 // for r = 0 to regs-1 11108 for (uint32_t r = 0; r < regs; ++r) 11109 { 11110 11111 if (single_regs) 11112 { 11113 // MemA[address,4] = S[d+r]; address = address+4; 11114 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 11115 if (!success) 11116 return false; 11117 11118 RegisterInfo data_reg; 11119 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11120 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11121 if (!MemAWrite (context, address, data, addr_byte_size)) 11122 return false; 11123 11124 address = address + 4; 11125 } 11126 else 11127 { 11128 // // Store as two word-aligned words in the correct order for current endianness. 11129 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11130 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11131 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 11132 if (!success) 11133 return false; 11134 11135 RegisterInfo data_reg; 11136 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11137 11138 if (GetByteOrder() == eByteOrderBig) 11139 { 11140 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11141 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11142 return false; 11143 11144 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11145 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 11146 return false; 11147 } 11148 else 11149 { 11150 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11151 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11152 return false; 11153 11154 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11155 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11156 return false; 11157 } 11158 // address = address+8; 11159 address = address + 8; 11160 } 11161 } 11162 } 11163 return true; 11164 } 11165 11166 // A8.6.320 11167 // This instruction loads a single extension register from memory, using an address from an ARM core register, with 11168 // an optional offset. 11169 bool 11170 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 11171 { 11172 #if 0 11173 if ConditionPassed() then 11174 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11175 base = if n == 15 then Align(PC,4) else R[n]; 11176 address = if add then (base + imm32) else (base - imm32); 11177 if single_reg then 11178 S[d] = MemA[address,4]; 11179 else 11180 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11181 // Combine the word-aligned words in the correct order for current endianness. 11182 D[d] = if BigEndian() then word1:word2 else word2:word1; 11183 #endif 11184 11185 bool success = false; 11186 11187 if (ConditionPassed (opcode)) 11188 { 11189 bool single_reg; 11190 bool add; 11191 uint32_t imm32; 11192 uint32_t d; 11193 uint32_t n; 11194 11195 switch (encoding) 11196 { 11197 case eEncodingT1: 11198 case eEncodingA1: 11199 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11200 single_reg = false; 11201 add = BitIsSet (opcode, 23); 11202 imm32 = Bits32 (opcode, 7, 0) << 2; 11203 11204 // d = UInt(D:Vd); n = UInt(Rn); 11205 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11206 n = Bits32 (opcode, 19, 16); 11207 11208 break; 11209 11210 case eEncodingT2: 11211 case eEncodingA2: 11212 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11213 single_reg = true; 11214 add = BitIsSet (opcode, 23); 11215 imm32 = Bits32 (opcode, 7, 0) << 2; 11216 11217 // d = UInt(Vd:D); n = UInt(Rn); 11218 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11219 n = Bits32 (opcode, 19, 16); 11220 11221 break; 11222 11223 default: 11224 return false; 11225 } 11226 RegisterInfo base_reg; 11227 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11228 11229 uint32_t Rn = ReadCoreReg (n, &success); 11230 if (!success) 11231 return false; 11232 11233 // base = if n == 15 then Align(PC,4) else R[n]; 11234 uint32_t base; 11235 if (n == 15) 11236 base = AlignPC (Rn); 11237 else 11238 base = Rn; 11239 11240 // address = if add then (base + imm32) else (base - imm32); 11241 addr_t address; 11242 if (add) 11243 address = base + imm32; 11244 else 11245 address = base - imm32; 11246 11247 const uint32_t addr_byte_size = GetAddressByteSize(); 11248 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11249 11250 EmulateInstruction::Context context; 11251 context.type = eContextRegisterLoad; 11252 context.SetRegisterPlusOffset (base_reg, address - base); 11253 11254 if (single_reg) 11255 { 11256 // S[d] = MemA[address,4]; 11257 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11258 if (!success) 11259 return false; 11260 11261 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11262 return false; 11263 } 11264 else 11265 { 11266 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11267 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11268 if (!success) 11269 return false; 11270 11271 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11272 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11273 if (!success) 11274 return false; 11275 // // Combine the word-aligned words in the correct order for current endianness. 11276 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11277 uint64_t data64; 11278 if (GetByteOrder() == eByteOrderBig) 11279 { 11280 data64 = word1; 11281 data64 = (data64 << 32) | word2; 11282 } 11283 else 11284 { 11285 data64 = word2; 11286 data64 = (data64 << 32) | word1; 11287 } 11288 11289 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11290 return false; 11291 } 11292 } 11293 return true; 11294 } 11295 11296 // A8.6.400 VSTR 11297 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11298 // optional offset. 11299 bool 11300 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11301 { 11302 #if 0 11303 if ConditionPassed() then 11304 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11305 address = if add then (R[n] + imm32) else (R[n] - imm32); 11306 if single_reg then 11307 MemA[address,4] = S[d]; 11308 else 11309 // Store as two word-aligned words in the correct order for current endianness. 11310 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11311 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11312 #endif 11313 11314 bool success = false; 11315 11316 if (ConditionPassed (opcode)) 11317 { 11318 bool single_reg; 11319 bool add; 11320 uint32_t imm32; 11321 uint32_t d; 11322 uint32_t n; 11323 11324 switch (encoding) 11325 { 11326 case eEncodingT1: 11327 case eEncodingA1: 11328 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11329 single_reg = false; 11330 add = BitIsSet (opcode, 23); 11331 imm32 = Bits32 (opcode, 7, 0) << 2; 11332 11333 // d = UInt(D:Vd); n = UInt(Rn); 11334 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11335 n = Bits32 (opcode, 19, 16); 11336 11337 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11338 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11339 return false; 11340 11341 break; 11342 11343 case eEncodingT2: 11344 case eEncodingA2: 11345 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11346 single_reg = true; 11347 add = BitIsSet (opcode, 23); 11348 imm32 = Bits32 (opcode, 7, 0) << 2; 11349 11350 // d = UInt(Vd:D); n = UInt(Rn); 11351 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11352 n = Bits32 (opcode, 19, 16); 11353 11354 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11355 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11356 return false; 11357 11358 break; 11359 11360 default: 11361 return false; 11362 } 11363 11364 RegisterInfo base_reg; 11365 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11366 11367 uint32_t Rn = ReadCoreReg (n, &success); 11368 if (!success) 11369 return false; 11370 11371 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11372 addr_t address; 11373 if (add) 11374 address = Rn + imm32; 11375 else 11376 address = Rn - imm32; 11377 11378 const uint32_t addr_byte_size = GetAddressByteSize(); 11379 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11380 11381 RegisterInfo data_reg; 11382 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11383 EmulateInstruction::Context context; 11384 context.type = eContextRegisterStore; 11385 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11386 11387 if (single_reg) 11388 { 11389 // MemA[address,4] = S[d]; 11390 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11391 if (!success) 11392 return false; 11393 11394 if (!MemAWrite (context, address, data, addr_byte_size)) 11395 return false; 11396 } 11397 else 11398 { 11399 // // Store as two word-aligned words in the correct order for current endianness. 11400 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11401 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11402 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11403 if (!success) 11404 return false; 11405 11406 if (GetByteOrder() == eByteOrderBig) 11407 { 11408 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11409 return false; 11410 11411 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11412 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11413 return false; 11414 } 11415 else 11416 { 11417 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11418 return false; 11419 11420 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11421 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11422 return false; 11423 } 11424 } 11425 } 11426 return true; 11427 } 11428 11429 // A8.6.307 VLDI1 (multiple single elements) 11430 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11431 // element of each register is loaded. 11432 bool 11433 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11434 { 11435 #if 0 11436 if ConditionPassed() then 11437 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11438 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11439 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11440 for r = 0 to regs-1 11441 for e = 0 to elements-1 11442 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11443 address = address + ebytes; 11444 #endif 11445 11446 bool success = false; 11447 11448 if (ConditionPassed (opcode)) 11449 { 11450 uint32_t regs; 11451 uint32_t alignment; 11452 uint32_t ebytes; 11453 uint32_t esize; 11454 uint32_t elements; 11455 uint32_t d; 11456 uint32_t n; 11457 uint32_t m; 11458 bool wback; 11459 bool register_index; 11460 11461 switch (encoding) 11462 { 11463 case eEncodingT1: 11464 case eEncodingA1: 11465 { 11466 // case type of 11467 // when '0111' 11468 // regs = 1; if align<1> == '1' then UNDEFINED; 11469 // when '1010' 11470 // regs = 2; if align == '11' then UNDEFINED; 11471 // when '0110' 11472 // regs = 3; if align<1> == '1' then UNDEFINED; 11473 // when '0010' 11474 // regs = 4; 11475 // otherwise 11476 // SEE 'Related encodings'; 11477 uint32_t type = Bits32 (opcode, 11, 8); 11478 uint32_t align = Bits32 (opcode, 5, 4); 11479 if (type == 7) // '0111' 11480 { 11481 regs = 1; 11482 if (BitIsSet (align, 1)) 11483 return false; 11484 } 11485 else if (type == 10) // '1010' 11486 { 11487 regs = 2; 11488 if (align == 3) 11489 return false; 11490 11491 } 11492 else if (type == 6) // '0110' 11493 { 11494 regs = 3; 11495 if (BitIsSet (align, 1)) 11496 return false; 11497 } 11498 else if (type == 2) // '0010' 11499 { 11500 regs = 4; 11501 } 11502 else 11503 return false; 11504 11505 // alignment = if align == '00' then 1 else 4 << UInt(align); 11506 if (align == 0) 11507 alignment = 1; 11508 else 11509 alignment = 4 << align; 11510 11511 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11512 ebytes = 1 << Bits32 (opcode, 7, 6); 11513 esize = 8 * ebytes; 11514 elements = 8 / ebytes; 11515 11516 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11517 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11518 n = Bits32 (opcode, 19, 15); 11519 m = Bits32 (opcode, 3, 0); 11520 11521 // wback = (m != 15); register_index = (m != 15 && m != 13); 11522 wback = (m != 15); 11523 register_index = ((m != 15) && (m != 13)); 11524 11525 // if d+regs > 32 then UNPREDICTABLE; 11526 if ((d + regs) > 32) 11527 return false; 11528 } 11529 break; 11530 11531 default: 11532 return false; 11533 } 11534 11535 RegisterInfo base_reg; 11536 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11537 11538 uint32_t Rn = ReadCoreReg (n, &success); 11539 if (!success) 11540 return false; 11541 11542 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11543 addr_t address = Rn; 11544 if ((address % alignment) != 0) 11545 return false; 11546 11547 EmulateInstruction::Context context; 11548 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11549 if (wback) 11550 { 11551 uint32_t Rm = ReadCoreReg (m, &success); 11552 if (!success) 11553 return false; 11554 11555 uint32_t offset; 11556 if (register_index) 11557 offset = Rm; 11558 else 11559 offset = 8 * regs; 11560 11561 uint32_t value = Rn + offset; 11562 context.type = eContextAdjustBaseRegister; 11563 context.SetRegisterPlusOffset (base_reg, offset); 11564 11565 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11566 return false; 11567 11568 } 11569 11570 // for r = 0 to regs-1 11571 for (uint32_t r = 0; r < regs; ++r) 11572 { 11573 // for e = 0 to elements-1 11574 uint64_t assembled_data = 0; 11575 for (uint32_t e = 0; e < elements; ++e) 11576 { 11577 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11578 context.type = eContextRegisterLoad; 11579 context.SetRegisterPlusOffset (base_reg, address - Rn); 11580 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11581 if (!success) 11582 return false; 11583 11584 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11585 11586 // address = address + ebytes; 11587 address = address + ebytes; 11588 } 11589 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11590 return false; 11591 } 11592 } 11593 return true; 11594 } 11595 11596 // A8.6.308 VLD1 (single element to one lane) 11597 // 11598 bool 11599 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11600 { 11601 #if 0 11602 if ConditionPassed() then 11603 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11604 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11605 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11606 Elem[D[d],index,esize] = MemU[address,ebytes]; 11607 #endif 11608 11609 bool success = false; 11610 11611 if (ConditionPassed (opcode)) 11612 { 11613 uint32_t ebytes; 11614 uint32_t esize; 11615 uint32_t index; 11616 uint32_t alignment; 11617 uint32_t d; 11618 uint32_t n; 11619 uint32_t m; 11620 bool wback; 11621 bool register_index; 11622 11623 switch (encoding) 11624 { 11625 case eEncodingT1: 11626 case eEncodingA1: 11627 { 11628 uint32_t size = Bits32 (opcode, 11, 10); 11629 uint32_t index_align = Bits32 (opcode, 7, 4); 11630 // if size == '11' then SEE VLD1 (single element to all lanes); 11631 if (size == 3) 11632 return EmulateVLD1SingleAll (opcode, encoding); 11633 // case size of 11634 if (size == 0) // when '00' 11635 { 11636 // if index_align<0> != '0' then UNDEFINED; 11637 if (BitIsClear (index_align, 0)) 11638 return false; 11639 11640 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11641 ebytes = 1; 11642 esize = 8; 11643 index = Bits32 (index_align, 3, 1); 11644 alignment = 1; 11645 } 11646 else if (size == 1) // when '01' 11647 { 11648 // if index_align<1> != '0' then UNDEFINED; 11649 if (BitIsClear (index_align, 1)) 11650 return false; 11651 11652 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11653 ebytes = 2; 11654 esize = 16; 11655 index = Bits32 (index_align, 3, 2); 11656 11657 // alignment = if index_align<0> == '0' then 1 else 2; 11658 if (BitIsClear (index_align, 0)) 11659 alignment = 1; 11660 else 11661 alignment = 2; 11662 } 11663 else if (size == 2) // when '10' 11664 { 11665 // if index_align<2> != '0' then UNDEFINED; 11666 if (BitIsClear (index_align, 2)) 11667 return false; 11668 11669 // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED; 11670 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11671 return false; 11672 11673 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11674 ebytes = 4; 11675 esize = 32; 11676 index = Bit32 (index_align, 3); 11677 11678 // alignment = if index_align<1:0> == '00' then 1 else 4; 11679 if (Bits32 (index_align, 1, 0) == 0) 11680 alignment = 1; 11681 else 11682 alignment = 4; 11683 } 11684 else 11685 { 11686 return false; 11687 } 11688 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11689 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11690 n = Bits32 (opcode, 19, 16); 11691 m = Bits32 (opcode, 3, 0); 11692 11693 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11694 wback = (m != 15); 11695 register_index = ((m != 15) && (m != 13)); 11696 11697 if (n == 15) 11698 return false; 11699 11700 } 11701 break; 11702 11703 default: 11704 return false; 11705 } 11706 11707 RegisterInfo base_reg; 11708 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11709 11710 uint32_t Rn = ReadCoreReg (n, &success); 11711 if (!success) 11712 return false; 11713 11714 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11715 addr_t address = Rn; 11716 if ((address % alignment) != 0) 11717 return false; 11718 11719 EmulateInstruction::Context context; 11720 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11721 if (wback) 11722 { 11723 uint32_t Rm = ReadCoreReg (m, &success); 11724 if (!success) 11725 return false; 11726 11727 uint32_t offset; 11728 if (register_index) 11729 offset = Rm; 11730 else 11731 offset = ebytes; 11732 11733 uint32_t value = Rn + offset; 11734 11735 context.type = eContextAdjustBaseRegister; 11736 context.SetRegisterPlusOffset (base_reg, offset); 11737 11738 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11739 return false; 11740 } 11741 11742 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11743 uint32_t element = MemURead (context, address, esize, 0, &success); 11744 if (!success) 11745 return false; 11746 11747 element = element << (index * esize); 11748 11749 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11750 if (!success) 11751 return false; 11752 11753 uint64_t all_ones = -1; 11754 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11755 // at element & to the right of element. 11756 if (index > 0) 11757 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11758 // now mask should be 0's where element goes & 1's 11759 // everywhere else. 11760 11761 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11762 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11763 11764 context.type = eContextRegisterLoad; 11765 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11766 return false; 11767 } 11768 return true; 11769 } 11770 11771 // A8.6.391 VST1 (multiple single elements) 11772 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without 11773 // interleaving. Every element of each register is stored. 11774 bool 11775 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11776 { 11777 #if 0 11778 if ConditionPassed() then 11779 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11780 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11781 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11782 for r = 0 to regs-1 11783 for e = 0 to elements-1 11784 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11785 address = address + ebytes; 11786 #endif 11787 11788 bool success = false; 11789 11790 if (ConditionPassed (opcode)) 11791 { 11792 uint32_t regs; 11793 uint32_t alignment; 11794 uint32_t ebytes; 11795 uint32_t esize; 11796 uint32_t elements; 11797 uint32_t d; 11798 uint32_t n; 11799 uint32_t m; 11800 bool wback; 11801 bool register_index; 11802 11803 switch (encoding) 11804 { 11805 case eEncodingT1: 11806 case eEncodingA1: 11807 { 11808 uint32_t type = Bits32 (opcode, 11, 8); 11809 uint32_t align = Bits32 (opcode, 5, 4); 11810 11811 // case type of 11812 if (type == 7) // when '0111' 11813 { 11814 // regs = 1; if align<1> == '1' then UNDEFINED; 11815 regs = 1; 11816 if (BitIsSet (align, 1)) 11817 return false; 11818 } 11819 else if (type == 10) // when '1010' 11820 { 11821 // regs = 2; if align == '11' then UNDEFINED; 11822 regs = 2; 11823 if (align == 3) 11824 return false; 11825 } 11826 else if (type == 6) // when '0110' 11827 { 11828 // regs = 3; if align<1> == '1' then UNDEFINED; 11829 regs = 3; 11830 if (BitIsSet (align, 1)) 11831 return false; 11832 } 11833 else if (type == 2) // when '0010' 11834 // regs = 4; 11835 regs = 4; 11836 else // otherwise 11837 // SEE 'Related encodings'; 11838 return false; 11839 11840 // alignment = if align == '00' then 1 else 4 << UInt(align); 11841 if (align == 0) 11842 alignment = 1; 11843 else 11844 alignment = 4 << align; 11845 11846 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11847 ebytes = 1 << Bits32 (opcode,7, 6); 11848 esize = 8 * ebytes; 11849 elements = 8 / ebytes; 11850 11851 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11852 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11853 n = Bits32 (opcode, 19, 16); 11854 m = Bits32 (opcode, 3, 0); 11855 11856 // wback = (m != 15); register_index = (m != 15 && m != 13); 11857 wback = (m != 15); 11858 register_index = ((m != 15) && (m != 13)); 11859 11860 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11861 if ((d + regs) > 32) 11862 return false; 11863 11864 if (n == 15) 11865 return false; 11866 11867 } 11868 break; 11869 11870 default: 11871 return false; 11872 } 11873 11874 RegisterInfo base_reg; 11875 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11876 11877 uint32_t Rn = ReadCoreReg (n, &success); 11878 if (!success) 11879 return false; 11880 11881 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11882 addr_t address = Rn; 11883 if ((address % alignment) != 0) 11884 return false; 11885 11886 EmulateInstruction::Context context; 11887 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11888 if (wback) 11889 { 11890 uint32_t Rm = ReadCoreReg (m, &success); 11891 if (!success) 11892 return false; 11893 11894 uint32_t offset; 11895 if (register_index) 11896 offset = Rm; 11897 else 11898 offset = 8 * regs; 11899 11900 context.type = eContextAdjustBaseRegister; 11901 context.SetRegisterPlusOffset (base_reg, offset); 11902 11903 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11904 return false; 11905 } 11906 11907 RegisterInfo data_reg; 11908 context.type = eContextRegisterStore; 11909 // for r = 0 to regs-1 11910 for (uint32_t r = 0; r < regs; ++r) 11911 { 11912 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11913 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11914 if (!success) 11915 return false; 11916 11917 // for e = 0 to elements-1 11918 for (uint32_t e = 0; e < elements; ++e) 11919 { 11920 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11921 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11922 11923 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11924 if (!MemUWrite (context, address, word, ebytes)) 11925 return false; 11926 11927 // address = address + ebytes; 11928 address = address + ebytes; 11929 } 11930 } 11931 } 11932 return true; 11933 } 11934 11935 // A8.6.392 VST1 (single element from one lane) 11936 // This instruction stores one element to memory from one element of a register. 11937 bool 11938 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11939 { 11940 #if 0 11941 if ConditionPassed() then 11942 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11943 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11944 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11945 MemU[address,ebytes] = Elem[D[d],index,esize]; 11946 #endif 11947 11948 bool success = false; 11949 11950 if (ConditionPassed (opcode)) 11951 { 11952 uint32_t ebytes; 11953 uint32_t esize; 11954 uint32_t index; 11955 uint32_t alignment; 11956 uint32_t d; 11957 uint32_t n; 11958 uint32_t m; 11959 bool wback; 11960 bool register_index; 11961 11962 switch (encoding) 11963 { 11964 case eEncodingT1: 11965 case eEncodingA1: 11966 { 11967 uint32_t size = Bits32 (opcode, 11, 10); 11968 uint32_t index_align = Bits32 (opcode, 7, 4); 11969 11970 // if size == '11' then UNDEFINED; 11971 if (size == 3) 11972 return false; 11973 11974 // case size of 11975 if (size == 0) // when '00' 11976 { 11977 // if index_align<0> != '0' then UNDEFINED; 11978 if (BitIsClear (index_align, 0)) 11979 return false; 11980 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11981 ebytes = 1; 11982 esize = 8; 11983 index = Bits32 (index_align, 3, 1); 11984 alignment = 1; 11985 } 11986 else if (size == 1) // when '01' 11987 { 11988 // if index_align<1> != '0' then UNDEFINED; 11989 if (BitIsClear (index_align, 1)) 11990 return false; 11991 11992 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11993 ebytes = 2; 11994 esize = 16; 11995 index = Bits32 (index_align, 3, 2); 11996 11997 // alignment = if index_align<0> == '0' then 1 else 2; 11998 if (BitIsClear (index_align, 0)) 11999 alignment = 1; 12000 else 12001 alignment = 2; 12002 } 12003 else if (size == 2) // when '10' 12004 { 12005 // if index_align<2> != '0' then UNDEFINED; 12006 if (BitIsClear (index_align, 2)) 12007 return false; 12008 12009 // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED; 12010 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 12011 return false; 12012 12013 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12014 ebytes = 4; 12015 esize = 32; 12016 index = Bit32 (index_align, 3); 12017 12018 // alignment = if index_align<1:0> == '00' then 1 else 4; 12019 if (Bits32 (index_align, 1, 0) == 0) 12020 alignment = 1; 12021 else 12022 alignment = 4; 12023 } 12024 else 12025 { 12026 return false; 12027 } 12028 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12029 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 12030 n = Bits32 (opcode, 19, 16); 12031 m = Bits32 (opcode, 3, 0); 12032 12033 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 12034 wback = (m != 15); 12035 register_index = ((m != 15) && (m != 13)); 12036 12037 if (n == 15) 12038 return false; 12039 } 12040 break; 12041 12042 default: 12043 return false; 12044 } 12045 12046 RegisterInfo base_reg; 12047 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12048 12049 uint32_t Rn = ReadCoreReg (n, &success); 12050 if (!success) 12051 return false; 12052 12053 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12054 addr_t address = Rn; 12055 if ((address % alignment) != 0) 12056 return false; 12057 12058 EmulateInstruction::Context context; 12059 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12060 if (wback) 12061 { 12062 uint32_t Rm = ReadCoreReg (m, &success); 12063 if (!success) 12064 return false; 12065 12066 uint32_t offset; 12067 if (register_index) 12068 offset = Rm; 12069 else 12070 offset = ebytes; 12071 12072 context.type = eContextAdjustBaseRegister; 12073 context.SetRegisterPlusOffset (base_reg, offset); 12074 12075 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12076 return false; 12077 } 12078 12079 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12080 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12081 if (!success) 12082 return false; 12083 12084 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 12085 12086 RegisterInfo data_reg; 12087 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12088 context.type = eContextRegisterStore; 12089 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 12090 12091 if (!MemUWrite (context, address, word, ebytes)) 12092 return false; 12093 } 12094 return true; 12095 } 12096 12097 // A8.6.309 VLD1 (single element to all lanes) 12098 // This instruction loads one element from memory into every element of one or two vectors. 12099 bool 12100 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 12101 { 12102 #if 0 12103 if ConditionPassed() then 12104 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12105 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12106 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12107 replicated_element = Replicate(MemU[address,ebytes], elements); 12108 for r = 0 to regs-1 12109 D[d+r] = replicated_element; 12110 #endif 12111 12112 bool success = false; 12113 12114 if (ConditionPassed (opcode)) 12115 { 12116 uint32_t ebytes; 12117 uint32_t elements; 12118 uint32_t regs; 12119 uint32_t alignment; 12120 uint32_t d; 12121 uint32_t n; 12122 uint32_t m; 12123 bool wback; 12124 bool register_index; 12125 12126 switch (encoding) 12127 { 12128 case eEncodingT1: 12129 case eEncodingA1: 12130 { 12131 //if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12132 uint32_t size = Bits32 (opcode, 7, 6); 12133 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 12134 return false; 12135 12136 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' then 1 else 2; 12137 ebytes = 1 << size; 12138 elements = 8 / ebytes; 12139 if (BitIsClear (opcode, 5)) 12140 regs = 1; 12141 else 12142 regs = 2; 12143 12144 //alignment = if a == '0' then 1 else ebytes; 12145 if (BitIsClear (opcode, 4)) 12146 alignment = 1; 12147 else 12148 alignment = ebytes; 12149 12150 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12151 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 12152 n = Bits32 (opcode, 19, 16); 12153 m = Bits32 (opcode, 3, 0); 12154 12155 //wback = (m != 15); register_index = (m != 15 && m != 13); 12156 wback = (m != 15); 12157 register_index = ((m != 15) && (m != 13)); 12158 12159 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12160 if ((d + regs) > 32) 12161 return false; 12162 12163 if (n == 15) 12164 return false; 12165 } 12166 break; 12167 12168 default: 12169 return false; 12170 } 12171 12172 RegisterInfo base_reg; 12173 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12174 12175 uint32_t Rn = ReadCoreReg (n, &success); 12176 if (!success) 12177 return false; 12178 12179 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12180 addr_t address = Rn; 12181 if ((address % alignment) != 0) 12182 return false; 12183 12184 EmulateInstruction::Context context; 12185 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12186 if (wback) 12187 { 12188 uint32_t Rm = ReadCoreReg (m, &success); 12189 if (!success) 12190 return false; 12191 12192 uint32_t offset; 12193 if (register_index) 12194 offset = Rm; 12195 else 12196 offset = ebytes; 12197 12198 context.type = eContextAdjustBaseRegister; 12199 context.SetRegisterPlusOffset (base_reg, offset); 12200 12201 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12202 return false; 12203 } 12204 12205 // replicated_element = Replicate(MemU[address,ebytes], elements); 12206 12207 context.type = eContextRegisterLoad; 12208 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12209 if (!success) 12210 return false; 12211 12212 uint64_t replicated_element = 0; 12213 uint32_t esize = ebytes * 8; 12214 for (uint32_t e = 0; e < elements; ++e) 12215 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12216 12217 // for r = 0 to regs-1 12218 for (uint32_t r = 0; r < regs; ++r) 12219 { 12220 // D[d+r] = replicated_element; 12221 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12222 return false; 12223 } 12224 } 12225 return true; 12226 } 12227 12228 // B6.2.13 SUBS PC, LR and related instructions 12229 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12230 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12231 bool 12232 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12233 { 12234 #if 0 12235 if ConditionPassed() then 12236 EncodingSpecificOperations(); 12237 if CurrentInstrSet() == InstrSet_ThumbEE then 12238 UNPREDICTABLE; 12239 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12240 case opcode of 12241 when '0000' result = R[n] AND operand2; // AND 12242 when '0001' result = R[n] EOR operand2; // EOR 12243 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12244 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12245 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12246 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12247 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12248 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12249 when '1100' result = R[n] OR operand2; // ORR 12250 when '1101' result = operand2; // MOV 12251 when '1110' result = R[n] AND NOT(operand2); // BIC 12252 when '1111' result = NOT(operand2); // MVN 12253 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12254 BranchWritePC(result); 12255 #endif 12256 12257 bool success = false; 12258 12259 if (ConditionPassed (opcode)) 12260 { 12261 uint32_t n; 12262 uint32_t m; 12263 uint32_t imm32; 12264 bool register_form; 12265 ARM_ShifterType shift_t; 12266 uint32_t shift_n; 12267 uint32_t code; 12268 12269 switch (encoding) 12270 { 12271 case eEncodingT1: 12272 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12273 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; // = SUB 12274 n = 14; 12275 imm32 = Bits32 (opcode, 7, 0); 12276 register_form = false; 12277 code = 2; 12278 12279 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12280 if (InITBlock() && !LastInITBlock()) 12281 return false; 12282 12283 break; 12284 12285 case eEncodingA1: 12286 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12287 n = Bits32 (opcode, 19, 16); 12288 imm32 = ARMExpandImm (opcode); 12289 register_form = false; 12290 code = Bits32 (opcode, 24, 21); 12291 12292 break; 12293 12294 case eEncodingA2: 12295 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12296 n = Bits32 (opcode, 19, 16); 12297 m = Bits32 (opcode, 3, 0); 12298 register_form = true; 12299 12300 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12301 shift_n = DecodeImmShiftARM (opcode, shift_t); 12302 12303 break; 12304 12305 default: 12306 return false; 12307 } 12308 12309 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12310 uint32_t operand2; 12311 if (register_form) 12312 { 12313 uint32_t Rm = ReadCoreReg (m, &success); 12314 if (!success) 12315 return false; 12316 12317 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12318 if (!success) 12319 return false; 12320 } 12321 else 12322 { 12323 operand2 = imm32; 12324 } 12325 12326 uint32_t Rn = ReadCoreReg (n, &success); 12327 if (!success) 12328 return false; 12329 12330 AddWithCarryResult result; 12331 12332 // case opcode of 12333 switch (code) 12334 { 12335 case 0: // when '0000' 12336 // result = R[n] AND operand2; // AND 12337 result.result = Rn & operand2; 12338 break; 12339 12340 case 1: // when '0001' 12341 // result = R[n] EOR operand2; // EOR 12342 result.result = Rn ^ operand2; 12343 break; 12344 12345 case 2: // when '0010' 12346 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12347 result = AddWithCarry (Rn, ~(operand2), 1); 12348 break; 12349 12350 case 3: // when '0011' 12351 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12352 result = AddWithCarry (~(Rn), operand2, 1); 12353 break; 12354 12355 case 4: // when '0100' 12356 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12357 result = AddWithCarry (Rn, operand2, 0); 12358 break; 12359 12360 case 5: // when '0101' 12361 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12362 result = AddWithCarry (Rn, operand2, APSR_C); 12363 break; 12364 12365 case 6: // when '0110' 12366 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12367 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12368 break; 12369 12370 case 7: // when '0111' 12371 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12372 result = AddWithCarry (~(Rn), operand2, APSR_C); 12373 break; 12374 12375 case 10: // when '1100' 12376 // result = R[n] OR operand2; // ORR 12377 result.result = Rn | operand2; 12378 break; 12379 12380 case 11: // when '1101' 12381 // result = operand2; // MOV 12382 result.result = operand2; 12383 break; 12384 12385 case 12: // when '1110' 12386 // result = R[n] AND NOT(operand2); // BIC 12387 result.result = Rn & ~(operand2); 12388 break; 12389 12390 case 15: // when '1111' 12391 // result = NOT(operand2); // MVN 12392 result.result = ~(operand2); 12393 break; 12394 12395 default: 12396 return false; 12397 } 12398 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12399 12400 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12401 // the best. 12402 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12403 if (!success) 12404 return false; 12405 12406 CPSRWriteByInstr (spsr, 15, true); 12407 12408 // BranchWritePC(result); 12409 EmulateInstruction::Context context; 12410 context.type = eContextAdjustPC; 12411 context.SetImmediate (result.result); 12412 12413 BranchWritePC (context, result.result); 12414 } 12415 return true; 12416 } 12417 12418 EmulateInstructionARM::ARMOpcode* 12419 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12420 { 12421 static ARMOpcode 12422 g_arm_opcodes[] = 12423 { 12424 //---------------------------------------------------------------------- 12425 // Prologue instructions 12426 //---------------------------------------------------------------------- 12427 12428 // push register(s) 12429 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12430 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12431 12432 // set r7 to point to a stack offset 12433 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12434 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12435 // copy the stack pointer to ip 12436 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12437 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12438 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12439 12440 // adjust the stack pointer 12441 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12442 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12443 12444 // push one register 12445 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12446 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12447 12448 // vector push consecutive extension register(s) 12449 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12450 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12451 12452 //---------------------------------------------------------------------- 12453 // Epilogue instructions 12454 //---------------------------------------------------------------------- 12455 12456 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12457 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12458 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12459 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12460 12461 //---------------------------------------------------------------------- 12462 // Supervisor Call (previously Software Interrupt) 12463 //---------------------------------------------------------------------- 12464 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12465 12466 //---------------------------------------------------------------------- 12467 // Branch instructions 12468 //---------------------------------------------------------------------- 12469 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>". 12470 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12471 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12472 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12473 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12474 // for example, "bx lr" 12475 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12476 // bxj 12477 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12478 12479 //---------------------------------------------------------------------- 12480 // Data-processing instructions 12481 //---------------------------------------------------------------------- 12482 // adc (immediate) 12483 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12484 // adc (register) 12485 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12486 // add (immediate) 12487 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12488 // add (register) 12489 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12490 // add (register-shifted register) 12491 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12492 // adr 12493 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12494 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12495 // and (immediate) 12496 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12497 // and (register) 12498 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12499 // bic (immediate) 12500 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12501 // bic (register) 12502 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12503 // eor (immediate) 12504 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12505 // eor (register) 12506 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12507 // orr (immediate) 12508 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12509 // orr (register) 12510 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12511 // rsb (immediate) 12512 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12513 // rsb (register) 12514 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12515 // rsc (immediate) 12516 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12517 // rsc (register) 12518 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12519 // sbc (immediate) 12520 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12521 // sbc (register) 12522 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12523 // sub (immediate, ARM) 12524 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12525 // sub (sp minus immediate) 12526 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12527 // sub (register) 12528 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12529 // teq (immediate) 12530 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12531 // teq (register) 12532 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12533 // tst (immediate) 12534 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12535 // tst (register) 12536 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12537 12538 // mov (immediate) 12539 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12540 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12541 // mov (register) 12542 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12543 // mvn (immediate) 12544 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12545 // mvn (register) 12546 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12547 // cmn (immediate) 12548 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12549 // cmn (register) 12550 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12551 // cmp (immediate) 12552 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12553 // cmp (register) 12554 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12555 // asr (immediate) 12556 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12557 // asr (register) 12558 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12559 // lsl (immediate) 12560 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12561 // lsl (register) 12562 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12563 // lsr (immediate) 12564 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12565 // lsr (register) 12566 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12567 // rrx is a special case encoding of ror (immediate) 12568 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12569 // ror (immediate) 12570 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12571 // ror (register) 12572 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12573 // mul 12574 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12575 12576 // subs pc, lr and related instructions 12577 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12578 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12579 12580 //---------------------------------------------------------------------- 12581 // Load instructions 12582 //---------------------------------------------------------------------- 12583 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12584 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12585 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12586 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12587 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12588 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12589 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12590 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12591 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12592 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12593 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12594 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12595 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12596 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12597 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12598 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12599 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12600 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12601 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12602 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12603 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12604 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12605 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12606 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12607 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12608 12609 //---------------------------------------------------------------------- 12610 // Store instructions 12611 //---------------------------------------------------------------------- 12612 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12613 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12614 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12615 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12616 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12617 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12618 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12619 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12620 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12621 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12622 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12623 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12624 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12625 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12626 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12627 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12628 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12629 12630 //---------------------------------------------------------------------- 12631 // Other instructions 12632 //---------------------------------------------------------------------- 12633 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12634 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12635 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12636 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12637 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12638 12639 }; 12640 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 12641 12642 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12643 { 12644 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12645 (g_arm_opcodes[i].variants & arm_isa) != 0) 12646 return &g_arm_opcodes[i]; 12647 } 12648 return NULL; 12649 } 12650 12651 12652 EmulateInstructionARM::ARMOpcode* 12653 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12654 { 12655 12656 static ARMOpcode 12657 g_thumb_opcodes[] = 12658 { 12659 //---------------------------------------------------------------------- 12660 // Prologue instructions 12661 //---------------------------------------------------------------------- 12662 12663 // push register(s) 12664 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12665 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12666 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12667 12668 // set r7 to point to a stack offset 12669 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12670 // copy the stack pointer to r7 12671 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12672 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12673 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12674 12675 // PC-relative load into register (see also EmulateADDSPRm) 12676 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12677 12678 // adjust the stack pointer 12679 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12680 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12681 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12682 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12683 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12684 12685 // vector push consecutive extension register(s) 12686 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12687 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12688 12689 //---------------------------------------------------------------------- 12690 // Epilogue instructions 12691 //---------------------------------------------------------------------- 12692 12693 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12694 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12695 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12696 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12697 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12698 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12699 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12700 12701 //---------------------------------------------------------------------- 12702 // Supervisor Call (previously Software Interrupt) 12703 //---------------------------------------------------------------------- 12704 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12705 12706 //---------------------------------------------------------------------- 12707 // If Then makes up to four following instructions conditional. 12708 //---------------------------------------------------------------------- 12709 // The next 5 opcode _must_ come before the if then instruction 12710 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12711 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12712 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12713 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12714 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12715 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12716 12717 //---------------------------------------------------------------------- 12718 // Branch instructions 12719 //---------------------------------------------------------------------- 12720 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12721 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12722 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12723 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12724 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12725 // J1 == J2 == 1 12726 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12727 // J1 == J2 == 1 12728 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12729 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12730 // for example, "bx lr" 12731 { 0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12732 // bxj 12733 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12734 // compare and branch 12735 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12736 // table branch byte 12737 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12738 // table branch halfword 12739 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12740 12741 //---------------------------------------------------------------------- 12742 // Data-processing instructions 12743 //---------------------------------------------------------------------- 12744 // adc (immediate) 12745 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12746 // adc (register) 12747 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12748 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12749 // add (register) 12750 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12751 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12752 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12753 // adr 12754 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12755 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12756 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12757 // and (immediate) 12758 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12759 // and (register) 12760 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12761 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12762 // bic (immediate) 12763 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12764 // bic (register) 12765 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12766 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12767 // eor (immediate) 12768 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12769 // eor (register) 12770 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12771 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12772 // orr (immediate) 12773 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12774 // orr (register) 12775 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12776 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12777 // rsb (immediate) 12778 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12779 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12780 // rsb (register) 12781 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12782 // sbc (immediate) 12783 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12784 // sbc (register) 12785 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12786 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12787 // add (immediate, Thumb) 12788 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12789 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12790 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12791 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12792 // sub (immediate, Thumb) 12793 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12794 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12795 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12796 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12797 // sub (sp minus immediate) 12798 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12799 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12800 // sub (register) 12801 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12802 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12803 // teq (immediate) 12804 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12805 // teq (register) 12806 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12807 // tst (immediate) 12808 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12809 // tst (register) 12810 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12811 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12812 12813 12814 // move from high register to high register 12815 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12816 // move from low register to low register 12817 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12818 // mov{s}<c>.w <Rd>, <Rm> 12819 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12820 // move immediate 12821 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12822 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12823 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12824 // mvn (immediate) 12825 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12826 // mvn (register) 12827 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12828 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12829 // cmn (immediate) 12830 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12831 // cmn (register) 12832 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12833 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12834 // cmp (immediate) 12835 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12836 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12837 // cmp (register) (Rn and Rm both from r0-r7) 12838 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12839 // cmp (register) (Rn and Rm not both from r0-r7) 12840 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12841 { 0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 12842 // asr (immediate) 12843 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12844 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12845 // asr (register) 12846 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12847 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12848 // lsl (immediate) 12849 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12850 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12851 // lsl (register) 12852 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12853 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12854 // lsr (immediate) 12855 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12856 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12857 // lsr (register) 12858 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12859 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12860 // rrx is a special case encoding of ror (immediate) 12861 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12862 // ror (immediate) 12863 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12864 // ror (register) 12865 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12866 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12867 // mul 12868 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12869 // mul 12870 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12871 12872 // subs pc, lr and related instructions 12873 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12874 12875 //---------------------------------------------------------------------- 12876 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12877 // otherwise the wrong instructions will be selected. 12878 //---------------------------------------------------------------------- 12879 12880 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12881 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12882 12883 //---------------------------------------------------------------------- 12884 // Load instructions 12885 //---------------------------------------------------------------------- 12886 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12887 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12888 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12889 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12890 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12891 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12892 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12893 // Thumb2 PC-relative load into register 12894 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12895 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12896 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12897 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12898 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12899 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12900 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12901 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12902 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12903 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12904 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12905 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12906 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12907 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12908 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12909 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12910 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12911 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12912 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12913 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12914 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12915 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12916 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12917 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12918 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12919 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12920 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12921 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12922 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12923 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12924 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12925 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12926 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12927 12928 //---------------------------------------------------------------------- 12929 // Store instructions 12930 //---------------------------------------------------------------------- 12931 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12932 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12933 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12934 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12935 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12936 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12937 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12938 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12939 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12940 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12941 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12942 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12943 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12944 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12945 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12946 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12947 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12948 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12949 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12950 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12951 { 0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12952 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12953 12954 //---------------------------------------------------------------------- 12955 // Other instructions 12956 //---------------------------------------------------------------------- 12957 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12958 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12959 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12960 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12961 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12962 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12963 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12964 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12965 }; 12966 12967 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 12968 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12969 { 12970 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12971 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12972 return &g_thumb_opcodes[i]; 12973 } 12974 return NULL; 12975 } 12976 12977 bool 12978 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12979 { 12980 m_arch = arch; 12981 m_arm_isa = 0; 12982 const char *arch_cstr = arch.GetArchitectureName (); 12983 if (arch_cstr) 12984 { 12985 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12986 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12987 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12988 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12989 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12990 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12991 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12992 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12993 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12994 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12995 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12996 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12997 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12998 } 12999 return m_arm_isa != 0; 13000 } 13001 13002 bool 13003 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 13004 { 13005 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 13006 { 13007 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 13008 m_opcode_mode = eModeThumb; 13009 else 13010 { 13011 AddressClass addr_class = inst_addr.GetAddressClass(); 13012 13013 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 13014 m_opcode_mode = eModeARM; 13015 else if (addr_class == eAddressClassCodeAlternateISA) 13016 m_opcode_mode = eModeThumb; 13017 else 13018 return false; 13019 } 13020 if (m_opcode_mode == eModeThumb) 13021 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13022 else 13023 m_opcode_cpsr = CPSR_MODE_USR; 13024 return true; 13025 } 13026 return false; 13027 } 13028 13029 bool 13030 EmulateInstructionARM::ReadInstruction () 13031 { 13032 bool success = false; 13033 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13034 if (success) 13035 { 13036 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 13037 if (success) 13038 { 13039 Context read_inst_context; 13040 read_inst_context.type = eContextReadOpcode; 13041 read_inst_context.SetNoArgs (); 13042 13043 if (m_opcode_cpsr & MASK_CPSR_T) 13044 { 13045 m_opcode_mode = eModeThumb; 13046 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13047 13048 if (success) 13049 { 13050 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 13051 { 13052 m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder()); 13053 } 13054 else 13055 { 13056 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder()); 13057 } 13058 } 13059 } 13060 else 13061 { 13062 m_opcode_mode = eModeARM; 13063 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder()); 13064 } 13065 } 13066 } 13067 if (!success) 13068 { 13069 m_opcode_mode = eModeInvalid; 13070 m_addr = LLDB_INVALID_ADDRESS; 13071 } 13072 return success; 13073 } 13074 13075 uint32_t 13076 EmulateInstructionARM::ArchVersion () 13077 { 13078 return m_arm_isa; 13079 } 13080 13081 bool 13082 EmulateInstructionARM::ConditionPassed (const uint32_t opcode) 13083 { 13084 // If we are ignoring conditions, then always return true. 13085 // this allows us to iterate over disassembly code and still 13086 // emulate an instruction even if we don't have all the right 13087 // bits set in the CPSR register... 13088 if (m_ignore_conditions) 13089 return true; 13090 13091 const uint32_t cond = CurrentCond (opcode); 13092 if (cond == UINT32_MAX) 13093 return false; 13094 13095 bool result = false; 13096 switch (UnsignedBits(cond, 3, 1)) 13097 { 13098 case 0: 13099 if (m_opcode_cpsr == 0) 13100 result = true; 13101 else 13102 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13103 break; 13104 case 1: 13105 if (m_opcode_cpsr == 0) 13106 result = true; 13107 else 13108 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13109 break; 13110 case 2: 13111 if (m_opcode_cpsr == 0) 13112 result = true; 13113 else 13114 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13115 break; 13116 case 3: 13117 if (m_opcode_cpsr == 0) 13118 result = true; 13119 else 13120 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13121 break; 13122 case 4: 13123 if (m_opcode_cpsr == 0) 13124 result = true; 13125 else 13126 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13127 break; 13128 case 5: 13129 if (m_opcode_cpsr == 0) 13130 result = true; 13131 else 13132 { 13133 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13134 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13135 result = n == v; 13136 } 13137 break; 13138 case 6: 13139 if (m_opcode_cpsr == 0) 13140 result = true; 13141 else 13142 { 13143 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13144 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13145 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13146 } 13147 break; 13148 case 7: 13149 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13150 // opcodes different meanings, but always means execution happens. 13151 return true; 13152 } 13153 13154 if (cond & 1) 13155 result = !result; 13156 return result; 13157 } 13158 13159 uint32_t 13160 EmulateInstructionARM::CurrentCond (const uint32_t opcode) 13161 { 13162 switch (m_opcode_mode) 13163 { 13164 case eModeInvalid: 13165 break; 13166 13167 case eModeARM: 13168 return UnsignedBits(opcode, 31, 28); 13169 13170 case eModeThumb: 13171 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13172 // 'cond' field of the encoding. 13173 { 13174 const uint32_t byte_size = m_opcode.GetByteSize(); 13175 if (byte_size == 2) 13176 { 13177 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 13178 return Bits32(opcode, 11, 8); 13179 } 13180 else if (byte_size == 4) 13181 { 13182 if (Bits32(opcode, 31, 27) == 0x1e && 13183 Bits32(opcode, 15, 14) == 0x02 && 13184 Bits32(opcode, 12, 12) == 0x00 && 13185 Bits32(opcode, 25, 22) <= 0x0d) 13186 { 13187 return Bits32(opcode, 25, 22); 13188 } 13189 } 13190 else 13191 // We have an invalid thumb instruction, let's bail out. 13192 break; 13193 13194 return m_it_session.GetCond(); 13195 } 13196 } 13197 return UINT32_MAX; // Return invalid value 13198 } 13199 13200 bool 13201 EmulateInstructionARM::InITBlock() 13202 { 13203 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13204 } 13205 13206 bool 13207 EmulateInstructionARM::LastInITBlock() 13208 { 13209 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13210 } 13211 13212 bool 13213 EmulateInstructionARM::BadMode (uint32_t mode) 13214 { 13215 13216 switch (mode) 13217 { 13218 case 16: return false; // '10000' 13219 case 17: return false; // '10001' 13220 case 18: return false; // '10010' 13221 case 19: return false; // '10011' 13222 case 22: return false; // '10110' 13223 case 23: return false; // '10111' 13224 case 27: return false; // '11011' 13225 case 31: return false; // '11111' 13226 default: return true; 13227 } 13228 return true; 13229 } 13230 13231 bool 13232 EmulateInstructionARM::CurrentModeIsPrivileged () 13233 { 13234 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13235 13236 if (BadMode (mode)) 13237 return false; 13238 13239 if (mode == 16) 13240 return false; 13241 13242 return true; 13243 } 13244 13245 void 13246 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13247 { 13248 bool privileged = CurrentModeIsPrivileged(); 13249 13250 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13251 13252 if (BitIsSet (bytemask, 3)) 13253 { 13254 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13255 if (affect_execstate) 13256 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13257 } 13258 13259 if (BitIsSet (bytemask, 2)) 13260 { 13261 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13262 } 13263 13264 if (BitIsSet (bytemask, 1)) 13265 { 13266 if (affect_execstate) 13267 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13268 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13269 if (privileged) 13270 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13271 } 13272 13273 if (BitIsSet (bytemask, 0)) 13274 { 13275 if (privileged) 13276 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13277 if (affect_execstate) 13278 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13279 if (privileged) 13280 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13281 } 13282 13283 m_opcode_cpsr = tmp_cpsr; 13284 } 13285 13286 13287 bool 13288 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13289 { 13290 addr_t target; 13291 13292 // Check the current instruction set. 13293 if (CurrentInstrSet() == eModeARM) 13294 target = addr & 0xfffffffc; 13295 else 13296 target = addr & 0xfffffffe; 13297 13298 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13299 return false; 13300 13301 return true; 13302 } 13303 13304 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13305 bool 13306 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13307 { 13308 addr_t target; 13309 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13310 // we want to record it and issue a WriteRegister callback so the clients 13311 // can track the mode changes accordingly. 13312 bool cpsr_changed = false; 13313 13314 if (BitIsSet(addr, 0)) 13315 { 13316 if (CurrentInstrSet() != eModeThumb) 13317 { 13318 SelectInstrSet(eModeThumb); 13319 cpsr_changed = true; 13320 } 13321 target = addr & 0xfffffffe; 13322 context.SetISA (eModeThumb); 13323 } 13324 else if (BitIsClear(addr, 1)) 13325 { 13326 if (CurrentInstrSet() != eModeARM) 13327 { 13328 SelectInstrSet(eModeARM); 13329 cpsr_changed = true; 13330 } 13331 target = addr & 0xfffffffc; 13332 context.SetISA (eModeARM); 13333 } 13334 else 13335 return false; // address<1:0> == '10' => UNPREDICTABLE 13336 13337 if (cpsr_changed) 13338 { 13339 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13340 return false; 13341 } 13342 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13343 return false; 13344 13345 return true; 13346 } 13347 13348 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13349 bool 13350 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13351 { 13352 if (ArchVersion() >= ARMv5T) 13353 return BXWritePC(context, addr); 13354 else 13355 return BranchWritePC((const Context)context, addr); 13356 } 13357 13358 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13359 bool 13360 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13361 { 13362 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13363 return BXWritePC(context, addr); 13364 else 13365 return BranchWritePC((const Context)context, addr); 13366 } 13367 13368 EmulateInstructionARM::Mode 13369 EmulateInstructionARM::CurrentInstrSet () 13370 { 13371 return m_opcode_mode; 13372 } 13373 13374 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13375 // ReadInstruction() is performed. This function has a side effect of updating 13376 // the m_new_inst_cpsr member variable if necessary. 13377 bool 13378 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13379 { 13380 m_new_inst_cpsr = m_opcode_cpsr; 13381 switch (arm_or_thumb) 13382 { 13383 default: 13384 return false; 13385 case eModeARM: 13386 // Clear the T bit. 13387 m_new_inst_cpsr &= ~MASK_CPSR_T; 13388 break; 13389 case eModeThumb: 13390 // Set the T bit. 13391 m_new_inst_cpsr |= MASK_CPSR_T; 13392 break; 13393 } 13394 return true; 13395 } 13396 13397 // This function returns TRUE if the processor currently provides support for 13398 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13399 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13400 bool 13401 EmulateInstructionARM::UnalignedSupport() 13402 { 13403 return (ArchVersion() >= ARMv7); 13404 } 13405 13406 // The main addition and subtraction instructions can produce status information 13407 // about both unsigned carry and signed overflow conditions. This status 13408 // information can be used to synthesize multi-word additions and subtractions. 13409 EmulateInstructionARM::AddWithCarryResult 13410 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13411 { 13412 uint32_t result; 13413 uint8_t carry_out; 13414 uint8_t overflow; 13415 13416 uint64_t unsigned_sum = x + y + carry_in; 13417 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13418 13419 result = UnsignedBits(unsigned_sum, 31, 0); 13420 // carry_out = (result == unsigned_sum ? 0 : 1); 13421 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13422 13423 if (carry_in) 13424 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13425 else 13426 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13427 13428 AddWithCarryResult res = { result, carry_out, overflow }; 13429 return res; 13430 } 13431 13432 uint32_t 13433 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13434 { 13435 lldb::RegisterKind reg_kind; 13436 uint32_t reg_num; 13437 switch (num) 13438 { 13439 case SP_REG: 13440 reg_kind = eRegisterKindGeneric; 13441 reg_num = LLDB_REGNUM_GENERIC_SP; 13442 break; 13443 case LR_REG: 13444 reg_kind = eRegisterKindGeneric; 13445 reg_num = LLDB_REGNUM_GENERIC_RA; 13446 break; 13447 case PC_REG: 13448 reg_kind = eRegisterKindGeneric; 13449 reg_num = LLDB_REGNUM_GENERIC_PC; 13450 break; 13451 default: 13452 if (num < SP_REG) 13453 { 13454 reg_kind = eRegisterKindDWARF; 13455 reg_num = dwarf_r0 + num; 13456 } 13457 else 13458 { 13459 //assert(0 && "Invalid register number"); 13460 *success = false; 13461 return UINT32_MAX; 13462 } 13463 break; 13464 } 13465 13466 // Read our register. 13467 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13468 13469 // When executing an ARM instruction , PC reads as the address of the current 13470 // instruction plus 8. 13471 // When executing a Thumb instruction , PC reads as the address of the current 13472 // instruction plus 4. 13473 if (num == 15) 13474 { 13475 if (CurrentInstrSet() == eModeARM) 13476 val += 8; 13477 else 13478 val += 4; 13479 } 13480 13481 return val; 13482 } 13483 13484 // Write the result to the ARM core register Rd, and optionally update the 13485 // condition flags based on the result. 13486 // 13487 // This helper method tries to encapsulate the following pseudocode from the 13488 // ARM Architecture Reference Manual: 13489 // 13490 // if d == 15 then // Can only occur for encoding A1 13491 // ALUWritePC(result); // setflags is always FALSE here 13492 // else 13493 // R[d] = result; 13494 // if setflags then 13495 // APSR.N = result<31>; 13496 // APSR.Z = IsZeroBit(result); 13497 // APSR.C = carry; 13498 // // APSR.V unchanged 13499 // 13500 // In the above case, the API client does not pass in the overflow arg, which 13501 // defaults to ~0u. 13502 bool 13503 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13504 const uint32_t result, 13505 const uint32_t Rd, 13506 bool setflags, 13507 const uint32_t carry, 13508 const uint32_t overflow) 13509 { 13510 if (Rd == 15) 13511 { 13512 if (!ALUWritePC (context, result)) 13513 return false; 13514 } 13515 else 13516 { 13517 lldb::RegisterKind reg_kind; 13518 uint32_t reg_num; 13519 switch (Rd) 13520 { 13521 case SP_REG: 13522 reg_kind = eRegisterKindGeneric; 13523 reg_num = LLDB_REGNUM_GENERIC_SP; 13524 break; 13525 case LR_REG: 13526 reg_kind = eRegisterKindGeneric; 13527 reg_num = LLDB_REGNUM_GENERIC_RA; 13528 break; 13529 default: 13530 reg_kind = eRegisterKindDWARF; 13531 reg_num = dwarf_r0 + Rd; 13532 } 13533 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13534 return false; 13535 if (setflags) 13536 return WriteFlags (context, result, carry, overflow); 13537 } 13538 return true; 13539 } 13540 13541 // This helper method tries to encapsulate the following pseudocode from the 13542 // ARM Architecture Reference Manual: 13543 // 13544 // APSR.N = result<31>; 13545 // APSR.Z = IsZeroBit(result); 13546 // APSR.C = carry; 13547 // APSR.V = overflow 13548 // 13549 // Default arguments can be specified for carry and overflow parameters, which means 13550 // not to update the respective flags. 13551 bool 13552 EmulateInstructionARM::WriteFlags (Context &context, 13553 const uint32_t result, 13554 const uint32_t carry, 13555 const uint32_t overflow) 13556 { 13557 m_new_inst_cpsr = m_opcode_cpsr; 13558 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13559 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13560 if (carry != ~0u) 13561 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13562 if (overflow != ~0u) 13563 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13564 if (m_new_inst_cpsr != m_opcode_cpsr) 13565 { 13566 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13567 return false; 13568 } 13569 return true; 13570 } 13571 13572 bool 13573 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13574 { 13575 // Advance the ITSTATE bits to their values for the next instruction. 13576 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13577 m_it_session.ITAdvance(); 13578 13579 ARMOpcode *opcode_data = NULL; 13580 13581 if (m_opcode_mode == eModeThumb) 13582 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13583 else if (m_opcode_mode == eModeARM) 13584 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13585 13586 if (opcode_data == NULL) 13587 return false; 13588 13589 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13590 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13591 13592 bool success = false; 13593 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13594 { 13595 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13596 dwarf_cpsr, 13597 0, 13598 &success); 13599 } 13600 13601 // Only return false if we are unable to read the CPSR if we care about conditions 13602 if (success == false && m_ignore_conditions == false) 13603 return false; 13604 13605 uint32_t orig_pc_value = 0; 13606 if (auto_advance_pc) 13607 { 13608 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13609 if (!success) 13610 return false; 13611 } 13612 13613 // Call the Emulate... function. 13614 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13615 if (!success) 13616 return false; 13617 13618 if (auto_advance_pc) 13619 { 13620 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13621 if (!success) 13622 return false; 13623 13624 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13625 { 13626 if (opcode_data->size == eSize32) 13627 after_pc_value += 4; 13628 else if (opcode_data->size == eSize16) 13629 after_pc_value += 2; 13630 13631 EmulateInstruction::Context context; 13632 context.type = eContextAdvancePC; 13633 context.SetNoArgs(); 13634 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13635 return false; 13636 13637 } 13638 } 13639 return true; 13640 } 13641 13642 bool 13643 EmulateInstructionARM::IsInstructionConditional() 13644 { 13645 const uint32_t cond = CurrentCond (m_opcode.GetOpcode32()); 13646 return cond != 0xe && cond != 0xf && cond != UINT32_MAX; 13647 } 13648 13649 bool 13650 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13651 { 13652 if (!test_data) 13653 { 13654 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13655 return false; 13656 } 13657 13658 static ConstString opcode_key ("opcode"); 13659 static ConstString before_key ("before_state"); 13660 static ConstString after_key ("after_state"); 13661 13662 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13663 13664 uint32_t test_opcode; 13665 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13666 { 13667 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13668 return false; 13669 } 13670 test_opcode = value_sp->GetUInt64Value (); 13671 13672 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13673 { 13674 m_opcode_mode = eModeARM; 13675 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13676 } 13677 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13678 { 13679 m_opcode_mode = eModeThumb; 13680 if (test_opcode < 0x10000) 13681 m_opcode.SetOpcode16 (test_opcode, GetByteOrder()); 13682 else 13683 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13684 13685 } 13686 else 13687 { 13688 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13689 return false; 13690 } 13691 13692 EmulationStateARM before_state; 13693 EmulationStateARM after_state; 13694 13695 value_sp = test_data->GetValueForKey (before_key); 13696 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13697 { 13698 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13699 return false; 13700 } 13701 13702 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13703 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13704 { 13705 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13706 return false; 13707 } 13708 13709 value_sp = test_data->GetValueForKey (after_key); 13710 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13711 { 13712 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13713 return false; 13714 } 13715 13716 state_dictionary = value_sp->GetAsDictionary (); 13717 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13718 { 13719 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13720 return false; 13721 } 13722 13723 SetBaton ((void *) &before_state); 13724 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13725 &EmulationStateARM::WritePseudoMemory, 13726 &EmulationStateARM::ReadPseudoRegister, 13727 &EmulationStateARM::WritePseudoRegister); 13728 13729 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13730 if (!success) 13731 { 13732 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13733 return false; 13734 } 13735 13736 success = before_state.CompareState (after_state); 13737 if (!success) 13738 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13739 13740 return success; 13741 } 13742 // 13743 // 13744 //const char * 13745 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13746 //{ 13747 // if (reg_kind == eRegisterKindGeneric) 13748 // { 13749 // switch (reg_num) 13750 // { 13751 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 13752 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 13753 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 13754 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 13755 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13756 // default: return NULL; 13757 // } 13758 // } 13759 // else if (reg_kind == eRegisterKindDWARF) 13760 // { 13761 // return GetARMDWARFRegisterName (reg_num); 13762 // } 13763 // return NULL; 13764 //} 13765 // 13766 bool 13767 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13768 { 13769 unwind_plan.Clear(); 13770 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13771 13772 UnwindPlan::RowSP row(new UnwindPlan::Row); 13773 13774 // Our previous Call Frame Address is the stack pointer 13775 row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0); 13776 13777 unwind_plan.AppendRow (row); 13778 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13779 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 13780 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 13781 unwind_plan.SetReturnAddressRegister (dwarf_lr); 13782 return true; 13783 } 13784