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 296 bool is_apple = false; 297 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 298 is_apple = true; 299 switch (m_arch.GetTriple().getOS()) 300 { 301 case llvm::Triple::Darwin: 302 case llvm::Triple::MacOSX: 303 case llvm::Triple::IOS: 304 is_apple = true; 305 break; 306 default: 307 break; 308 } 309 310 /* On Apple iOS et al, the frame pointer register is always r7. 311 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 312 */ 313 314 uint32_t fp_regnum = 11; 315 316 if (is_apple) 317 fp_regnum = 7; 318 319 if (m_opcode_mode == eModeThumb) 320 fp_regnum = 7; 321 322 return fp_regnum; 323 } 324 325 uint32_t 326 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const 327 { 328 bool is_apple = false; 329 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 330 is_apple = true; 331 switch (m_arch.GetTriple().getOS()) 332 { 333 case llvm::Triple::Darwin: 334 case llvm::Triple::MacOSX: 335 case llvm::Triple::IOS: 336 is_apple = true; 337 break; 338 default: 339 break; 340 } 341 342 /* On Apple iOS et al, the frame pointer register is always r7. 343 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 344 */ 345 346 uint32_t fp_regnum = dwarf_r11; 347 348 if (is_apple) 349 fp_regnum = dwarf_r7; 350 351 if (m_opcode_mode == eModeThumb) 352 fp_regnum = dwarf_r7; 353 354 return fp_regnum; 355 } 356 357 // Push Multiple Registers stores multiple registers to the stack, storing to 358 // consecutive memory locations ending just below the address in SP, and updates 359 // SP to point to the start of the stored data. 360 bool 361 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding) 362 { 363 #if 0 364 // ARM pseudo code... 365 if (ConditionPassed()) 366 { 367 EncodingSpecificOperations(); 368 NullCheckIfThumbEE(13); 369 address = SP - 4*BitCount(registers); 370 371 for (i = 0 to 14) 372 { 373 if (registers<i> == '1') 374 { 375 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 376 MemA[address,4] = bits(32) UNKNOWN; 377 else 378 MemA[address,4] = R[i]; 379 address = address + 4; 380 } 381 } 382 383 if (registers<15> == '1') // Only possible for encoding A1 or A2 384 MemA[address,4] = PCStoreValue(); 385 386 SP = SP - 4*BitCount(registers); 387 } 388 #endif 389 390 bool success = false; 391 if (ConditionPassed(opcode)) 392 { 393 const uint32_t addr_byte_size = GetAddressByteSize(); 394 const addr_t sp = ReadCoreReg (SP_REG, &success); 395 if (!success) 396 return false; 397 uint32_t registers = 0; 398 uint32_t Rt; // the source register 399 switch (encoding) { 400 case eEncodingT1: 401 registers = Bits32(opcode, 7, 0); 402 // The M bit represents LR. 403 if (Bit32(opcode, 8)) 404 registers |= (1u << 14); 405 // if BitCount(registers) < 1 then UNPREDICTABLE; 406 if (BitCount(registers) < 1) 407 return false; 408 break; 409 case eEncodingT2: 410 // Ignore bits 15 & 13. 411 registers = Bits32(opcode, 15, 0) & ~0xa000; 412 // if BitCount(registers) < 2 then UNPREDICTABLE; 413 if (BitCount(registers) < 2) 414 return false; 415 break; 416 case eEncodingT3: 417 Rt = Bits32(opcode, 15, 12); 418 // if BadReg(t) then UNPREDICTABLE; 419 if (BadReg(Rt)) 420 return false; 421 registers = (1u << Rt); 422 break; 423 case eEncodingA1: 424 registers = Bits32(opcode, 15, 0); 425 // Instead of return false, let's handle the following case as well, 426 // which amounts to pushing one reg onto the full descending stacks. 427 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 428 break; 429 case eEncodingA2: 430 Rt = Bits32(opcode, 15, 12); 431 // if t == 13 then UNPREDICTABLE; 432 if (Rt == dwarf_sp) 433 return false; 434 registers = (1u << Rt); 435 break; 436 default: 437 return false; 438 } 439 addr_t sp_offset = addr_byte_size * BitCount (registers); 440 addr_t addr = sp - sp_offset; 441 uint32_t i; 442 443 EmulateInstruction::Context context; 444 context.type = EmulateInstruction::eContextPushRegisterOnStack; 445 RegisterInfo reg_info; 446 RegisterInfo sp_reg; 447 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 448 for (i=0; i<15; ++i) 449 { 450 if (BitIsSet (registers, i)) 451 { 452 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info); 453 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 454 uint32_t reg_value = ReadCoreReg(i, &success); 455 if (!success) 456 return false; 457 if (!MemAWrite (context, addr, reg_value, addr_byte_size)) 458 return false; 459 addr += addr_byte_size; 460 } 461 } 462 463 if (BitIsSet (registers, 15)) 464 { 465 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info); 466 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp); 467 const uint32_t pc = ReadCoreReg(PC_REG, &success); 468 if (!success) 469 return false; 470 if (!MemAWrite (context, addr, pc, addr_byte_size)) 471 return false; 472 } 473 474 context.type = EmulateInstruction::eContextAdjustStackPointer; 475 context.SetImmediateSigned (-sp_offset); 476 477 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 478 return false; 479 } 480 return true; 481 } 482 483 // Pop Multiple Registers loads multiple registers from the stack, loading from 484 // consecutive memory locations staring at the address in SP, and updates 485 // SP to point just above the loaded data. 486 bool 487 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding) 488 { 489 #if 0 490 // ARM pseudo code... 491 if (ConditionPassed()) 492 { 493 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 494 address = SP; 495 for i = 0 to 14 496 if registers<i> == '1' then 497 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 498 if registers<15> == '1' then 499 if UnalignedAllowed then 500 LoadWritePC(MemU[address,4]); 501 else 502 LoadWritePC(MemA[address,4]); 503 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 504 if registers<13> == '1' then SP = bits(32) UNKNOWN; 505 } 506 #endif 507 508 bool success = false; 509 510 if (ConditionPassed(opcode)) 511 { 512 const uint32_t addr_byte_size = GetAddressByteSize(); 513 const addr_t sp = ReadCoreReg (SP_REG, &success); 514 if (!success) 515 return false; 516 uint32_t registers = 0; 517 uint32_t Rt; // the destination register 518 switch (encoding) { 519 case eEncodingT1: 520 registers = Bits32(opcode, 7, 0); 521 // The P bit represents PC. 522 if (Bit32(opcode, 8)) 523 registers |= (1u << 15); 524 // if BitCount(registers) < 1 then UNPREDICTABLE; 525 if (BitCount(registers) < 1) 526 return false; 527 break; 528 case eEncodingT2: 529 // Ignore bit 13. 530 registers = Bits32(opcode, 15, 0) & ~0x2000; 531 // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 532 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 533 return false; 534 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 535 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 536 return false; 537 break; 538 case eEncodingT3: 539 Rt = Bits32(opcode, 15, 12); 540 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 541 if (Rt == 13) 542 return false; 543 if (Rt == 15 && InITBlock() && !LastInITBlock()) 544 return false; 545 registers = (1u << Rt); 546 break; 547 case eEncodingA1: 548 registers = Bits32(opcode, 15, 0); 549 // Instead of return false, let's handle the following case as well, 550 // which amounts to popping one reg from the full descending stacks. 551 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 552 553 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 554 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 555 return false; 556 break; 557 case eEncodingA2: 558 Rt = Bits32(opcode, 15, 12); 559 // if t == 13 then UNPREDICTABLE; 560 if (Rt == dwarf_sp) 561 return false; 562 registers = (1u << Rt); 563 break; 564 default: 565 return false; 566 } 567 addr_t sp_offset = addr_byte_size * BitCount (registers); 568 addr_t addr = sp; 569 uint32_t i, data; 570 571 EmulateInstruction::Context context; 572 context.type = EmulateInstruction::eContextPopRegisterOffStack; 573 574 RegisterInfo sp_reg; 575 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 576 577 for (i=0; i<15; ++i) 578 { 579 if (BitIsSet (registers, i)) 580 { 581 context.SetAddress(addr); 582 data = MemARead(context, addr, 4, 0, &success); 583 if (!success) 584 return false; 585 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data)) 586 return false; 587 addr += addr_byte_size; 588 } 589 } 590 591 if (BitIsSet (registers, 15)) 592 { 593 context.SetRegisterPlusOffset (sp_reg, addr - sp); 594 data = MemARead(context, addr, 4, 0, &success); 595 if (!success) 596 return false; 597 // In ARMv5T and above, this is an interworking branch. 598 if (!LoadWritePC(context, data)) 599 return false; 600 //addr += addr_byte_size; 601 } 602 603 context.type = EmulateInstruction::eContextAdjustStackPointer; 604 context.SetImmediateSigned (sp_offset); 605 606 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 607 return false; 608 } 609 return true; 610 } 611 612 // Set r7 or ip to point to saved value residing within the stack. 613 // ADD (SP plus immediate) 614 bool 615 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding) 616 { 617 #if 0 618 // ARM pseudo code... 619 if (ConditionPassed()) 620 { 621 EncodingSpecificOperations(); 622 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 623 if d == 15 then 624 ALUWritePC(result); // setflags is always FALSE here 625 else 626 R[d] = result; 627 if setflags then 628 APSR.N = result<31>; 629 APSR.Z = IsZeroBit(result); 630 APSR.C = carry; 631 APSR.V = overflow; 632 } 633 #endif 634 635 bool success = false; 636 637 if (ConditionPassed(opcode)) 638 { 639 const addr_t sp = ReadCoreReg (SP_REG, &success); 640 if (!success) 641 return false; 642 uint32_t Rd; // the destination register 643 uint32_t imm32; 644 switch (encoding) { 645 case eEncodingT1: 646 Rd = 7; 647 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 648 break; 649 case eEncodingA1: 650 Rd = Bits32(opcode, 15, 12); 651 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 652 break; 653 default: 654 return false; 655 } 656 addr_t sp_offset = imm32; 657 addr_t addr = sp + sp_offset; // a pointer to the stack area 658 659 EmulateInstruction::Context context; 660 if (Rd == GetFramePointerRegisterNumber()) 661 context.type = eContextSetFramePointer; 662 else 663 context.type = EmulateInstruction::eContextRegisterPlusOffset; 664 RegisterInfo sp_reg; 665 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 666 context.SetRegisterPlusOffset (sp_reg, sp_offset); 667 668 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr)) 669 return false; 670 } 671 return true; 672 } 673 674 // Set r7 or ip to the current stack pointer. 675 // MOV (register) 676 bool 677 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding) 678 { 679 #if 0 680 // ARM pseudo code... 681 if (ConditionPassed()) 682 { 683 EncodingSpecificOperations(); 684 result = R[m]; 685 if d == 15 then 686 ALUWritePC(result); // setflags is always FALSE here 687 else 688 R[d] = result; 689 if setflags then 690 APSR.N = result<31>; 691 APSR.Z = IsZeroBit(result); 692 // APSR.C unchanged 693 // APSR.V unchanged 694 } 695 #endif 696 697 bool success = false; 698 699 if (ConditionPassed(opcode)) 700 { 701 const addr_t sp = ReadCoreReg (SP_REG, &success); 702 if (!success) 703 return false; 704 uint32_t Rd; // the destination register 705 switch (encoding) { 706 case eEncodingT1: 707 Rd = 7; 708 break; 709 case eEncodingA1: 710 Rd = 12; 711 break; 712 default: 713 return false; 714 } 715 716 EmulateInstruction::Context context; 717 if (Rd == GetFramePointerRegisterNumber()) 718 context.type = EmulateInstruction::eContextSetFramePointer; 719 else 720 context.type = EmulateInstruction::eContextRegisterPlusOffset; 721 RegisterInfo sp_reg; 722 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 723 context.SetRegisterPlusOffset (sp_reg, 0); 724 725 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 726 return false; 727 } 728 return true; 729 } 730 731 // Move from high register (r8-r15) to low register (r0-r7). 732 // MOV (register) 733 bool 734 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding) 735 { 736 return EmulateMOVRdRm (opcode, encoding); 737 } 738 739 // Move from register to register. 740 // MOV (register) 741 bool 742 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding) 743 { 744 #if 0 745 // ARM pseudo code... 746 if (ConditionPassed()) 747 { 748 EncodingSpecificOperations(); 749 result = R[m]; 750 if d == 15 then 751 ALUWritePC(result); // setflags is always FALSE here 752 else 753 R[d] = result; 754 if setflags then 755 APSR.N = result<31>; 756 APSR.Z = IsZeroBit(result); 757 // APSR.C unchanged 758 // APSR.V unchanged 759 } 760 #endif 761 762 bool success = false; 763 764 if (ConditionPassed(opcode)) 765 { 766 uint32_t Rm; // the source register 767 uint32_t Rd; // the destination register 768 bool setflags; 769 switch (encoding) { 770 case eEncodingT1: 771 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 772 Rm = Bits32(opcode, 6, 3); 773 setflags = false; 774 if (Rd == 15 && InITBlock() && !LastInITBlock()) 775 return false; 776 break; 777 case eEncodingT2: 778 Rd = Bits32(opcode, 2, 0); 779 Rm = Bits32(opcode, 5, 3); 780 setflags = true; 781 if (InITBlock()) 782 return false; 783 break; 784 case eEncodingT3: 785 Rd = Bits32(opcode, 11, 8); 786 Rm = Bits32(opcode, 3, 0); 787 setflags = BitIsSet(opcode, 20); 788 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 789 if (setflags && (BadReg(Rd) || BadReg(Rm))) 790 return false; 791 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; 792 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 793 return false; 794 break; 795 case eEncodingA1: 796 Rd = Bits32(opcode, 15, 12); 797 Rm = Bits32(opcode, 3, 0); 798 setflags = BitIsSet(opcode, 20); 799 800 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 801 if (Rd == 15 && setflags) 802 return EmulateSUBSPcLrEtc (opcode, encoding); 803 break; 804 default: 805 return false; 806 } 807 uint32_t result = ReadCoreReg(Rm, &success); 808 if (!success) 809 return false; 810 811 // The context specifies that Rm is to be moved into Rd. 812 EmulateInstruction::Context context; 813 if (Rd == 13) 814 context.type = EmulateInstruction::eContextAdjustStackPointer; 815 else 816 context.type = EmulateInstruction::eContextRegisterPlusOffset; 817 RegisterInfo dwarf_reg; 818 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 819 context.SetRegisterPlusOffset (dwarf_reg, 0); 820 821 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 822 return false; 823 } 824 return true; 825 } 826 827 // Move (immediate) writes an immediate value to the destination register. It 828 // can optionally update the condition flags based on the value. 829 // MOV (immediate) 830 bool 831 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding) 832 { 833 #if 0 834 // ARM pseudo code... 835 if (ConditionPassed()) 836 { 837 EncodingSpecificOperations(); 838 result = imm32; 839 if d == 15 then // Can only occur for ARM encoding 840 ALUWritePC(result); // setflags is always FALSE here 841 else 842 R[d] = result; 843 if setflags then 844 APSR.N = result<31>; 845 APSR.Z = IsZeroBit(result); 846 APSR.C = carry; 847 // APSR.V unchanged 848 } 849 #endif 850 851 if (ConditionPassed(opcode)) 852 { 853 uint32_t Rd; // the destination register 854 uint32_t imm32; // the immediate value to be written to Rd 855 uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 856 // for setflags == false, this value is a don't care 857 // initialized to 0 to silence the static analyzer 858 bool setflags; 859 switch (encoding) { 860 case eEncodingT1: 861 Rd = Bits32(opcode, 10, 8); 862 setflags = !InITBlock(); 863 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 864 carry = APSR_C; 865 866 break; 867 868 case eEncodingT2: 869 Rd = Bits32(opcode, 11, 8); 870 setflags = BitIsSet(opcode, 20); 871 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 872 if (BadReg(Rd)) 873 return false; 874 875 break; 876 877 case eEncodingT3: 878 { 879 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32); 880 Rd = Bits32 (opcode, 11, 8); 881 setflags = false; 882 uint32_t imm4 = Bits32 (opcode, 19, 16); 883 uint32_t imm3 = Bits32 (opcode, 14, 12); 884 uint32_t i = Bit32 (opcode, 26); 885 uint32_t imm8 = Bits32 (opcode, 7, 0); 886 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 887 888 // if BadReg(d) then UNPREDICTABLE; 889 if (BadReg (Rd)) 890 return false; 891 } 892 break; 893 894 case eEncodingA1: 895 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C); 896 Rd = Bits32 (opcode, 15, 12); 897 setflags = BitIsSet (opcode, 20); 898 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); 899 900 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 901 if ((Rd == 15) && setflags) 902 return EmulateSUBSPcLrEtc (opcode, encoding); 903 904 break; 905 906 case eEncodingA2: 907 { 908 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 909 Rd = Bits32 (opcode, 15, 12); 910 setflags = false; 911 uint32_t imm4 = Bits32 (opcode, 19, 16); 912 uint32_t imm12 = Bits32 (opcode, 11, 0); 913 imm32 = (imm4 << 12) | imm12; 914 915 // if d == 15 then UNPREDICTABLE; 916 if (Rd == 15) 917 return false; 918 } 919 break; 920 921 default: 922 return false; 923 } 924 uint32_t result = imm32; 925 926 // The context specifies that an immediate is to be moved into Rd. 927 EmulateInstruction::Context context; 928 context.type = EmulateInstruction::eContextImmediate; 929 context.SetNoArgs (); 930 931 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 932 return false; 933 } 934 return true; 935 } 936 937 // MUL multiplies two register values. The least significant 32 bits of the result are written to the destination 938 // register. These 32 bits do not depend on whether the source register values are considered to be signed values or 939 // unsigned values. 940 // 941 // Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is 942 // limited to only a few forms of the instruction. 943 bool 944 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding) 945 { 946 #if 0 947 if ConditionPassed() then 948 EncodingSpecificOperations(); 949 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 950 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 951 result = operand1 * operand2; 952 R[d] = result<31:0>; 953 if setflags then 954 APSR.N = result<31>; 955 APSR.Z = IsZeroBit(result); 956 if ArchVersion() == 4 then 957 APSR.C = bit UNKNOWN; 958 // else APSR.C unchanged 959 // APSR.V always unchanged 960 #endif 961 962 if (ConditionPassed(opcode)) 963 { 964 uint32_t d; 965 uint32_t n; 966 uint32_t m; 967 bool setflags; 968 969 // EncodingSpecificOperations(); 970 switch (encoding) 971 { 972 case eEncodingT1: 973 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 974 d = Bits32 (opcode, 2, 0); 975 n = Bits32 (opcode, 5, 3); 976 m = Bits32 (opcode, 2, 0); 977 setflags = !InITBlock(); 978 979 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 980 if ((ArchVersion() < ARMv6) && (d == n)) 981 return false; 982 983 break; 984 985 case eEncodingT2: 986 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 987 d = Bits32 (opcode, 11, 8); 988 n = Bits32 (opcode, 19, 16); 989 m = Bits32 (opcode, 3, 0); 990 setflags = false; 991 992 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 993 if (BadReg (d) || BadReg (n) || BadReg (m)) 994 return false; 995 996 break; 997 998 case eEncodingA1: 999 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 1000 d = Bits32 (opcode, 19, 16); 1001 n = Bits32 (opcode, 3, 0); 1002 m = Bits32 (opcode, 11, 8); 1003 setflags = BitIsSet (opcode, 20); 1004 1005 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1006 if ((d == 15) || (n == 15) || (m == 15)) 1007 return false; 1008 1009 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1010 if ((ArchVersion() < ARMv6) && (d == n)) 1011 return false; 1012 1013 break; 1014 1015 default: 1016 return false; 1017 } 1018 1019 bool success = false; 1020 1021 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1022 uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1023 if (!success) 1024 return false; 1025 1026 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1027 uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1028 if (!success) 1029 return false; 1030 1031 // result = operand1 * operand2; 1032 uint64_t result = operand1 * operand2; 1033 1034 // R[d] = result<31:0>; 1035 RegisterInfo op1_reg; 1036 RegisterInfo op2_reg; 1037 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1038 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1039 1040 EmulateInstruction::Context context; 1041 context.type = eContextArithmetic; 1042 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 1043 1044 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result))) 1045 return false; 1046 1047 // if setflags then 1048 if (setflags) 1049 { 1050 // APSR.N = result<31>; 1051 // APSR.Z = IsZeroBit(result); 1052 m_new_inst_cpsr = m_opcode_cpsr; 1053 SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31)); 1054 SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1055 if (m_new_inst_cpsr != m_opcode_cpsr) 1056 { 1057 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1058 return false; 1059 } 1060 1061 // if ArchVersion() == 4 then 1062 // APSR.C = bit UNKNOWN; 1063 } 1064 } 1065 return true; 1066 } 1067 1068 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. 1069 // It can optionally update the condition flags based on the value. 1070 bool 1071 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding) 1072 { 1073 #if 0 1074 // ARM pseudo code... 1075 if (ConditionPassed()) 1076 { 1077 EncodingSpecificOperations(); 1078 result = NOT(imm32); 1079 if d == 15 then // Can only occur for ARM encoding 1080 ALUWritePC(result); // setflags is always FALSE here 1081 else 1082 R[d] = result; 1083 if setflags then 1084 APSR.N = result<31>; 1085 APSR.Z = IsZeroBit(result); 1086 APSR.C = carry; 1087 // APSR.V unchanged 1088 } 1089 #endif 1090 1091 if (ConditionPassed(opcode)) 1092 { 1093 uint32_t Rd; // the destination register 1094 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1095 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1096 bool setflags; 1097 switch (encoding) { 1098 case eEncodingT1: 1099 Rd = Bits32(opcode, 11, 8); 1100 setflags = BitIsSet(opcode, 20); 1101 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1102 break; 1103 case eEncodingA1: 1104 Rd = Bits32(opcode, 15, 12); 1105 setflags = BitIsSet(opcode, 20); 1106 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1107 1108 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1109 if (Rd == 15 && setflags) 1110 return EmulateSUBSPcLrEtc (opcode, encoding); 1111 break; 1112 default: 1113 return false; 1114 } 1115 uint32_t result = ~imm32; 1116 1117 // The context specifies that an immediate is to be moved into Rd. 1118 EmulateInstruction::Context context; 1119 context.type = EmulateInstruction::eContextImmediate; 1120 context.SetNoArgs (); 1121 1122 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1123 return false; 1124 } 1125 return true; 1126 } 1127 1128 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. 1129 // It can optionally update the condition flags based on the result. 1130 bool 1131 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding) 1132 { 1133 #if 0 1134 // ARM pseudo code... 1135 if (ConditionPassed()) 1136 { 1137 EncodingSpecificOperations(); 1138 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1139 result = NOT(shifted); 1140 if d == 15 then // Can only occur for ARM encoding 1141 ALUWritePC(result); // setflags is always FALSE here 1142 else 1143 R[d] = result; 1144 if setflags then 1145 APSR.N = result<31>; 1146 APSR.Z = IsZeroBit(result); 1147 APSR.C = carry; 1148 // APSR.V unchanged 1149 } 1150 #endif 1151 1152 if (ConditionPassed(opcode)) 1153 { 1154 uint32_t Rm; // the source register 1155 uint32_t Rd; // the destination register 1156 ARM_ShifterType shift_t; 1157 uint32_t shift_n; // the shift applied to the value read from Rm 1158 bool setflags; 1159 uint32_t carry; // the carry bit after the shift operation 1160 switch (encoding) { 1161 case eEncodingT1: 1162 Rd = Bits32(opcode, 2, 0); 1163 Rm = Bits32(opcode, 5, 3); 1164 setflags = !InITBlock(); 1165 shift_t = SRType_LSL; 1166 shift_n = 0; 1167 if (InITBlock()) 1168 return false; 1169 break; 1170 case eEncodingT2: 1171 Rd = Bits32(opcode, 11, 8); 1172 Rm = Bits32(opcode, 3, 0); 1173 setflags = BitIsSet(opcode, 20); 1174 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1175 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1176 if (BadReg(Rd) || BadReg(Rm)) 1177 return false; 1178 break; 1179 case eEncodingA1: 1180 Rd = Bits32(opcode, 15, 12); 1181 Rm = Bits32(opcode, 3, 0); 1182 setflags = BitIsSet(opcode, 20); 1183 shift_n = DecodeImmShiftARM(opcode, shift_t); 1184 break; 1185 default: 1186 return false; 1187 } 1188 bool success = false; 1189 uint32_t value = ReadCoreReg(Rm, &success); 1190 if (!success) 1191 return false; 1192 1193 uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1194 if (!success) 1195 return false; 1196 uint32_t result = ~shifted; 1197 1198 // The context specifies that an immediate is to be moved into Rd. 1199 EmulateInstruction::Context context; 1200 context.type = EmulateInstruction::eContextImmediate; 1201 context.SetNoArgs (); 1202 1203 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1204 return false; 1205 } 1206 return true; 1207 } 1208 1209 // PC relative immediate load into register, possibly followed by ADD (SP plus register). 1210 // LDR (literal) 1211 bool 1212 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding) 1213 { 1214 #if 0 1215 // ARM pseudo code... 1216 if (ConditionPassed()) 1217 { 1218 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1219 base = Align(PC,4); 1220 address = if add then (base + imm32) else (base - imm32); 1221 data = MemU[address,4]; 1222 if t == 15 then 1223 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1224 elsif UnalignedSupport() || address<1:0> = '00' then 1225 R[t] = data; 1226 else // Can only apply before ARMv7 1227 if CurrentInstrSet() == InstrSet_ARM then 1228 R[t] = ROR(data, 8*UInt(address<1:0>)); 1229 else 1230 R[t] = bits(32) UNKNOWN; 1231 } 1232 #endif 1233 1234 if (ConditionPassed(opcode)) 1235 { 1236 bool success = false; 1237 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1238 if (!success) 1239 return false; 1240 1241 // PC relative immediate load context 1242 EmulateInstruction::Context context; 1243 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1244 RegisterInfo pc_reg; 1245 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 1246 context.SetRegisterPlusOffset (pc_reg, 0); 1247 1248 uint32_t Rt; // the destination register 1249 uint32_t imm32; // immediate offset from the PC 1250 bool add; // +imm32 or -imm32? 1251 addr_t base; // the base address 1252 addr_t address; // the PC relative address 1253 uint32_t data; // the literal data value from the PC relative load 1254 switch (encoding) { 1255 case eEncodingT1: 1256 Rt = Bits32(opcode, 10, 8); 1257 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1258 add = true; 1259 break; 1260 case eEncodingT2: 1261 Rt = Bits32(opcode, 15, 12); 1262 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1263 add = BitIsSet(opcode, 23); 1264 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1265 return false; 1266 break; 1267 default: 1268 return false; 1269 } 1270 1271 base = Align(pc, 4); 1272 if (add) 1273 address = base + imm32; 1274 else 1275 address = base - imm32; 1276 1277 context.SetRegisterPlusOffset(pc_reg, address - base); 1278 data = MemURead(context, address, 4, 0, &success); 1279 if (!success) 1280 return false; 1281 1282 if (Rt == 15) 1283 { 1284 if (Bits32(address, 1, 0) == 0) 1285 { 1286 // In ARMv5T and above, this is an interworking branch. 1287 if (!LoadWritePC(context, data)) 1288 return false; 1289 } 1290 else 1291 return false; 1292 } 1293 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 1294 { 1295 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 1296 return false; 1297 } 1298 else // We don't handle ARM for now. 1299 return false; 1300 1301 } 1302 return true; 1303 } 1304 1305 // An add operation to adjust the SP. 1306 // ADD (SP plus immediate) 1307 bool 1308 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding) 1309 { 1310 #if 0 1311 // ARM pseudo code... 1312 if (ConditionPassed()) 1313 { 1314 EncodingSpecificOperations(); 1315 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1316 if d == 15 then // Can only occur for ARM encoding 1317 ALUWritePC(result); // setflags is always FALSE here 1318 else 1319 R[d] = result; 1320 if setflags then 1321 APSR.N = result<31>; 1322 APSR.Z = IsZeroBit(result); 1323 APSR.C = carry; 1324 APSR.V = overflow; 1325 } 1326 #endif 1327 1328 bool success = false; 1329 1330 if (ConditionPassed(opcode)) 1331 { 1332 const addr_t sp = ReadCoreReg (SP_REG, &success); 1333 if (!success) 1334 return false; 1335 uint32_t imm32; // the immediate operand 1336 uint32_t d; 1337 bool setflags; 1338 switch (encoding) 1339 { 1340 case eEncodingT1: 1341 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1342 d = Bits32 (opcode, 10, 8); 1343 imm32 = (Bits32 (opcode, 7, 0) << 2); 1344 setflags = false; 1345 break; 1346 1347 case eEncodingT2: 1348 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1349 d = 13; 1350 imm32 = ThumbImm7Scaled (opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1351 setflags = false; 1352 break; 1353 1354 case eEncodingT3: 1355 // d = UInt(Rd); setflags = (S == "1"); imm32 = ThumbExpandImm(i:imm3:imm8); 1356 d = Bits32 (opcode, 11, 8); 1357 imm32 = ThumbExpandImm (opcode); 1358 setflags = Bit32 (opcode, 20); 1359 1360 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 1361 if (d == 15 && setflags == 1) 1362 return false; // CMN (immediate) not yet supported 1363 1364 // if d == 15 && S == "0" then UNPREDICTABLE; 1365 if (d == 15 && setflags == 0) 1366 return false; 1367 break; 1368 1369 case eEncodingT4: 1370 { 1371 // if Rn == '1111' then SEE ADR; 1372 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 1373 d = Bits32 (opcode, 11, 8); 1374 setflags = false; 1375 uint32_t i = Bit32 (opcode, 26); 1376 uint32_t imm3 = Bits32 (opcode, 14, 12); 1377 uint32_t imm8 = Bits32 (opcode, 7, 0); 1378 imm32 = (i << 11) | (imm3 << 8) | imm8; 1379 1380 // if d == 15 then UNPREDICTABLE; 1381 if (d == 15) 1382 return false; 1383 } 1384 break; 1385 1386 default: 1387 return false; 1388 } 1389 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 1390 AddWithCarryResult res = AddWithCarry (sp, imm32, 0); 1391 1392 EmulateInstruction::Context context; 1393 if (d == 13) 1394 context.type = EmulateInstruction::eContextAdjustStackPointer; 1395 else 1396 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1397 1398 RegisterInfo sp_reg; 1399 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1400 context.SetRegisterPlusOffset (sp_reg, res.result - sp); 1401 1402 if (d == 15) 1403 { 1404 if (!ALUWritePC (context, res.result)) 1405 return false; 1406 } 1407 else 1408 { 1409 // R[d] = result; 1410 // if setflags then 1411 // APSR.N = result<31>; 1412 // APSR.Z = IsZeroBit(result); 1413 // APSR.C = carry; 1414 // APSR.V = overflow; 1415 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 1416 return false; 1417 } 1418 } 1419 return true; 1420 } 1421 1422 // An add operation to adjust the SP. 1423 // ADD (SP plus register) 1424 bool 1425 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding) 1426 { 1427 #if 0 1428 // ARM pseudo code... 1429 if (ConditionPassed()) 1430 { 1431 EncodingSpecificOperations(); 1432 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1433 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1434 if d == 15 then 1435 ALUWritePC(result); // setflags is always FALSE here 1436 else 1437 R[d] = result; 1438 if setflags then 1439 APSR.N = result<31>; 1440 APSR.Z = IsZeroBit(result); 1441 APSR.C = carry; 1442 APSR.V = overflow; 1443 } 1444 #endif 1445 1446 bool success = false; 1447 1448 if (ConditionPassed(opcode)) 1449 { 1450 const addr_t sp = ReadCoreReg (SP_REG, &success); 1451 if (!success) 1452 return false; 1453 uint32_t Rm; // the second operand 1454 switch (encoding) { 1455 case eEncodingT2: 1456 Rm = Bits32(opcode, 6, 3); 1457 break; 1458 default: 1459 return false; 1460 } 1461 int32_t reg_value = ReadCoreReg(Rm, &success); 1462 if (!success) 1463 return false; 1464 1465 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1466 1467 EmulateInstruction::Context context; 1468 context.type = eContextArithmetic; 1469 RegisterInfo sp_reg; 1470 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 1471 1472 RegisterInfo other_reg; 1473 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1474 context.SetRegisterRegisterOperands (sp_reg, other_reg); 1475 1476 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr)) 1477 return false; 1478 } 1479 return true; 1480 } 1481 1482 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine 1483 // at a PC-relative address, and changes instruction set from ARM to Thumb, or 1484 // from Thumb to ARM. 1485 // BLX (immediate) 1486 bool 1487 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding) 1488 { 1489 #if 0 1490 // ARM pseudo code... 1491 if (ConditionPassed()) 1492 { 1493 EncodingSpecificOperations(); 1494 if CurrentInstrSet() == InstrSet_ARM then 1495 LR = PC - 4; 1496 else 1497 LR = PC<31:1> : '1'; 1498 if targetInstrSet == InstrSet_ARM then 1499 targetAddress = Align(PC,4) + imm32; 1500 else 1501 targetAddress = PC + imm32; 1502 SelectInstrSet(targetInstrSet); 1503 BranchWritePC(targetAddress); 1504 } 1505 #endif 1506 1507 bool success = true; 1508 1509 if (ConditionPassed(opcode)) 1510 { 1511 EmulateInstruction::Context context; 1512 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 1513 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1514 if (!success) 1515 return false; 1516 addr_t lr; // next instruction address 1517 addr_t target; // target address 1518 int32_t imm32; // PC-relative offset 1519 switch (encoding) { 1520 case eEncodingT1: 1521 { 1522 lr = pc | 1u; // return address 1523 uint32_t S = Bit32(opcode, 26); 1524 uint32_t imm10 = Bits32(opcode, 25, 16); 1525 uint32_t J1 = Bit32(opcode, 13); 1526 uint32_t J2 = Bit32(opcode, 11); 1527 uint32_t imm11 = Bits32(opcode, 10, 0); 1528 uint32_t I1 = !(J1 ^ S); 1529 uint32_t I2 = !(J2 ^ S); 1530 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 1531 imm32 = llvm::SignExtend32<25>(imm25); 1532 target = pc + imm32; 1533 SelectInstrSet (eModeThumb); 1534 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 1535 if (InITBlock() && !LastInITBlock()) 1536 return false; 1537 break; 1538 } 1539 case eEncodingT2: 1540 { 1541 lr = pc | 1u; // return address 1542 uint32_t S = Bit32(opcode, 26); 1543 uint32_t imm10H = Bits32(opcode, 25, 16); 1544 uint32_t J1 = Bit32(opcode, 13); 1545 uint32_t J2 = Bit32(opcode, 11); 1546 uint32_t imm10L = Bits32(opcode, 10, 1); 1547 uint32_t I1 = !(J1 ^ S); 1548 uint32_t I2 = !(J2 ^ S); 1549 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 1550 imm32 = llvm::SignExtend32<25>(imm25); 1551 target = Align(pc, 4) + imm32; 1552 SelectInstrSet (eModeARM); 1553 context.SetISAAndImmediateSigned (eModeARM, 4 + imm32); 1554 if (InITBlock() && !LastInITBlock()) 1555 return false; 1556 break; 1557 } 1558 case eEncodingA1: 1559 lr = pc - 4; // return address 1560 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 1561 target = Align(pc, 4) + imm32; 1562 SelectInstrSet (eModeARM); 1563 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 1564 break; 1565 case eEncodingA2: 1566 lr = pc - 4; // return address 1567 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1); 1568 target = pc + imm32; 1569 SelectInstrSet (eModeThumb); 1570 context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32); 1571 break; 1572 default: 1573 return false; 1574 } 1575 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1576 return false; 1577 if (!BranchWritePC(context, target)) 1578 return false; 1579 if (m_opcode_cpsr != m_new_inst_cpsr) 1580 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1581 return false; 1582 } 1583 return true; 1584 } 1585 1586 // Branch with Link and Exchange (register) calls a subroutine at an address and 1587 // instruction set specified by a register. 1588 // BLX (register) 1589 bool 1590 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding) 1591 { 1592 #if 0 1593 // ARM pseudo code... 1594 if (ConditionPassed()) 1595 { 1596 EncodingSpecificOperations(); 1597 target = R[m]; 1598 if CurrentInstrSet() == InstrSet_ARM then 1599 next_instr_addr = PC - 4; 1600 LR = next_instr_addr; 1601 else 1602 next_instr_addr = PC - 2; 1603 LR = next_instr_addr<31:1> : '1'; 1604 BXWritePC(target); 1605 } 1606 #endif 1607 1608 bool success = false; 1609 1610 if (ConditionPassed(opcode)) 1611 { 1612 EmulateInstruction::Context context; 1613 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1614 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1615 addr_t lr; // next instruction address 1616 if (!success) 1617 return false; 1618 uint32_t Rm; // the register with the target address 1619 switch (encoding) { 1620 case eEncodingT1: 1621 lr = (pc - 2) | 1u; // return address 1622 Rm = Bits32(opcode, 6, 3); 1623 // if m == 15 then UNPREDICTABLE; 1624 if (Rm == 15) 1625 return false; 1626 if (InITBlock() && !LastInITBlock()) 1627 return false; 1628 break; 1629 case eEncodingA1: 1630 lr = pc - 4; // return address 1631 Rm = Bits32(opcode, 3, 0); 1632 // if m == 15 then UNPREDICTABLE; 1633 if (Rm == 15) 1634 return false; 1635 break; 1636 default: 1637 return false; 1638 } 1639 addr_t target = ReadCoreReg (Rm, &success); 1640 if (!success) 1641 return false; 1642 RegisterInfo dwarf_reg; 1643 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1644 context.SetRegister (dwarf_reg); 1645 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 1646 return false; 1647 if (!BXWritePC(context, target)) 1648 return false; 1649 } 1650 return true; 1651 } 1652 1653 // Branch and Exchange causes a branch to an address and instruction set specified by a register. 1654 bool 1655 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding) 1656 { 1657 #if 0 1658 // ARM pseudo code... 1659 if (ConditionPassed()) 1660 { 1661 EncodingSpecificOperations(); 1662 BXWritePC(R[m]); 1663 } 1664 #endif 1665 1666 if (ConditionPassed(opcode)) 1667 { 1668 EmulateInstruction::Context context; 1669 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1670 uint32_t Rm; // the register with the target address 1671 switch (encoding) { 1672 case eEncodingT1: 1673 Rm = Bits32(opcode, 6, 3); 1674 if (InITBlock() && !LastInITBlock()) 1675 return false; 1676 break; 1677 case eEncodingA1: 1678 Rm = Bits32(opcode, 3, 0); 1679 break; 1680 default: 1681 return false; 1682 } 1683 bool success = false; 1684 addr_t target = ReadCoreReg (Rm, &success); 1685 if (!success) 1686 return false; 1687 1688 RegisterInfo dwarf_reg; 1689 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1690 context.SetRegister (dwarf_reg); 1691 if (!BXWritePC(context, target)) 1692 return false; 1693 } 1694 return true; 1695 } 1696 1697 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an 1698 // address and instruction set specified by a register as though it were a BX instruction. 1699 // 1700 // TODO: Emulate Jazelle architecture? 1701 // We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation. 1702 bool 1703 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding) 1704 { 1705 #if 0 1706 // ARM pseudo code... 1707 if (ConditionPassed()) 1708 { 1709 EncodingSpecificOperations(); 1710 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 1711 BXWritePC(R[m]); 1712 else 1713 if JazelleAcceptsExecution() then 1714 SwitchToJazelleExecution(); 1715 else 1716 SUBARCHITECTURE_DEFINED handler call; 1717 } 1718 #endif 1719 1720 if (ConditionPassed(opcode)) 1721 { 1722 EmulateInstruction::Context context; 1723 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 1724 uint32_t Rm; // the register with the target address 1725 switch (encoding) { 1726 case eEncodingT1: 1727 Rm = Bits32(opcode, 19, 16); 1728 if (BadReg(Rm)) 1729 return false; 1730 if (InITBlock() && !LastInITBlock()) 1731 return false; 1732 break; 1733 case eEncodingA1: 1734 Rm = Bits32(opcode, 3, 0); 1735 if (Rm == 15) 1736 return false; 1737 break; 1738 default: 1739 return false; 1740 } 1741 bool success = false; 1742 addr_t target = ReadCoreReg (Rm, &success); 1743 if (!success) 1744 return false; 1745 1746 RegisterInfo dwarf_reg; 1747 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1748 context.SetRegister (dwarf_reg); 1749 if (!BXWritePC(context, target)) 1750 return false; 1751 } 1752 return true; 1753 } 1754 1755 // Set r7 to point to some ip offset. 1756 // SUB (immediate) 1757 bool 1758 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding) 1759 { 1760 #if 0 1761 // ARM pseudo code... 1762 if (ConditionPassed()) 1763 { 1764 EncodingSpecificOperations(); 1765 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1766 if d == 15 then // Can only occur for ARM encoding 1767 ALUWritePC(result); // setflags is always FALSE here 1768 else 1769 R[d] = result; 1770 if setflags then 1771 APSR.N = result<31>; 1772 APSR.Z = IsZeroBit(result); 1773 APSR.C = carry; 1774 APSR.V = overflow; 1775 } 1776 #endif 1777 1778 if (ConditionPassed(opcode)) 1779 { 1780 bool success = false; 1781 const addr_t ip = ReadCoreReg (12, &success); 1782 if (!success) 1783 return false; 1784 uint32_t imm32; 1785 switch (encoding) { 1786 case eEncodingA1: 1787 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1788 break; 1789 default: 1790 return false; 1791 } 1792 addr_t ip_offset = imm32; 1793 addr_t addr = ip - ip_offset; // the adjusted ip value 1794 1795 EmulateInstruction::Context context; 1796 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1797 RegisterInfo dwarf_reg; 1798 GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg); 1799 context.SetRegisterPlusOffset (dwarf_reg, -ip_offset); 1800 1801 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr)) 1802 return false; 1803 } 1804 return true; 1805 } 1806 1807 // Set ip to point to some stack offset. 1808 // SUB (SP minus immediate) 1809 bool 1810 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding) 1811 { 1812 #if 0 1813 // ARM pseudo code... 1814 if (ConditionPassed()) 1815 { 1816 EncodingSpecificOperations(); 1817 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1818 if d == 15 then // Can only occur for ARM encoding 1819 ALUWritePC(result); // setflags is always FALSE here 1820 else 1821 R[d] = result; 1822 if setflags then 1823 APSR.N = result<31>; 1824 APSR.Z = IsZeroBit(result); 1825 APSR.C = carry; 1826 APSR.V = overflow; 1827 } 1828 #endif 1829 1830 if (ConditionPassed(opcode)) 1831 { 1832 bool success = false; 1833 const addr_t sp = ReadCoreReg (SP_REG, &success); 1834 if (!success) 1835 return false; 1836 uint32_t imm32; 1837 switch (encoding) { 1838 case eEncodingA1: 1839 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1840 break; 1841 default: 1842 return false; 1843 } 1844 addr_t sp_offset = imm32; 1845 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 1846 1847 EmulateInstruction::Context context; 1848 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1849 RegisterInfo dwarf_reg; 1850 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 1851 context.SetRegisterPlusOffset (dwarf_reg, -sp_offset); 1852 1853 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr)) 1854 return false; 1855 } 1856 return true; 1857 } 1858 1859 // This instruction subtracts an immediate value from the SP value, and writes 1860 // the result to the destination register. 1861 // 1862 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage. 1863 bool 1864 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding) 1865 { 1866 #if 0 1867 // ARM pseudo code... 1868 if (ConditionPassed()) 1869 { 1870 EncodingSpecificOperations(); 1871 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 1872 if d == 15 then // Can only occur for ARM encoding 1873 ALUWritePC(result); // setflags is always FALSE here 1874 else 1875 R[d] = result; 1876 if setflags then 1877 APSR.N = result<31>; 1878 APSR.Z = IsZeroBit(result); 1879 APSR.C = carry; 1880 APSR.V = overflow; 1881 } 1882 #endif 1883 1884 bool success = false; 1885 if (ConditionPassed(opcode)) 1886 { 1887 const addr_t sp = ReadCoreReg (SP_REG, &success); 1888 if (!success) 1889 return false; 1890 1891 uint32_t Rd; 1892 bool setflags; 1893 uint32_t imm32; 1894 switch (encoding) { 1895 case eEncodingT1: 1896 Rd = 13; 1897 setflags = false; 1898 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1899 break; 1900 case eEncodingT2: 1901 Rd = Bits32(opcode, 11, 8); 1902 setflags = BitIsSet(opcode, 20); 1903 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 1904 if (Rd == 15 && setflags) 1905 return EmulateCMPImm(opcode, eEncodingT2); 1906 if (Rd == 15 && !setflags) 1907 return false; 1908 break; 1909 case eEncodingT3: 1910 Rd = Bits32(opcode, 11, 8); 1911 setflags = false; 1912 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 1913 if (Rd == 15) 1914 return false; 1915 break; 1916 case eEncodingA1: 1917 Rd = Bits32(opcode, 15, 12); 1918 setflags = BitIsSet(opcode, 20); 1919 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1920 1921 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 1922 if (Rd == 15 && setflags) 1923 return EmulateSUBSPcLrEtc (opcode, encoding); 1924 break; 1925 default: 1926 return false; 1927 } 1928 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 1929 1930 EmulateInstruction::Context context; 1931 if (Rd == 13) 1932 { 1933 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting to negate it, or the wrong 1934 // value gets passed down to context.SetImmediateSigned. 1935 context.type = EmulateInstruction::eContextAdjustStackPointer; 1936 context.SetImmediateSigned (-imm64); // the stack pointer offset 1937 } 1938 else 1939 { 1940 context.type = EmulateInstruction::eContextImmediate; 1941 context.SetNoArgs (); 1942 } 1943 1944 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 1945 return false; 1946 } 1947 return true; 1948 } 1949 1950 // A store operation to the stack that also updates the SP. 1951 bool 1952 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding) 1953 { 1954 #if 0 1955 // ARM pseudo code... 1956 if (ConditionPassed()) 1957 { 1958 EncodingSpecificOperations(); 1959 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 1960 address = if index then offset_addr else R[n]; 1961 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 1962 if wback then R[n] = offset_addr; 1963 } 1964 #endif 1965 1966 bool success = false; 1967 if (ConditionPassed(opcode)) 1968 { 1969 const uint32_t addr_byte_size = GetAddressByteSize(); 1970 const addr_t sp = ReadCoreReg (SP_REG, &success); 1971 if (!success) 1972 return false; 1973 uint32_t Rt; // the source register 1974 uint32_t imm12; 1975 uint32_t Rn; // This function assumes Rn is the SP, but we should verify that. 1976 1977 bool index; 1978 bool add; 1979 bool wback; 1980 switch (encoding) { 1981 case eEncodingA1: 1982 Rt = Bits32(opcode, 15, 12); 1983 imm12 = Bits32(opcode, 11, 0); 1984 Rn = Bits32 (opcode, 19, 16); 1985 1986 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 1987 return false; 1988 1989 index = BitIsSet (opcode, 24); 1990 add = BitIsSet (opcode, 23); 1991 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 1992 1993 if (wback && ((Rn == 15) || (Rn == Rt))) 1994 return false; 1995 break; 1996 default: 1997 return false; 1998 } 1999 addr_t offset_addr; 2000 if (add) 2001 offset_addr = sp + imm12; 2002 else 2003 offset_addr = sp - imm12; 2004 2005 addr_t addr; 2006 if (index) 2007 addr = offset_addr; 2008 else 2009 addr = sp; 2010 2011 EmulateInstruction::Context context; 2012 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2013 RegisterInfo sp_reg; 2014 RegisterInfo dwarf_reg; 2015 2016 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2017 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2018 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2019 if (Rt != 15) 2020 { 2021 uint32_t reg_value = ReadCoreReg(Rt, &success); 2022 if (!success) 2023 return false; 2024 if (!MemUWrite (context, addr, reg_value, addr_byte_size)) 2025 return false; 2026 } 2027 else 2028 { 2029 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2030 if (!success) 2031 return false; 2032 if (!MemUWrite (context, addr, pc, addr_byte_size)) 2033 return false; 2034 } 2035 2036 2037 if (wback) 2038 { 2039 context.type = EmulateInstruction::eContextAdjustStackPointer; 2040 context.SetImmediateSigned (addr - sp); 2041 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr)) 2042 return false; 2043 } 2044 } 2045 return true; 2046 } 2047 2048 // Vector Push stores multiple extension registers to the stack. 2049 // It also updates SP to point to the start of the stored data. 2050 bool 2051 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding) 2052 { 2053 #if 0 2054 // ARM pseudo code... 2055 if (ConditionPassed()) 2056 { 2057 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2058 address = SP - imm32; 2059 SP = SP - imm32; 2060 if single_regs then 2061 for r = 0 to regs-1 2062 MemA[address,4] = S[d+r]; address = address+4; 2063 else 2064 for r = 0 to regs-1 2065 // Store as two word-aligned words in the correct order for current endianness. 2066 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2067 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2068 address = address+8; 2069 } 2070 #endif 2071 2072 bool success = false; 2073 if (ConditionPassed(opcode)) 2074 { 2075 const uint32_t addr_byte_size = GetAddressByteSize(); 2076 const addr_t sp = ReadCoreReg (SP_REG, &success); 2077 if (!success) 2078 return false; 2079 bool single_regs; 2080 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2081 uint32_t imm32; // stack offset 2082 uint32_t regs; // number of registers 2083 switch (encoding) { 2084 case eEncodingT1: 2085 case eEncodingA1: 2086 single_regs = false; 2087 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2088 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2089 // If UInt(imm8) is odd, see "FSTMX". 2090 regs = Bits32(opcode, 7, 0) / 2; 2091 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2092 if (regs == 0 || regs > 16 || (d + regs) > 32) 2093 return false; 2094 break; 2095 case eEncodingT2: 2096 case eEncodingA2: 2097 single_regs = true; 2098 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2099 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2100 regs = Bits32(opcode, 7, 0); 2101 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2102 if (regs == 0 || regs > 16 || (d + regs) > 32) 2103 return false; 2104 break; 2105 default: 2106 return false; 2107 } 2108 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2109 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2110 addr_t sp_offset = imm32; 2111 addr_t addr = sp - sp_offset; 2112 uint32_t i; 2113 2114 EmulateInstruction::Context context; 2115 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2116 2117 RegisterInfo dwarf_reg; 2118 RegisterInfo sp_reg; 2119 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2120 for (i=0; i<regs; ++i) 2121 { 2122 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2123 context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp); 2124 // uint64_t to accommodate 64-bit registers. 2125 uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success); 2126 if (!success) 2127 return false; 2128 if (!MemAWrite (context, addr, reg_value, reg_byte_size)) 2129 return false; 2130 addr += reg_byte_size; 2131 } 2132 2133 context.type = EmulateInstruction::eContextAdjustStackPointer; 2134 context.SetImmediateSigned (-sp_offset); 2135 2136 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2137 return false; 2138 } 2139 return true; 2140 } 2141 2142 // Vector Pop loads multiple extension registers from the stack. 2143 // It also updates SP to point just above the loaded data. 2144 bool 2145 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding) 2146 { 2147 #if 0 2148 // ARM pseudo code... 2149 if (ConditionPassed()) 2150 { 2151 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2152 address = SP; 2153 SP = SP + imm32; 2154 if single_regs then 2155 for r = 0 to regs-1 2156 S[d+r] = MemA[address,4]; address = address+4; 2157 else 2158 for r = 0 to regs-1 2159 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2160 // Combine the word-aligned words in the correct order for current endianness. 2161 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2162 } 2163 #endif 2164 2165 bool success = false; 2166 if (ConditionPassed(opcode)) 2167 { 2168 const uint32_t addr_byte_size = GetAddressByteSize(); 2169 const addr_t sp = ReadCoreReg (SP_REG, &success); 2170 if (!success) 2171 return false; 2172 bool single_regs; 2173 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2174 uint32_t imm32; // stack offset 2175 uint32_t regs; // number of registers 2176 switch (encoding) { 2177 case eEncodingT1: 2178 case eEncodingA1: 2179 single_regs = false; 2180 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2181 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2182 // If UInt(imm8) is odd, see "FLDMX". 2183 regs = Bits32(opcode, 7, 0) / 2; 2184 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2185 if (regs == 0 || regs > 16 || (d + regs) > 32) 2186 return false; 2187 break; 2188 case eEncodingT2: 2189 case eEncodingA2: 2190 single_regs = true; 2191 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2192 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2193 regs = Bits32(opcode, 7, 0); 2194 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2195 if (regs == 0 || regs > 16 || (d + regs) > 32) 2196 return false; 2197 break; 2198 default: 2199 return false; 2200 } 2201 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2202 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2203 addr_t sp_offset = imm32; 2204 addr_t addr = sp; 2205 uint32_t i; 2206 uint64_t data; // uint64_t to accommodate 64-bit registers. 2207 2208 EmulateInstruction::Context context; 2209 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2210 2211 RegisterInfo dwarf_reg; 2212 RegisterInfo sp_reg; 2213 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 2214 for (i=0; i<regs; ++i) 2215 { 2216 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2217 context.SetAddress(addr); 2218 data = MemARead(context, addr, reg_byte_size, 0, &success); 2219 if (!success) 2220 return false; 2221 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2222 return false; 2223 addr += reg_byte_size; 2224 } 2225 2226 context.type = EmulateInstruction::eContextAdjustStackPointer; 2227 context.SetImmediateSigned (sp_offset); 2228 2229 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2230 return false; 2231 } 2232 return true; 2233 } 2234 2235 // SVC (previously SWI) 2236 bool 2237 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding) 2238 { 2239 #if 0 2240 // ARM pseudo code... 2241 if (ConditionPassed()) 2242 { 2243 EncodingSpecificOperations(); 2244 CallSupervisor(); 2245 } 2246 #endif 2247 2248 bool success = false; 2249 2250 if (ConditionPassed(opcode)) 2251 { 2252 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2253 addr_t lr; // next instruction address 2254 if (!success) 2255 return false; 2256 uint32_t imm32; // the immediate constant 2257 uint32_t mode; // ARM or Thumb mode 2258 switch (encoding) { 2259 case eEncodingT1: 2260 lr = (pc + 2) | 1u; // return address 2261 imm32 = Bits32(opcode, 7, 0); 2262 mode = eModeThumb; 2263 break; 2264 case eEncodingA1: 2265 lr = pc + 4; // return address 2266 imm32 = Bits32(opcode, 23, 0); 2267 mode = eModeARM; 2268 break; 2269 default: 2270 return false; 2271 } 2272 2273 EmulateInstruction::Context context; 2274 context.type = EmulateInstruction::eContextSupervisorCall; 2275 context.SetISAAndImmediate (mode, imm32); 2276 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr)) 2277 return false; 2278 } 2279 return true; 2280 } 2281 2282 // If Then makes up to four following instructions (the IT block) conditional. 2283 bool 2284 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding) 2285 { 2286 #if 0 2287 // ARM pseudo code... 2288 EncodingSpecificOperations(); 2289 ITSTATE.IT<7:0> = firstcond:mask; 2290 #endif 2291 2292 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2293 return true; 2294 } 2295 2296 bool 2297 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding) 2298 { 2299 // NOP, nothing to do... 2300 return true; 2301 } 2302 2303 // Branch causes a branch to a target address. 2304 bool 2305 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding) 2306 { 2307 #if 0 2308 // ARM pseudo code... 2309 if (ConditionPassed()) 2310 { 2311 EncodingSpecificOperations(); 2312 BranchWritePC(PC + imm32); 2313 } 2314 #endif 2315 2316 bool success = false; 2317 2318 if (ConditionPassed(opcode)) 2319 { 2320 EmulateInstruction::Context context; 2321 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2322 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2323 if (!success) 2324 return false; 2325 addr_t target; // target address 2326 int32_t imm32; // PC-relative offset 2327 switch (encoding) { 2328 case eEncodingT1: 2329 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2330 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2331 target = pc + imm32; 2332 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2333 break; 2334 case eEncodingT2: 2335 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2336 target = pc + imm32; 2337 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2338 break; 2339 case eEncodingT3: 2340 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2341 { 2342 if (Bits32(opcode, 25, 23) == 7) 2343 return false; // See Branches and miscellaneous control on page A6-235. 2344 2345 uint32_t S = Bit32(opcode, 26); 2346 uint32_t imm6 = Bits32(opcode, 21, 16); 2347 uint32_t J1 = Bit32(opcode, 13); 2348 uint32_t J2 = Bit32(opcode, 11); 2349 uint32_t imm11 = Bits32(opcode, 10, 0); 2350 uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2351 imm32 = llvm::SignExtend32<21>(imm21); 2352 target = pc + imm32; 2353 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2354 break; 2355 } 2356 case eEncodingT4: 2357 { 2358 uint32_t S = Bit32(opcode, 26); 2359 uint32_t imm10 = Bits32(opcode, 25, 16); 2360 uint32_t J1 = Bit32(opcode, 13); 2361 uint32_t J2 = Bit32(opcode, 11); 2362 uint32_t imm11 = Bits32(opcode, 10, 0); 2363 uint32_t I1 = !(J1 ^ S); 2364 uint32_t I2 = !(J2 ^ S); 2365 uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2366 imm32 = llvm::SignExtend32<25>(imm25); 2367 target = pc + imm32; 2368 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2369 break; 2370 } 2371 case eEncodingA1: 2372 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2373 target = pc + imm32; 2374 context.SetISAAndImmediateSigned (eModeARM, 8 + imm32); 2375 break; 2376 default: 2377 return false; 2378 } 2379 if (!BranchWritePC(context, target)) 2380 return false; 2381 } 2382 return true; 2383 } 2384 2385 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with 2386 // zero and conditionally branch forward a constant value. They do not affect the condition flags. 2387 // CBNZ, CBZ 2388 bool 2389 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding) 2390 { 2391 #if 0 2392 // ARM pseudo code... 2393 EncodingSpecificOperations(); 2394 if nonzero ^ IsZero(R[n]) then 2395 BranchWritePC(PC + imm32); 2396 #endif 2397 2398 bool success = false; 2399 2400 // Read the register value from the operand register Rn. 2401 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2402 if (!success) 2403 return false; 2404 2405 EmulateInstruction::Context context; 2406 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2407 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2408 if (!success) 2409 return false; 2410 2411 addr_t target; // target address 2412 uint32_t imm32; // PC-relative offset to branch forward 2413 bool nonzero; 2414 switch (encoding) { 2415 case eEncodingT1: 2416 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2417 nonzero = BitIsSet(opcode, 11); 2418 target = pc + imm32; 2419 context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32); 2420 break; 2421 default: 2422 return false; 2423 } 2424 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2425 if (!BranchWritePC(context, target)) 2426 return false; 2427 2428 return true; 2429 } 2430 2431 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets. 2432 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2433 // The branch length is twice the value of the byte returned from the table. 2434 // 2435 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets. 2436 // A base register provides a pointer to the table, and a second register supplies an index into the table. 2437 // The branch length is twice the value of the halfword returned from the table. 2438 // TBB, TBH 2439 bool 2440 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding) 2441 { 2442 #if 0 2443 // ARM pseudo code... 2444 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2445 if is_tbh then 2446 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2447 else 2448 halfwords = UInt(MemU[R[n]+R[m], 1]); 2449 BranchWritePC(PC + 2*halfwords); 2450 #endif 2451 2452 bool success = false; 2453 2454 if (ConditionPassed(opcode)) 2455 { 2456 uint32_t Rn; // the base register which contains the address of the table of branch lengths 2457 uint32_t Rm; // the index register which contains an integer pointing to a byte/halfword in the table 2458 bool is_tbh; // true if table branch halfword 2459 switch (encoding) { 2460 case eEncodingT1: 2461 Rn = Bits32(opcode, 19, 16); 2462 Rm = Bits32(opcode, 3, 0); 2463 is_tbh = BitIsSet(opcode, 4); 2464 if (Rn == 13 || BadReg(Rm)) 2465 return false; 2466 if (InITBlock() && !LastInITBlock()) 2467 return false; 2468 break; 2469 default: 2470 return false; 2471 } 2472 2473 // Read the address of the table from the operand register Rn. 2474 // The PC can be used, in which case the table immediately follows this instruction. 2475 uint32_t base = ReadCoreReg(Rn, &success); 2476 if (!success) 2477 return false; 2478 2479 // the table index 2480 uint32_t index = ReadCoreReg(Rm, &success); 2481 if (!success) 2482 return false; 2483 2484 // the offsetted table address 2485 addr_t addr = base + (is_tbh ? index*2 : index); 2486 2487 // PC-relative offset to branch forward 2488 EmulateInstruction::Context context; 2489 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2490 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 2491 if (!success) 2492 return false; 2493 2494 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2495 if (!success) 2496 return false; 2497 2498 // target address 2499 addr_t target = pc + offset; 2500 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2501 context.SetISAAndImmediateSigned (eModeThumb, 4 + offset); 2502 2503 if (!BranchWritePC(context, target)) 2504 return false; 2505 } 2506 2507 return true; 2508 } 2509 2510 // This instruction adds an immediate value to a register value, and writes the result to the destination register. 2511 // It can optionally update the condition flags based on the result. 2512 bool 2513 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding) 2514 { 2515 #if 0 2516 if ConditionPassed() then 2517 EncodingSpecificOperations(); 2518 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2519 R[d] = result; 2520 if setflags then 2521 APSR.N = result<31>; 2522 APSR.Z = IsZeroBit(result); 2523 APSR.C = carry; 2524 APSR.V = overflow; 2525 #endif 2526 2527 bool success = false; 2528 2529 if (ConditionPassed(opcode)) 2530 { 2531 uint32_t d; 2532 uint32_t n; 2533 bool setflags; 2534 uint32_t imm32; 2535 uint32_t carry_out; 2536 2537 //EncodingSpecificOperations(); 2538 switch (encoding) 2539 { 2540 case eEncodingT1: 2541 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32); 2542 d = Bits32 (opcode, 2, 0); 2543 n = Bits32 (opcode, 5, 3); 2544 setflags = !InITBlock(); 2545 imm32 = Bits32 (opcode, 8,6); 2546 2547 break; 2548 2549 case eEncodingT2: 2550 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32); 2551 d = Bits32 (opcode, 10, 8); 2552 n = Bits32 (opcode, 10, 8); 2553 setflags = !InITBlock(); 2554 imm32 = Bits32 (opcode, 7, 0); 2555 2556 break; 2557 2558 case eEncodingT3: 2559 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 2560 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8); 2561 d = Bits32 (opcode, 11, 8); 2562 n = Bits32 (opcode, 19, 16); 2563 setflags = BitIsSet (opcode, 20); 2564 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out); 2565 2566 // if Rn == '1101' then SEE ADD (SP plus immediate); 2567 if (n == 13) 2568 return EmulateADDSPImm(opcode, eEncodingT3); 2569 2570 // if BadReg(d) || n == 15 then UNPREDICTABLE; 2571 if (BadReg (d) || (n == 15)) 2572 return false; 2573 2574 break; 2575 2576 case eEncodingT4: 2577 { 2578 // if Rn == '1111' then SEE ADR; 2579 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 2580 d = Bits32 (opcode, 11, 8); 2581 n = Bits32 (opcode, 19, 16); 2582 setflags = false; 2583 uint32_t i = Bit32 (opcode, 26); 2584 uint32_t imm3 = Bits32 (opcode, 14, 12); 2585 uint32_t imm8 = Bits32 (opcode, 7, 0); 2586 imm32 = (i << 11) | (imm3 << 8) | imm8; 2587 2588 // if Rn == '1101' then SEE ADD (SP plus immediate); 2589 if (n == 13) 2590 return EmulateADDSPImm(opcode, eEncodingT4); 2591 2592 // if BadReg(d) then UNPREDICTABLE; 2593 if (BadReg (d)) 2594 return false; 2595 2596 break; 2597 } 2598 2599 default: 2600 return false; 2601 } 2602 2603 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 2604 if (!success) 2605 return false; 2606 2607 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2608 AddWithCarryResult res = AddWithCarry (Rn, imm32, 0); 2609 2610 RegisterInfo reg_n; 2611 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 2612 2613 EmulateInstruction::Context context; 2614 context.type = eContextArithmetic; 2615 context.SetRegisterPlusOffset (reg_n, imm32); 2616 2617 //R[d] = result; 2618 //if setflags then 2619 //APSR.N = result<31>; 2620 //APSR.Z = IsZeroBit(result); 2621 //APSR.C = carry; 2622 //APSR.V = overflow; 2623 if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow)) 2624 return false; 2625 2626 } 2627 return true; 2628 } 2629 2630 // This instruction adds an immediate value to a register value, and writes the result to the destination 2631 // register. It can optionally update the condition flags based on the result. 2632 bool 2633 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding) 2634 { 2635 #if 0 2636 // ARM pseudo code... 2637 if ConditionPassed() then 2638 EncodingSpecificOperations(); 2639 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2640 if d == 15 then 2641 ALUWritePC(result); // setflags is always FALSE here 2642 else 2643 R[d] = result; 2644 if setflags then 2645 APSR.N = result<31>; 2646 APSR.Z = IsZeroBit(result); 2647 APSR.C = carry; 2648 APSR.V = overflow; 2649 #endif 2650 2651 bool success = false; 2652 2653 if (ConditionPassed(opcode)) 2654 { 2655 uint32_t Rd, Rn; 2656 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 2657 bool setflags; 2658 switch (encoding) 2659 { 2660 case eEncodingA1: 2661 Rd = Bits32(opcode, 15, 12); 2662 Rn = Bits32(opcode, 19, 16); 2663 setflags = BitIsSet(opcode, 20); 2664 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2665 break; 2666 default: 2667 return false; 2668 } 2669 2670 // Read the first operand. 2671 uint32_t val1 = ReadCoreReg(Rn, &success); 2672 if (!success) 2673 return false; 2674 2675 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 2676 2677 EmulateInstruction::Context context; 2678 if (Rd == 13) 2679 context.type = EmulateInstruction::eContextAdjustStackPointer; 2680 else if (Rd == GetFramePointerRegisterNumber()) 2681 context.type = EmulateInstruction::eContextSetFramePointer; 2682 else 2683 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2684 2685 RegisterInfo dwarf_reg; 2686 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 2687 context.SetRegisterPlusOffset (dwarf_reg, imm32); 2688 2689 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2690 return false; 2691 } 2692 return true; 2693 } 2694 2695 // This instruction adds a register value and an optionally-shifted register value, and writes the result 2696 // to the destination register. It can optionally update the condition flags based on the result. 2697 bool 2698 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding) 2699 { 2700 #if 0 2701 // ARM pseudo code... 2702 if ConditionPassed() then 2703 EncodingSpecificOperations(); 2704 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2705 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2706 if d == 15 then 2707 ALUWritePC(result); // setflags is always FALSE here 2708 else 2709 R[d] = result; 2710 if setflags then 2711 APSR.N = result<31>; 2712 APSR.Z = IsZeroBit(result); 2713 APSR.C = carry; 2714 APSR.V = overflow; 2715 #endif 2716 2717 bool success = false; 2718 2719 if (ConditionPassed(opcode)) 2720 { 2721 uint32_t Rd, Rn, Rm; 2722 ARM_ShifterType shift_t; 2723 uint32_t shift_n; // the shift applied to the value read from Rm 2724 bool setflags; 2725 switch (encoding) 2726 { 2727 case eEncodingT1: 2728 Rd = Bits32(opcode, 2, 0); 2729 Rn = Bits32(opcode, 5, 3); 2730 Rm = Bits32(opcode, 8, 6); 2731 setflags = !InITBlock(); 2732 shift_t = SRType_LSL; 2733 shift_n = 0; 2734 break; 2735 case eEncodingT2: 2736 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2737 Rm = Bits32(opcode, 6, 3); 2738 setflags = false; 2739 shift_t = SRType_LSL; 2740 shift_n = 0; 2741 if (Rn == 15 && Rm == 15) 2742 return false; 2743 if (Rd == 15 && InITBlock() && !LastInITBlock()) 2744 return false; 2745 break; 2746 case eEncodingA1: 2747 Rd = Bits32(opcode, 15, 12); 2748 Rn = Bits32(opcode, 19, 16); 2749 Rm = Bits32(opcode, 3, 0); 2750 setflags = BitIsSet(opcode, 20); 2751 shift_n = DecodeImmShiftARM(opcode, shift_t); 2752 break; 2753 default: 2754 return false; 2755 } 2756 2757 // Read the first operand. 2758 uint32_t val1 = ReadCoreReg(Rn, &success); 2759 if (!success) 2760 return false; 2761 2762 // Read the second operand. 2763 uint32_t val2 = ReadCoreReg(Rm, &success); 2764 if (!success) 2765 return false; 2766 2767 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2768 if (!success) 2769 return false; 2770 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2771 2772 EmulateInstruction::Context context; 2773 context.type = eContextArithmetic; 2774 RegisterInfo op1_reg; 2775 RegisterInfo op2_reg; 2776 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 2777 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 2778 context.SetRegisterRegisterOperands (op1_reg, op2_reg); 2779 2780 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 2781 return false; 2782 } 2783 return true; 2784 } 2785 2786 // Compare Negative (immediate) adds a register value and an immediate value. 2787 // It updates the condition flags based on the result, and discards the result. 2788 bool 2789 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding) 2790 { 2791 #if 0 2792 // ARM pseudo code... 2793 if ConditionPassed() then 2794 EncodingSpecificOperations(); 2795 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 2796 APSR.N = result<31>; 2797 APSR.Z = IsZeroBit(result); 2798 APSR.C = carry; 2799 APSR.V = overflow; 2800 #endif 2801 2802 bool success = false; 2803 2804 uint32_t Rn; // the first operand 2805 uint32_t imm32; // the immediate value to be compared with 2806 switch (encoding) { 2807 case eEncodingT1: 2808 Rn = Bits32(opcode, 19, 16); 2809 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2810 if (Rn == 15) 2811 return false; 2812 break; 2813 case eEncodingA1: 2814 Rn = Bits32(opcode, 19, 16); 2815 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2816 break; 2817 default: 2818 return false; 2819 } 2820 // Read the register value from the operand register Rn. 2821 uint32_t reg_val = ReadCoreReg(Rn, &success); 2822 if (!success) 2823 return false; 2824 2825 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 2826 2827 EmulateInstruction::Context context; 2828 context.type = EmulateInstruction::eContextImmediate; 2829 context.SetNoArgs (); 2830 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2831 return false; 2832 2833 return true; 2834 } 2835 2836 // Compare Negative (register) adds a register value and an optionally-shifted register value. 2837 // It updates the condition flags based on the result, and discards the result. 2838 bool 2839 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding) 2840 { 2841 #if 0 2842 // ARM pseudo code... 2843 if ConditionPassed() then 2844 EncodingSpecificOperations(); 2845 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2846 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 2847 APSR.N = result<31>; 2848 APSR.Z = IsZeroBit(result); 2849 APSR.C = carry; 2850 APSR.V = overflow; 2851 #endif 2852 2853 bool success = false; 2854 2855 uint32_t Rn; // the first operand 2856 uint32_t Rm; // the second operand 2857 ARM_ShifterType shift_t; 2858 uint32_t shift_n; // the shift applied to the value read from Rm 2859 switch (encoding) { 2860 case eEncodingT1: 2861 Rn = Bits32(opcode, 2, 0); 2862 Rm = Bits32(opcode, 5, 3); 2863 shift_t = SRType_LSL; 2864 shift_n = 0; 2865 break; 2866 case eEncodingT2: 2867 Rn = Bits32(opcode, 19, 16); 2868 Rm = Bits32(opcode, 3, 0); 2869 shift_n = DecodeImmShiftThumb(opcode, shift_t); 2870 // if n == 15 || BadReg(m) then UNPREDICTABLE; 2871 if (Rn == 15 || BadReg(Rm)) 2872 return false; 2873 break; 2874 case eEncodingA1: 2875 Rn = Bits32(opcode, 19, 16); 2876 Rm = Bits32(opcode, 3, 0); 2877 shift_n = DecodeImmShiftARM(opcode, shift_t); 2878 break; 2879 default: 2880 return false; 2881 } 2882 // Read the register value from register Rn. 2883 uint32_t val1 = ReadCoreReg(Rn, &success); 2884 if (!success) 2885 return false; 2886 2887 // Read the register value from register Rm. 2888 uint32_t val2 = ReadCoreReg(Rm, &success); 2889 if (!success) 2890 return false; 2891 2892 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 2893 if (!success) 2894 return false; 2895 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 2896 2897 EmulateInstruction::Context context; 2898 context.type = EmulateInstruction::eContextImmediate; 2899 context.SetNoArgs(); 2900 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2901 return false; 2902 2903 return true; 2904 } 2905 2906 // Compare (immediate) subtracts an immediate value from a register value. 2907 // It updates the condition flags based on the result, and discards the result. 2908 bool 2909 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding) 2910 { 2911 #if 0 2912 // ARM pseudo code... 2913 if ConditionPassed() then 2914 EncodingSpecificOperations(); 2915 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 2916 APSR.N = result<31>; 2917 APSR.Z = IsZeroBit(result); 2918 APSR.C = carry; 2919 APSR.V = overflow; 2920 #endif 2921 2922 bool success = false; 2923 2924 uint32_t Rn; // the first operand 2925 uint32_t imm32; // the immediate value to be compared with 2926 switch (encoding) { 2927 case eEncodingT1: 2928 Rn = Bits32(opcode, 10, 8); 2929 imm32 = Bits32(opcode, 7, 0); 2930 break; 2931 case eEncodingT2: 2932 Rn = Bits32(opcode, 19, 16); 2933 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2934 if (Rn == 15) 2935 return false; 2936 break; 2937 case eEncodingA1: 2938 Rn = Bits32(opcode, 19, 16); 2939 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2940 break; 2941 default: 2942 return false; 2943 } 2944 // Read the register value from the operand register Rn. 2945 uint32_t reg_val = ReadCoreReg(Rn, &success); 2946 if (!success) 2947 return false; 2948 2949 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 2950 2951 EmulateInstruction::Context context; 2952 context.type = EmulateInstruction::eContextImmediate; 2953 context.SetNoArgs (); 2954 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 2955 return false; 2956 2957 return true; 2958 } 2959 2960 // Compare (register) subtracts an optionally-shifted register value from a register value. 2961 // It updates the condition flags based on the result, and discards the result. 2962 bool 2963 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding) 2964 { 2965 #if 0 2966 // ARM pseudo code... 2967 if ConditionPassed() then 2968 EncodingSpecificOperations(); 2969 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 2970 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 2971 APSR.N = result<31>; 2972 APSR.Z = IsZeroBit(result); 2973 APSR.C = carry; 2974 APSR.V = overflow; 2975 #endif 2976 2977 bool success = false; 2978 2979 uint32_t Rn; // the first operand 2980 uint32_t Rm; // the second operand 2981 ARM_ShifterType shift_t; 2982 uint32_t shift_n; // the shift applied to the value read from Rm 2983 switch (encoding) { 2984 case eEncodingT1: 2985 Rn = Bits32(opcode, 2, 0); 2986 Rm = Bits32(opcode, 5, 3); 2987 shift_t = SRType_LSL; 2988 shift_n = 0; 2989 break; 2990 case eEncodingT2: 2991 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 2992 Rm = Bits32(opcode, 6, 3); 2993 shift_t = SRType_LSL; 2994 shift_n = 0; 2995 if (Rn < 8 && Rm < 8) 2996 return false; 2997 if (Rn == 15 || Rm == 15) 2998 return false; 2999 break; 3000 case eEncodingT3: 3001 Rn = Bits32(opcode, 19, 16); 3002 Rm = Bits32(opcode, 3, 0); 3003 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3004 if (Rn == 15 || BadReg(Rm)) 3005 return false; 3006 break; 3007 case eEncodingA1: 3008 Rn = Bits32(opcode, 19, 16); 3009 Rm = Bits32(opcode, 3, 0); 3010 shift_n = DecodeImmShiftARM(opcode, shift_t); 3011 break; 3012 default: 3013 return false; 3014 } 3015 // Read the register value from register Rn. 3016 uint32_t val1 = ReadCoreReg(Rn, &success); 3017 if (!success) 3018 return false; 3019 3020 // Read the register value from register Rm. 3021 uint32_t val2 = ReadCoreReg(Rm, &success); 3022 if (!success) 3023 return false; 3024 3025 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3026 if (!success) 3027 return false; 3028 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3029 3030 EmulateInstruction::Context context; 3031 context.type = EmulateInstruction::eContextImmediate; 3032 context.SetNoArgs(); 3033 if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) 3034 return false; 3035 3036 return true; 3037 } 3038 3039 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, 3040 // shifting in copies of its sign bit, and writes the result to the destination register. It can 3041 // optionally update the condition flags based on the result. 3042 bool 3043 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding) 3044 { 3045 #if 0 3046 // ARM pseudo code... 3047 if ConditionPassed() then 3048 EncodingSpecificOperations(); 3049 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3050 if d == 15 then // Can only occur for ARM encoding 3051 ALUWritePC(result); // setflags is always FALSE here 3052 else 3053 R[d] = result; 3054 if setflags then 3055 APSR.N = result<31>; 3056 APSR.Z = IsZeroBit(result); 3057 APSR.C = carry; 3058 // APSR.V unchanged 3059 #endif 3060 3061 return EmulateShiftImm (opcode, encoding, SRType_ASR); 3062 } 3063 3064 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, 3065 // shifting in copies of its sign bit, and writes the result to the destination register. 3066 // The variable number of bits is read from the bottom byte of a register. It can optionally update 3067 // the condition flags based on the result. 3068 bool 3069 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding) 3070 { 3071 #if 0 3072 // ARM pseudo code... 3073 if ConditionPassed() then 3074 EncodingSpecificOperations(); 3075 shift_n = UInt(R[m]<7:0>); 3076 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3077 R[d] = result; 3078 if setflags then 3079 APSR.N = result<31>; 3080 APSR.Z = IsZeroBit(result); 3081 APSR.C = carry; 3082 // APSR.V unchanged 3083 #endif 3084 3085 return EmulateShiftReg (opcode, encoding, SRType_ASR); 3086 } 3087 3088 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, 3089 // shifting in zeros, and writes the result to the destination register. It can optionally 3090 // update the condition flags based on the result. 3091 bool 3092 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding) 3093 { 3094 #if 0 3095 // ARM pseudo code... 3096 if ConditionPassed() then 3097 EncodingSpecificOperations(); 3098 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3099 if d == 15 then // Can only occur for ARM encoding 3100 ALUWritePC(result); // setflags is always FALSE here 3101 else 3102 R[d] = result; 3103 if setflags then 3104 APSR.N = result<31>; 3105 APSR.Z = IsZeroBit(result); 3106 APSR.C = carry; 3107 // APSR.V unchanged 3108 #endif 3109 3110 return EmulateShiftImm (opcode, encoding, SRType_LSL); 3111 } 3112 3113 // Logical Shift Left (register) shifts a register value left by a variable number of bits, 3114 // shifting in zeros, and writes the result to the destination register. The variable number 3115 // of bits is read from the bottom byte of a register. It can optionally update the condition 3116 // flags based on the result. 3117 bool 3118 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding) 3119 { 3120 #if 0 3121 // ARM pseudo code... 3122 if ConditionPassed() then 3123 EncodingSpecificOperations(); 3124 shift_n = UInt(R[m]<7:0>); 3125 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3126 R[d] = result; 3127 if setflags then 3128 APSR.N = result<31>; 3129 APSR.Z = IsZeroBit(result); 3130 APSR.C = carry; 3131 // APSR.V unchanged 3132 #endif 3133 3134 return EmulateShiftReg (opcode, encoding, SRType_LSL); 3135 } 3136 3137 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, 3138 // shifting in zeros, and writes the result to the destination register. It can optionally 3139 // update the condition flags based on the result. 3140 bool 3141 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding) 3142 { 3143 #if 0 3144 // ARM pseudo code... 3145 if ConditionPassed() then 3146 EncodingSpecificOperations(); 3147 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3148 if d == 15 then // Can only occur for ARM encoding 3149 ALUWritePC(result); // setflags is always FALSE here 3150 else 3151 R[d] = result; 3152 if setflags then 3153 APSR.N = result<31>; 3154 APSR.Z = IsZeroBit(result); 3155 APSR.C = carry; 3156 // APSR.V unchanged 3157 #endif 3158 3159 return EmulateShiftImm (opcode, encoding, SRType_LSR); 3160 } 3161 3162 // Logical Shift Right (register) shifts a register value right by a variable number of bits, 3163 // shifting in zeros, and writes the result to the destination register. The variable number 3164 // of bits is read from the bottom byte of a register. It can optionally update the condition 3165 // flags based on the result. 3166 bool 3167 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding) 3168 { 3169 #if 0 3170 // ARM pseudo code... 3171 if ConditionPassed() then 3172 EncodingSpecificOperations(); 3173 shift_n = UInt(R[m]<7:0>); 3174 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3175 R[d] = result; 3176 if setflags then 3177 APSR.N = result<31>; 3178 APSR.Z = IsZeroBit(result); 3179 APSR.C = carry; 3180 // APSR.V unchanged 3181 #endif 3182 3183 return EmulateShiftReg (opcode, encoding, SRType_LSR); 3184 } 3185 3186 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. 3187 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3188 // It can optionally update the condition flags based on the result. 3189 bool 3190 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding) 3191 { 3192 #if 0 3193 // ARM pseudo code... 3194 if ConditionPassed() then 3195 EncodingSpecificOperations(); 3196 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3197 if d == 15 then // Can only occur for ARM encoding 3198 ALUWritePC(result); // setflags is always FALSE here 3199 else 3200 R[d] = result; 3201 if setflags then 3202 APSR.N = result<31>; 3203 APSR.Z = IsZeroBit(result); 3204 APSR.C = carry; 3205 // APSR.V unchanged 3206 #endif 3207 3208 return EmulateShiftImm (opcode, encoding, SRType_ROR); 3209 } 3210 3211 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. 3212 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left. 3213 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition 3214 // flags based on the result. 3215 bool 3216 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding) 3217 { 3218 #if 0 3219 // ARM pseudo code... 3220 if ConditionPassed() then 3221 EncodingSpecificOperations(); 3222 shift_n = UInt(R[m]<7:0>); 3223 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3224 R[d] = result; 3225 if setflags then 3226 APSR.N = result<31>; 3227 APSR.Z = IsZeroBit(result); 3228 APSR.C = carry; 3229 // APSR.V unchanged 3230 #endif 3231 3232 return EmulateShiftReg (opcode, encoding, SRType_ROR); 3233 } 3234 3235 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place, 3236 // with the carry flag shifted into bit [31]. 3237 // 3238 // RRX can optionally update the condition flags based on the result. 3239 // In that case, bit [0] is shifted into the carry flag. 3240 bool 3241 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding) 3242 { 3243 #if 0 3244 // ARM pseudo code... 3245 if ConditionPassed() then 3246 EncodingSpecificOperations(); 3247 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3248 if d == 15 then // Can only occur for ARM encoding 3249 ALUWritePC(result); // setflags is always FALSE here 3250 else 3251 R[d] = result; 3252 if setflags then 3253 APSR.N = result<31>; 3254 APSR.Z = IsZeroBit(result); 3255 APSR.C = carry; 3256 // APSR.V unchanged 3257 #endif 3258 3259 return EmulateShiftImm (opcode, encoding, SRType_RRX); 3260 } 3261 3262 bool 3263 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3264 { 3265 // assert(shift_type == SRType_ASR 3266 // || shift_type == SRType_LSL 3267 // || shift_type == SRType_LSR 3268 // || shift_type == SRType_ROR 3269 // || shift_type == SRType_RRX); 3270 3271 bool success = false; 3272 3273 if (ConditionPassed(opcode)) 3274 { 3275 uint32_t Rd; // the destination register 3276 uint32_t Rm; // the first operand register 3277 uint32_t imm5; // encoding for the shift amount 3278 uint32_t carry; // the carry bit after the shift operation 3279 bool setflags; 3280 3281 // Special case handling! 3282 // A8.6.139 ROR (immediate) -- Encoding T1 3283 ARMEncoding use_encoding = encoding; 3284 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) 3285 { 3286 // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to 3287 // have the same decoding of bit fields as the other Thumb2 shift operations. 3288 use_encoding = eEncodingT2; 3289 } 3290 3291 switch (use_encoding) { 3292 case eEncodingT1: 3293 // Due to the above special case handling! 3294 if (shift_type == SRType_ROR) 3295 return false; 3296 3297 Rd = Bits32(opcode, 2, 0); 3298 Rm = Bits32(opcode, 5, 3); 3299 setflags = !InITBlock(); 3300 imm5 = Bits32(opcode, 10, 6); 3301 break; 3302 case eEncodingT2: 3303 // A8.6.141 RRX 3304 // There's no imm form of RRX instructions. 3305 if (shift_type == SRType_RRX) 3306 return false; 3307 3308 Rd = Bits32(opcode, 11, 8); 3309 Rm = Bits32(opcode, 3, 0); 3310 setflags = BitIsSet(opcode, 20); 3311 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3312 if (BadReg(Rd) || BadReg(Rm)) 3313 return false; 3314 break; 3315 case eEncodingA1: 3316 Rd = Bits32(opcode, 15, 12); 3317 Rm = Bits32(opcode, 3, 0); 3318 setflags = BitIsSet(opcode, 20); 3319 imm5 = Bits32(opcode, 11, 7); 3320 break; 3321 default: 3322 return false; 3323 } 3324 3325 // A8.6.139 ROR (immediate) 3326 if (shift_type == SRType_ROR && imm5 == 0) 3327 shift_type = SRType_RRX; 3328 3329 // Get the first operand. 3330 uint32_t value = ReadCoreReg (Rm, &success); 3331 if (!success) 3332 return false; 3333 3334 // Decode the shift amount if not RRX. 3335 uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3336 3337 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3338 if (!success) 3339 return false; 3340 3341 // The context specifies that an immediate is to be moved into Rd. 3342 EmulateInstruction::Context context; 3343 context.type = EmulateInstruction::eContextImmediate; 3344 context.SetNoArgs (); 3345 3346 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3347 return false; 3348 } 3349 return true; 3350 } 3351 3352 bool 3353 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type) 3354 { 3355 // assert(shift_type == SRType_ASR 3356 // || shift_type == SRType_LSL 3357 // || shift_type == SRType_LSR 3358 // || shift_type == SRType_ROR); 3359 3360 bool success = false; 3361 3362 if (ConditionPassed(opcode)) 3363 { 3364 uint32_t Rd; // the destination register 3365 uint32_t Rn; // the first operand register 3366 uint32_t Rm; // the register whose bottom byte contains the amount to shift by 3367 uint32_t carry; // the carry bit after the shift operation 3368 bool setflags; 3369 switch (encoding) { 3370 case eEncodingT1: 3371 Rd = Bits32(opcode, 2, 0); 3372 Rn = Rd; 3373 Rm = Bits32(opcode, 5, 3); 3374 setflags = !InITBlock(); 3375 break; 3376 case eEncodingT2: 3377 Rd = Bits32(opcode, 11, 8); 3378 Rn = Bits32(opcode, 19, 16); 3379 Rm = Bits32(opcode, 3, 0); 3380 setflags = BitIsSet(opcode, 20); 3381 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3382 return false; 3383 break; 3384 case eEncodingA1: 3385 Rd = Bits32(opcode, 15, 12); 3386 Rn = Bits32(opcode, 3, 0); 3387 Rm = Bits32(opcode, 11, 8); 3388 setflags = BitIsSet(opcode, 20); 3389 if (Rd == 15 || Rn == 15 || Rm == 15) 3390 return false; 3391 break; 3392 default: 3393 return false; 3394 } 3395 3396 // Get the first operand. 3397 uint32_t value = ReadCoreReg (Rn, &success); 3398 if (!success) 3399 return false; 3400 // Get the Rm register content. 3401 uint32_t val = ReadCoreReg (Rm, &success); 3402 if (!success) 3403 return false; 3404 3405 // Get the shift amount. 3406 uint32_t amt = Bits32(val, 7, 0); 3407 3408 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3409 if (!success) 3410 return false; 3411 3412 // The context specifies that an immediate is to be moved into Rd. 3413 EmulateInstruction::Context context; 3414 context.type = EmulateInstruction::eContextImmediate; 3415 context.SetNoArgs (); 3416 3417 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3418 return false; 3419 } 3420 return true; 3421 } 3422 3423 // LDM loads multiple registers from consecutive memory locations, using an 3424 // address from a base register. Optionally the address just above the highest of those locations 3425 // can be written back to the base register. 3426 bool 3427 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding) 3428 { 3429 #if 0 3430 // ARM pseudo code... 3431 if ConditionPassed() 3432 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3433 address = R[n]; 3434 3435 for i = 0 to 14 3436 if registers<i> == '1' then 3437 R[i] = MemA[address, 4]; address = address + 4; 3438 if registers<15> == '1' then 3439 LoadWritePC (MemA[address, 4]); 3440 3441 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3442 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3443 3444 #endif 3445 3446 bool success = false; 3447 if (ConditionPassed(opcode)) 3448 { 3449 uint32_t n; 3450 uint32_t registers = 0; 3451 bool wback; 3452 const uint32_t addr_byte_size = GetAddressByteSize(); 3453 switch (encoding) 3454 { 3455 case eEncodingT1: 3456 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0'); 3457 n = Bits32 (opcode, 10, 8); 3458 registers = Bits32 (opcode, 7, 0); 3459 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3460 wback = BitIsClear (registers, n); 3461 // if BitCount(registers) < 1 then UNPREDICTABLE; 3462 if (BitCount(registers) < 1) 3463 return false; 3464 break; 3465 case eEncodingT2: 3466 // if W == '1' && Rn == '1101' then SEE POP; 3467 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3468 n = Bits32 (opcode, 19, 16); 3469 registers = Bits32 (opcode, 15, 0); 3470 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3471 wback = BitIsSet (opcode, 21); 3472 3473 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3474 if ((n == 15) 3475 || (BitCount (registers) < 2) 3476 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3477 return false; 3478 3479 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3480 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3481 return false; 3482 3483 // if wback && registers<n> == '1' then UNPREDICTABLE; 3484 if (wback 3485 && BitIsSet (registers, n)) 3486 return false; 3487 break; 3488 3489 case eEncodingA1: 3490 n = Bits32 (opcode, 19, 16); 3491 registers = Bits32 (opcode, 15, 0); 3492 wback = BitIsSet (opcode, 21); 3493 if ((n == 15) 3494 || (BitCount (registers) < 1)) 3495 return false; 3496 break; 3497 default: 3498 return false; 3499 } 3500 3501 int32_t offset = 0; 3502 const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3503 if (!success) 3504 return false; 3505 3506 EmulateInstruction::Context context; 3507 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3508 RegisterInfo dwarf_reg; 3509 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3510 context.SetRegisterPlusOffset (dwarf_reg, offset); 3511 3512 for (int i = 0; i < 14; ++i) 3513 { 3514 if (BitIsSet (registers, i)) 3515 { 3516 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3517 context.SetRegisterPlusOffset (dwarf_reg, offset); 3518 if (wback && (n == 13)) // Pop Instruction 3519 { 3520 context.type = EmulateInstruction::eContextPopRegisterOffStack; 3521 context.SetAddress(base_address + offset); 3522 } 3523 3524 // R[i] = MemA [address, 4]; address = address + 4; 3525 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3526 if (!success) 3527 return false; 3528 3529 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3530 return false; 3531 3532 offset += addr_byte_size; 3533 } 3534 } 3535 3536 if (BitIsSet (registers, 15)) 3537 { 3538 //LoadWritePC (MemA [address, 4]); 3539 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3540 context.SetRegisterPlusOffset (dwarf_reg, offset); 3541 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); 3542 if (!success) 3543 return false; 3544 // In ARMv5T and above, this is an interworking branch. 3545 if (!LoadWritePC(context, data)) 3546 return false; 3547 } 3548 3549 if (wback && BitIsClear (registers, n)) 3550 { 3551 // R[n] = R[n] + 4 * BitCount (registers) 3552 int32_t offset = addr_byte_size * BitCount (registers); 3553 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3554 context.SetRegisterPlusOffset (dwarf_reg, offset); 3555 3556 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset)) 3557 return false; 3558 } 3559 if (wback && BitIsSet (registers, n)) 3560 // R[n] bits(32) UNKNOWN; 3561 return WriteBits32Unknown (n); 3562 } 3563 return true; 3564 } 3565 3566 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register. 3567 // The consecutive memory locations end at this address and the address just below the lowest of those locations 3568 // can optionally be written back to the base register. 3569 bool 3570 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding) 3571 { 3572 #if 0 3573 // ARM pseudo code... 3574 if ConditionPassed() then 3575 EncodingSpecificOperations(); 3576 address = R[n] - 4*BitCount(registers) + 4; 3577 3578 for i = 0 to 14 3579 if registers<i> == '1' then 3580 R[i] = MemA[address,4]; address = address + 4; 3581 3582 if registers<15> == '1' then 3583 LoadWritePC(MemA[address,4]); 3584 3585 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3586 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3587 #endif 3588 3589 bool success = false; 3590 3591 if (ConditionPassed(opcode)) 3592 { 3593 uint32_t n; 3594 uint32_t registers = 0; 3595 bool wback; 3596 const uint32_t addr_byte_size = GetAddressByteSize(); 3597 3598 // EncodingSpecificOperations(); 3599 switch (encoding) 3600 { 3601 case eEncodingA1: 3602 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3603 n = Bits32 (opcode, 19, 16); 3604 registers = Bits32 (opcode, 15, 0); 3605 wback = BitIsSet (opcode, 21); 3606 3607 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3608 if ((n == 15) || (BitCount (registers) < 1)) 3609 return false; 3610 3611 break; 3612 3613 default: 3614 return false; 3615 } 3616 // address = R[n] - 4*BitCount(registers) + 4; 3617 3618 int32_t offset = 0; 3619 addr_t Rn = ReadCoreReg (n, &success); 3620 3621 if (!success) 3622 return false; 3623 3624 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size; 3625 3626 EmulateInstruction::Context context; 3627 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3628 RegisterInfo dwarf_reg; 3629 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3630 context.SetRegisterPlusOffset (dwarf_reg, offset); 3631 3632 // for i = 0 to 14 3633 for (int i = 0; i < 14; ++i) 3634 { 3635 // if registers<i> == '1' then 3636 if (BitIsSet (registers, i)) 3637 { 3638 // R[i] = MemA[address,4]; address = address + 4; 3639 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3640 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3641 if (!success) 3642 return false; 3643 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3644 return false; 3645 offset += addr_byte_size; 3646 } 3647 } 3648 3649 // if registers<15> == '1' then 3650 // LoadWritePC(MemA[address,4]); 3651 if (BitIsSet (registers, 15)) 3652 { 3653 context.SetRegisterPlusOffset (dwarf_reg, offset); 3654 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3655 if (!success) 3656 return false; 3657 // In ARMv5T and above, this is an interworking branch. 3658 if (!LoadWritePC(context, data)) 3659 return false; 3660 } 3661 3662 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3663 if (wback && BitIsClear (registers, n)) 3664 { 3665 if (!success) 3666 return false; 3667 3668 offset = (addr_byte_size * BitCount (registers)) * -1; 3669 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3670 context.SetImmediateSigned (offset); 3671 addr_t addr = Rn + offset; 3672 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3673 return false; 3674 } 3675 3676 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3677 if (wback && BitIsSet (registers, n)) 3678 return WriteBits32Unknown (n); 3679 } 3680 return true; 3681 } 3682 3683 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register. The 3684 // consecutive memory locations end just below this address, and the address of the lowest of those locations can 3685 // be optionally written back to the base register. 3686 bool 3687 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding) 3688 { 3689 #if 0 3690 // ARM pseudo code... 3691 if ConditionPassed() then 3692 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 3693 address = R[n] - 4*BitCount(registers); 3694 3695 for i = 0 to 14 3696 if registers<i> == '1' then 3697 R[i] = MemA[address,4]; address = address + 4; 3698 if registers<15> == '1' then 3699 LoadWritePC(MemA[address,4]); 3700 3701 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3702 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3703 #endif 3704 3705 bool success = false; 3706 3707 if (ConditionPassed(opcode)) 3708 { 3709 uint32_t n; 3710 uint32_t registers = 0; 3711 bool wback; 3712 const uint32_t addr_byte_size = GetAddressByteSize(); 3713 switch (encoding) 3714 { 3715 case eEncodingT1: 3716 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3717 n = Bits32 (opcode, 19, 16); 3718 registers = Bits32 (opcode, 15, 0); 3719 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 3720 wback = BitIsSet (opcode, 21); 3721 3722 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; 3723 if ((n == 15) 3724 || (BitCount (registers) < 2) 3725 || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15))) 3726 return false; 3727 3728 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 3729 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock()) 3730 return false; 3731 3732 // if wback && registers<n> == '1' then UNPREDICTABLE; 3733 if (wback && BitIsSet (registers, n)) 3734 return false; 3735 3736 break; 3737 3738 case eEncodingA1: 3739 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3740 n = Bits32 (opcode, 19, 16); 3741 registers = Bits32 (opcode, 15, 0); 3742 wback = BitIsSet (opcode, 21); 3743 3744 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3745 if ((n == 15) || (BitCount (registers) < 1)) 3746 return false; 3747 3748 break; 3749 3750 default: 3751 return false; 3752 } 3753 3754 // address = R[n] - 4*BitCount(registers); 3755 3756 int32_t offset = 0; 3757 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3758 3759 if (!success) 3760 return false; 3761 3762 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 3763 EmulateInstruction::Context context; 3764 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3765 RegisterInfo dwarf_reg; 3766 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3767 context.SetRegisterPlusOffset (dwarf_reg, Rn - address); 3768 3769 for (int i = 0; i < 14; ++i) 3770 { 3771 if (BitIsSet (registers, i)) 3772 { 3773 // R[i] = MemA[address,4]; address = address + 4; 3774 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset)); 3775 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3776 if (!success) 3777 return false; 3778 3779 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3780 return false; 3781 3782 offset += addr_byte_size; 3783 } 3784 } 3785 3786 // if registers<15> == '1' then 3787 // LoadWritePC(MemA[address,4]); 3788 if (BitIsSet (registers, 15)) 3789 { 3790 context.SetRegisterPlusOffset (dwarf_reg, offset); 3791 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3792 if (!success) 3793 return false; 3794 // In ARMv5T and above, this is an interworking branch. 3795 if (!LoadWritePC(context, data)) 3796 return false; 3797 } 3798 3799 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 3800 if (wback && BitIsClear (registers, n)) 3801 { 3802 if (!success) 3803 return false; 3804 3805 offset = (addr_byte_size * BitCount (registers)) * -1; 3806 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3807 context.SetImmediateSigned (offset); 3808 addr_t addr = Rn + offset; 3809 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3810 return false; 3811 } 3812 3813 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3814 if (wback && BitIsSet (registers, n)) 3815 return WriteBits32Unknown (n); 3816 } 3817 return true; 3818 } 3819 3820 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register. The 3821 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can 3822 // optinoally be written back to the base register. 3823 bool 3824 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding) 3825 { 3826 #if 0 3827 if ConditionPassed() then 3828 EncodingSpecificOperations(); 3829 address = R[n] + 4; 3830 3831 for i = 0 to 14 3832 if registers<i> == '1' then 3833 R[i] = MemA[address,4]; address = address + 4; 3834 if registers<15> == '1' then 3835 LoadWritePC(MemA[address,4]); 3836 3837 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3838 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 3839 #endif 3840 3841 bool success = false; 3842 3843 if (ConditionPassed(opcode)) 3844 { 3845 uint32_t n; 3846 uint32_t registers = 0; 3847 bool wback; 3848 const uint32_t addr_byte_size = GetAddressByteSize(); 3849 switch (encoding) 3850 { 3851 case eEncodingA1: 3852 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 3853 n = Bits32 (opcode, 19, 16); 3854 registers = Bits32 (opcode, 15, 0); 3855 wback = BitIsSet (opcode, 21); 3856 3857 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 3858 if ((n == 15) || (BitCount (registers) < 1)) 3859 return false; 3860 3861 break; 3862 default: 3863 return false; 3864 } 3865 // address = R[n] + 4; 3866 3867 int32_t offset = 0; 3868 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3869 3870 if (!success) 3871 return false; 3872 3873 addr_t address = Rn + addr_byte_size; 3874 3875 EmulateInstruction::Context context; 3876 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3877 RegisterInfo dwarf_reg; 3878 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 3879 context.SetRegisterPlusOffset (dwarf_reg, offset); 3880 3881 for (int i = 0; i < 14; ++i) 3882 { 3883 if (BitIsSet (registers, i)) 3884 { 3885 // R[i] = MemA[address,4]; address = address + 4; 3886 3887 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size); 3888 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3889 if (!success) 3890 return false; 3891 3892 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data)) 3893 return false; 3894 3895 offset += addr_byte_size; 3896 } 3897 } 3898 3899 // if registers<15> == '1' then 3900 // LoadWritePC(MemA[address,4]); 3901 if (BitIsSet (registers, 15)) 3902 { 3903 context.SetRegisterPlusOffset (dwarf_reg, offset); 3904 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success); 3905 if (!success) 3906 return false; 3907 // In ARMv5T and above, this is an interworking branch. 3908 if (!LoadWritePC(context, data)) 3909 return false; 3910 } 3911 3912 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 3913 if (wback && BitIsClear (registers, n)) 3914 { 3915 if (!success) 3916 return false; 3917 3918 offset = addr_byte_size * BitCount (registers); 3919 context.type = EmulateInstruction::eContextAdjustBaseRegister; 3920 context.SetImmediateSigned (offset); 3921 addr_t addr = Rn + offset; 3922 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr)) 3923 return false; 3924 } 3925 3926 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3927 if (wback && BitIsSet (registers, n)) 3928 return WriteBits32Unknown (n); 3929 } 3930 return true; 3931 } 3932 3933 // Load Register (immediate) calculates an address from a base register value and 3934 // an immediate offset, loads a word from memory, and writes to a register. 3935 // LDR (immediate, Thumb) 3936 bool 3937 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding) 3938 { 3939 #if 0 3940 // ARM pseudo code... 3941 if (ConditionPassed()) 3942 { 3943 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 3944 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 3945 address = if index then offset_addr else R[n]; 3946 data = MemU[address,4]; 3947 if wback then R[n] = offset_addr; 3948 if t == 15 then 3949 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 3950 elsif UnalignedSupport() || address<1:0> = '00' then 3951 R[t] = data; 3952 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 3953 } 3954 #endif 3955 3956 bool success = false; 3957 3958 if (ConditionPassed(opcode)) 3959 { 3960 uint32_t Rt; // the destination register 3961 uint32_t Rn; // the base register 3962 uint32_t imm32; // the immediate offset used to form the address 3963 addr_t offset_addr; // the offset address 3964 addr_t address; // the calculated address 3965 uint32_t data; // the literal data value from memory load 3966 bool add, index, wback; 3967 switch (encoding) { 3968 case eEncodingT1: 3969 Rt = Bits32(opcode, 2, 0); 3970 Rn = Bits32(opcode, 5, 3); 3971 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 3972 // index = TRUE; add = TRUE; wback = FALSE 3973 add = true; 3974 index = true; 3975 wback = false; 3976 3977 break; 3978 3979 case eEncodingT2: 3980 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 3981 Rt = Bits32 (opcode, 10, 8); 3982 Rn = 13; 3983 imm32 = Bits32 (opcode, 7, 0) << 2; 3984 3985 // index = TRUE; add = TRUE; wback = FALSE; 3986 index = true; 3987 add = true; 3988 wback = false; 3989 3990 break; 3991 3992 case eEncodingT3: 3993 // if Rn == '1111' then SEE LDR (literal); 3994 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 3995 Rt = Bits32 (opcode, 15, 12); 3996 Rn = Bits32 (opcode, 19, 16); 3997 imm32 = Bits32 (opcode, 11, 0); 3998 3999 // index = TRUE; add = TRUE; wback = FALSE; 4000 index = true; 4001 add = true; 4002 wback = false; 4003 4004 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4005 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4006 return false; 4007 4008 break; 4009 4010 case eEncodingT4: 4011 // if Rn == '1111' then SEE LDR (literal); 4012 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4013 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; 4014 // if P == '0' && W == '0' then UNDEFINED; 4015 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 4016 return false; 4017 4018 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4019 Rt = Bits32 (opcode, 15, 12); 4020 Rn = Bits32 (opcode, 19, 16); 4021 imm32 = Bits32 (opcode, 7, 0); 4022 4023 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4024 index = BitIsSet (opcode, 10); 4025 add = BitIsSet (opcode, 9); 4026 wback = BitIsSet (opcode, 8); 4027 4028 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; 4029 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock())) 4030 return false; 4031 4032 break; 4033 4034 default: 4035 return false; 4036 } 4037 uint32_t base = ReadCoreReg (Rn, &success); 4038 if (!success) 4039 return false; 4040 if (add) 4041 offset_addr = base + imm32; 4042 else 4043 offset_addr = base - imm32; 4044 4045 address = (index ? offset_addr : base); 4046 4047 RegisterInfo base_reg; 4048 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4049 if (wback) 4050 { 4051 EmulateInstruction::Context ctx; 4052 if (Rn == 13) 4053 { 4054 ctx.type = eContextAdjustStackPointer; 4055 ctx.SetImmediateSigned((int32_t) (offset_addr - base)); 4056 } 4057 else if (Rn == GetFramePointerRegisterNumber()) 4058 { 4059 ctx.type = eContextSetFramePointer; 4060 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4061 } 4062 else 4063 { 4064 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4065 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4066 } 4067 4068 4069 if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr)) 4070 return false; 4071 } 4072 4073 // Prepare to write to the Rt register. 4074 EmulateInstruction::Context context; 4075 context.type = EmulateInstruction::eContextRegisterLoad; 4076 context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base)); 4077 4078 // Read memory from the address. 4079 data = MemURead(context, address, 4, 0, &success); 4080 if (!success) 4081 return false; 4082 4083 if (Rt == 15) 4084 { 4085 if (Bits32(address, 1, 0) == 0) 4086 { 4087 if (!LoadWritePC(context, data)) 4088 return false; 4089 } 4090 else 4091 return false; 4092 } 4093 else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) 4094 { 4095 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data)) 4096 return false; 4097 } 4098 else 4099 WriteBits32Unknown (Rt); 4100 } 4101 return true; 4102 } 4103 4104 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address 4105 // from a base register. The consecutive memory locations start at this address, and the address just above the last 4106 // of those locations can optionally be written back to the base register. 4107 bool 4108 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding) 4109 { 4110 #if 0 4111 if ConditionPassed() then 4112 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4113 address = R[n]; 4114 4115 for i = 0 to 14 4116 if registers<i> == '1' then 4117 if i == n && wback && i != LowestSetBit(registers) then 4118 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4119 else 4120 MemA[address,4] = R[i]; 4121 address = address + 4; 4122 4123 if registers<15> == '1' then // Only possible for encoding A1 4124 MemA[address,4] = PCStoreValue(); 4125 if wback then R[n] = R[n] + 4*BitCount(registers); 4126 #endif 4127 4128 bool success = false; 4129 4130 if (ConditionPassed(opcode)) 4131 { 4132 uint32_t n; 4133 uint32_t registers = 0; 4134 bool wback; 4135 const uint32_t addr_byte_size = GetAddressByteSize(); 4136 4137 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4138 switch (encoding) 4139 { 4140 case eEncodingT1: 4141 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4142 n = Bits32 (opcode, 10, 8); 4143 registers = Bits32 (opcode, 7, 0); 4144 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4145 wback = true; 4146 4147 // if BitCount(registers) < 1 then UNPREDICTABLE; 4148 if (BitCount (registers) < 1) 4149 return false; 4150 4151 break; 4152 4153 case eEncodingT2: 4154 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4155 n = Bits32 (opcode, 19, 16); 4156 registers = Bits32 (opcode, 15, 0); 4157 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4158 wback = BitIsSet (opcode, 21); 4159 4160 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4161 if ((n == 15) || (BitCount (registers) < 2)) 4162 return false; 4163 4164 // if wback && registers<n> == '1' then UNPREDICTABLE; 4165 if (wback && BitIsSet (registers, n)) 4166 return false; 4167 4168 break; 4169 4170 case eEncodingA1: 4171 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4172 n = Bits32 (opcode, 19, 16); 4173 registers = Bits32 (opcode, 15, 0); 4174 wback = BitIsSet (opcode, 21); 4175 4176 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4177 if ((n == 15) || (BitCount (registers) < 1)) 4178 return false; 4179 4180 break; 4181 4182 default: 4183 return false; 4184 } 4185 4186 // address = R[n]; 4187 int32_t offset = 0; 4188 const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4189 if (!success) 4190 return false; 4191 4192 EmulateInstruction::Context context; 4193 context.type = EmulateInstruction::eContextRegisterStore; 4194 RegisterInfo base_reg; 4195 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4196 4197 // for i = 0 to 14 4198 uint32_t lowest_set_bit = 14; 4199 for (uint32_t i = 0; i < 14; ++i) 4200 { 4201 // if registers<i> == '1' then 4202 if (BitIsSet (registers, i)) 4203 { 4204 if (i < lowest_set_bit) 4205 lowest_set_bit = i; 4206 // if i == n && wback && i != LowestSetBit(registers) then 4207 if ((i == n) && wback && (i != lowest_set_bit)) 4208 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4209 WriteBits32UnknownToMemory (address + offset); 4210 else 4211 { 4212 // MemA[address,4] = R[i]; 4213 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4214 if (!success) 4215 return false; 4216 4217 RegisterInfo data_reg; 4218 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4219 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4220 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4221 return false; 4222 } 4223 4224 // address = address + 4; 4225 offset += addr_byte_size; 4226 } 4227 } 4228 4229 // if registers<15> == '1' then // Only possible for encoding A1 4230 // MemA[address,4] = PCStoreValue(); 4231 if (BitIsSet (registers, 15)) 4232 { 4233 RegisterInfo pc_reg; 4234 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4235 context.SetRegisterPlusOffset (pc_reg, 8); 4236 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4237 if (!success) 4238 return false; 4239 4240 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4241 return false; 4242 } 4243 4244 // if wback then R[n] = R[n] + 4*BitCount(registers); 4245 if (wback) 4246 { 4247 offset = addr_byte_size * BitCount (registers); 4248 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4249 context.SetImmediateSigned (offset); 4250 addr_t data = address + offset; 4251 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4252 return false; 4253 } 4254 } 4255 return true; 4256 } 4257 4258 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address 4259 // from a base register. The consecutive memory locations end at this address, and the address just below the lowest 4260 // of those locations can optionally be written back to the base register. 4261 bool 4262 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding) 4263 { 4264 #if 0 4265 if ConditionPassed() then 4266 EncodingSpecificOperations(); 4267 address = R[n] - 4*BitCount(registers) + 4; 4268 4269 for i = 0 to 14 4270 if registers<i> == '1' then 4271 if i == n && wback && i != LowestSetBit(registers) then 4272 MemA[address,4] = bits(32) UNKNOWN; 4273 else 4274 MemA[address,4] = R[i]; 4275 address = address + 4; 4276 4277 if registers<15> == '1' then 4278 MemA[address,4] = PCStoreValue(); 4279 4280 if wback then R[n] = R[n] - 4*BitCount(registers); 4281 #endif 4282 4283 bool success = false; 4284 4285 if (ConditionPassed(opcode)) 4286 { 4287 uint32_t n; 4288 uint32_t registers = 0; 4289 bool wback; 4290 const uint32_t addr_byte_size = GetAddressByteSize(); 4291 4292 // EncodingSpecificOperations(); 4293 switch (encoding) 4294 { 4295 case eEncodingA1: 4296 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4297 n = Bits32 (opcode, 19, 16); 4298 registers = Bits32 (opcode, 15, 0); 4299 wback = BitIsSet (opcode, 21); 4300 4301 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4302 if ((n == 15) || (BitCount (registers) < 1)) 4303 return false; 4304 break; 4305 default: 4306 return false; 4307 } 4308 4309 // address = R[n] - 4*BitCount(registers) + 4; 4310 int32_t offset = 0; 4311 addr_t Rn = ReadCoreReg (n, &success); 4312 if (!success) 4313 return false; 4314 4315 addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4; 4316 4317 EmulateInstruction::Context context; 4318 context.type = EmulateInstruction::eContextRegisterStore; 4319 RegisterInfo base_reg; 4320 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4321 4322 // for i = 0 to 14 4323 uint32_t lowest_bit_set = 14; 4324 for (uint32_t i = 0; i < 14; ++i) 4325 { 4326 // if registers<i> == '1' then 4327 if (BitIsSet (registers, i)) 4328 { 4329 if (i < lowest_bit_set) 4330 lowest_bit_set = i; 4331 //if i == n && wback && i != LowestSetBit(registers) then 4332 if ((i == n) && wback && (i != lowest_bit_set)) 4333 // MemA[address,4] = bits(32) UNKNOWN; 4334 WriteBits32UnknownToMemory (address + offset); 4335 else 4336 { 4337 // MemA[address,4] = R[i]; 4338 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4339 if (!success) 4340 return false; 4341 4342 RegisterInfo data_reg; 4343 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4344 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4345 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4346 return false; 4347 } 4348 4349 // address = address + 4; 4350 offset += addr_byte_size; 4351 } 4352 } 4353 4354 // if registers<15> == '1' then 4355 // MemA[address,4] = PCStoreValue(); 4356 if (BitIsSet (registers, 15)) 4357 { 4358 RegisterInfo pc_reg; 4359 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4360 context.SetRegisterPlusOffset (pc_reg, 8); 4361 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4362 if (!success) 4363 return false; 4364 4365 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4366 return false; 4367 } 4368 4369 // if wback then R[n] = R[n] - 4*BitCount(registers); 4370 if (wback) 4371 { 4372 offset = (addr_byte_size * BitCount (registers)) * -1; 4373 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4374 context.SetImmediateSigned (offset); 4375 addr_t data = Rn + offset; 4376 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4377 return false; 4378 } 4379 } 4380 return true; 4381 } 4382 4383 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address 4384 // from a base register. The consecutive memory locations end just below this address, and the address of the first of 4385 // those locations can optionally be written back to the base register. 4386 bool 4387 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding) 4388 { 4389 #if 0 4390 if ConditionPassed() then 4391 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4392 address = R[n] - 4*BitCount(registers); 4393 4394 for i = 0 to 14 4395 if registers<i> == '1' then 4396 if i == n && wback && i != LowestSetBit(registers) then 4397 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4398 else 4399 MemA[address,4] = R[i]; 4400 address = address + 4; 4401 4402 if registers<15> == '1' then // Only possible for encoding A1 4403 MemA[address,4] = PCStoreValue(); 4404 4405 if wback then R[n] = R[n] - 4*BitCount(registers); 4406 #endif 4407 4408 4409 bool success = false; 4410 4411 if (ConditionPassed(opcode)) 4412 { 4413 uint32_t n; 4414 uint32_t registers = 0; 4415 bool wback; 4416 const uint32_t addr_byte_size = GetAddressByteSize(); 4417 4418 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4419 switch (encoding) 4420 { 4421 case eEncodingT1: 4422 // if W == '1' && Rn == '1101' then SEE PUSH; 4423 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13)) 4424 { 4425 // See PUSH 4426 } 4427 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4428 n = Bits32 (opcode, 19, 16); 4429 registers = Bits32 (opcode, 15, 0); 4430 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4431 wback = BitIsSet (opcode, 21); 4432 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4433 if ((n == 15) || BitCount (registers) < 2) 4434 return false; 4435 // if wback && registers<n> == '1' then UNPREDICTABLE; 4436 if (wback && BitIsSet (registers, n)) 4437 return false; 4438 break; 4439 4440 case eEncodingA1: 4441 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE PUSH; 4442 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2) 4443 { 4444 // See Push 4445 } 4446 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4447 n = Bits32 (opcode, 19, 16); 4448 registers = Bits32 (opcode, 15, 0); 4449 wback = BitIsSet (opcode, 21); 4450 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4451 if ((n == 15) || BitCount (registers) < 1) 4452 return false; 4453 break; 4454 4455 default: 4456 return false; 4457 } 4458 4459 // address = R[n] - 4*BitCount(registers); 4460 4461 int32_t offset = 0; 4462 addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4463 if (!success) 4464 return false; 4465 4466 addr_t address = Rn - (addr_byte_size * BitCount (registers)); 4467 4468 EmulateInstruction::Context context; 4469 context.type = EmulateInstruction::eContextRegisterStore; 4470 RegisterInfo base_reg; 4471 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4472 4473 // for i = 0 to 14 4474 uint32_t lowest_set_bit = 14; 4475 for (uint32_t i = 0; i < 14; ++i) 4476 { 4477 // if registers<i> == '1' then 4478 if (BitIsSet (registers, i)) 4479 { 4480 if (i < lowest_set_bit) 4481 lowest_set_bit = i; 4482 // if i == n && wback && i != LowestSetBit(registers) then 4483 if ((i == n) && wback && (i != lowest_set_bit)) 4484 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4485 WriteBits32UnknownToMemory (address + offset); 4486 else 4487 { 4488 // MemA[address,4] = R[i]; 4489 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4490 if (!success) 4491 return false; 4492 4493 RegisterInfo data_reg; 4494 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4495 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset)); 4496 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4497 return false; 4498 } 4499 4500 // address = address + 4; 4501 offset += addr_byte_size; 4502 } 4503 } 4504 4505 // if registers<15> == '1' then // Only possible for encoding A1 4506 // MemA[address,4] = PCStoreValue(); 4507 if (BitIsSet (registers, 15)) 4508 { 4509 RegisterInfo pc_reg; 4510 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4511 context.SetRegisterPlusOffset (pc_reg, 8); 4512 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4513 if (!success) 4514 return false; 4515 4516 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4517 return false; 4518 } 4519 4520 // if wback then R[n] = R[n] - 4*BitCount(registers); 4521 if (wback) 4522 { 4523 offset = (addr_byte_size * BitCount (registers)) * -1; 4524 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4525 context.SetImmediateSigned (offset); 4526 addr_t data = Rn + offset; 4527 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4528 return false; 4529 } 4530 } 4531 return true; 4532 } 4533 4534 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address 4535 // from a base register. The consecutive memory locations start just above this address, and the address of the last 4536 // of those locations can optionally be written back to the base register. 4537 bool 4538 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding) 4539 { 4540 #if 0 4541 if ConditionPassed() then 4542 EncodingSpecificOperations(); 4543 address = R[n] + 4; 4544 4545 for i = 0 to 14 4546 if registers<i> == '1' then 4547 if i == n && wback && i != LowestSetBit(registers) then 4548 MemA[address,4] = bits(32) UNKNOWN; 4549 else 4550 MemA[address,4] = R[i]; 4551 address = address + 4; 4552 4553 if registers<15> == '1' then 4554 MemA[address,4] = PCStoreValue(); 4555 4556 if wback then R[n] = R[n] + 4*BitCount(registers); 4557 #endif 4558 4559 bool success = false; 4560 4561 if (ConditionPassed(opcode)) 4562 { 4563 uint32_t n; 4564 uint32_t registers = 0; 4565 bool wback; 4566 const uint32_t addr_byte_size = GetAddressByteSize(); 4567 4568 // EncodingSpecificOperations(); 4569 switch (encoding) 4570 { 4571 case eEncodingA1: 4572 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4573 n = Bits32 (opcode, 19, 16); 4574 registers = Bits32 (opcode, 15, 0); 4575 wback = BitIsSet (opcode, 21); 4576 4577 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4578 if ((n == 15) && (BitCount (registers) < 1)) 4579 return false; 4580 break; 4581 default: 4582 return false; 4583 } 4584 // address = R[n] + 4; 4585 4586 int32_t offset = 0; 4587 addr_t Rn = ReadCoreReg (n, &success); 4588 if (!success) 4589 return false; 4590 4591 addr_t address = Rn + addr_byte_size; 4592 4593 EmulateInstruction::Context context; 4594 context.type = EmulateInstruction::eContextRegisterStore; 4595 RegisterInfo base_reg; 4596 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4597 4598 uint32_t lowest_set_bit = 14; 4599 // for i = 0 to 14 4600 for (uint32_t i = 0; i < 14; ++i) 4601 { 4602 // if registers<i> == '1' then 4603 if (BitIsSet (registers, i)) 4604 { 4605 if (i < lowest_set_bit) 4606 lowest_set_bit = i; 4607 // if i == n && wback && i != LowestSetBit(registers) then 4608 if ((i == n) && wback && (i != lowest_set_bit)) 4609 // MemA[address,4] = bits(32) UNKNOWN; 4610 WriteBits32UnknownToMemory (address + offset); 4611 // else 4612 else 4613 { 4614 // MemA[address,4] = R[i]; 4615 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success); 4616 if (!success) 4617 return false; 4618 4619 RegisterInfo data_reg; 4620 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4621 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size); 4622 if (!MemAWrite (context, address + offset, data, addr_byte_size)) 4623 return false; 4624 } 4625 4626 // address = address + 4; 4627 offset += addr_byte_size; 4628 } 4629 } 4630 4631 // if registers<15> == '1' then 4632 // MemA[address,4] = PCStoreValue(); 4633 if (BitIsSet (registers, 15)) 4634 { 4635 RegisterInfo pc_reg; 4636 GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg); 4637 context.SetRegisterPlusOffset (pc_reg, 8); 4638 const uint32_t pc = ReadCoreReg (PC_REG, &success); 4639 if (!success) 4640 return false; 4641 4642 if (!MemAWrite (context, address + offset, pc, addr_byte_size)) 4643 return false; 4644 } 4645 4646 // if wback then R[n] = R[n] + 4*BitCount(registers); 4647 if (wback) 4648 { 4649 offset = addr_byte_size * BitCount (registers); 4650 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4651 context.SetImmediateSigned (offset); 4652 addr_t data = Rn + offset; 4653 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data)) 4654 return false; 4655 } 4656 } 4657 return true; 4658 } 4659 4660 // STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word 4661 // from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. 4662 bool 4663 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding) 4664 { 4665 #if 0 4666 if ConditionPassed() then 4667 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4668 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4669 address = if index then offset_addr else R[n]; 4670 if UnalignedSupport() || address<1:0> == '00' then 4671 MemU[address,4] = R[t]; 4672 else // Can only occur before ARMv7 4673 MemU[address,4] = bits(32) UNKNOWN; 4674 if wback then R[n] = offset_addr; 4675 #endif 4676 4677 bool success = false; 4678 4679 if (ConditionPassed(opcode)) 4680 { 4681 const uint32_t addr_byte_size = GetAddressByteSize(); 4682 4683 uint32_t t; 4684 uint32_t n; 4685 uint32_t imm32; 4686 bool index; 4687 bool add; 4688 bool wback; 4689 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4690 switch (encoding) 4691 { 4692 case eEncodingT1: 4693 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 4694 t = Bits32 (opcode, 2, 0); 4695 n = Bits32 (opcode, 5, 3); 4696 imm32 = Bits32 (opcode, 10, 6) << 2; 4697 4698 // index = TRUE; add = TRUE; wback = FALSE; 4699 index = true; 4700 add = false; 4701 wback = false; 4702 break; 4703 4704 case eEncodingT2: 4705 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4706 t = Bits32 (opcode, 10, 8); 4707 n = 13; 4708 imm32 = Bits32 (opcode, 7, 0) << 2; 4709 4710 // index = TRUE; add = TRUE; wback = FALSE; 4711 index = true; 4712 add = true; 4713 wback = false; 4714 break; 4715 4716 case eEncodingT3: 4717 // if Rn == '1111' then UNDEFINED; 4718 if (Bits32 (opcode, 19, 16) == 15) 4719 return false; 4720 4721 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4722 t = Bits32 (opcode, 15, 12); 4723 n = Bits32 (opcode, 19, 16); 4724 imm32 = Bits32 (opcode, 11, 0); 4725 4726 // index = TRUE; add = TRUE; wback = FALSE; 4727 index = true; 4728 add = true; 4729 wback = false; 4730 4731 // if t == 15 then UNPREDICTABLE; 4732 if (t == 15) 4733 return false; 4734 break; 4735 4736 case eEncodingT4: 4737 // if P == '1' && U == '1' && W == '0' then SEE STRT; 4738 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; 4739 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 4740 if ((Bits32 (opcode, 19, 16) == 15) 4741 || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))) 4742 return false; 4743 4744 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4745 t = Bits32 (opcode, 15, 12); 4746 n = Bits32 (opcode, 19, 16); 4747 imm32 = Bits32 (opcode, 7, 0); 4748 4749 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4750 index = BitIsSet (opcode, 10); 4751 add = BitIsSet (opcode, 9); 4752 wback = BitIsSet (opcode, 8); 4753 4754 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 4755 if ((t == 15) || (wback && (n == t))) 4756 return false; 4757 break; 4758 4759 default: 4760 return false; 4761 } 4762 4763 addr_t offset_addr; 4764 addr_t address; 4765 4766 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4767 uint32_t base_address = ReadCoreReg (n, &success); 4768 if (!success) 4769 return false; 4770 4771 if (add) 4772 offset_addr = base_address + imm32; 4773 else 4774 offset_addr = base_address - imm32; 4775 4776 // address = if index then offset_addr else R[n]; 4777 if (index) 4778 address = offset_addr; 4779 else 4780 address = base_address; 4781 4782 EmulateInstruction::Context context; 4783 context.type = eContextRegisterStore; 4784 RegisterInfo base_reg; 4785 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4786 4787 // if UnalignedSupport() || address<1:0> == '00' then 4788 if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 4789 { 4790 // MemU[address,4] = R[t]; 4791 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4792 if (!success) 4793 return false; 4794 4795 RegisterInfo data_reg; 4796 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4797 int32_t offset = address - base_address; 4798 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset); 4799 if (!MemUWrite (context, address, data, addr_byte_size)) 4800 return false; 4801 } 4802 else 4803 { 4804 // MemU[address,4] = bits(32) UNKNOWN; 4805 WriteBits32UnknownToMemory (address); 4806 } 4807 4808 // if wback then R[n] = offset_addr; 4809 if (wback) 4810 { 4811 context.type = eContextRegisterLoad; 4812 context.SetAddress (offset_addr); 4813 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 4814 return false; 4815 } 4816 } 4817 return true; 4818 } 4819 4820 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a 4821 // word from a register to memory. The offset register value can optionally be shifted. 4822 bool 4823 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding) 4824 { 4825 #if 0 4826 if ConditionPassed() then 4827 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4828 offset = Shift(R[m], shift_t, shift_n, APSR.C); 4829 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4830 address = if index then offset_addr else R[n]; 4831 if t == 15 then // Only possible for encoding A1 4832 data = PCStoreValue(); 4833 else 4834 data = R[t]; 4835 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4836 MemU[address,4] = data; 4837 else // Can only occur before ARMv7 4838 MemU[address,4] = bits(32) UNKNOWN; 4839 if wback then R[n] = offset_addr; 4840 #endif 4841 4842 bool success = false; 4843 4844 if (ConditionPassed(opcode)) 4845 { 4846 const uint32_t addr_byte_size = GetAddressByteSize(); 4847 4848 uint32_t t; 4849 uint32_t n; 4850 uint32_t m; 4851 ARM_ShifterType shift_t; 4852 uint32_t shift_n; 4853 bool index; 4854 bool add; 4855 bool wback; 4856 4857 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 4858 switch (encoding) 4859 { 4860 case eEncodingT1: 4861 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 4862 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4863 t = Bits32 (opcode, 2, 0); 4864 n = Bits32 (opcode, 5, 3); 4865 m = Bits32 (opcode, 8, 6); 4866 4867 // index = TRUE; add = TRUE; wback = FALSE; 4868 index = true; 4869 add = true; 4870 wback = false; 4871 4872 // (shift_t, shift_n) = (SRType_LSL, 0); 4873 shift_t = SRType_LSL; 4874 shift_n = 0; 4875 break; 4876 4877 case eEncodingT2: 4878 // if Rn == '1111' then UNDEFINED; 4879 if (Bits32 (opcode, 19, 16) == 15) 4880 return false; 4881 4882 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4883 t = Bits32 (opcode, 15, 12); 4884 n = Bits32 (opcode, 19, 16); 4885 m = Bits32 (opcode, 3, 0); 4886 4887 // index = TRUE; add = TRUE; wback = FALSE; 4888 index = true; 4889 add = true; 4890 wback = false; 4891 4892 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 4893 shift_t = SRType_LSL; 4894 shift_n = Bits32 (opcode, 5, 4); 4895 4896 // if t == 15 || BadReg(m) then UNPREDICTABLE; 4897 if ((t == 15) || (BadReg (m))) 4898 return false; 4899 break; 4900 4901 case eEncodingA1: 4902 { 4903 // if P == '0' && W == '1' then SEE STRT; 4904 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 4905 t = Bits32 (opcode, 15, 12); 4906 n = Bits32 (opcode, 19, 16); 4907 m = Bits32 (opcode, 3, 0); 4908 4909 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 4910 index = BitIsSet (opcode, 24); 4911 add = BitIsSet (opcode, 23); 4912 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 4913 4914 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 4915 uint32_t typ = Bits32 (opcode, 6, 5); 4916 uint32_t imm5 = Bits32 (opcode, 11, 7); 4917 shift_n = DecodeImmShift(typ, imm5, shift_t); 4918 4919 // if m == 15 then UNPREDICTABLE; 4920 if (m == 15) 4921 return false; 4922 4923 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 4924 if (wback && ((n == 15) || (n == t))) 4925 return false; 4926 4927 break; 4928 } 4929 default: 4930 return false; 4931 } 4932 4933 addr_t offset_addr; 4934 addr_t address; 4935 int32_t offset = 0; 4936 4937 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4938 if (!success) 4939 return false; 4940 4941 uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 4942 if (!success) 4943 return false; 4944 4945 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 4946 offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success); 4947 if (!success) 4948 return false; 4949 4950 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 4951 if (add) 4952 offset_addr = base_address + offset; 4953 else 4954 offset_addr = base_address - offset; 4955 4956 // address = if index then offset_addr else R[n]; 4957 if (index) 4958 address = offset_addr; 4959 else 4960 address = base_address; 4961 4962 uint32_t data; 4963 // if t == 15 then // Only possible for encoding A1 4964 if (t == 15) 4965 // data = PCStoreValue(); 4966 data = ReadCoreReg (PC_REG, &success); 4967 else 4968 // data = R[t]; 4969 data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 4970 4971 if (!success) 4972 return false; 4973 4974 EmulateInstruction::Context context; 4975 context.type = eContextRegisterStore; 4976 4977 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 4978 if (UnalignedSupport () 4979 || (BitIsClear (address, 1) && BitIsClear (address, 0)) 4980 || CurrentInstrSet() == eModeARM) 4981 { 4982 // MemU[address,4] = data; 4983 4984 RegisterInfo base_reg; 4985 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4986 4987 RegisterInfo data_reg; 4988 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 4989 4990 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 4991 if (!MemUWrite (context, address, data, addr_byte_size)) 4992 return false; 4993 4994 } 4995 else 4996 // MemU[address,4] = bits(32) UNKNOWN; 4997 WriteBits32UnknownToMemory (address); 4998 4999 // if wback then R[n] = offset_addr; 5000 if (wback) 5001 { 5002 context.type = eContextRegisterLoad; 5003 context.SetAddress (offset_addr); 5004 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5005 return false; 5006 } 5007 5008 } 5009 return true; 5010 } 5011 5012 bool 5013 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding) 5014 { 5015 #if 0 5016 if ConditionPassed() then 5017 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5018 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5019 address = if index then offset_addr else R[n]; 5020 MemU[address,1] = R[t]<7:0>; 5021 if wback then R[n] = offset_addr; 5022 #endif 5023 5024 5025 bool success = false; 5026 5027 if (ConditionPassed(opcode)) 5028 { 5029 uint32_t t; 5030 uint32_t n; 5031 uint32_t imm32; 5032 bool index; 5033 bool add; 5034 bool wback; 5035 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5036 switch (encoding) 5037 { 5038 case eEncodingT1: 5039 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5040 t = Bits32 (opcode, 2, 0); 5041 n = Bits32 (opcode, 5, 3); 5042 imm32 = Bits32 (opcode, 10, 6); 5043 5044 // index = TRUE; add = TRUE; wback = FALSE; 5045 index = true; 5046 add = true; 5047 wback = false; 5048 break; 5049 5050 case eEncodingT2: 5051 // if Rn == '1111' then UNDEFINED; 5052 if (Bits32 (opcode, 19, 16) == 15) 5053 return false; 5054 5055 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5056 t = Bits32 (opcode, 15, 12); 5057 n = Bits32 (opcode, 19, 16); 5058 imm32 = Bits32 (opcode, 11, 0); 5059 5060 // index = TRUE; add = TRUE; wback = FALSE; 5061 index = true; 5062 add = true; 5063 wback = false; 5064 5065 // if BadReg(t) then UNPREDICTABLE; 5066 if (BadReg (t)) 5067 return false; 5068 break; 5069 5070 case eEncodingT3: 5071 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5072 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5073 if (Bits32 (opcode, 19, 16) == 15) 5074 return false; 5075 5076 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5077 t = Bits32 (opcode, 15, 12); 5078 n = Bits32 (opcode, 19, 16); 5079 imm32 = Bits32 (opcode, 7, 0); 5080 5081 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5082 index = BitIsSet (opcode, 10); 5083 add = BitIsSet (opcode, 9); 5084 wback = BitIsSet (opcode, 8); 5085 5086 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5087 if ((BadReg (t)) || (wback && (n == t))) 5088 return false; 5089 break; 5090 5091 default: 5092 return false; 5093 } 5094 5095 addr_t offset_addr; 5096 addr_t address; 5097 addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5098 if (!success) 5099 return false; 5100 5101 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5102 if (add) 5103 offset_addr = base_address + imm32; 5104 else 5105 offset_addr = base_address - imm32; 5106 5107 // address = if index then offset_addr else R[n]; 5108 if (index) 5109 address = offset_addr; 5110 else 5111 address = base_address; 5112 5113 // MemU[address,1] = R[t]<7:0> 5114 RegisterInfo base_reg; 5115 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5116 5117 RegisterInfo data_reg; 5118 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5119 5120 EmulateInstruction::Context context; 5121 context.type = eContextRegisterStore; 5122 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address); 5123 5124 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5125 if (!success) 5126 return false; 5127 5128 data = Bits32 (data, 7, 0); 5129 5130 if (!MemUWrite (context, address, data, 1)) 5131 return false; 5132 5133 // if wback then R[n] = offset_addr; 5134 if (wback) 5135 { 5136 context.type = eContextRegisterLoad; 5137 context.SetAddress (offset_addr); 5138 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5139 return false; 5140 } 5141 5142 } 5143 5144 return true; 5145 } 5146 5147 // STRH (register) calculates an address from a base register value and an offset register value, and stores a 5148 // halfword from a register to memory. The offset register value can be shifted left by 0, 1, 2, or 3 bits. 5149 bool 5150 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding) 5151 { 5152 #if 0 5153 if ConditionPassed() then 5154 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5155 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5156 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5157 address = if index then offset_addr else R[n]; 5158 if UnalignedSupport() || address<0> == '0' then 5159 MemU[address,2] = R[t]<15:0>; 5160 else // Can only occur before ARMv7 5161 MemU[address,2] = bits(16) UNKNOWN; 5162 if wback then R[n] = offset_addr; 5163 #endif 5164 5165 bool success = false; 5166 5167 if (ConditionPassed(opcode)) 5168 { 5169 uint32_t t; 5170 uint32_t n; 5171 uint32_t m; 5172 bool index; 5173 bool add; 5174 bool wback; 5175 ARM_ShifterType shift_t; 5176 uint32_t shift_n; 5177 5178 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5179 switch (encoding) 5180 { 5181 case eEncodingT1: 5182 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 5183 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5184 t = Bits32 (opcode, 2, 0); 5185 n = Bits32 (opcode, 5, 3); 5186 m = Bits32 (opcode, 8, 6); 5187 5188 // index = TRUE; add = TRUE; wback = FALSE; 5189 index = true; 5190 add = true; 5191 wback = false; 5192 5193 // (shift_t, shift_n) = (SRType_LSL, 0); 5194 shift_t = SRType_LSL; 5195 shift_n = 0; 5196 5197 break; 5198 5199 case eEncodingT2: 5200 // if Rn == '1111' then UNDEFINED; 5201 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5202 t = Bits32 (opcode, 15, 12); 5203 n = Bits32 (opcode, 19, 16); 5204 m = Bits32 (opcode, 3, 0); 5205 if (n == 15) 5206 return false; 5207 5208 // index = TRUE; add = TRUE; wback = FALSE; 5209 index = true; 5210 add = true; 5211 wback = false; 5212 5213 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5214 shift_t = SRType_LSL; 5215 shift_n = Bits32 (opcode, 5, 4); 5216 5217 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5218 if (BadReg (t) || BadReg (m)) 5219 return false; 5220 5221 break; 5222 5223 case eEncodingA1: 5224 // if P == '0' && W == '1' then SEE STRHT; 5225 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5226 t = Bits32 (opcode, 15, 12); 5227 n = Bits32 (opcode, 19, 16); 5228 m = Bits32 (opcode, 3, 0); 5229 5230 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5231 index = BitIsSet (opcode, 24); 5232 add = BitIsSet (opcode, 23); 5233 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5234 5235 // (shift_t, shift_n) = (SRType_LSL, 0); 5236 shift_t = SRType_LSL; 5237 shift_n = 0; 5238 5239 // if t == 15 || m == 15 then UNPREDICTABLE; 5240 if ((t == 15) || (m == 15)) 5241 return false; 5242 5243 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5244 if (wback && ((n == 15) || (n == t))) 5245 return false; 5246 5247 break; 5248 5249 default: 5250 return false; 5251 } 5252 5253 uint32_t Rm = ReadCoreReg (m, &success); 5254 if (!success) 5255 return false; 5256 5257 uint32_t Rn = ReadCoreReg (n, &success); 5258 if (!success) 5259 return false; 5260 5261 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5262 uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 5263 if (!success) 5264 return false; 5265 5266 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5267 addr_t offset_addr; 5268 if (add) 5269 offset_addr = Rn + offset; 5270 else 5271 offset_addr = Rn - offset; 5272 5273 // address = if index then offset_addr else R[n]; 5274 addr_t address; 5275 if (index) 5276 address = offset_addr; 5277 else 5278 address = Rn; 5279 5280 EmulateInstruction::Context context; 5281 context.type = eContextRegisterStore; 5282 RegisterInfo base_reg; 5283 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5284 RegisterInfo offset_reg; 5285 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5286 5287 // if UnalignedSupport() || address<0> == '0' then 5288 if (UnalignedSupport() || BitIsClear (address, 0)) 5289 { 5290 // MemU[address,2] = R[t]<15:0>; 5291 uint32_t Rt = ReadCoreReg (t, &success); 5292 if (!success) 5293 return false; 5294 5295 EmulateInstruction::Context context; 5296 context.type = eContextRegisterStore; 5297 RegisterInfo base_reg; 5298 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5299 RegisterInfo offset_reg; 5300 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5301 RegisterInfo data_reg; 5302 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5303 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 5304 5305 if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2)) 5306 return false; 5307 } 5308 else // Can only occur before ARMv7 5309 { 5310 // MemU[address,2] = bits(16) UNKNOWN; 5311 } 5312 5313 // if wback then R[n] = offset_addr; 5314 if (wback) 5315 { 5316 context.type = eContextAdjustBaseRegister; 5317 context.SetAddress (offset_addr); 5318 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5319 return false; 5320 } 5321 } 5322 5323 return true; 5324 } 5325 5326 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value, 5327 // and writes the result to the destination register. It can optionally update the condition flags 5328 // based on the result. 5329 bool 5330 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding) 5331 { 5332 #if 0 5333 // ARM pseudo code... 5334 if ConditionPassed() then 5335 EncodingSpecificOperations(); 5336 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5337 if d == 15 then // Can only occur for ARM encoding 5338 ALUWritePC(result); // setflags is always FALSE here 5339 else 5340 R[d] = result; 5341 if setflags then 5342 APSR.N = result<31>; 5343 APSR.Z = IsZeroBit(result); 5344 APSR.C = carry; 5345 APSR.V = overflow; 5346 #endif 5347 5348 bool success = false; 5349 5350 if (ConditionPassed(opcode)) 5351 { 5352 uint32_t Rd, Rn; 5353 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 5354 bool setflags; 5355 switch (encoding) 5356 { 5357 case eEncodingT1: 5358 Rd = Bits32(opcode, 11, 8); 5359 Rn = Bits32(opcode, 19, 16); 5360 setflags = BitIsSet(opcode, 20); 5361 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5362 if (BadReg(Rd) || BadReg(Rn)) 5363 return false; 5364 break; 5365 case eEncodingA1: 5366 Rd = Bits32(opcode, 15, 12); 5367 Rn = Bits32(opcode, 19, 16); 5368 setflags = BitIsSet(opcode, 20); 5369 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5370 5371 if (Rd == 15 && setflags) 5372 return EmulateSUBSPcLrEtc (opcode, encoding); 5373 break; 5374 default: 5375 return false; 5376 } 5377 5378 // Read the first operand. 5379 int32_t val1 = ReadCoreReg(Rn, &success); 5380 if (!success) 5381 return false; 5382 5383 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5384 5385 EmulateInstruction::Context context; 5386 context.type = EmulateInstruction::eContextImmediate; 5387 context.SetNoArgs (); 5388 5389 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5390 return false; 5391 } 5392 return true; 5393 } 5394 5395 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted 5396 // register value, and writes the result to the destination register. It can optionally update the 5397 // condition flags based on the result. 5398 bool 5399 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding) 5400 { 5401 #if 0 5402 // ARM pseudo code... 5403 if ConditionPassed() then 5404 EncodingSpecificOperations(); 5405 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5406 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5407 if d == 15 then // Can only occur for ARM encoding 5408 ALUWritePC(result); // setflags is always FALSE here 5409 else 5410 R[d] = result; 5411 if setflags then 5412 APSR.N = result<31>; 5413 APSR.Z = IsZeroBit(result); 5414 APSR.C = carry; 5415 APSR.V = overflow; 5416 #endif 5417 5418 bool success = false; 5419 5420 if (ConditionPassed(opcode)) 5421 { 5422 uint32_t Rd, Rn, Rm; 5423 ARM_ShifterType shift_t; 5424 uint32_t shift_n; // the shift applied to the value read from Rm 5425 bool setflags; 5426 switch (encoding) 5427 { 5428 case eEncodingT1: 5429 Rd = Rn = Bits32(opcode, 2, 0); 5430 Rm = Bits32(opcode, 5, 3); 5431 setflags = !InITBlock(); 5432 shift_t = SRType_LSL; 5433 shift_n = 0; 5434 break; 5435 case eEncodingT2: 5436 Rd = Bits32(opcode, 11, 8); 5437 Rn = Bits32(opcode, 19, 16); 5438 Rm = Bits32(opcode, 3, 0); 5439 setflags = BitIsSet(opcode, 20); 5440 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5441 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5442 return false; 5443 break; 5444 case eEncodingA1: 5445 Rd = Bits32(opcode, 15, 12); 5446 Rn = Bits32(opcode, 19, 16); 5447 Rm = Bits32(opcode, 3, 0); 5448 setflags = BitIsSet(opcode, 20); 5449 shift_n = DecodeImmShiftARM(opcode, shift_t); 5450 5451 if (Rd == 15 && setflags) 5452 return EmulateSUBSPcLrEtc (opcode, encoding); 5453 break; 5454 default: 5455 return false; 5456 } 5457 5458 // Read the first operand. 5459 int32_t val1 = ReadCoreReg(Rn, &success); 5460 if (!success) 5461 return false; 5462 5463 // Read the second operand. 5464 int32_t val2 = ReadCoreReg(Rm, &success); 5465 if (!success) 5466 return false; 5467 5468 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5469 if (!success) 5470 return false; 5471 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5472 5473 EmulateInstruction::Context context; 5474 context.type = EmulateInstruction::eContextImmediate; 5475 context.SetNoArgs (); 5476 5477 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 5478 return false; 5479 } 5480 return true; 5481 } 5482 5483 // This instruction adds an immediate value to the PC value to form a PC-relative address, 5484 // and writes the result to the destination register. 5485 bool 5486 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding) 5487 { 5488 #if 0 5489 // ARM pseudo code... 5490 if ConditionPassed() then 5491 EncodingSpecificOperations(); 5492 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5493 if d == 15 then // Can only occur for ARM encodings 5494 ALUWritePC(result); 5495 else 5496 R[d] = result; 5497 #endif 5498 5499 bool success = false; 5500 5501 if (ConditionPassed(opcode)) 5502 { 5503 uint32_t Rd; 5504 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5505 bool add; 5506 switch (encoding) 5507 { 5508 case eEncodingT1: 5509 Rd = Bits32(opcode, 10, 8); 5510 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5511 add = true; 5512 break; 5513 case eEncodingT2: 5514 case eEncodingT3: 5515 Rd = Bits32(opcode, 11, 8); 5516 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5517 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5518 if (BadReg(Rd)) 5519 return false; 5520 break; 5521 case eEncodingA1: 5522 case eEncodingA2: 5523 Rd = Bits32(opcode, 15, 12); 5524 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5525 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 5526 break; 5527 default: 5528 return false; 5529 } 5530 5531 // Read the PC value. 5532 uint32_t pc = ReadCoreReg(PC_REG, &success); 5533 if (!success) 5534 return false; 5535 5536 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 5537 5538 EmulateInstruction::Context context; 5539 context.type = EmulateInstruction::eContextImmediate; 5540 context.SetNoArgs (); 5541 5542 if (!WriteCoreReg(context, result, Rd)) 5543 return false; 5544 } 5545 return true; 5546 } 5547 5548 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result 5549 // to the destination register. It can optionally update the condition flags based on the result. 5550 bool 5551 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding) 5552 { 5553 #if 0 5554 // ARM pseudo code... 5555 if ConditionPassed() then 5556 EncodingSpecificOperations(); 5557 result = R[n] AND imm32; 5558 if d == 15 then // Can only occur for ARM encoding 5559 ALUWritePC(result); // setflags is always FALSE here 5560 else 5561 R[d] = result; 5562 if setflags then 5563 APSR.N = result<31>; 5564 APSR.Z = IsZeroBit(result); 5565 APSR.C = carry; 5566 // APSR.V unchanged 5567 #endif 5568 5569 bool success = false; 5570 5571 if (ConditionPassed(opcode)) 5572 { 5573 uint32_t Rd, Rn; 5574 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 5575 bool setflags; 5576 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5577 switch (encoding) 5578 { 5579 case eEncodingT1: 5580 Rd = Bits32(opcode, 11, 8); 5581 Rn = Bits32(opcode, 19, 16); 5582 setflags = BitIsSet(opcode, 20); 5583 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5584 // if Rd == '1111' && S == '1' then SEE TST (immediate); 5585 if (Rd == 15 && setflags) 5586 return EmulateTSTImm(opcode, eEncodingT1); 5587 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 5588 return false; 5589 break; 5590 case eEncodingA1: 5591 Rd = Bits32(opcode, 15, 12); 5592 Rn = Bits32(opcode, 19, 16); 5593 setflags = BitIsSet(opcode, 20); 5594 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5595 5596 if (Rd == 15 && setflags) 5597 return EmulateSUBSPcLrEtc (opcode, encoding); 5598 break; 5599 default: 5600 return false; 5601 } 5602 5603 // Read the first operand. 5604 uint32_t val1 = ReadCoreReg(Rn, &success); 5605 if (!success) 5606 return false; 5607 5608 uint32_t result = val1 & imm32; 5609 5610 EmulateInstruction::Context context; 5611 context.type = EmulateInstruction::eContextImmediate; 5612 context.SetNoArgs (); 5613 5614 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5615 return false; 5616 } 5617 return true; 5618 } 5619 5620 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value, 5621 // and writes the result to the destination register. It can optionally update the condition flags 5622 // based on the result. 5623 bool 5624 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding) 5625 { 5626 #if 0 5627 // ARM pseudo code... 5628 if ConditionPassed() then 5629 EncodingSpecificOperations(); 5630 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5631 result = R[n] AND shifted; 5632 if d == 15 then // Can only occur for ARM encoding 5633 ALUWritePC(result); // setflags is always FALSE here 5634 else 5635 R[d] = result; 5636 if setflags then 5637 APSR.N = result<31>; 5638 APSR.Z = IsZeroBit(result); 5639 APSR.C = carry; 5640 // APSR.V unchanged 5641 #endif 5642 5643 bool success = false; 5644 5645 if (ConditionPassed(opcode)) 5646 { 5647 uint32_t Rd, Rn, Rm; 5648 ARM_ShifterType shift_t; 5649 uint32_t shift_n; // the shift applied to the value read from Rm 5650 bool setflags; 5651 uint32_t carry; 5652 switch (encoding) 5653 { 5654 case eEncodingT1: 5655 Rd = Rn = Bits32(opcode, 2, 0); 5656 Rm = Bits32(opcode, 5, 3); 5657 setflags = !InITBlock(); 5658 shift_t = SRType_LSL; 5659 shift_n = 0; 5660 break; 5661 case eEncodingT2: 5662 Rd = Bits32(opcode, 11, 8); 5663 Rn = Bits32(opcode, 19, 16); 5664 Rm = Bits32(opcode, 3, 0); 5665 setflags = BitIsSet(opcode, 20); 5666 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5667 // if Rd == '1111' && S == '1' then SEE TST (register); 5668 if (Rd == 15 && setflags) 5669 return EmulateTSTReg(opcode, eEncodingT2); 5670 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 5671 return false; 5672 break; 5673 case eEncodingA1: 5674 Rd = Bits32(opcode, 15, 12); 5675 Rn = Bits32(opcode, 19, 16); 5676 Rm = Bits32(opcode, 3, 0); 5677 setflags = BitIsSet(opcode, 20); 5678 shift_n = DecodeImmShiftARM(opcode, shift_t); 5679 5680 if (Rd == 15 && setflags) 5681 return EmulateSUBSPcLrEtc (opcode, encoding); 5682 break; 5683 default: 5684 return false; 5685 } 5686 5687 // Read the first operand. 5688 uint32_t val1 = ReadCoreReg(Rn, &success); 5689 if (!success) 5690 return false; 5691 5692 // Read the second operand. 5693 uint32_t val2 = ReadCoreReg(Rm, &success); 5694 if (!success) 5695 return false; 5696 5697 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5698 if (!success) 5699 return false; 5700 uint32_t result = val1 & shifted; 5701 5702 EmulateInstruction::Context context; 5703 context.type = EmulateInstruction::eContextImmediate; 5704 context.SetNoArgs (); 5705 5706 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5707 return false; 5708 } 5709 return true; 5710 } 5711 5712 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an 5713 // immediate value, and writes the result to the destination register. It can optionally update the 5714 // condition flags based on the result. 5715 bool 5716 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding) 5717 { 5718 #if 0 5719 // ARM pseudo code... 5720 if ConditionPassed() then 5721 EncodingSpecificOperations(); 5722 result = R[n] AND NOT(imm32); 5723 if d == 15 then // Can only occur for ARM encoding 5724 ALUWritePC(result); // setflags is always FALSE here 5725 else 5726 R[d] = result; 5727 if setflags then 5728 APSR.N = result<31>; 5729 APSR.Z = IsZeroBit(result); 5730 APSR.C = carry; 5731 // APSR.V unchanged 5732 #endif 5733 5734 bool success = false; 5735 5736 if (ConditionPassed(opcode)) 5737 { 5738 uint32_t Rd, Rn; 5739 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn 5740 bool setflags; 5741 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 5742 switch (encoding) 5743 { 5744 case eEncodingT1: 5745 Rd = Bits32(opcode, 11, 8); 5746 Rn = Bits32(opcode, 19, 16); 5747 setflags = BitIsSet(opcode, 20); 5748 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 5749 if (BadReg(Rd) || BadReg(Rn)) 5750 return false; 5751 break; 5752 case eEncodingA1: 5753 Rd = Bits32(opcode, 15, 12); 5754 Rn = Bits32(opcode, 19, 16); 5755 setflags = BitIsSet(opcode, 20); 5756 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 5757 5758 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5759 if (Rd == 15 && setflags) 5760 return EmulateSUBSPcLrEtc (opcode, encoding); 5761 break; 5762 default: 5763 return false; 5764 } 5765 5766 // Read the first operand. 5767 uint32_t val1 = ReadCoreReg(Rn, &success); 5768 if (!success) 5769 return false; 5770 5771 uint32_t result = val1 & ~imm32; 5772 5773 EmulateInstruction::Context context; 5774 context.type = EmulateInstruction::eContextImmediate; 5775 context.SetNoArgs (); 5776 5777 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5778 return false; 5779 } 5780 return true; 5781 } 5782 5783 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an 5784 // optionally-shifted register value, and writes the result to the destination register. 5785 // It can optionally update the condition flags based on the result. 5786 bool 5787 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding) 5788 { 5789 #if 0 5790 // ARM pseudo code... 5791 if ConditionPassed() then 5792 EncodingSpecificOperations(); 5793 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 5794 result = R[n] AND NOT(shifted); 5795 if d == 15 then // Can only occur for ARM encoding 5796 ALUWritePC(result); // setflags is always FALSE here 5797 else 5798 R[d] = result; 5799 if setflags then 5800 APSR.N = result<31>; 5801 APSR.Z = IsZeroBit(result); 5802 APSR.C = carry; 5803 // APSR.V unchanged 5804 #endif 5805 5806 bool success = false; 5807 5808 if (ConditionPassed(opcode)) 5809 { 5810 uint32_t Rd, Rn, Rm; 5811 ARM_ShifterType shift_t; 5812 uint32_t shift_n; // the shift applied to the value read from Rm 5813 bool setflags; 5814 uint32_t carry; 5815 switch (encoding) 5816 { 5817 case eEncodingT1: 5818 Rd = Rn = Bits32(opcode, 2, 0); 5819 Rm = Bits32(opcode, 5, 3); 5820 setflags = !InITBlock(); 5821 shift_t = SRType_LSL; 5822 shift_n = 0; 5823 break; 5824 case eEncodingT2: 5825 Rd = Bits32(opcode, 11, 8); 5826 Rn = Bits32(opcode, 19, 16); 5827 Rm = Bits32(opcode, 3, 0); 5828 setflags = BitIsSet(opcode, 20); 5829 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5830 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5831 return false; 5832 break; 5833 case eEncodingA1: 5834 Rd = Bits32(opcode, 15, 12); 5835 Rn = Bits32(opcode, 19, 16); 5836 Rm = Bits32(opcode, 3, 0); 5837 setflags = BitIsSet(opcode, 20); 5838 shift_n = DecodeImmShiftARM(opcode, shift_t); 5839 5840 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 5841 if (Rd == 15 && setflags) 5842 return EmulateSUBSPcLrEtc (opcode, encoding); 5843 break; 5844 default: 5845 return false; 5846 } 5847 5848 // Read the first operand. 5849 uint32_t val1 = ReadCoreReg(Rn, &success); 5850 if (!success) 5851 return false; 5852 5853 // Read the second operand. 5854 uint32_t val2 = ReadCoreReg(Rm, &success); 5855 if (!success) 5856 return false; 5857 5858 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 5859 if (!success) 5860 return false; 5861 uint32_t result = val1 & ~shifted; 5862 5863 EmulateInstruction::Context context; 5864 context.type = EmulateInstruction::eContextImmediate; 5865 context.SetNoArgs (); 5866 5867 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 5868 return false; 5869 } 5870 return true; 5871 } 5872 5873 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word 5874 // from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. 5875 bool 5876 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding) 5877 { 5878 #if 0 5879 if ConditionPassed() then 5880 EncodingSpecificOperations(); 5881 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5882 address = if index then offset_addr else R[n]; 5883 data = MemU[address,4]; 5884 if wback then R[n] = offset_addr; 5885 if t == 15 then 5886 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5887 elsif UnalignedSupport() || address<1:0> = '00' then 5888 R[t] = data; 5889 else // Can only apply before ARMv7 5890 R[t] = ROR(data, 8*UInt(address<1:0>)); 5891 #endif 5892 5893 bool success = false; 5894 5895 if (ConditionPassed(opcode)) 5896 { 5897 const uint32_t addr_byte_size = GetAddressByteSize(); 5898 5899 uint32_t t; 5900 uint32_t n; 5901 uint32_t imm32; 5902 bool index; 5903 bool add; 5904 bool wback; 5905 5906 switch (encoding) 5907 { 5908 case eEncodingA1: 5909 // if Rn == '1111' then SEE LDR (literal); 5910 // if P == '0' && W == '1' then SEE LDRT; 5911 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; 5912 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5913 t = Bits32 (opcode, 15, 12); 5914 n = Bits32 (opcode, 19, 16); 5915 imm32 = Bits32 (opcode, 11, 0); 5916 5917 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 5918 index = BitIsSet (opcode, 24); 5919 add = BitIsSet (opcode, 23); 5920 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 5921 5922 // if wback && n == t then UNPREDICTABLE; 5923 if (wback && (n == t)) 5924 return false; 5925 5926 break; 5927 5928 default: 5929 return false; 5930 } 5931 5932 addr_t address; 5933 addr_t offset_addr; 5934 addr_t base_address = ReadCoreReg (n, &success); 5935 if (!success) 5936 return false; 5937 5938 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5939 if (add) 5940 offset_addr = base_address + imm32; 5941 else 5942 offset_addr = base_address - imm32; 5943 5944 // address = if index then offset_addr else R[n]; 5945 if (index) 5946 address = offset_addr; 5947 else 5948 address = base_address; 5949 5950 // data = MemU[address,4]; 5951 5952 RegisterInfo base_reg; 5953 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5954 5955 EmulateInstruction::Context context; 5956 context.type = eContextRegisterLoad; 5957 context.SetRegisterPlusOffset (base_reg, address - base_address); 5958 5959 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 5960 if (!success) 5961 return false; 5962 5963 // if wback then R[n] = offset_addr; 5964 if (wback) 5965 { 5966 context.type = eContextAdjustBaseRegister; 5967 context.SetAddress (offset_addr); 5968 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 5969 return false; 5970 } 5971 5972 // if t == 15 then 5973 if (t == 15) 5974 { 5975 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 5976 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 5977 { 5978 // LoadWritePC (data); 5979 context.type = eContextRegisterLoad; 5980 context.SetRegisterPlusOffset (base_reg, address - base_address); 5981 LoadWritePC (context, data); 5982 } 5983 else 5984 return false; 5985 } 5986 // elsif UnalignedSupport() || address<1:0> = '00' then 5987 else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0))) 5988 { 5989 // R[t] = data; 5990 context.type = eContextRegisterLoad; 5991 context.SetRegisterPlusOffset (base_reg, address - base_address); 5992 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 5993 return false; 5994 } 5995 // else // Can only apply before ARMv7 5996 else 5997 { 5998 // R[t] = ROR(data, 8*UInt(address<1:0>)); 5999 data = ROR (data, Bits32 (address, 1, 0), &success); 6000 if (!success) 6001 return false; 6002 context.type = eContextRegisterLoad; 6003 context.SetImmediate (data); 6004 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6005 return false; 6006 } 6007 6008 } 6009 return true; 6010 } 6011 6012 // LDR (register) calculates an address from a base register value and an offset register value, loads a word 6013 // from memory, and writes it to a register. The offset register value can optionally be shifted. 6014 bool 6015 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding) 6016 { 6017 #if 0 6018 if ConditionPassed() then 6019 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6020 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6021 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6022 address = if index then offset_addr else R[n]; 6023 data = MemU[address,4]; 6024 if wback then R[n] = offset_addr; 6025 if t == 15 then 6026 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6027 elsif UnalignedSupport() || address<1:0> = '00' then 6028 R[t] = data; 6029 else // Can only apply before ARMv7 6030 if CurrentInstrSet() == InstrSet_ARM then 6031 R[t] = ROR(data, 8*UInt(address<1:0>)); 6032 else 6033 R[t] = bits(32) UNKNOWN; 6034 #endif 6035 6036 bool success = false; 6037 6038 if (ConditionPassed(opcode)) 6039 { 6040 const uint32_t addr_byte_size = GetAddressByteSize(); 6041 6042 uint32_t t; 6043 uint32_t n; 6044 uint32_t m; 6045 bool index; 6046 bool add; 6047 bool wback; 6048 ARM_ShifterType shift_t; 6049 uint32_t shift_n; 6050 6051 switch (encoding) 6052 { 6053 case eEncodingT1: 6054 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6055 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6056 t = Bits32 (opcode, 2, 0); 6057 n = Bits32 (opcode, 5, 3); 6058 m = Bits32 (opcode, 8, 6); 6059 6060 // index = TRUE; add = TRUE; wback = FALSE; 6061 index = true; 6062 add = true; 6063 wback = false; 6064 6065 // (shift_t, shift_n) = (SRType_LSL, 0); 6066 shift_t = SRType_LSL; 6067 shift_n = 0; 6068 6069 break; 6070 6071 case eEncodingT2: 6072 // if Rn == '1111' then SEE LDR (literal); 6073 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6074 t = Bits32 (opcode, 15, 12); 6075 n = Bits32 (opcode, 19, 16); 6076 m = Bits32 (opcode, 3, 0); 6077 6078 // index = TRUE; add = TRUE; wback = FALSE; 6079 index = true; 6080 add = true; 6081 wback = false; 6082 6083 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6084 shift_t = SRType_LSL; 6085 shift_n = Bits32 (opcode, 5, 4); 6086 6087 // if BadReg(m) then UNPREDICTABLE; 6088 if (BadReg (m)) 6089 return false; 6090 6091 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6092 if ((t == 15) && InITBlock() && !LastInITBlock()) 6093 return false; 6094 6095 break; 6096 6097 case eEncodingA1: 6098 { 6099 // if P == '0' && W == '1' then SEE LDRT; 6100 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6101 t = Bits32 (opcode, 15, 12); 6102 n = Bits32 (opcode, 19, 16); 6103 m = Bits32 (opcode, 3, 0); 6104 6105 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6106 index = BitIsSet (opcode, 24); 6107 add = BitIsSet (opcode, 23); 6108 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6109 6110 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6111 uint32_t type = Bits32 (opcode, 6, 5); 6112 uint32_t imm5 = Bits32 (opcode, 11, 7); 6113 shift_n = DecodeImmShift (type, imm5, shift_t); 6114 6115 // if m == 15 then UNPREDICTABLE; 6116 if (m == 15) 6117 return false; 6118 6119 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6120 if (wback && ((n == 15) || (n == t))) 6121 return false; 6122 } 6123 break; 6124 6125 6126 default: 6127 return false; 6128 } 6129 6130 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6131 if (!success) 6132 return false; 6133 6134 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6135 if (!success) 6136 return false; 6137 6138 addr_t offset_addr; 6139 addr_t address; 6140 6141 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is an application level alias for the CPSR". 6142 addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success); 6143 if (!success) 6144 return false; 6145 6146 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6147 if (add) 6148 offset_addr = Rn + offset; 6149 else 6150 offset_addr = Rn - offset; 6151 6152 // address = if index then offset_addr else R[n]; 6153 if (index) 6154 address = offset_addr; 6155 else 6156 address = Rn; 6157 6158 // data = MemU[address,4]; 6159 RegisterInfo base_reg; 6160 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6161 6162 EmulateInstruction::Context context; 6163 context.type = eContextRegisterLoad; 6164 context.SetRegisterPlusOffset (base_reg, address - Rn); 6165 6166 uint64_t data = MemURead (context, address, addr_byte_size, 0, &success); 6167 if (!success) 6168 return false; 6169 6170 // if wback then R[n] = offset_addr; 6171 if (wback) 6172 { 6173 context.type = eContextAdjustBaseRegister; 6174 context.SetAddress (offset_addr); 6175 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6176 return false; 6177 } 6178 6179 // if t == 15 then 6180 if (t == 15) 6181 { 6182 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6183 if (BitIsClear (address, 1) && BitIsClear (address, 0)) 6184 { 6185 context.type = eContextRegisterLoad; 6186 context.SetRegisterPlusOffset (base_reg, address - Rn); 6187 LoadWritePC (context, data); 6188 } 6189 else 6190 return false; 6191 } 6192 // elsif UnalignedSupport() || address<1:0> = '00' then 6193 else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0))) 6194 { 6195 // R[t] = data; 6196 context.type = eContextRegisterLoad; 6197 context.SetRegisterPlusOffset (base_reg, address - Rn); 6198 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6199 return false; 6200 } 6201 else // Can only apply before ARMv7 6202 { 6203 // if CurrentInstrSet() == InstrSet_ARM then 6204 if (CurrentInstrSet () == eModeARM) 6205 { 6206 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6207 data = ROR (data, Bits32 (address, 1, 0), &success); 6208 if (!success) 6209 return false; 6210 context.type = eContextRegisterLoad; 6211 context.SetImmediate (data); 6212 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6213 return false; 6214 } 6215 else 6216 { 6217 // R[t] = bits(32) UNKNOWN; 6218 WriteBits32Unknown (t); 6219 } 6220 } 6221 } 6222 return true; 6223 } 6224 6225 // LDRB (immediate, Thumb) 6226 bool 6227 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding) 6228 { 6229 #if 0 6230 if ConditionPassed() then 6231 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6232 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6233 address = if index then offset_addr else R[n]; 6234 R[t] = ZeroExtend(MemU[address,1], 32); 6235 if wback then R[n] = offset_addr; 6236 #endif 6237 6238 bool success = false; 6239 6240 if (ConditionPassed(opcode)) 6241 { 6242 uint32_t t; 6243 uint32_t n; 6244 uint32_t imm32; 6245 bool index; 6246 bool add; 6247 bool wback; 6248 6249 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6250 switch (encoding) 6251 { 6252 case eEncodingT1: 6253 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6254 t = Bits32 (opcode, 2, 0); 6255 n = Bits32 (opcode, 5, 3); 6256 imm32 = Bits32 (opcode, 10, 6); 6257 6258 // index = TRUE; add = TRUE; wback = FALSE; 6259 index = true; 6260 add = true; 6261 wback= false; 6262 6263 break; 6264 6265 case eEncodingT2: 6266 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6267 t = Bits32 (opcode, 15, 12); 6268 n = Bits32 (opcode, 19, 16); 6269 imm32 = Bits32 (opcode, 11, 0); 6270 6271 // index = TRUE; add = TRUE; wback = FALSE; 6272 index = true; 6273 add = true; 6274 wback = false; 6275 6276 // if Rt == '1111' then SEE PLD; 6277 if (t == 15) 6278 return false; // PLD is not implemented yet 6279 6280 // if Rn == '1111' then SEE LDRB (literal); 6281 if (n == 15) 6282 return EmulateLDRBLiteral(opcode, eEncodingT1); 6283 6284 // if t == 13 then UNPREDICTABLE; 6285 if (t == 13) 6286 return false; 6287 6288 break; 6289 6290 case eEncodingT3: 6291 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6292 // if P == '0' && W == '0' then UNDEFINED; 6293 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6294 return false; 6295 6296 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6297 t = Bits32 (opcode, 15, 12); 6298 n = Bits32 (opcode, 19, 16); 6299 imm32 = Bits32 (opcode, 7, 0); 6300 6301 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6302 index = BitIsSet (opcode, 10); 6303 add = BitIsSet (opcode, 9); 6304 wback = BitIsSet (opcode, 8); 6305 6306 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6307 if (t == 15) 6308 return false; // PLD is not implemented yet 6309 6310 // if Rn == '1111' then SEE LDRB (literal); 6311 if (n == 15) 6312 return EmulateLDRBLiteral(opcode, eEncodingT1); 6313 6314 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6315 if (BadReg (t) || (wback && (n == t))) 6316 return false; 6317 6318 break; 6319 6320 default: 6321 return false; 6322 } 6323 6324 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6325 if (!success) 6326 return false; 6327 6328 addr_t address; 6329 addr_t offset_addr; 6330 6331 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6332 if (add) 6333 offset_addr = Rn + imm32; 6334 else 6335 offset_addr = Rn - imm32; 6336 6337 // address = if index then offset_addr else R[n]; 6338 if (index) 6339 address = offset_addr; 6340 else 6341 address = Rn; 6342 6343 // R[t] = ZeroExtend(MemU[address,1], 32); 6344 RegisterInfo base_reg; 6345 RegisterInfo data_reg; 6346 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6347 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6348 6349 EmulateInstruction::Context context; 6350 context.type = eContextRegisterLoad; 6351 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 6352 6353 uint64_t data = MemURead (context, address, 1, 0, &success); 6354 if (!success) 6355 return false; 6356 6357 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6358 return false; 6359 6360 // if wback then R[n] = offset_addr; 6361 if (wback) 6362 { 6363 context.type = eContextAdjustBaseRegister; 6364 context.SetAddress (offset_addr); 6365 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6366 return false; 6367 } 6368 } 6369 return true; 6370 } 6371 6372 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 6373 // zero-extends it to form a 32-bit word and writes it to a register. 6374 bool 6375 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding) 6376 { 6377 #if 0 6378 if ConditionPassed() then 6379 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6380 base = Align(PC,4); 6381 address = if add then (base + imm32) else (base - imm32); 6382 R[t] = ZeroExtend(MemU[address,1], 32); 6383 #endif 6384 6385 bool success = false; 6386 6387 if (ConditionPassed(opcode)) 6388 { 6389 uint32_t t; 6390 uint32_t imm32; 6391 bool add; 6392 switch (encoding) 6393 { 6394 case eEncodingT1: 6395 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6396 t = Bits32 (opcode, 15, 12); 6397 imm32 = Bits32 (opcode, 11, 0); 6398 add = BitIsSet (opcode, 23); 6399 6400 // if Rt == '1111' then SEE PLD; 6401 if (t == 15) 6402 return false; // PLD is not implemented yet 6403 6404 // if t == 13 then UNPREDICTABLE; 6405 if (t == 13) 6406 return false; 6407 6408 break; 6409 6410 case eEncodingA1: 6411 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6412 t = Bits32 (opcode, 15, 12); 6413 imm32 = Bits32 (opcode, 11, 0); 6414 add = BitIsSet (opcode, 23); 6415 6416 // if t == 15 then UNPREDICTABLE; 6417 if (t == 15) 6418 return false; 6419 break; 6420 6421 default: 6422 return false; 6423 } 6424 6425 // base = Align(PC,4); 6426 uint32_t pc_val = ReadCoreReg (PC_REG, &success); 6427 if (!success) 6428 return false; 6429 6430 uint32_t base = AlignPC (pc_val); 6431 6432 addr_t address; 6433 // address = if add then (base + imm32) else (base - imm32); 6434 if (add) 6435 address = base + imm32; 6436 else 6437 address = base - imm32; 6438 6439 // R[t] = ZeroExtend(MemU[address,1], 32); 6440 EmulateInstruction::Context context; 6441 context.type = eContextRelativeBranchImmediate; 6442 context.SetImmediate (address - base); 6443 6444 uint64_t data = MemURead (context, address, 1, 0, &success); 6445 if (!success) 6446 return false; 6447 6448 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6449 return false; 6450 } 6451 return true; 6452 } 6453 6454 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from 6455 // memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6456 // optionally be shifted. 6457 bool 6458 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding) 6459 { 6460 #if 0 6461 if ConditionPassed() then 6462 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6463 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6464 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6465 address = if index then offset_addr else R[n]; 6466 R[t] = ZeroExtend(MemU[address,1],32); 6467 if wback then R[n] = offset_addr; 6468 #endif 6469 6470 bool success = false; 6471 6472 if (ConditionPassed(opcode)) 6473 { 6474 uint32_t t; 6475 uint32_t n; 6476 uint32_t m; 6477 bool index; 6478 bool add; 6479 bool wback; 6480 ARM_ShifterType shift_t; 6481 uint32_t shift_n; 6482 6483 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6484 switch (encoding) 6485 { 6486 case eEncodingT1: 6487 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6488 t = Bits32 (opcode, 2, 0); 6489 n = Bits32 (opcode, 5, 3); 6490 m = Bits32 (opcode, 8, 6); 6491 6492 // index = TRUE; add = TRUE; wback = FALSE; 6493 index = true; 6494 add = true; 6495 wback = false; 6496 6497 // (shift_t, shift_n) = (SRType_LSL, 0); 6498 shift_t = SRType_LSL; 6499 shift_n = 0; 6500 break; 6501 6502 case eEncodingT2: 6503 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6504 t = Bits32 (opcode, 15, 12); 6505 n = Bits32 (opcode, 19, 16); 6506 m = Bits32 (opcode, 3, 0); 6507 6508 // index = TRUE; add = TRUE; wback = FALSE; 6509 index = true; 6510 add = true; 6511 wback = false; 6512 6513 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6514 shift_t = SRType_LSL; 6515 shift_n = Bits32 (opcode, 5, 4); 6516 6517 // if Rt == '1111' then SEE PLD; 6518 if (t == 15) 6519 return false; // PLD is not implemented yet 6520 6521 // if Rn == '1111' then SEE LDRB (literal); 6522 if (n == 15) 6523 return EmulateLDRBLiteral(opcode, eEncodingT1); 6524 6525 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6526 if ((t == 13) || BadReg (m)) 6527 return false; 6528 break; 6529 6530 case eEncodingA1: 6531 { 6532 // if P == '0' && W == '1' then SEE LDRBT; 6533 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6534 t = Bits32 (opcode, 15, 12); 6535 n = Bits32 (opcode, 19, 16); 6536 m = Bits32 (opcode, 3, 0); 6537 6538 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6539 index = BitIsSet (opcode, 24); 6540 add = BitIsSet (opcode, 23); 6541 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6542 6543 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6544 uint32_t type = Bits32 (opcode, 6, 5); 6545 uint32_t imm5 = Bits32 (opcode, 11, 7); 6546 shift_n = DecodeImmShift (type, imm5, shift_t); 6547 6548 // if t == 15 || m == 15 then UNPREDICTABLE; 6549 if ((t == 15) || (m == 15)) 6550 return false; 6551 6552 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6553 if (wback && ((n == 15) || (n == t))) 6554 return false; 6555 } 6556 break; 6557 6558 default: 6559 return false; 6560 } 6561 6562 addr_t offset_addr; 6563 addr_t address; 6564 6565 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6566 uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6567 if (!success) 6568 return false; 6569 6570 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6571 if (!success) 6572 return false; 6573 6574 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6575 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6576 if (!success) 6577 return false; 6578 6579 if (add) 6580 offset_addr = Rn + offset; 6581 else 6582 offset_addr = Rn - offset; 6583 6584 // address = if index then offset_addr else R[n]; 6585 if (index) 6586 address = offset_addr; 6587 else 6588 address = Rn; 6589 6590 // R[t] = ZeroExtend(MemU[address,1],32); 6591 RegisterInfo base_reg; 6592 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6593 6594 EmulateInstruction::Context context; 6595 context.type = eContextRegisterLoad; 6596 context.SetRegisterPlusOffset (base_reg, address - Rn); 6597 6598 uint64_t data = MemURead (context, address, 1, 0, &success); 6599 if (!success) 6600 return false; 6601 6602 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6603 return false; 6604 6605 // if wback then R[n] = offset_addr; 6606 if (wback) 6607 { 6608 context.type = eContextAdjustBaseRegister; 6609 context.SetAddress (offset_addr); 6610 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6611 return false; 6612 } 6613 } 6614 return true; 6615 } 6616 6617 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a 6618 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, 6619 // post-indexed, or pre-indexed addressing. 6620 bool 6621 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding) 6622 { 6623 #if 0 6624 if ConditionPassed() then 6625 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6626 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6627 address = if index then offset_addr else R[n]; 6628 data = MemU[address,2]; 6629 if wback then R[n] = offset_addr; 6630 if UnalignedSupport() || address<0> = '0' then 6631 R[t] = ZeroExtend(data, 32); 6632 else // Can only apply before ARMv7 6633 R[t] = bits(32) UNKNOWN; 6634 #endif 6635 6636 6637 bool success = false; 6638 6639 if (ConditionPassed(opcode)) 6640 { 6641 uint32_t t; 6642 uint32_t n; 6643 uint32_t imm32; 6644 bool index; 6645 bool add; 6646 bool wback; 6647 6648 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6649 switch (encoding) 6650 { 6651 case eEncodingT1: 6652 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 6653 t = Bits32 (opcode, 2, 0); 6654 n = Bits32 (opcode, 5, 3); 6655 imm32 = Bits32 (opcode, 10, 6) << 1; 6656 6657 // index = TRUE; add = TRUE; wback = FALSE; 6658 index = true; 6659 add = true; 6660 wback = false; 6661 6662 break; 6663 6664 case eEncodingT2: 6665 // if Rt == '1111' then SEE "Unallocated memory hints"; 6666 // if Rn == '1111' then SEE LDRH (literal); 6667 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6668 t = Bits32 (opcode, 15, 12); 6669 n = Bits32 (opcode, 19, 16); 6670 imm32 = Bits32 (opcode, 11, 0); 6671 6672 // index = TRUE; add = TRUE; wback = FALSE; 6673 index = true; 6674 add = true; 6675 wback = false; 6676 6677 // if t == 13 then UNPREDICTABLE; 6678 if (t == 13) 6679 return false; 6680 break; 6681 6682 case eEncodingT3: 6683 // if Rn == '1111' then SEE LDRH (literal); 6684 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 6685 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 6686 // if P == '0' && W == '0' then UNDEFINED; 6687 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 6688 return false; 6689 6690 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6691 t = Bits32 (opcode, 15, 12); 6692 n = Bits32 (opcode, 19, 16); 6693 imm32 = Bits32 (opcode, 7, 0); 6694 6695 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6696 index = BitIsSet (opcode, 10); 6697 add = BitIsSet (opcode, 9); 6698 wback = BitIsSet (opcode, 8); 6699 6700 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6701 if (BadReg (t) || (wback && (n == t))) 6702 return false; 6703 break; 6704 6705 default: 6706 return false; 6707 } 6708 6709 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6710 uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6711 if (!success) 6712 return false; 6713 6714 addr_t offset_addr; 6715 addr_t address; 6716 6717 if (add) 6718 offset_addr = Rn + imm32; 6719 else 6720 offset_addr = Rn - imm32; 6721 6722 // address = if index then offset_addr else R[n]; 6723 if (index) 6724 address = offset_addr; 6725 else 6726 address = Rn; 6727 6728 // data = MemU[address,2]; 6729 RegisterInfo base_reg; 6730 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6731 6732 EmulateInstruction::Context context; 6733 context.type = eContextRegisterLoad; 6734 context.SetRegisterPlusOffset (base_reg, address - Rn); 6735 6736 uint64_t data = MemURead (context, address, 2, 0, &success); 6737 if (!success) 6738 return false; 6739 6740 // if wback then R[n] = offset_addr; 6741 if (wback) 6742 { 6743 context.type = eContextAdjustBaseRegister; 6744 context.SetAddress (offset_addr); 6745 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 6746 return false; 6747 } 6748 6749 // if UnalignedSupport() || address<0> = '0' then 6750 if (UnalignedSupport () || BitIsClear (address, 0)) 6751 { 6752 // R[t] = ZeroExtend(data, 32); 6753 context.type = eContextRegisterLoad; 6754 context.SetRegisterPlusOffset (base_reg, address - Rn); 6755 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6756 return false; 6757 } 6758 else // Can only apply before ARMv7 6759 { 6760 // R[t] = bits(32) UNKNOWN; 6761 WriteBits32Unknown (t); 6762 } 6763 } 6764 return true; 6765 } 6766 6767 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory, 6768 // zero-extends it to form a 32-bit word, and writes it to a register. 6769 bool 6770 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding) 6771 { 6772 #if 0 6773 if ConditionPassed() then 6774 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6775 base = Align(PC,4); 6776 address = if add then (base + imm32) else (base - imm32); 6777 data = MemU[address,2]; 6778 if UnalignedSupport() || address<0> = '0' then 6779 R[t] = ZeroExtend(data, 32); 6780 else // Can only apply before ARMv7 6781 R[t] = bits(32) UNKNOWN; 6782 #endif 6783 6784 bool success = false; 6785 6786 if (ConditionPassed(opcode)) 6787 { 6788 uint32_t t; 6789 uint32_t imm32; 6790 bool add; 6791 6792 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6793 switch (encoding) 6794 { 6795 case eEncodingT1: 6796 // if Rt == '1111' then SEE "Unallocated memory hints"; 6797 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6798 t = Bits32 (opcode, 15, 12); 6799 imm32 = Bits32 (opcode, 11, 0); 6800 add = BitIsSet (opcode, 23); 6801 6802 // if t == 13 then UNPREDICTABLE; 6803 if (t == 13) 6804 return false; 6805 6806 break; 6807 6808 case eEncodingA1: 6809 { 6810 uint32_t imm4H = Bits32 (opcode, 11, 8); 6811 uint32_t imm4L = Bits32 (opcode, 3, 0); 6812 6813 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 6814 t = Bits32 (opcode, 15, 12); 6815 imm32 = (imm4H << 4) | imm4L; 6816 add = BitIsSet (opcode, 23); 6817 6818 // if t == 15 then UNPREDICTABLE; 6819 if (t == 15) 6820 return false; 6821 break; 6822 } 6823 6824 default: 6825 return false; 6826 } 6827 6828 // base = Align(PC,4); 6829 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 6830 if (!success) 6831 return false; 6832 6833 addr_t base = AlignPC (pc_value); 6834 addr_t address; 6835 6836 // address = if add then (base + imm32) else (base - imm32); 6837 if (add) 6838 address = base + imm32; 6839 else 6840 address = base - imm32; 6841 6842 // data = MemU[address,2]; 6843 RegisterInfo base_reg; 6844 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 6845 6846 EmulateInstruction::Context context; 6847 context.type = eContextRegisterLoad; 6848 context.SetRegisterPlusOffset (base_reg, address - base); 6849 6850 uint64_t data = MemURead (context, address, 2, 0, &success); 6851 if (!success) 6852 return false; 6853 6854 6855 // if UnalignedSupport() || address<0> = '0' then 6856 if (UnalignedSupport () || BitIsClear (address, 0)) 6857 { 6858 // R[t] = ZeroExtend(data, 32); 6859 context.type = eContextRegisterLoad; 6860 context.SetRegisterPlusOffset (base_reg, address - base); 6861 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6862 return false; 6863 6864 } 6865 else // Can only apply before ARMv7 6866 { 6867 // R[t] = bits(32) UNKNOWN; 6868 WriteBits32Unknown (t); 6869 } 6870 } 6871 return true; 6872 } 6873 6874 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword 6875 // from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can 6876 // be shifted left by 0, 1, 2, or 3 bits. 6877 bool 6878 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding) 6879 { 6880 #if 0 6881 if ConditionPassed() then 6882 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6883 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6884 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6885 address = if index then offset_addr else R[n]; 6886 data = MemU[address,2]; 6887 if wback then R[n] = offset_addr; 6888 if UnalignedSupport() || address<0> = '0' then 6889 R[t] = ZeroExtend(data, 32); 6890 else // Can only apply before ARMv7 6891 R[t] = bits(32) UNKNOWN; 6892 #endif 6893 6894 bool success = false; 6895 6896 if (ConditionPassed(opcode)) 6897 { 6898 uint32_t t; 6899 uint32_t n; 6900 uint32_t m; 6901 bool index; 6902 bool add; 6903 bool wback; 6904 ARM_ShifterType shift_t; 6905 uint32_t shift_n; 6906 6907 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6908 switch (encoding) 6909 { 6910 case eEncodingT1: 6911 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 6912 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6913 t = Bits32 (opcode, 2, 0); 6914 n = Bits32 (opcode, 5, 3); 6915 m = Bits32 (opcode, 8, 6); 6916 6917 // index = TRUE; add = TRUE; wback = FALSE; 6918 index = true; 6919 add = true; 6920 wback = false; 6921 6922 // (shift_t, shift_n) = (SRType_LSL, 0); 6923 shift_t = SRType_LSL; 6924 shift_n = 0; 6925 6926 break; 6927 6928 case eEncodingT2: 6929 // if Rn == '1111' then SEE LDRH (literal); 6930 // if Rt == '1111' then SEE "Unallocated memory hints"; 6931 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6932 t = Bits32 (opcode, 15, 12); 6933 n = Bits32 (opcode, 19, 16); 6934 m = Bits32 (opcode, 3, 0); 6935 6936 // index = TRUE; add = TRUE; wback = FALSE; 6937 index = true; 6938 add = true; 6939 wback = false; 6940 6941 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6942 shift_t = SRType_LSL; 6943 shift_n = Bits32 (opcode, 5, 4); 6944 6945 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6946 if ((t == 13) || BadReg (m)) 6947 return false; 6948 break; 6949 6950 case eEncodingA1: 6951 // if P == '0' && W == '1' then SEE LDRHT; 6952 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6953 t = Bits32 (opcode, 15, 12); 6954 n = Bits32 (opcode, 19, 16); 6955 m = Bits32 (opcode, 3, 0); 6956 6957 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 6958 index = BitIsSet (opcode, 24); 6959 add = BitIsSet (opcode, 23); 6960 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 6961 6962 // (shift_t, shift_n) = (SRType_LSL, 0); 6963 shift_t = SRType_LSL; 6964 shift_n = 0; 6965 6966 // if t == 15 || m == 15 then UNPREDICTABLE; 6967 if ((t == 15) || (m == 15)) 6968 return false; 6969 6970 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6971 if (wback && ((n == 15) || (n == t))) 6972 return false; 6973 6974 break; 6975 6976 default: 6977 return false; 6978 } 6979 6980 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 6981 6982 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6983 if (!success) 6984 return false; 6985 6986 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 6987 if (!success) 6988 return false; 6989 6990 addr_t offset_addr; 6991 addr_t address; 6992 6993 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6994 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6995 if (!success) 6996 return false; 6997 6998 if (add) 6999 offset_addr = Rn + offset; 7000 else 7001 offset_addr = Rn - offset; 7002 7003 // address = if index then offset_addr else R[n]; 7004 if (index) 7005 address = offset_addr; 7006 else 7007 address = Rn; 7008 7009 // data = MemU[address,2]; 7010 RegisterInfo base_reg; 7011 RegisterInfo offset_reg; 7012 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7013 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7014 7015 EmulateInstruction::Context context; 7016 context.type = eContextRegisterLoad; 7017 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7018 uint64_t data = MemURead (context, address, 2, 0, &success); 7019 if (!success) 7020 return false; 7021 7022 // if wback then R[n] = offset_addr; 7023 if (wback) 7024 { 7025 context.type = eContextAdjustBaseRegister; 7026 context.SetAddress (offset_addr); 7027 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7028 return false; 7029 } 7030 7031 // if UnalignedSupport() || address<0> = '0' then 7032 if (UnalignedSupport() || BitIsClear (address, 0)) 7033 { 7034 // R[t] = ZeroExtend(data, 32); 7035 context.type = eContextRegisterLoad; 7036 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7037 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7038 return false; 7039 } 7040 else // Can only apply before ARMv7 7041 { 7042 // R[t] = bits(32) UNKNOWN; 7043 WriteBits32Unknown (t); 7044 } 7045 } 7046 return true; 7047 } 7048 7049 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from 7050 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, 7051 // or pre-indexed addressing. 7052 bool 7053 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding) 7054 { 7055 #if 0 7056 if ConditionPassed() then 7057 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7058 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7059 address = if index then offset_addr else R[n]; 7060 R[t] = SignExtend(MemU[address,1], 32); 7061 if wback then R[n] = offset_addr; 7062 #endif 7063 7064 bool success = false; 7065 7066 if (ConditionPassed(opcode)) 7067 { 7068 uint32_t t; 7069 uint32_t n; 7070 uint32_t imm32; 7071 bool index; 7072 bool add; 7073 bool wback; 7074 7075 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7076 switch (encoding) 7077 { 7078 case eEncodingT1: 7079 // if Rt == '1111' then SEE PLI; 7080 // if Rn == '1111' then SEE LDRSB (literal); 7081 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7082 t = Bits32 (opcode, 15, 12); 7083 n = Bits32 (opcode, 19, 16); 7084 imm32 = Bits32 (opcode, 11, 0); 7085 7086 // index = TRUE; add = TRUE; wback = FALSE; 7087 index = true; 7088 add = true; 7089 wback = false; 7090 7091 // if t == 13 then UNPREDICTABLE; 7092 if (t == 13) 7093 return false; 7094 7095 break; 7096 7097 case eEncodingT2: 7098 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7099 // if Rn == '1111' then SEE LDRSB (literal); 7100 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7101 // if P == '0' && W == '0' then UNDEFINED; 7102 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7103 return false; 7104 7105 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7106 t = Bits32 (opcode, 15, 12); 7107 n = Bits32 (opcode, 19, 16); 7108 imm32 = Bits32 (opcode, 7, 0); 7109 7110 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7111 index = BitIsSet (opcode, 10); 7112 add = BitIsSet (opcode, 9); 7113 wback = BitIsSet (opcode, 8); 7114 7115 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7116 if (((t == 13) || ((t == 15) 7117 && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8)))) 7118 || (wback && (n == t))) 7119 return false; 7120 7121 break; 7122 7123 case eEncodingA1: 7124 { 7125 // if Rn == '1111' then SEE LDRSB (literal); 7126 // if P == '0' && W == '1' then SEE LDRSBT; 7127 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7128 t = Bits32 (opcode, 15, 12); 7129 n = Bits32 (opcode, 19, 16); 7130 7131 uint32_t imm4H = Bits32 (opcode, 11, 8); 7132 uint32_t imm4L = Bits32 (opcode, 3, 0); 7133 imm32 = (imm4H << 4) | imm4L; 7134 7135 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7136 index = BitIsSet (opcode, 24); 7137 add = BitIsSet (opcode, 23); 7138 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21)); 7139 7140 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7141 if ((t == 15) || (wback && (n == t))) 7142 return false; 7143 7144 break; 7145 } 7146 7147 default: 7148 return false; 7149 } 7150 7151 uint64_t Rn = ReadCoreReg (n, &success); 7152 if (!success) 7153 return false; 7154 7155 addr_t offset_addr; 7156 addr_t address; 7157 7158 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7159 if (add) 7160 offset_addr = Rn + imm32; 7161 else 7162 offset_addr = Rn - imm32; 7163 7164 // address = if index then offset_addr else R[n]; 7165 if (index) 7166 address = offset_addr; 7167 else 7168 address = Rn; 7169 7170 // R[t] = SignExtend(MemU[address,1], 32); 7171 RegisterInfo base_reg; 7172 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7173 7174 EmulateInstruction::Context context; 7175 context.type = eContextRegisterLoad; 7176 context.SetRegisterPlusOffset (base_reg, address - Rn); 7177 7178 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7179 if (!success) 7180 return false; 7181 7182 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7183 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7184 return false; 7185 7186 // if wback then R[n] = offset_addr; 7187 if (wback) 7188 { 7189 context.type = eContextAdjustBaseRegister; 7190 context.SetAddress (offset_addr); 7191 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7192 return false; 7193 } 7194 } 7195 7196 return true; 7197 } 7198 7199 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, 7200 // sign-extends it to form a 32-bit word, and writes tit to a register. 7201 bool 7202 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding) 7203 { 7204 #if 0 7205 if ConditionPassed() then 7206 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7207 base = Align(PC,4); 7208 address = if add then (base + imm32) else (base - imm32); 7209 R[t] = SignExtend(MemU[address,1], 32); 7210 #endif 7211 7212 bool success = false; 7213 7214 if (ConditionPassed(opcode)) 7215 { 7216 uint32_t t; 7217 uint32_t imm32; 7218 bool add; 7219 7220 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7221 switch (encoding) 7222 { 7223 case eEncodingT1: 7224 // if Rt == '1111' then SEE PLI; 7225 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7226 t = Bits32 (opcode, 15, 12); 7227 imm32 = Bits32 (opcode, 11, 0); 7228 add = BitIsSet (opcode, 23); 7229 7230 // if t == 13 then UNPREDICTABLE; 7231 if (t == 13) 7232 return false; 7233 7234 break; 7235 7236 case eEncodingA1: 7237 { 7238 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7239 t = Bits32 (opcode, 15, 12); 7240 uint32_t imm4H = Bits32 (opcode, 11, 8); 7241 uint32_t imm4L = Bits32 (opcode, 3, 0); 7242 imm32 = (imm4H << 4) | imm4L; 7243 add = BitIsSet (opcode, 23); 7244 7245 // if t == 15 then UNPREDICTABLE; 7246 if (t == 15) 7247 return false; 7248 7249 break; 7250 } 7251 7252 default: 7253 return false; 7254 } 7255 7256 // base = Align(PC,4); 7257 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7258 if (!success) 7259 return false; 7260 uint64_t base = AlignPC (pc_value); 7261 7262 // address = if add then (base + imm32) else (base - imm32); 7263 addr_t address; 7264 if (add) 7265 address = base + imm32; 7266 else 7267 address = base - imm32; 7268 7269 // R[t] = SignExtend(MemU[address,1], 32); 7270 RegisterInfo base_reg; 7271 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7272 7273 EmulateInstruction::Context context; 7274 context.type = eContextRegisterLoad; 7275 context.SetRegisterPlusOffset (base_reg, address - base); 7276 7277 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7278 if (!success) 7279 return false; 7280 7281 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7282 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7283 return false; 7284 } 7285 return true; 7286 } 7287 7288 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from 7289 // memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7290 // shifted left by 0, 1, 2, or 3 bits. 7291 bool 7292 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding) 7293 { 7294 #if 0 7295 if ConditionPassed() then 7296 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7297 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7298 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7299 address = if index then offset_addr else R[n]; 7300 R[t] = SignExtend(MemU[address,1], 32); 7301 if wback then R[n] = offset_addr; 7302 #endif 7303 7304 bool success = false; 7305 7306 if (ConditionPassed(opcode)) 7307 { 7308 uint32_t t; 7309 uint32_t n; 7310 uint32_t m; 7311 bool index; 7312 bool add; 7313 bool wback; 7314 ARM_ShifterType shift_t; 7315 uint32_t shift_n; 7316 7317 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7318 switch (encoding) 7319 { 7320 case eEncodingT1: 7321 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7322 t = Bits32 (opcode, 2, 0); 7323 n = Bits32 (opcode, 5, 3); 7324 m = Bits32 (opcode, 8, 6); 7325 7326 // index = TRUE; add = TRUE; wback = FALSE; 7327 index = true; 7328 add = true; 7329 wback = false; 7330 7331 // (shift_t, shift_n) = (SRType_LSL, 0); 7332 shift_t = SRType_LSL; 7333 shift_n = 0; 7334 7335 break; 7336 7337 case eEncodingT2: 7338 // if Rt == '1111' then SEE PLI; 7339 // if Rn == '1111' then SEE LDRSB (literal); 7340 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7341 t = Bits32 (opcode, 15, 12); 7342 n = Bits32 (opcode, 19, 16); 7343 m = Bits32 (opcode, 3, 0); 7344 7345 // index = TRUE; add = TRUE; wback = FALSE; 7346 index = true; 7347 add = true; 7348 wback = false; 7349 7350 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7351 shift_t = SRType_LSL; 7352 shift_n = Bits32 (opcode, 5, 4); 7353 7354 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7355 if ((t == 13) || BadReg (m)) 7356 return false; 7357 break; 7358 7359 case eEncodingA1: 7360 // if P == '0' && W == '1' then SEE LDRSBT; 7361 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7362 t = Bits32 (opcode, 15, 12); 7363 n = Bits32 (opcode, 19, 16); 7364 m = Bits32 (opcode, 3, 0); 7365 7366 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7367 index = BitIsSet (opcode, 24); 7368 add = BitIsSet (opcode, 23); 7369 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7370 7371 // (shift_t, shift_n) = (SRType_LSL, 0); 7372 shift_t = SRType_LSL; 7373 shift_n = 0; 7374 7375 // if t == 15 || m == 15 then UNPREDICTABLE; 7376 if ((t == 15) || (m == 15)) 7377 return false; 7378 7379 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7380 if (wback && ((n == 15) || (n == t))) 7381 return false; 7382 break; 7383 7384 default: 7385 return false; 7386 } 7387 7388 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7389 if (!success) 7390 return false; 7391 7392 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7393 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7394 if (!success) 7395 return false; 7396 7397 addr_t offset_addr; 7398 addr_t address; 7399 7400 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7401 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7402 if (!success) 7403 return false; 7404 7405 if (add) 7406 offset_addr = Rn + offset; 7407 else 7408 offset_addr = Rn - offset; 7409 7410 // address = if index then offset_addr else R[n]; 7411 if (index) 7412 address = offset_addr; 7413 else 7414 address = Rn; 7415 7416 // R[t] = SignExtend(MemU[address,1], 32); 7417 RegisterInfo base_reg; 7418 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7419 RegisterInfo offset_reg; 7420 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7421 7422 EmulateInstruction::Context context; 7423 context.type = eContextRegisterLoad; 7424 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7425 7426 uint64_t unsigned_data = MemURead (context, address, 1, 0, &success); 7427 if (!success) 7428 return false; 7429 7430 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7431 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7432 return false; 7433 7434 // if wback then R[n] = offset_addr; 7435 if (wback) 7436 { 7437 context.type = eContextAdjustBaseRegister; 7438 context.SetAddress (offset_addr); 7439 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7440 return false; 7441 } 7442 } 7443 return true; 7444 } 7445 7446 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from 7447 // memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or 7448 // pre-indexed addressing. 7449 bool 7450 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding) 7451 { 7452 #if 0 7453 if ConditionPassed() then 7454 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7455 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7456 address = if index then offset_addr else R[n]; 7457 data = MemU[address,2]; 7458 if wback then R[n] = offset_addr; 7459 if UnalignedSupport() || address<0> = '0' then 7460 R[t] = SignExtend(data, 32); 7461 else // Can only apply before ARMv7 7462 R[t] = bits(32) UNKNOWN; 7463 #endif 7464 7465 bool success = false; 7466 7467 if (ConditionPassed(opcode)) 7468 { 7469 uint32_t t; 7470 uint32_t n; 7471 uint32_t imm32; 7472 bool index; 7473 bool add; 7474 bool wback; 7475 7476 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7477 switch (encoding) 7478 { 7479 case eEncodingT1: 7480 // if Rn == '1111' then SEE LDRSH (literal); 7481 // if Rt == '1111' then SEE "Unallocated memory hints"; 7482 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7483 t = Bits32 (opcode, 15, 12); 7484 n = Bits32 (opcode, 19, 16); 7485 imm32 = Bits32 (opcode, 11, 0); 7486 7487 // index = TRUE; add = TRUE; wback = FALSE; 7488 index = true; 7489 add = true; 7490 wback = false; 7491 7492 // if t == 13 then UNPREDICTABLE; 7493 if (t == 13) 7494 return false; 7495 7496 break; 7497 7498 case eEncodingT2: 7499 // if Rn == '1111' then SEE LDRSH (literal); 7500 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints"; 7501 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7502 // if P == '0' && W == '0' then UNDEFINED; 7503 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)) 7504 return false; 7505 7506 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7507 t = Bits32 (opcode, 15, 12); 7508 n = Bits32 (opcode, 19, 16); 7509 imm32 = Bits32 (opcode, 7, 0); 7510 7511 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7512 index = BitIsSet (opcode, 10); 7513 add = BitIsSet (opcode, 9); 7514 wback = BitIsSet (opcode, 8); 7515 7516 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7517 if (BadReg (t) || (wback && (n == t))) 7518 return false; 7519 7520 break; 7521 7522 case eEncodingA1: 7523 { 7524 // if Rn == '1111' then SEE LDRSH (literal); 7525 // if P == '0' && W == '1' then SEE LDRSHT; 7526 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7527 t = Bits32 (opcode, 15, 12); 7528 n = Bits32 (opcode, 19, 16); 7529 uint32_t imm4H = Bits32 (opcode, 11,8); 7530 uint32_t imm4L = Bits32 (opcode, 3, 0); 7531 imm32 = (imm4H << 4) | imm4L; 7532 7533 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7534 index = BitIsSet (opcode, 24); 7535 add = BitIsSet (opcode, 23); 7536 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7537 7538 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7539 if ((t == 15) || (wback && (n == t))) 7540 return false; 7541 7542 break; 7543 } 7544 7545 default: 7546 return false; 7547 } 7548 7549 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7550 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7551 if (!success) 7552 return false; 7553 7554 addr_t offset_addr; 7555 if (add) 7556 offset_addr = Rn + imm32; 7557 else 7558 offset_addr = Rn - imm32; 7559 7560 // address = if index then offset_addr else R[n]; 7561 addr_t address; 7562 if (index) 7563 address = offset_addr; 7564 else 7565 address = Rn; 7566 7567 // data = MemU[address,2]; 7568 RegisterInfo base_reg; 7569 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7570 7571 EmulateInstruction::Context context; 7572 context.type = eContextRegisterLoad; 7573 context.SetRegisterPlusOffset (base_reg, address - Rn); 7574 7575 uint64_t data = MemURead (context, address, 2, 0, &success); 7576 if (!success) 7577 return false; 7578 7579 // if wback then R[n] = offset_addr; 7580 if (wback) 7581 { 7582 context.type = eContextAdjustBaseRegister; 7583 context.SetAddress (offset_addr); 7584 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7585 return false; 7586 } 7587 7588 // if UnalignedSupport() || address<0> = '0' then 7589 if (UnalignedSupport() || BitIsClear (address, 0)) 7590 { 7591 // R[t] = SignExtend(data, 32); 7592 int64_t signed_data = llvm::SignExtend64<16>(data); 7593 context.type = eContextRegisterLoad; 7594 context.SetRegisterPlusOffset (base_reg, address - Rn); 7595 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7596 return false; 7597 } 7598 else // Can only apply before ARMv7 7599 { 7600 // R[t] = bits(32) UNKNOWN; 7601 WriteBits32Unknown (t); 7602 } 7603 } 7604 return true; 7605 } 7606 7607 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, 7608 // sign-extends it to from a 32-bit word, and writes it to a register. 7609 bool 7610 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding) 7611 { 7612 #if 0 7613 if ConditionPassed() then 7614 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7615 base = Align(PC,4); 7616 address = if add then (base + imm32) else (base - imm32); 7617 data = MemU[address,2]; 7618 if UnalignedSupport() || address<0> = '0' then 7619 R[t] = SignExtend(data, 32); 7620 else // Can only apply before ARMv7 7621 R[t] = bits(32) UNKNOWN; 7622 #endif 7623 7624 bool success = false; 7625 7626 if (ConditionPassed(opcode)) 7627 { 7628 uint32_t t; 7629 uint32_t imm32; 7630 bool add; 7631 7632 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7633 switch (encoding) 7634 { 7635 case eEncodingT1: 7636 // if Rt == '1111' then SEE "Unallocated memory hints"; 7637 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7638 t = Bits32 (opcode, 15, 12); 7639 imm32 = Bits32 (opcode, 11, 0); 7640 add = BitIsSet (opcode, 23); 7641 7642 // if t == 13 then UNPREDICTABLE; 7643 if (t == 13) 7644 return false; 7645 7646 break; 7647 7648 case eEncodingA1: 7649 { 7650 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7651 t = Bits32 (opcode, 15, 12); 7652 uint32_t imm4H = Bits32 (opcode, 11, 8); 7653 uint32_t imm4L = Bits32 (opcode, 3, 0); 7654 imm32 = (imm4H << 4) | imm4L; 7655 add = BitIsSet (opcode, 23); 7656 7657 // if t == 15 then UNPREDICTABLE; 7658 if (t == 15) 7659 return false; 7660 7661 break; 7662 } 7663 default: 7664 return false; 7665 } 7666 7667 // base = Align(PC,4); 7668 uint64_t pc_value = ReadCoreReg (PC_REG, &success); 7669 if (!success) 7670 return false; 7671 7672 uint64_t base = AlignPC (pc_value); 7673 7674 addr_t address; 7675 // address = if add then (base + imm32) else (base - imm32); 7676 if (add) 7677 address = base + imm32; 7678 else 7679 address = base - imm32; 7680 7681 // data = MemU[address,2]; 7682 RegisterInfo base_reg; 7683 GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7684 7685 EmulateInstruction::Context context; 7686 context.type = eContextRegisterLoad; 7687 context.SetRegisterPlusOffset (base_reg, imm32); 7688 7689 uint64_t data = MemURead (context, address, 2, 0, &success); 7690 if (!success) 7691 return false; 7692 7693 // if UnalignedSupport() || address<0> = '0' then 7694 if (UnalignedSupport() || BitIsClear (address, 0)) 7695 { 7696 // R[t] = SignExtend(data, 32); 7697 int64_t signed_data = llvm::SignExtend64<16>(data); 7698 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7699 return false; 7700 } 7701 else // Can only apply before ARMv7 7702 { 7703 // R[t] = bits(32) UNKNOWN; 7704 WriteBits32Unknown (t); 7705 } 7706 } 7707 return true; 7708 } 7709 7710 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword 7711 // from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be 7712 // shifted left by 0, 1, 2, or 3 bits. 7713 bool 7714 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding) 7715 { 7716 #if 0 7717 if ConditionPassed() then 7718 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7719 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7720 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7721 address = if index then offset_addr else R[n]; 7722 data = MemU[address,2]; 7723 if wback then R[n] = offset_addr; 7724 if UnalignedSupport() || address<0> = '0' then 7725 R[t] = SignExtend(data, 32); 7726 else // Can only apply before ARMv7 7727 R[t] = bits(32) UNKNOWN; 7728 #endif 7729 7730 bool success = false; 7731 7732 if (ConditionPassed(opcode)) 7733 { 7734 uint32_t t; 7735 uint32_t n; 7736 uint32_t m; 7737 bool index; 7738 bool add; 7739 bool wback; 7740 ARM_ShifterType shift_t; 7741 uint32_t shift_n; 7742 7743 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7744 switch (encoding) 7745 { 7746 case eEncodingT1: 7747 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; 7748 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7749 t = Bits32 (opcode, 2, 0); 7750 n = Bits32 (opcode, 5, 3); 7751 m = Bits32 (opcode, 8, 6); 7752 7753 // index = TRUE; add = TRUE; wback = FALSE; 7754 index = true; 7755 add = true; 7756 wback = false; 7757 7758 // (shift_t, shift_n) = (SRType_LSL, 0); 7759 shift_t = SRType_LSL; 7760 shift_n = 0; 7761 7762 break; 7763 7764 case eEncodingT2: 7765 // if Rn == '1111' then SEE LDRSH (literal); 7766 // if Rt == '1111' then SEE "Unallocated memory hints"; 7767 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7768 t = Bits32 (opcode, 15, 12); 7769 n = Bits32 (opcode, 19, 16); 7770 m = Bits32 (opcode, 3, 0); 7771 7772 // index = TRUE; add = TRUE; wback = FALSE; 7773 index = true; 7774 add = true; 7775 wback = false; 7776 7777 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7778 shift_t = SRType_LSL; 7779 shift_n = Bits32 (opcode, 5, 4); 7780 7781 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7782 if ((t == 13) || BadReg (m)) 7783 return false; 7784 7785 break; 7786 7787 case eEncodingA1: 7788 // if P == '0' && W == '1' then SEE LDRSHT; 7789 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7790 t = Bits32 (opcode, 15, 12); 7791 n = Bits32 (opcode, 19, 16); 7792 m = Bits32 (opcode, 3, 0); 7793 7794 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 7795 index = BitIsSet (opcode, 24); 7796 add = BitIsSet (opcode, 23); 7797 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 7798 7799 // (shift_t, shift_n) = (SRType_LSL, 0); 7800 shift_t = SRType_LSL; 7801 shift_n = 0; 7802 7803 // if t == 15 || m == 15 then UNPREDICTABLE; 7804 if ((t == 15) || (m == 15)) 7805 return false; 7806 7807 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7808 if (wback && ((n == 15) || (n == t))) 7809 return false; 7810 7811 break; 7812 7813 default: 7814 return false; 7815 } 7816 7817 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7818 if (!success) 7819 return false; 7820 7821 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7822 if (!success) 7823 return false; 7824 7825 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7826 addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success); 7827 if (!success) 7828 return false; 7829 7830 addr_t offset_addr; 7831 addr_t address; 7832 7833 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7834 if (add) 7835 offset_addr = Rn + offset; 7836 else 7837 offset_addr = Rn - offset; 7838 7839 // address = if index then offset_addr else R[n]; 7840 if (index) 7841 address = offset_addr; 7842 else 7843 address = Rn; 7844 7845 // data = MemU[address,2]; 7846 RegisterInfo base_reg; 7847 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7848 7849 RegisterInfo offset_reg; 7850 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7851 7852 EmulateInstruction::Context context; 7853 context.type = eContextRegisterLoad; 7854 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7855 7856 uint64_t data = MemURead (context, address, 2, 0, &success); 7857 if (!success) 7858 return false; 7859 7860 // if wback then R[n] = offset_addr; 7861 if (wback) 7862 { 7863 context.type = eContextAdjustBaseRegister; 7864 context.SetAddress (offset_addr); 7865 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 7866 return false; 7867 } 7868 7869 // if UnalignedSupport() || address<0> = '0' then 7870 if (UnalignedSupport() || BitIsClear (address, 0)) 7871 { 7872 // R[t] = SignExtend(data, 32); 7873 context.type = eContextRegisterLoad; 7874 context.SetRegisterPlusIndirectOffset (base_reg, offset_reg); 7875 7876 int64_t signed_data = llvm::SignExtend64<16>(data); 7877 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data)) 7878 return false; 7879 } 7880 else // Can only apply before ARMv7 7881 { 7882 // R[t] = bits(32) UNKNOWN; 7883 WriteBits32Unknown (t); 7884 } 7885 } 7886 return true; 7887 } 7888 7889 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7890 // register. You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 7891 bool 7892 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding) 7893 { 7894 #if 0 7895 if ConditionPassed() then 7896 EncodingSpecificOperations(); 7897 rotated = ROR(R[m], rotation); 7898 R[d] = SignExtend(rotated<7:0>, 32); 7899 #endif 7900 7901 bool success = false; 7902 7903 if (ConditionPassed(opcode)) 7904 { 7905 uint32_t d; 7906 uint32_t m; 7907 uint32_t rotation; 7908 7909 // EncodingSpecificOperations(); 7910 switch (encoding) 7911 { 7912 case eEncodingT1: 7913 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7914 d = Bits32 (opcode, 2, 0); 7915 m = Bits32 (opcode, 5, 3); 7916 rotation = 0; 7917 7918 break; 7919 7920 case eEncodingT2: 7921 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7922 d = Bits32 (opcode, 11, 8); 7923 m = Bits32 (opcode, 3, 0); 7924 rotation = Bits32 (opcode, 5, 4) << 3; 7925 7926 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 7927 if (BadReg (d) || BadReg (m)) 7928 return false; 7929 7930 break; 7931 7932 case eEncodingA1: 7933 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 7934 d = Bits32 (opcode, 15, 12); 7935 m = Bits32 (opcode, 3, 0); 7936 rotation = Bits32 (opcode, 11, 10) << 3; 7937 7938 // if d == 15 || m == 15 then UNPREDICTABLE; 7939 if ((d == 15) || (m == 15)) 7940 return false; 7941 7942 break; 7943 7944 default: 7945 return false; 7946 } 7947 7948 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7949 if (!success) 7950 return false; 7951 7952 // rotated = ROR(R[m], rotation); 7953 uint64_t rotated = ROR (Rm, rotation, &success); 7954 if (!success) 7955 return false; 7956 7957 // R[d] = SignExtend(rotated<7:0>, 32); 7958 int64_t data = llvm::SignExtend64<8>(rotated); 7959 7960 RegisterInfo source_reg; 7961 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 7962 7963 EmulateInstruction::Context context; 7964 context.type = eContextRegisterLoad; 7965 context.SetRegister (source_reg); 7966 7967 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 7968 return false; 7969 } 7970 return true; 7971 } 7972 7973 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination 7974 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 7975 bool 7976 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding) 7977 { 7978 #if 0 7979 if ConditionPassed() then 7980 EncodingSpecificOperations(); 7981 rotated = ROR(R[m], rotation); 7982 R[d] = SignExtend(rotated<15:0>, 32); 7983 #endif 7984 7985 bool success = false; 7986 7987 if (ConditionPassed(opcode)) 7988 { 7989 uint32_t d; 7990 uint32_t m; 7991 uint32_t rotation; 7992 7993 // EncodingSpecificOperations(); 7994 switch (encoding) 7995 { 7996 case eEncodingT1: 7997 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 7998 d = Bits32 (opcode, 2, 0); 7999 m = Bits32 (opcode, 5, 3); 8000 rotation = 0; 8001 8002 break; 8003 8004 case eEncodingT2: 8005 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8006 d = Bits32 (opcode, 11, 8); 8007 m = Bits32 (opcode, 3, 0); 8008 rotation = Bits32 (opcode, 5, 4) << 3; 8009 8010 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8011 if (BadReg (d) || BadReg (m)) 8012 return false; 8013 8014 break; 8015 8016 case eEncodingA1: 8017 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8018 d = Bits32 (opcode, 15, 12); 8019 m = Bits32 (opcode, 3, 0); 8020 rotation = Bits32 (opcode, 11, 10) << 3; 8021 8022 // if d == 15 || m == 15 then UNPREDICTABLE; 8023 if ((d == 15) || (m == 15)) 8024 return false; 8025 8026 break; 8027 8028 default: 8029 return false; 8030 } 8031 8032 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8033 if (!success) 8034 return false; 8035 8036 // rotated = ROR(R[m], rotation); 8037 uint64_t rotated = ROR (Rm, rotation, &success); 8038 if (!success) 8039 return false; 8040 8041 // R[d] = SignExtend(rotated<15:0>, 32); 8042 RegisterInfo source_reg; 8043 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8044 8045 EmulateInstruction::Context context; 8046 context.type = eContextRegisterLoad; 8047 context.SetRegister (source_reg); 8048 8049 int64_t data = llvm::SignExtend64<16> (rotated); 8050 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data)) 8051 return false; 8052 } 8053 8054 return true; 8055 } 8056 8057 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination 8058 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. 8059 bool 8060 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding) 8061 { 8062 #if 0 8063 if ConditionPassed() then 8064 EncodingSpecificOperations(); 8065 rotated = ROR(R[m], rotation); 8066 R[d] = ZeroExtend(rotated<7:0>, 32); 8067 #endif 8068 8069 bool success = false; 8070 8071 if (ConditionPassed(opcode)) 8072 { 8073 uint32_t d; 8074 uint32_t m; 8075 uint32_t rotation; 8076 8077 // EncodingSpecificOperations(); 8078 switch (encoding) 8079 { 8080 case eEncodingT1: 8081 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8082 d = Bits32 (opcode, 2, 0); 8083 m = Bits32 (opcode, 5, 3); 8084 rotation = 0; 8085 8086 break; 8087 8088 case eEncodingT2: 8089 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8090 d = Bits32 (opcode, 11, 8); 8091 m = Bits32 (opcode, 3, 0); 8092 rotation = Bits32 (opcode, 5, 4) << 3; 8093 8094 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8095 if (BadReg (d) || BadReg (m)) 8096 return false; 8097 8098 break; 8099 8100 case eEncodingA1: 8101 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8102 d = Bits32 (opcode, 15, 12); 8103 m = Bits32 (opcode, 3, 0); 8104 rotation = Bits32 (opcode, 11, 10) << 3; 8105 8106 // if d == 15 || m == 15 then UNPREDICTABLE; 8107 if ((d == 15) || (m == 15)) 8108 return false; 8109 8110 break; 8111 8112 default: 8113 return false; 8114 } 8115 8116 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8117 if (!success) 8118 return false; 8119 8120 // rotated = ROR(R[m], rotation); 8121 uint64_t rotated = ROR (Rm, rotation, &success); 8122 if (!success) 8123 return false; 8124 8125 // R[d] = ZeroExtend(rotated<7:0>, 32); 8126 RegisterInfo source_reg; 8127 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8128 8129 EmulateInstruction::Context context; 8130 context.type = eContextRegisterLoad; 8131 context.SetRegister (source_reg); 8132 8133 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0))) 8134 return false; 8135 } 8136 return true; 8137 } 8138 8139 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination 8140 // register. You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. 8141 bool 8142 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding) 8143 { 8144 #if 0 8145 if ConditionPassed() then 8146 EncodingSpecificOperations(); 8147 rotated = ROR(R[m], rotation); 8148 R[d] = ZeroExtend(rotated<15:0>, 32); 8149 #endif 8150 8151 bool success = false; 8152 8153 if (ConditionPassed(opcode)) 8154 { 8155 uint32_t d; 8156 uint32_t m; 8157 uint32_t rotation; 8158 8159 switch (encoding) 8160 { 8161 case eEncodingT1: 8162 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8163 d = Bits32 (opcode, 2, 0); 8164 m = Bits32 (opcode, 5, 3); 8165 rotation = 0; 8166 8167 break; 8168 8169 case eEncodingT2: 8170 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8171 d = Bits32 (opcode, 11, 8); 8172 m = Bits32 (opcode, 3, 0); 8173 rotation = Bits32 (opcode, 5, 4) << 3; 8174 8175 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8176 if (BadReg (d) || BadReg (m)) 8177 return false; 8178 8179 break; 8180 8181 case eEncodingA1: 8182 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8183 d = Bits32 (opcode, 15, 12); 8184 m = Bits32 (opcode, 3, 0); 8185 rotation = Bits32 (opcode, 11, 10) << 3; 8186 8187 // if d == 15 || m == 15 then UNPREDICTABLE; 8188 if ((d == 15) || (m == 15)) 8189 return false; 8190 8191 break; 8192 8193 default: 8194 return false; 8195 } 8196 8197 uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8198 if (!success) 8199 return false; 8200 8201 // rotated = ROR(R[m], rotation); 8202 uint64_t rotated = ROR (Rm, rotation, &success); 8203 if (!success) 8204 return false; 8205 8206 // R[d] = ZeroExtend(rotated<15:0>, 32); 8207 RegisterInfo source_reg; 8208 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8209 8210 EmulateInstruction::Context context; 8211 context.type = eContextRegisterLoad; 8212 context.SetRegister (source_reg); 8213 8214 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0))) 8215 return false; 8216 } 8217 return true; 8218 } 8219 8220 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following 8221 // word respectively. 8222 bool 8223 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding) 8224 { 8225 #if 0 8226 if ConditionPassed() then 8227 EncodingSpecificOperations(); 8228 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8229 UNPREDICTABLE; 8230 else 8231 address = if increment then R[n] else R[n]-8; 8232 if wordhigher then address = address+4; 8233 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8234 BranchWritePC(MemA[address,4]); 8235 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8236 #endif 8237 8238 bool success = false; 8239 8240 if (ConditionPassed(opcode)) 8241 { 8242 uint32_t n; 8243 bool wback; 8244 bool increment; 8245 bool wordhigher; 8246 8247 // EncodingSpecificOperations(); 8248 switch (encoding) 8249 { 8250 case eEncodingT1: 8251 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE; 8252 n = Bits32 (opcode, 19, 16); 8253 wback = BitIsSet (opcode, 21); 8254 increment = false; 8255 wordhigher = false; 8256 8257 // if n == 15 then UNPREDICTABLE; 8258 if (n == 15) 8259 return false; 8260 8261 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8262 if (InITBlock() && !LastInITBlock()) 8263 return false; 8264 8265 break; 8266 8267 case eEncodingT2: 8268 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8269 n = Bits32 (opcode, 19, 16); 8270 wback = BitIsSet (opcode, 21); 8271 increment = true; 8272 wordhigher = false; 8273 8274 // if n == 15 then UNPREDICTABLE; 8275 if (n == 15) 8276 return false; 8277 8278 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8279 if (InITBlock() && !LastInITBlock()) 8280 return false; 8281 8282 break; 8283 8284 case eEncodingA1: 8285 // n = UInt(Rn); 8286 n = Bits32 (opcode, 19, 16); 8287 8288 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8289 wback = BitIsSet (opcode, 21); 8290 increment = BitIsSet (opcode, 23); 8291 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23)); 8292 8293 // if n == 15 then UNPREDICTABLE; 8294 if (n == 15) 8295 return false; 8296 8297 break; 8298 8299 default: 8300 return false; 8301 } 8302 8303 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8304 if (!CurrentModeIsPrivileged ()) 8305 // UNPREDICTABLE; 8306 return false; 8307 else 8308 { 8309 uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8310 if (!success) 8311 return false; 8312 8313 addr_t address; 8314 // address = if increment then R[n] else R[n]-8; 8315 if (increment) 8316 address = Rn; 8317 else 8318 address = Rn - 8; 8319 8320 // if wordhigher then address = address+4; 8321 if (wordhigher) 8322 address = address + 4; 8323 8324 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8325 RegisterInfo base_reg; 8326 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8327 8328 EmulateInstruction::Context context; 8329 context.type = eContextReturnFromException; 8330 context.SetRegisterPlusOffset (base_reg, address - Rn); 8331 8332 uint64_t data = MemARead (context, address + 4, 4, 0, &success); 8333 if (!success) 8334 return false; 8335 8336 CPSRWriteByInstr (data, 15, true); 8337 8338 // BranchWritePC(MemA[address,4]); 8339 uint64_t data2 = MemARead (context, address, 4, 0, &success); 8340 if (!success) 8341 return false; 8342 8343 BranchWritePC (context, data2); 8344 8345 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8346 if (wback) 8347 { 8348 context.type = eContextAdjustBaseRegister; 8349 if (increment) 8350 { 8351 context.SetOffset (8); 8352 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8)) 8353 return false; 8354 } 8355 else 8356 { 8357 context.SetOffset (-8); 8358 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8)) 8359 return false; 8360 } 8361 } // if wback 8362 } 8363 } // if ConditionPassed() 8364 return true; 8365 } 8366 8367 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value, 8368 // and writes the result to the destination register. It can optionally update the condition flags based on 8369 // the result. 8370 bool 8371 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding) 8372 { 8373 #if 0 8374 // ARM pseudo code... 8375 if ConditionPassed() then 8376 EncodingSpecificOperations(); 8377 result = R[n] EOR imm32; 8378 if d == 15 then // Can only occur for ARM encoding 8379 ALUWritePC(result); // setflags is always FALSE here 8380 else 8381 R[d] = result; 8382 if setflags then 8383 APSR.N = result<31>; 8384 APSR.Z = IsZeroBit(result); 8385 APSR.C = carry; 8386 // APSR.V unchanged 8387 #endif 8388 8389 bool success = false; 8390 8391 if (ConditionPassed(opcode)) 8392 { 8393 uint32_t Rd, Rn; 8394 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8395 bool setflags; 8396 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8397 switch (encoding) 8398 { 8399 case eEncodingT1: 8400 Rd = Bits32(opcode, 11, 8); 8401 Rn = Bits32(opcode, 19, 16); 8402 setflags = BitIsSet(opcode, 20); 8403 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8404 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8405 if (Rd == 15 && setflags) 8406 return EmulateTEQImm (opcode, eEncodingT1); 8407 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8408 return false; 8409 break; 8410 case eEncodingA1: 8411 Rd = Bits32(opcode, 15, 12); 8412 Rn = Bits32(opcode, 19, 16); 8413 setflags = BitIsSet(opcode, 20); 8414 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8415 8416 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8417 if (Rd == 15 && setflags) 8418 return EmulateSUBSPcLrEtc (opcode, encoding); 8419 break; 8420 default: 8421 return false; 8422 } 8423 8424 // Read the first operand. 8425 uint32_t val1 = ReadCoreReg(Rn, &success); 8426 if (!success) 8427 return false; 8428 8429 uint32_t result = val1 ^ imm32; 8430 8431 EmulateInstruction::Context context; 8432 context.type = EmulateInstruction::eContextImmediate; 8433 context.SetNoArgs (); 8434 8435 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8436 return false; 8437 } 8438 return true; 8439 } 8440 8441 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an 8442 // optionally-shifted register value, and writes the result to the destination register. 8443 // It can optionally update the condition flags based on the result. 8444 bool 8445 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding) 8446 { 8447 #if 0 8448 // ARM pseudo code... 8449 if ConditionPassed() then 8450 EncodingSpecificOperations(); 8451 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8452 result = R[n] EOR shifted; 8453 if d == 15 then // Can only occur for ARM encoding 8454 ALUWritePC(result); // setflags is always FALSE here 8455 else 8456 R[d] = result; 8457 if setflags then 8458 APSR.N = result<31>; 8459 APSR.Z = IsZeroBit(result); 8460 APSR.C = carry; 8461 // APSR.V unchanged 8462 #endif 8463 8464 bool success = false; 8465 8466 if (ConditionPassed(opcode)) 8467 { 8468 uint32_t Rd, Rn, Rm; 8469 ARM_ShifterType shift_t; 8470 uint32_t shift_n; // the shift applied to the value read from Rm 8471 bool setflags; 8472 uint32_t carry; 8473 switch (encoding) 8474 { 8475 case eEncodingT1: 8476 Rd = Rn = Bits32(opcode, 2, 0); 8477 Rm = Bits32(opcode, 5, 3); 8478 setflags = !InITBlock(); 8479 shift_t = SRType_LSL; 8480 shift_n = 0; 8481 break; 8482 case eEncodingT2: 8483 Rd = Bits32(opcode, 11, 8); 8484 Rn = Bits32(opcode, 19, 16); 8485 Rm = Bits32(opcode, 3, 0); 8486 setflags = BitIsSet(opcode, 20); 8487 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8488 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8489 if (Rd == 15 && setflags) 8490 return EmulateTEQReg (opcode, eEncodingT1); 8491 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8492 return false; 8493 break; 8494 case eEncodingA1: 8495 Rd = Bits32(opcode, 15, 12); 8496 Rn = Bits32(opcode, 19, 16); 8497 Rm = Bits32(opcode, 3, 0); 8498 setflags = BitIsSet(opcode, 20); 8499 shift_n = DecodeImmShiftARM(opcode, shift_t); 8500 8501 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8502 if (Rd == 15 && setflags) 8503 return EmulateSUBSPcLrEtc (opcode, encoding); 8504 break; 8505 default: 8506 return false; 8507 } 8508 8509 // Read the first operand. 8510 uint32_t val1 = ReadCoreReg(Rn, &success); 8511 if (!success) 8512 return false; 8513 8514 // Read the second operand. 8515 uint32_t val2 = ReadCoreReg(Rm, &success); 8516 if (!success) 8517 return false; 8518 8519 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8520 if (!success) 8521 return false; 8522 uint32_t result = val1 ^ shifted; 8523 8524 EmulateInstruction::Context context; 8525 context.type = EmulateInstruction::eContextImmediate; 8526 context.SetNoArgs (); 8527 8528 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8529 return false; 8530 } 8531 return true; 8532 } 8533 8534 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and 8535 // writes the result to the destination register. It can optionally update the condition flags based 8536 // on the result. 8537 bool 8538 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding) 8539 { 8540 #if 0 8541 // ARM pseudo code... 8542 if ConditionPassed() then 8543 EncodingSpecificOperations(); 8544 result = R[n] OR imm32; 8545 if d == 15 then // Can only occur for ARM encoding 8546 ALUWritePC(result); // setflags is always FALSE here 8547 else 8548 R[d] = result; 8549 if setflags then 8550 APSR.N = result<31>; 8551 APSR.Z = IsZeroBit(result); 8552 APSR.C = carry; 8553 // APSR.V unchanged 8554 #endif 8555 8556 bool success = false; 8557 8558 if (ConditionPassed(opcode)) 8559 { 8560 uint32_t Rd, Rn; 8561 uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn 8562 bool setflags; 8563 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8564 switch (encoding) 8565 { 8566 case eEncodingT1: 8567 Rd = Bits32(opcode, 11, 8); 8568 Rn = Bits32(opcode, 19, 16); 8569 setflags = BitIsSet(opcode, 20); 8570 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8571 // if Rn == '1111' then SEE MOV (immediate); 8572 if (Rn == 15) 8573 return EmulateMOVRdImm (opcode, eEncodingT2); 8574 if (BadReg(Rd) || Rn == 13) 8575 return false; 8576 break; 8577 case eEncodingA1: 8578 Rd = Bits32(opcode, 15, 12); 8579 Rn = Bits32(opcode, 19, 16); 8580 setflags = BitIsSet(opcode, 20); 8581 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8582 8583 if (Rd == 15 && setflags) 8584 return EmulateSUBSPcLrEtc (opcode, encoding); 8585 break; 8586 default: 8587 return false; 8588 } 8589 8590 // Read the first operand. 8591 uint32_t val1 = ReadCoreReg(Rn, &success); 8592 if (!success) 8593 return false; 8594 8595 uint32_t result = val1 | imm32; 8596 8597 EmulateInstruction::Context context; 8598 context.type = EmulateInstruction::eContextImmediate; 8599 context.SetNoArgs (); 8600 8601 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8602 return false; 8603 } 8604 return true; 8605 } 8606 8607 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register 8608 // value, and writes the result to the destination register. It can optionally update the condition flags based 8609 // on the result. 8610 bool 8611 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding) 8612 { 8613 #if 0 8614 // ARM pseudo code... 8615 if ConditionPassed() then 8616 EncodingSpecificOperations(); 8617 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8618 result = R[n] OR shifted; 8619 if d == 15 then // Can only occur for ARM encoding 8620 ALUWritePC(result); // setflags is always FALSE here 8621 else 8622 R[d] = result; 8623 if setflags then 8624 APSR.N = result<31>; 8625 APSR.Z = IsZeroBit(result); 8626 APSR.C = carry; 8627 // APSR.V unchanged 8628 #endif 8629 8630 bool success = false; 8631 8632 if (ConditionPassed(opcode)) 8633 { 8634 uint32_t Rd, Rn, Rm; 8635 ARM_ShifterType shift_t; 8636 uint32_t shift_n; // the shift applied to the value read from Rm 8637 bool setflags; 8638 uint32_t carry; 8639 switch (encoding) 8640 { 8641 case eEncodingT1: 8642 Rd = Rn = Bits32(opcode, 2, 0); 8643 Rm = Bits32(opcode, 5, 3); 8644 setflags = !InITBlock(); 8645 shift_t = SRType_LSL; 8646 shift_n = 0; 8647 break; 8648 case eEncodingT2: 8649 Rd = Bits32(opcode, 11, 8); 8650 Rn = Bits32(opcode, 19, 16); 8651 Rm = Bits32(opcode, 3, 0); 8652 setflags = BitIsSet(opcode, 20); 8653 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8654 // if Rn == '1111' then SEE MOV (register); 8655 if (Rn == 15) 8656 return EmulateMOVRdRm (opcode, eEncodingT3); 8657 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 8658 return false; 8659 break; 8660 case eEncodingA1: 8661 Rd = Bits32(opcode, 15, 12); 8662 Rn = Bits32(opcode, 19, 16); 8663 Rm = Bits32(opcode, 3, 0); 8664 setflags = BitIsSet(opcode, 20); 8665 shift_n = DecodeImmShiftARM(opcode, shift_t); 8666 8667 if (Rd == 15 && setflags) 8668 return EmulateSUBSPcLrEtc (opcode, encoding); 8669 break; 8670 default: 8671 return false; 8672 } 8673 8674 // Read the first operand. 8675 uint32_t val1 = ReadCoreReg(Rn, &success); 8676 if (!success) 8677 return false; 8678 8679 // Read the second operand. 8680 uint32_t val2 = ReadCoreReg(Rm, &success); 8681 if (!success) 8682 return false; 8683 8684 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8685 if (!success) 8686 return false; 8687 uint32_t result = val1 | shifted; 8688 8689 EmulateInstruction::Context context; 8690 context.type = EmulateInstruction::eContextImmediate; 8691 context.SetNoArgs (); 8692 8693 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8694 return false; 8695 } 8696 return true; 8697 } 8698 8699 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to 8700 // the destination register. It can optionally update the condition flags based on the result. 8701 bool 8702 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding) 8703 { 8704 #if 0 8705 // ARM pseudo code... 8706 if ConditionPassed() then 8707 EncodingSpecificOperations(); 8708 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 8709 if d == 15 then // Can only occur for ARM encoding 8710 ALUWritePC(result); // setflags is always FALSE here 8711 else 8712 R[d] = result; 8713 if setflags then 8714 APSR.N = result<31>; 8715 APSR.Z = IsZeroBit(result); 8716 APSR.C = carry; 8717 APSR.V = overflow; 8718 #endif 8719 8720 bool success = false; 8721 8722 uint32_t Rd; // the destination register 8723 uint32_t Rn; // the first operand 8724 bool setflags; 8725 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8726 switch (encoding) { 8727 case eEncodingT1: 8728 Rd = Bits32(opcode, 2, 0); 8729 Rn = Bits32(opcode, 5, 3); 8730 setflags = !InITBlock(); 8731 imm32 = 0; 8732 break; 8733 case eEncodingT2: 8734 Rd = Bits32(opcode, 11, 8); 8735 Rn = Bits32(opcode, 19, 16); 8736 setflags = BitIsSet(opcode, 20); 8737 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 8738 if (BadReg(Rd) || BadReg(Rn)) 8739 return false; 8740 break; 8741 case eEncodingA1: 8742 Rd = Bits32(opcode, 15, 12); 8743 Rn = Bits32(opcode, 19, 16); 8744 setflags = BitIsSet(opcode, 20); 8745 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8746 8747 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8748 if (Rd == 15 && setflags) 8749 return EmulateSUBSPcLrEtc (opcode, encoding); 8750 break; 8751 default: 8752 return false; 8753 } 8754 // Read the register value from the operand register Rn. 8755 uint32_t reg_val = ReadCoreReg(Rn, &success); 8756 if (!success) 8757 return false; 8758 8759 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 8760 8761 EmulateInstruction::Context context; 8762 context.type = EmulateInstruction::eContextImmediate; 8763 context.SetNoArgs (); 8764 8765 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8766 return false; 8767 8768 return true; 8769 } 8770 8771 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the 8772 // result to the destination register. It can optionally update the condition flags based on the result. 8773 bool 8774 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding) 8775 { 8776 #if 0 8777 // ARM pseudo code... 8778 if ConditionPassed() then 8779 EncodingSpecificOperations(); 8780 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8781 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 8782 if d == 15 then // Can only occur for ARM encoding 8783 ALUWritePC(result); // setflags is always FALSE here 8784 else 8785 R[d] = result; 8786 if setflags then 8787 APSR.N = result<31>; 8788 APSR.Z = IsZeroBit(result); 8789 APSR.C = carry; 8790 APSR.V = overflow; 8791 #endif 8792 8793 bool success = false; 8794 8795 uint32_t Rd; // the destination register 8796 uint32_t Rn; // the first operand 8797 uint32_t Rm; // the second operand 8798 bool setflags; 8799 ARM_ShifterType shift_t; 8800 uint32_t shift_n; // the shift applied to the value read from Rm 8801 switch (encoding) { 8802 case eEncodingT1: 8803 Rd = Bits32(opcode, 11, 8); 8804 Rn = Bits32(opcode, 19, 16); 8805 Rm = Bits32(opcode, 3, 0); 8806 setflags = BitIsSet(opcode, 20); 8807 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8808 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 8809 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 8810 return false; 8811 break; 8812 case eEncodingA1: 8813 Rd = Bits32(opcode, 15, 12); 8814 Rn = Bits32(opcode, 19, 16); 8815 Rm = Bits32(opcode, 3, 0); 8816 setflags = BitIsSet(opcode, 20); 8817 shift_n = DecodeImmShiftARM(opcode, shift_t); 8818 8819 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8820 if (Rd == 15 && setflags) 8821 return EmulateSUBSPcLrEtc (opcode, encoding); 8822 break; 8823 default: 8824 return false; 8825 } 8826 // Read the register value from register Rn. 8827 uint32_t val1 = ReadCoreReg(Rn, &success); 8828 if (!success) 8829 return false; 8830 8831 // Read the register value from register Rm. 8832 uint32_t val2 = ReadCoreReg(Rm, &success); 8833 if (!success) 8834 return false; 8835 8836 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8837 if (!success) 8838 return false; 8839 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 8840 8841 EmulateInstruction::Context context; 8842 context.type = EmulateInstruction::eContextImmediate; 8843 context.SetNoArgs(); 8844 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8845 return false; 8846 8847 return true; 8848 } 8849 8850 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from 8851 // an immediate value, and writes the result to the destination register. It can optionally update the condition 8852 // flags based on the result. 8853 bool 8854 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding) 8855 { 8856 #if 0 8857 // ARM pseudo code... 8858 if ConditionPassed() then 8859 EncodingSpecificOperations(); 8860 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 8861 if d == 15 then 8862 ALUWritePC(result); // setflags is always FALSE here 8863 else 8864 R[d] = result; 8865 if setflags then 8866 APSR.N = result<31>; 8867 APSR.Z = IsZeroBit(result); 8868 APSR.C = carry; 8869 APSR.V = overflow; 8870 #endif 8871 8872 bool success = false; 8873 8874 uint32_t Rd; // the destination register 8875 uint32_t Rn; // the first operand 8876 bool setflags; 8877 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 8878 switch (encoding) { 8879 case eEncodingA1: 8880 Rd = Bits32(opcode, 15, 12); 8881 Rn = Bits32(opcode, 19, 16); 8882 setflags = BitIsSet(opcode, 20); 8883 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 8884 8885 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8886 if (Rd == 15 && setflags) 8887 return EmulateSUBSPcLrEtc (opcode, encoding); 8888 break; 8889 default: 8890 return false; 8891 } 8892 // Read the register value from the operand register Rn. 8893 uint32_t reg_val = ReadCoreReg(Rn, &success); 8894 if (!success) 8895 return false; 8896 8897 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 8898 8899 EmulateInstruction::Context context; 8900 context.type = EmulateInstruction::eContextImmediate; 8901 context.SetNoArgs (); 8902 8903 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8904 return false; 8905 8906 return true; 8907 } 8908 8909 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an 8910 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the 8911 // condition flags based on the result. 8912 bool 8913 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding) 8914 { 8915 #if 0 8916 // ARM pseudo code... 8917 if ConditionPassed() then 8918 EncodingSpecificOperations(); 8919 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 8920 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 8921 if d == 15 then 8922 ALUWritePC(result); // setflags is always FALSE here 8923 else 8924 R[d] = result; 8925 if setflags then 8926 APSR.N = result<31>; 8927 APSR.Z = IsZeroBit(result); 8928 APSR.C = carry; 8929 APSR.V = overflow; 8930 #endif 8931 8932 bool success = false; 8933 8934 uint32_t Rd; // the destination register 8935 uint32_t Rn; // the first operand 8936 uint32_t Rm; // the second operand 8937 bool setflags; 8938 ARM_ShifterType shift_t; 8939 uint32_t shift_n; // the shift applied to the value read from Rm 8940 switch (encoding) { 8941 case eEncodingA1: 8942 Rd = Bits32(opcode, 15, 12); 8943 Rn = Bits32(opcode, 19, 16); 8944 Rm = Bits32(opcode, 3, 0); 8945 setflags = BitIsSet(opcode, 20); 8946 shift_n = DecodeImmShiftARM(opcode, shift_t); 8947 8948 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 8949 if (Rd == 15 && setflags) 8950 return EmulateSUBSPcLrEtc (opcode, encoding); 8951 break; 8952 default: 8953 return false; 8954 } 8955 // Read the register value from register Rn. 8956 uint32_t val1 = ReadCoreReg(Rn, &success); 8957 if (!success) 8958 return false; 8959 8960 // Read the register value from register Rm. 8961 uint32_t val2 = ReadCoreReg(Rm, &success); 8962 if (!success) 8963 return false; 8964 8965 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 8966 if (!success) 8967 return false; 8968 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 8969 8970 EmulateInstruction::Context context; 8971 context.type = EmulateInstruction::eContextImmediate; 8972 context.SetNoArgs(); 8973 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 8974 return false; 8975 8976 return true; 8977 } 8978 8979 // Subtract with Carry (immediate) subtracts an immediate value and the value of 8980 // NOT (Carry flag) from a register value, and writes the result to the destination register. 8981 // It can optionally update the condition flags based on the result. 8982 bool 8983 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding) 8984 { 8985 #if 0 8986 // ARM pseudo code... 8987 if ConditionPassed() then 8988 EncodingSpecificOperations(); 8989 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 8990 if d == 15 then // Can only occur for ARM encoding 8991 ALUWritePC(result); // setflags is always FALSE here 8992 else 8993 R[d] = result; 8994 if setflags then 8995 APSR.N = result<31>; 8996 APSR.Z = IsZeroBit(result); 8997 APSR.C = carry; 8998 APSR.V = overflow; 8999 #endif 9000 9001 bool success = false; 9002 9003 uint32_t Rd; // the destination register 9004 uint32_t Rn; // the first operand 9005 bool setflags; 9006 uint32_t imm32; // the immediate value to be added to the value obtained from Rn 9007 switch (encoding) { 9008 case eEncodingT1: 9009 Rd = Bits32(opcode, 11, 8); 9010 Rn = Bits32(opcode, 19, 16); 9011 setflags = BitIsSet(opcode, 20); 9012 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9013 if (BadReg(Rd) || BadReg(Rn)) 9014 return false; 9015 break; 9016 case eEncodingA1: 9017 Rd = Bits32(opcode, 15, 12); 9018 Rn = Bits32(opcode, 19, 16); 9019 setflags = BitIsSet(opcode, 20); 9020 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9021 9022 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9023 if (Rd == 15 && setflags) 9024 return EmulateSUBSPcLrEtc (opcode, encoding); 9025 break; 9026 default: 9027 return false; 9028 } 9029 // Read the register value from the operand register Rn. 9030 uint32_t reg_val = ReadCoreReg(Rn, &success); 9031 if (!success) 9032 return false; 9033 9034 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9035 9036 EmulateInstruction::Context context; 9037 context.type = EmulateInstruction::eContextImmediate; 9038 context.SetNoArgs (); 9039 9040 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9041 return false; 9042 9043 return true; 9044 } 9045 9046 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of 9047 // NOT (Carry flag) from a register value, and writes the result to the destination register. 9048 // It can optionally update the condition flags based on the result. 9049 bool 9050 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding) 9051 { 9052 #if 0 9053 // ARM pseudo code... 9054 if ConditionPassed() then 9055 EncodingSpecificOperations(); 9056 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9057 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9058 if d == 15 then // Can only occur for ARM encoding 9059 ALUWritePC(result); // setflags is always FALSE here 9060 else 9061 R[d] = result; 9062 if setflags then 9063 APSR.N = result<31>; 9064 APSR.Z = IsZeroBit(result); 9065 APSR.C = carry; 9066 APSR.V = overflow; 9067 #endif 9068 9069 bool success = false; 9070 9071 uint32_t Rd; // the destination register 9072 uint32_t Rn; // the first operand 9073 uint32_t Rm; // the second operand 9074 bool setflags; 9075 ARM_ShifterType shift_t; 9076 uint32_t shift_n; // the shift applied to the value read from Rm 9077 switch (encoding) { 9078 case eEncodingT1: 9079 Rd = Rn = Bits32(opcode, 2, 0); 9080 Rm = Bits32(opcode, 5, 3); 9081 setflags = !InITBlock(); 9082 shift_t = SRType_LSL; 9083 shift_n = 0; 9084 break; 9085 case eEncodingT2: 9086 Rd = Bits32(opcode, 11, 8); 9087 Rn = Bits32(opcode, 19, 16); 9088 Rm = Bits32(opcode, 3, 0); 9089 setflags = BitIsSet(opcode, 20); 9090 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9091 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9092 return false; 9093 break; 9094 case eEncodingA1: 9095 Rd = Bits32(opcode, 15, 12); 9096 Rn = Bits32(opcode, 19, 16); 9097 Rm = Bits32(opcode, 3, 0); 9098 setflags = BitIsSet(opcode, 20); 9099 shift_n = DecodeImmShiftARM(opcode, shift_t); 9100 9101 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9102 if (Rd == 15 && setflags) 9103 return EmulateSUBSPcLrEtc (opcode, encoding); 9104 break; 9105 default: 9106 return false; 9107 } 9108 // Read the register value from register Rn. 9109 uint32_t val1 = ReadCoreReg(Rn, &success); 9110 if (!success) 9111 return false; 9112 9113 // Read the register value from register Rm. 9114 uint32_t val2 = ReadCoreReg(Rm, &success); 9115 if (!success) 9116 return false; 9117 9118 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9119 if (!success) 9120 return false; 9121 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9122 9123 EmulateInstruction::Context context; 9124 context.type = EmulateInstruction::eContextImmediate; 9125 context.SetNoArgs(); 9126 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9127 return false; 9128 9129 return true; 9130 } 9131 9132 // This instruction subtracts an immediate value from a register value, and writes the result 9133 // to the destination register. It can optionally update the condition flags based on the result. 9134 bool 9135 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding) 9136 { 9137 #if 0 9138 // ARM pseudo code... 9139 if ConditionPassed() then 9140 EncodingSpecificOperations(); 9141 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9142 R[d] = result; 9143 if setflags then 9144 APSR.N = result<31>; 9145 APSR.Z = IsZeroBit(result); 9146 APSR.C = carry; 9147 APSR.V = overflow; 9148 #endif 9149 9150 bool success = false; 9151 9152 uint32_t Rd; // the destination register 9153 uint32_t Rn; // the first operand 9154 bool setflags; 9155 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9156 switch (encoding) { 9157 case eEncodingT1: 9158 Rd = Bits32(opcode, 2, 0); 9159 Rn = Bits32(opcode, 5, 3); 9160 setflags = !InITBlock(); 9161 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9162 break; 9163 case eEncodingT2: 9164 Rd = Rn = Bits32(opcode, 10, 8); 9165 setflags = !InITBlock(); 9166 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9167 break; 9168 case eEncodingT3: 9169 Rd = Bits32(opcode, 11, 8); 9170 Rn = Bits32(opcode, 19, 16); 9171 setflags = BitIsSet(opcode, 20); 9172 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9173 9174 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9175 if (Rd == 15 && setflags) 9176 return EmulateCMPImm (opcode, eEncodingT2); 9177 9178 // if Rn == '1101' then SEE SUB (SP minus immediate); 9179 if (Rn == 13) 9180 return EmulateSUBSPImm (opcode, eEncodingT2); 9181 9182 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9183 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9184 return false; 9185 break; 9186 case eEncodingT4: 9187 Rd = Bits32(opcode, 11, 8); 9188 Rn = Bits32(opcode, 19, 16); 9189 setflags = BitIsSet(opcode, 20); 9190 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9191 9192 // if Rn == '1111' then SEE ADR; 9193 if (Rn == 15) 9194 return EmulateADR (opcode, eEncodingT2); 9195 9196 // if Rn == '1101' then SEE SUB (SP minus immediate); 9197 if (Rn == 13) 9198 return EmulateSUBSPImm (opcode, eEncodingT3); 9199 9200 if (BadReg(Rd)) 9201 return false; 9202 break; 9203 default: 9204 return false; 9205 } 9206 // Read the register value from the operand register Rn. 9207 uint32_t reg_val = ReadCoreReg(Rn, &success); 9208 if (!success) 9209 return false; 9210 9211 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9212 9213 EmulateInstruction::Context context; 9214 context.type = EmulateInstruction::eContextImmediate; 9215 context.SetNoArgs (); 9216 9217 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9218 return false; 9219 9220 return true; 9221 } 9222 9223 // This instruction subtracts an immediate value from a register value, and writes the result 9224 // to the destination register. It can optionally update the condition flags based on the result. 9225 bool 9226 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9227 { 9228 #if 0 9229 // ARM pseudo code... 9230 if ConditionPassed() then 9231 EncodingSpecificOperations(); 9232 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9233 if d == 15 then 9234 ALUWritePC(result); // setflags is always FALSE here 9235 else 9236 R[d] = result; 9237 if setflags then 9238 APSR.N = result<31>; 9239 APSR.Z = IsZeroBit(result); 9240 APSR.C = carry; 9241 APSR.V = overflow; 9242 #endif 9243 9244 bool success = false; 9245 9246 if (ConditionPassed(opcode)) 9247 { 9248 uint32_t Rd; // the destination register 9249 uint32_t Rn; // the first operand 9250 bool setflags; 9251 uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn 9252 switch (encoding) { 9253 case eEncodingA1: 9254 Rd = Bits32(opcode, 15, 12); 9255 Rn = Bits32(opcode, 19, 16); 9256 setflags = BitIsSet(opcode, 20); 9257 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9258 9259 // if Rn == '1111' && S == '0' then SEE ADR; 9260 if (Rn == 15 && !setflags) 9261 return EmulateADR (opcode, eEncodingA2); 9262 9263 // if Rn == '1101' then SEE SUB (SP minus immediate); 9264 if (Rn == 13) 9265 return EmulateSUBSPImm (opcode, eEncodingA1); 9266 9267 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9268 if (Rd == 15 && setflags) 9269 return EmulateSUBSPcLrEtc (opcode, encoding); 9270 break; 9271 default: 9272 return false; 9273 } 9274 // Read the register value from the operand register Rn. 9275 uint32_t reg_val = ReadCoreReg(Rn, &success); 9276 if (!success) 9277 return false; 9278 9279 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9280 9281 EmulateInstruction::Context context; 9282 if (Rd == 13) 9283 context.type = EmulateInstruction::eContextAdjustStackPointer; 9284 else 9285 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9286 9287 RegisterInfo dwarf_reg; 9288 GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg); 9289 int64_t imm32_signed = imm32; 9290 context.SetRegisterPlusOffset (dwarf_reg, -imm32_signed); 9291 9292 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow)) 9293 return false; 9294 } 9295 return true; 9296 } 9297 9298 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an 9299 // immediate value. It updates the condition flags based on the result, and discards the result. 9300 bool 9301 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding) 9302 { 9303 #if 0 9304 // ARM pseudo code... 9305 if ConditionPassed() then 9306 EncodingSpecificOperations(); 9307 result = R[n] EOR imm32; 9308 APSR.N = result<31>; 9309 APSR.Z = IsZeroBit(result); 9310 APSR.C = carry; 9311 // APSR.V unchanged 9312 #endif 9313 9314 bool success = false; 9315 9316 if (ConditionPassed(opcode)) 9317 { 9318 uint32_t Rn; 9319 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9320 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9321 switch (encoding) 9322 { 9323 case eEncodingT1: 9324 Rn = Bits32(opcode, 19, 16); 9325 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9326 if (BadReg(Rn)) 9327 return false; 9328 break; 9329 case eEncodingA1: 9330 Rn = Bits32(opcode, 19, 16); 9331 imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9332 break; 9333 default: 9334 return false; 9335 } 9336 9337 // Read the first operand. 9338 uint32_t val1 = ReadCoreReg(Rn, &success); 9339 if (!success) 9340 return false; 9341 9342 uint32_t result = val1 ^ imm32; 9343 9344 EmulateInstruction::Context context; 9345 context.type = EmulateInstruction::eContextImmediate; 9346 context.SetNoArgs (); 9347 9348 if (!WriteFlags(context, result, carry)) 9349 return false; 9350 } 9351 return true; 9352 } 9353 9354 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an 9355 // optionally-shifted register value. It updates the condition flags based on the result, and discards 9356 // the result. 9357 bool 9358 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding) 9359 { 9360 #if 0 9361 // ARM pseudo code... 9362 if ConditionPassed() then 9363 EncodingSpecificOperations(); 9364 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9365 result = R[n] EOR shifted; 9366 APSR.N = result<31>; 9367 APSR.Z = IsZeroBit(result); 9368 APSR.C = carry; 9369 // APSR.V unchanged 9370 #endif 9371 9372 bool success = false; 9373 9374 if (ConditionPassed(opcode)) 9375 { 9376 uint32_t Rn, Rm; 9377 ARM_ShifterType shift_t; 9378 uint32_t shift_n; // the shift applied to the value read from Rm 9379 uint32_t carry; 9380 switch (encoding) 9381 { 9382 case eEncodingT1: 9383 Rn = Bits32(opcode, 19, 16); 9384 Rm = Bits32(opcode, 3, 0); 9385 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9386 if (BadReg(Rn) || BadReg(Rm)) 9387 return false; 9388 break; 9389 case eEncodingA1: 9390 Rn = Bits32(opcode, 19, 16); 9391 Rm = Bits32(opcode, 3, 0); 9392 shift_n = DecodeImmShiftARM(opcode, shift_t); 9393 break; 9394 default: 9395 return false; 9396 } 9397 9398 // Read the first operand. 9399 uint32_t val1 = ReadCoreReg(Rn, &success); 9400 if (!success) 9401 return false; 9402 9403 // Read the second operand. 9404 uint32_t val2 = ReadCoreReg(Rm, &success); 9405 if (!success) 9406 return false; 9407 9408 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9409 if (!success) 9410 return false; 9411 uint32_t result = val1 ^ shifted; 9412 9413 EmulateInstruction::Context context; 9414 context.type = EmulateInstruction::eContextImmediate; 9415 context.SetNoArgs (); 9416 9417 if (!WriteFlags(context, result, carry)) 9418 return false; 9419 } 9420 return true; 9421 } 9422 9423 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value. 9424 // It updates the condition flags based on the result, and discards the result. 9425 bool 9426 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding) 9427 { 9428 #if 0 9429 // ARM pseudo code... 9430 if ConditionPassed() then 9431 EncodingSpecificOperations(); 9432 result = R[n] AND imm32; 9433 APSR.N = result<31>; 9434 APSR.Z = IsZeroBit(result); 9435 APSR.C = carry; 9436 // APSR.V unchanged 9437 #endif 9438 9439 bool success = false; 9440 9441 if (ConditionPassed(opcode)) 9442 { 9443 uint32_t Rn; 9444 uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn 9445 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9446 switch (encoding) 9447 { 9448 case eEncodingT1: 9449 Rn = Bits32(opcode, 19, 16); 9450 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9451 if (BadReg(Rn)) 9452 return false; 9453 break; 9454 case eEncodingA1: 9455 Rn = Bits32(opcode, 19, 16); 9456 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9457 break; 9458 default: 9459 return false; 9460 } 9461 9462 // Read the first operand. 9463 uint32_t val1 = ReadCoreReg(Rn, &success); 9464 if (!success) 9465 return false; 9466 9467 uint32_t result = val1 & imm32; 9468 9469 EmulateInstruction::Context context; 9470 context.type = EmulateInstruction::eContextImmediate; 9471 context.SetNoArgs (); 9472 9473 if (!WriteFlags(context, result, carry)) 9474 return false; 9475 } 9476 return true; 9477 } 9478 9479 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. 9480 // It updates the condition flags based on the result, and discards the result. 9481 bool 9482 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding) 9483 { 9484 #if 0 9485 // ARM pseudo code... 9486 if ConditionPassed() then 9487 EncodingSpecificOperations(); 9488 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9489 result = R[n] AND shifted; 9490 APSR.N = result<31>; 9491 APSR.Z = IsZeroBit(result); 9492 APSR.C = carry; 9493 // APSR.V unchanged 9494 #endif 9495 9496 bool success = false; 9497 9498 if (ConditionPassed(opcode)) 9499 { 9500 uint32_t Rn, Rm; 9501 ARM_ShifterType shift_t; 9502 uint32_t shift_n; // the shift applied to the value read from Rm 9503 uint32_t carry; 9504 switch (encoding) 9505 { 9506 case eEncodingT1: 9507 Rn = Bits32(opcode, 2, 0); 9508 Rm = Bits32(opcode, 5, 3); 9509 shift_t = SRType_LSL; 9510 shift_n = 0; 9511 break; 9512 case eEncodingT2: 9513 Rn = Bits32(opcode, 19, 16); 9514 Rm = Bits32(opcode, 3, 0); 9515 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9516 if (BadReg(Rn) || BadReg(Rm)) 9517 return false; 9518 break; 9519 case eEncodingA1: 9520 Rn = Bits32(opcode, 19, 16); 9521 Rm = Bits32(opcode, 3, 0); 9522 shift_n = DecodeImmShiftARM(opcode, shift_t); 9523 break; 9524 default: 9525 return false; 9526 } 9527 9528 // Read the first operand. 9529 uint32_t val1 = ReadCoreReg(Rn, &success); 9530 if (!success) 9531 return false; 9532 9533 // Read the second operand. 9534 uint32_t val2 = ReadCoreReg(Rm, &success); 9535 if (!success) 9536 return false; 9537 9538 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9539 if (!success) 9540 return false; 9541 uint32_t result = val1 & shifted; 9542 9543 EmulateInstruction::Context context; 9544 context.type = EmulateInstruction::eContextImmediate; 9545 context.SetNoArgs (); 9546 9547 if (!WriteFlags(context, result, carry)) 9548 return false; 9549 } 9550 return true; 9551 } 9552 9553 // A8.6.216 SUB (SP minus register) 9554 bool 9555 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding) 9556 { 9557 #if 0 9558 if ConditionPassed() then 9559 EncodingSpecificOperations(); 9560 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9561 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 9562 if d == 15 then // Can only occur for ARM encoding 9563 ALUWritePC(result); // setflags is always FALSE here 9564 else 9565 R[d] = result; 9566 if setflags then 9567 APSR.N = result<31>; 9568 APSR.Z = IsZeroBit(result); 9569 APSR.C = carry; 9570 APSR.V = overflow; 9571 #endif 9572 9573 bool success = false; 9574 9575 if (ConditionPassed(opcode)) 9576 { 9577 uint32_t d; 9578 uint32_t m; 9579 bool setflags; 9580 ARM_ShifterType shift_t; 9581 uint32_t shift_n; 9582 9583 switch (encoding) 9584 { 9585 case eEncodingT1: 9586 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 9587 d = Bits32 (opcode, 11, 8); 9588 m = Bits32 (opcode, 3, 0); 9589 setflags = BitIsSet (opcode, 20); 9590 9591 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9592 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9593 9594 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE; 9595 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 9596 return false; 9597 9598 // if d == 15 || BadReg(m) then UNPREDICTABLE; 9599 if ((d == 15) || BadReg (m)) 9600 return false; 9601 break; 9602 9603 case eEncodingA1: 9604 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 9605 d = Bits32 (opcode, 15, 12); 9606 m = Bits32 (opcode, 3, 0); 9607 setflags = BitIsSet (opcode, 20); 9608 9609 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9610 if (d == 15 && setflags) 9611 EmulateSUBSPcLrEtc (opcode, encoding); 9612 9613 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9614 shift_n = DecodeImmShiftARM (opcode, shift_t); 9615 break; 9616 9617 default: 9618 return false; 9619 } 9620 9621 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9622 uint32_t Rm = ReadCoreReg (m, &success); 9623 if (!success) 9624 return false; 9625 9626 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9627 if (!success) 9628 return false; 9629 9630 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 9631 uint32_t sp_val = ReadCoreReg (SP_REG, &success); 9632 if (!success) 9633 return false; 9634 9635 AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1); 9636 9637 EmulateInstruction::Context context; 9638 context.type = eContextArithmetic; 9639 RegisterInfo sp_reg; 9640 GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); 9641 RegisterInfo dwarf_reg; 9642 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 9643 context.SetRegisterRegisterOperands (sp_reg, dwarf_reg); 9644 9645 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9646 return false; 9647 } 9648 return true; 9649 } 9650 9651 9652 // A8.6.7 ADD (register-shifted register) 9653 bool 9654 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding) 9655 { 9656 #if 0 9657 if ConditionPassed() then 9658 EncodingSpecificOperations(); 9659 shift_n = UInt(R[s]<7:0>); 9660 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9661 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 9662 R[d] = result; 9663 if setflags then 9664 APSR.N = result<31>; 9665 APSR.Z = IsZeroBit(result); 9666 APSR.C = carry; 9667 APSR.V = overflow; 9668 #endif 9669 9670 bool success = false; 9671 9672 if (ConditionPassed(opcode)) 9673 { 9674 uint32_t d; 9675 uint32_t n; 9676 uint32_t m; 9677 uint32_t s; 9678 bool setflags; 9679 ARM_ShifterType shift_t; 9680 9681 switch (encoding) 9682 { 9683 case eEncodingA1: 9684 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 9685 d = Bits32 (opcode, 15, 12); 9686 n = Bits32 (opcode, 19, 16); 9687 m = Bits32 (opcode, 3, 0); 9688 s = Bits32 (opcode, 11, 8); 9689 9690 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 9691 setflags = BitIsSet (opcode, 20); 9692 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5)); 9693 9694 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 9695 if ((d == 15) || (m == 15) || (m == 15) || (s == 15)) 9696 return false; 9697 break; 9698 9699 default: 9700 return false; 9701 } 9702 9703 // shift_n = UInt(R[s]<7:0>); 9704 uint32_t Rs = ReadCoreReg (s, &success); 9705 if (!success) 9706 return false; 9707 9708 uint32_t shift_n = Bits32 (Rs, 7, 0); 9709 9710 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9711 uint32_t Rm = ReadCoreReg (m, &success); 9712 if (!success) 9713 return false; 9714 9715 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9716 if (!success) 9717 return false; 9718 9719 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 9720 uint32_t Rn = ReadCoreReg (n, &success); 9721 if (!success) 9722 return false; 9723 9724 AddWithCarryResult res = AddWithCarry (Rn, shifted, 0); 9725 9726 // R[d] = result; 9727 EmulateInstruction::Context context; 9728 context.type = eContextArithmetic; 9729 RegisterInfo reg_n; 9730 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9731 RegisterInfo reg_m; 9732 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9733 9734 context.SetRegisterRegisterOperands (reg_n, reg_m); 9735 9736 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result)) 9737 return false; 9738 9739 // if setflags then 9740 // APSR.N = result<31>; 9741 // APSR.Z = IsZeroBit(result); 9742 // APSR.C = carry; 9743 // APSR.V = overflow; 9744 if (setflags) 9745 return WriteFlags (context, res.result, res.carry_out, res.overflow); 9746 } 9747 return true; 9748 } 9749 9750 // A8.6.213 SUB (register) 9751 bool 9752 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding) 9753 { 9754 #if 0 9755 if ConditionPassed() then 9756 EncodingSpecificOperations(); 9757 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9758 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 9759 if d == 15 then // Can only occur for ARM encoding 9760 ALUWritePC(result); // setflags is always FALSE here 9761 else 9762 R[d] = result; 9763 if setflags then 9764 APSR.N = result<31>; 9765 APSR.Z = IsZeroBit(result); 9766 APSR.C = carry; 9767 APSR.V = overflow; 9768 #endif 9769 9770 bool success = false; 9771 9772 if (ConditionPassed(opcode)) 9773 { 9774 uint32_t d; 9775 uint32_t n; 9776 uint32_t m; 9777 bool setflags; 9778 ARM_ShifterType shift_t; 9779 uint32_t shift_n; 9780 9781 switch (encoding) 9782 { 9783 case eEncodingT1: 9784 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 9785 d = Bits32 (opcode, 2, 0); 9786 n = Bits32 (opcode, 5, 3); 9787 m = Bits32 (opcode, 8, 6); 9788 setflags = !InITBlock(); 9789 9790 // (shift_t, shift_n) = (SRType_LSL, 0); 9791 shift_t = SRType_LSL; 9792 shift_n = 0; 9793 9794 break; 9795 9796 case eEncodingT2: 9797 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 9798 d = Bits32 (opcode, 11, 8); 9799 n = Bits32 (opcode, 19, 16); 9800 m = Bits32 (opcode, 3, 0); 9801 setflags = BitIsSet (opcode, 20); 9802 9803 // if Rd == "1111" && S == "1" then SEE CMP (register); 9804 if (d == 15 && setflags == 1) 9805 return EmulateCMPImm (opcode, eEncodingT3); 9806 9807 // if Rn == "1101" then SEE SUB (SP minus register); 9808 if (n == 13) 9809 return EmulateSUBSPReg (opcode, eEncodingT1); 9810 9811 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 9812 shift_n = DecodeImmShiftThumb (opcode, shift_t); 9813 9814 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE; 9815 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m)) 9816 return false; 9817 9818 break; 9819 9820 case eEncodingA1: 9821 // if Rn == '1101' then SEE SUB (SP minus register); 9822 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 9823 d = Bits32 (opcode, 15, 12); 9824 n = Bits32 (opcode, 19, 16); 9825 m = Bits32 (opcode, 3, 0); 9826 setflags = BitIsSet (opcode, 20); 9827 9828 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; 9829 if ((d == 15) && setflags) 9830 EmulateSUBSPcLrEtc (opcode, encoding); 9831 9832 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 9833 shift_n = DecodeImmShiftARM (opcode, shift_t); 9834 9835 break; 9836 9837 default: 9838 return false; 9839 } 9840 9841 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9842 uint32_t Rm = ReadCoreReg (m, &success); 9843 if (!success) 9844 return false; 9845 9846 uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success); 9847 if (!success) 9848 return false; 9849 9850 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 9851 uint32_t Rn = ReadCoreReg (n, &success); 9852 if (!success) 9853 return false; 9854 9855 AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1); 9856 9857 // if d == 15 then // Can only occur for ARM encoding 9858 // ALUWritePC(result); // setflags is always FALSE here 9859 // else 9860 // R[d] = result; 9861 // if setflags then 9862 // APSR.N = result<31>; 9863 // APSR.Z = IsZeroBit(result); 9864 // APSR.C = carry; 9865 // APSR.V = overflow; 9866 9867 EmulateInstruction::Context context; 9868 context.type = eContextArithmetic; 9869 RegisterInfo reg_n; 9870 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n); 9871 RegisterInfo reg_m; 9872 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m); 9873 context.SetRegisterRegisterOperands (reg_n, reg_m); 9874 9875 if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow)) 9876 return false; 9877 } 9878 return true; 9879 } 9880 9881 // A8.6.202 STREX 9882 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a 9883 // word from a register to memory if the executing processor has exclusive access to the memory addressed. 9884 bool 9885 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding) 9886 { 9887 #if 0 9888 if ConditionPassed() then 9889 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 9890 address = R[n] + imm32; 9891 if ExclusiveMonitorsPass(address,4) then 9892 MemA[address,4] = R[t]; 9893 R[d] = 0; 9894 else 9895 R[d] = 1; 9896 #endif 9897 9898 bool success = false; 9899 9900 if (ConditionPassed(opcode)) 9901 { 9902 uint32_t d; 9903 uint32_t t; 9904 uint32_t n; 9905 uint32_t imm32; 9906 const uint32_t addr_byte_size = GetAddressByteSize(); 9907 9908 switch (encoding) 9909 { 9910 case eEncodingT1: 9911 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 9912 d = Bits32 (opcode, 11, 8); 9913 t = Bits32 (opcode, 15, 12); 9914 n = Bits32 (opcode, 19, 16); 9915 imm32 = Bits32 (opcode, 7, 0) << 2; 9916 9917 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 9918 if (BadReg (d) || BadReg (t) || (n == 15)) 9919 return false; 9920 9921 // if d == n || d == t then UNPREDICTABLE; 9922 if ((d == n) || (d == t)) 9923 return false; 9924 9925 break; 9926 9927 case eEncodingA1: 9928 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset 9929 d = Bits32 (opcode, 15, 12); 9930 t = Bits32 (opcode, 3, 0); 9931 n = Bits32 (opcode, 19, 16); 9932 imm32 = 0; 9933 9934 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 9935 if ((d == 15) || (t == 15) || (n == 15)) 9936 return false; 9937 9938 // if d == n || d == t then UNPREDICTABLE; 9939 if ((d == n) || (d == t)) 9940 return false; 9941 9942 break; 9943 9944 default: 9945 return false; 9946 } 9947 9948 // address = R[n] + imm32; 9949 uint32_t Rn = ReadCoreReg (n, &success); 9950 if (!success) 9951 return false; 9952 9953 addr_t address = Rn + imm32; 9954 9955 RegisterInfo base_reg; 9956 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 9957 RegisterInfo data_reg; 9958 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 9959 EmulateInstruction::Context context; 9960 context.type = eContextRegisterStore; 9961 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32); 9962 9963 // if ExclusiveMonitorsPass(address,4) then 9964 // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this 9965 // always return true. 9966 if (true) 9967 { 9968 // MemA[address,4] = R[t]; 9969 uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 9970 if (!success) 9971 return false; 9972 9973 if (!MemAWrite (context, address, Rt, addr_byte_size)) 9974 return false; 9975 9976 // R[d] = 0; 9977 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 9978 return false; 9979 } 9980 #if 0 // unreachable because if true 9981 else 9982 { 9983 // R[d] = 1; 9984 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 9985 return false; 9986 } 9987 #endif // unreachable because if true 9988 } 9989 return true; 9990 } 9991 9992 // A8.6.197 STRB (immediate, ARM) 9993 bool 9994 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding) 9995 { 9996 #if 0 9997 if ConditionPassed() then 9998 EncodingSpecificOperations(); 9999 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10000 address = if index then offset_addr else R[n]; 10001 MemU[address,1] = R[t]<7:0>; 10002 if wback then R[n] = offset_addr; 10003 #endif 10004 10005 bool success = false; 10006 10007 if (ConditionPassed(opcode)) 10008 { 10009 uint32_t t; 10010 uint32_t n; 10011 uint32_t imm32; 10012 bool index; 10013 bool add; 10014 bool wback; 10015 10016 switch (encoding) 10017 { 10018 case eEncodingA1: 10019 // if P == '0' && W == '1' then SEE STRBT; 10020 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10021 t = Bits32 (opcode, 15, 12); 10022 n = Bits32 (opcode, 19, 16); 10023 imm32 = Bits32 (opcode, 11, 0); 10024 10025 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10026 index = BitIsSet (opcode, 24); 10027 add = BitIsSet (opcode, 23); 10028 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10029 10030 // if t == 15 then UNPREDICTABLE; 10031 if (t == 15) 10032 return false; 10033 10034 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10035 if (wback && ((n == 15) || (n == t))) 10036 return false; 10037 10038 break; 10039 10040 default: 10041 return false; 10042 } 10043 10044 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10045 uint32_t Rn = ReadCoreReg (n, &success); 10046 if (!success) 10047 return false; 10048 10049 addr_t offset_addr; 10050 if (add) 10051 offset_addr = Rn + imm32; 10052 else 10053 offset_addr = Rn - imm32; 10054 10055 // address = if index then offset_addr else R[n]; 10056 addr_t address; 10057 if (index) 10058 address = offset_addr; 10059 else 10060 address = Rn; 10061 10062 // MemU[address,1] = R[t]<7:0>; 10063 uint32_t Rt = ReadCoreReg (t, &success); 10064 if (!success) 10065 return false; 10066 10067 RegisterInfo base_reg; 10068 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10069 RegisterInfo data_reg; 10070 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10071 EmulateInstruction::Context context; 10072 context.type = eContextRegisterStore; 10073 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10074 10075 if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1)) 10076 return false; 10077 10078 // if wback then R[n] = offset_addr; 10079 if (wback) 10080 { 10081 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10082 return false; 10083 } 10084 } 10085 return true; 10086 } 10087 10088 // A8.6.194 STR (immediate, ARM) 10089 bool 10090 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding) 10091 { 10092 #if 0 10093 if ConditionPassed() then 10094 EncodingSpecificOperations(); 10095 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10096 address = if index then offset_addr else R[n]; 10097 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10098 if wback then R[n] = offset_addr; 10099 #endif 10100 10101 bool success = false; 10102 10103 if (ConditionPassed(opcode)) 10104 { 10105 uint32_t t; 10106 uint32_t n; 10107 uint32_t imm32; 10108 bool index; 10109 bool add; 10110 bool wback; 10111 10112 const uint32_t addr_byte_size = GetAddressByteSize(); 10113 10114 switch (encoding) 10115 { 10116 case eEncodingA1: 10117 // if P == '0' && W == '1' then SEE STRT; 10118 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH; 10119 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10120 t = Bits32 (opcode, 15, 12); 10121 n = Bits32 (opcode, 19, 16); 10122 imm32 = Bits32 (opcode, 11, 0); 10123 10124 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10125 index = BitIsSet (opcode, 24); 10126 add = BitIsSet (opcode, 23); 10127 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10128 10129 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10130 if (wback && ((n == 15) || (n == t))) 10131 return false; 10132 10133 break; 10134 10135 default: 10136 return false; 10137 } 10138 10139 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10140 uint32_t Rn = ReadCoreReg (n, &success); 10141 if (!success) 10142 return false; 10143 10144 addr_t offset_addr; 10145 if (add) 10146 offset_addr = Rn + imm32; 10147 else 10148 offset_addr = Rn - imm32; 10149 10150 // address = if index then offset_addr else R[n]; 10151 addr_t address; 10152 if (index) 10153 address = offset_addr; 10154 else 10155 address = Rn; 10156 10157 RegisterInfo base_reg; 10158 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10159 RegisterInfo data_reg; 10160 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10161 EmulateInstruction::Context context; 10162 context.type = eContextRegisterStore; 10163 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10164 10165 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10166 uint32_t Rt = ReadCoreReg (t, &success); 10167 if (!success) 10168 return false; 10169 10170 if (t == 15) 10171 { 10172 uint32_t pc_value = ReadCoreReg (PC_REG, &success); 10173 if (!success) 10174 return false; 10175 10176 if (!MemUWrite (context, address, pc_value, addr_byte_size)) 10177 return false; 10178 } 10179 else 10180 { 10181 if (!MemUWrite (context, address, Rt, addr_byte_size)) 10182 return false; 10183 } 10184 10185 // if wback then R[n] = offset_addr; 10186 if (wback) 10187 { 10188 context.type = eContextAdjustBaseRegister; 10189 context.SetImmediate (offset_addr); 10190 10191 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10192 return false; 10193 } 10194 } 10195 return true; 10196 } 10197 10198 // A8.6.66 LDRD (immediate) 10199 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two 10200 // words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. 10201 bool 10202 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding) 10203 { 10204 #if 0 10205 if ConditionPassed() then 10206 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10207 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10208 address = if index then offset_addr else R[n]; 10209 R[t] = MemA[address,4]; 10210 R[t2] = MemA[address+4,4]; 10211 if wback then R[n] = offset_addr; 10212 #endif 10213 10214 bool success = false; 10215 10216 if (ConditionPassed(opcode)) 10217 { 10218 uint32_t t; 10219 uint32_t t2; 10220 uint32_t n; 10221 uint32_t imm32; 10222 bool index; 10223 bool add; 10224 bool wback; 10225 10226 switch (encoding) 10227 { 10228 case eEncodingT1: 10229 //if P == '0' && W == '0' then SEE 'Related encodings'; 10230 //if Rn == '1111' then SEE LDRD (literal); 10231 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 10232 t = Bits32 (opcode, 15, 12); 10233 t2 = Bits32 (opcode, 11, 8); 10234 n = Bits32 (opcode, 19, 16); 10235 imm32 = Bits32 (opcode, 7, 0) << 2; 10236 10237 //index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10238 index = BitIsSet (opcode, 24); 10239 add = BitIsSet (opcode, 23); 10240 wback = BitIsSet (opcode, 21); 10241 10242 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10243 if (wback && ((n == t) || (n == t2))) 10244 return false; 10245 10246 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10247 if (BadReg (t) || BadReg (t2) || (t == t2)) 10248 return false; 10249 10250 break; 10251 10252 case eEncodingA1: 10253 //if Rn == '1111' then SEE LDRD (literal); 10254 //if Rt<0> == '1' then UNPREDICTABLE; 10255 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10256 t = Bits32 (opcode, 15, 12); 10257 if (BitIsSet (t, 0)) 10258 return false; 10259 t2 = t + 1; 10260 n = Bits32 (opcode, 19, 16); 10261 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10262 10263 //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10264 index = BitIsSet (opcode, 24); 10265 add = BitIsSet (opcode, 23); 10266 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10267 10268 //if P == '0' && W == '1' then UNPREDICTABLE; 10269 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10270 return false; 10271 10272 //if wback && (n == t || n == t2) then UNPREDICTABLE; 10273 if (wback && ((n == t) || (n == t2))) 10274 return false; 10275 10276 //if t2 == 15 then UNPREDICTABLE; 10277 if (t2 == 15) 10278 return false; 10279 10280 break; 10281 10282 default: 10283 return false; 10284 } 10285 10286 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10287 uint32_t Rn = ReadCoreReg (n, &success); 10288 if (!success) 10289 return false; 10290 10291 addr_t offset_addr; 10292 if (add) 10293 offset_addr = Rn + imm32; 10294 else 10295 offset_addr = Rn - imm32; 10296 10297 //address = if index then offset_addr else R[n]; 10298 addr_t address; 10299 if (index) 10300 address = offset_addr; 10301 else 10302 address = Rn; 10303 10304 //R[t] = MemA[address,4]; 10305 RegisterInfo base_reg; 10306 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10307 10308 EmulateInstruction::Context context; 10309 if (n == 13) 10310 context.type = eContextPopRegisterOffStack; 10311 else 10312 context.type = eContextRegisterLoad; 10313 context.SetAddress(address); 10314 10315 const uint32_t addr_byte_size = GetAddressByteSize(); 10316 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10317 if (!success) 10318 return false; 10319 10320 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10321 return false; 10322 10323 //R[t2] = MemA[address+4,4]; 10324 context.SetAddress(address + 4); 10325 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10326 if (!success) 10327 return false; 10328 10329 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10330 return false; 10331 10332 //if wback then R[n] = offset_addr; 10333 if (wback) 10334 { 10335 context.type = eContextAdjustBaseRegister; 10336 context.SetAddress (offset_addr); 10337 10338 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10339 return false; 10340 } 10341 } 10342 return true; 10343 } 10344 10345 // A8.6.68 LDRD (register) 10346 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two 10347 // words from memory, and writes them to two registers. It can use offset, post-indexed or pre-indexed addressing. 10348 bool 10349 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding) 10350 { 10351 #if 0 10352 if ConditionPassed() then 10353 EncodingSpecificOperations(); 10354 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10355 address = if index then offset_addr else R[n]; 10356 R[t] = MemA[address,4]; 10357 R[t2] = MemA[address+4,4]; 10358 if wback then R[n] = offset_addr; 10359 #endif 10360 10361 bool success = false; 10362 10363 if (ConditionPassed(opcode)) 10364 { 10365 uint32_t t; 10366 uint32_t t2; 10367 uint32_t n; 10368 uint32_t m; 10369 bool index; 10370 bool add; 10371 bool wback; 10372 10373 switch (encoding) 10374 { 10375 case eEncodingA1: 10376 // if Rt<0> == '1' then UNPREDICTABLE; 10377 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10378 t = Bits32 (opcode, 15, 12); 10379 if (BitIsSet (t, 0)) 10380 return false; 10381 t2 = t + 1; 10382 n = Bits32 (opcode, 19, 16); 10383 m = Bits32 (opcode, 3, 0); 10384 10385 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10386 index = BitIsSet (opcode, 24); 10387 add = BitIsSet (opcode, 23); 10388 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10389 10390 // if P == '0' && W == '1' then UNPREDICTABLE; 10391 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10392 return false; 10393 10394 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10395 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10396 return false; 10397 10398 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10399 if (wback && ((n == 15) || (n == t) || (n == t2))) 10400 return false; 10401 10402 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10403 if ((ArchVersion() < 6) && wback && (m == n)) 10404 return false; 10405 break; 10406 10407 default: 10408 return false; 10409 } 10410 10411 uint32_t Rn = ReadCoreReg (n, &success); 10412 if (!success) 10413 return false; 10414 RegisterInfo base_reg; 10415 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10416 10417 uint32_t Rm = ReadCoreReg (m, &success); 10418 if (!success) 10419 return false; 10420 RegisterInfo offset_reg; 10421 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10422 10423 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10424 addr_t offset_addr; 10425 if (add) 10426 offset_addr = Rn + Rm; 10427 else 10428 offset_addr = Rn - Rm; 10429 10430 // address = if index then offset_addr else R[n]; 10431 addr_t address; 10432 if (index) 10433 address = offset_addr; 10434 else 10435 address = Rn; 10436 10437 EmulateInstruction::Context context; 10438 if (n == 13) 10439 context.type = eContextPopRegisterOffStack; 10440 else 10441 context.type = eContextRegisterLoad; 10442 context.SetAddress(address); 10443 10444 // R[t] = MemA[address,4]; 10445 const uint32_t addr_byte_size = GetAddressByteSize(); 10446 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10447 if (!success) 10448 return false; 10449 10450 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10451 return false; 10452 10453 // R[t2] = MemA[address+4,4]; 10454 10455 data = MemARead (context, address + 4, addr_byte_size, 0, &success); 10456 if (!success) 10457 return false; 10458 10459 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data)) 10460 return false; 10461 10462 // if wback then R[n] = offset_addr; 10463 if (wback) 10464 { 10465 context.type = eContextAdjustBaseRegister; 10466 context.SetAddress (offset_addr); 10467 10468 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10469 return false; 10470 } 10471 } 10472 return true; 10473 } 10474 10475 // A8.6.200 STRD (immediate) 10476 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and 10477 // stores two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. 10478 bool 10479 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding) 10480 { 10481 #if 0 10482 if ConditionPassed() then 10483 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10484 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10485 address = if index then offset_addr else R[n]; 10486 MemA[address,4] = R[t]; 10487 MemA[address+4,4] = R[t2]; 10488 if wback then R[n] = offset_addr; 10489 #endif 10490 10491 bool success = false; 10492 10493 if (ConditionPassed(opcode)) 10494 { 10495 uint32_t t; 10496 uint32_t t2; 10497 uint32_t n; 10498 uint32_t imm32; 10499 bool index; 10500 bool add; 10501 bool wback; 10502 10503 switch (encoding) 10504 { 10505 case eEncodingT1: 10506 // if P == '0' && W == '0' then SEE 'Related encodings'; 10507 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 10508 t = Bits32 (opcode, 15, 12); 10509 t2 = Bits32 (opcode, 11, 8); 10510 n = Bits32 (opcode, 19, 16); 10511 imm32 = Bits32 (opcode, 7, 0) << 2; 10512 10513 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10514 index = BitIsSet (opcode, 24); 10515 add = BitIsSet (opcode, 23); 10516 wback = BitIsSet (opcode, 21); 10517 10518 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10519 if (wback && ((n == t) || (n == t2))) 10520 return false; 10521 10522 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10523 if ((n == 15) || BadReg (t) || BadReg (t2)) 10524 return false; 10525 10526 break; 10527 10528 case eEncodingA1: 10529 // if Rt<0> == '1' then UNPREDICTABLE; 10530 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 10531 t = Bits32 (opcode, 15, 12); 10532 if (BitIsSet (t, 0)) 10533 return false; 10534 10535 t2 = t + 1; 10536 n = Bits32 (opcode, 19, 16); 10537 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0); 10538 10539 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10540 index = BitIsSet (opcode, 24); 10541 add = BitIsSet (opcode, 23); 10542 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10543 10544 // if P == '0' && W == '1' then UNPREDICTABLE; 10545 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10546 return false; 10547 10548 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10549 if (wback && ((n == 15) || (n == t) || (n == t2))) 10550 return false; 10551 10552 // if t2 == 15 then UNPREDICTABLE; 10553 if (t2 == 15) 10554 return false; 10555 10556 break; 10557 10558 default: 10559 return false; 10560 } 10561 10562 RegisterInfo base_reg; 10563 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10564 10565 uint32_t Rn = ReadCoreReg (n, &success); 10566 if (!success) 10567 return false; 10568 10569 //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10570 addr_t offset_addr; 10571 if (add) 10572 offset_addr = Rn + imm32; 10573 else 10574 offset_addr = Rn - imm32; 10575 10576 //address = if index then offset_addr else R[n]; 10577 addr_t address; 10578 if (index) 10579 address = offset_addr; 10580 else 10581 address = Rn; 10582 10583 //MemA[address,4] = R[t]; 10584 RegisterInfo data_reg; 10585 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10586 10587 uint32_t data = ReadCoreReg (t, &success); 10588 if (!success) 10589 return false; 10590 10591 EmulateInstruction::Context context; 10592 if (n == 13) 10593 context.type = eContextPushRegisterOnStack; 10594 else 10595 context.type = eContextRegisterStore; 10596 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 10597 10598 const uint32_t addr_byte_size = GetAddressByteSize(); 10599 10600 if (!MemAWrite (context, address, data, addr_byte_size)) 10601 return false; 10602 10603 //MemA[address+4,4] = R[t2]; 10604 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10605 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 10606 10607 data = ReadCoreReg (t2, &success); 10608 if (!success) 10609 return false; 10610 10611 if (!MemAWrite (context, address + 4, data, addr_byte_size)) 10612 return false; 10613 10614 //if wback then R[n] = offset_addr; 10615 if (wback) 10616 { 10617 context.type = eContextAdjustBaseRegister; 10618 context.SetAddress (offset_addr); 10619 10620 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10621 return false; 10622 } 10623 } 10624 return true; 10625 } 10626 10627 10628 // A8.6.201 STRD (register) 10629 bool 10630 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding) 10631 { 10632 #if 0 10633 if ConditionPassed() then 10634 EncodingSpecificOperations(); 10635 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10636 address = if index then offset_addr else R[n]; 10637 MemA[address,4] = R[t]; 10638 MemA[address+4,4] = R[t2]; 10639 if wback then R[n] = offset_addr; 10640 #endif 10641 10642 bool success = false; 10643 10644 if (ConditionPassed(opcode)) 10645 { 10646 uint32_t t; 10647 uint32_t t2; 10648 uint32_t n; 10649 uint32_t m; 10650 bool index; 10651 bool add; 10652 bool wback; 10653 10654 switch (encoding) 10655 { 10656 case eEncodingA1: 10657 // if Rt<0> == '1' then UNPREDICTABLE; 10658 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10659 t = Bits32 (opcode, 15, 12); 10660 if (BitIsSet (t, 0)) 10661 return false; 10662 10663 t2 = t+1; 10664 n = Bits32 (opcode, 19, 16); 10665 m = Bits32 (opcode, 3, 0); 10666 10667 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10668 index = BitIsSet (opcode, 24); 10669 add = BitIsSet (opcode, 23); 10670 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21); 10671 10672 // if P == '0' && W == '1' then UNPREDICTABLE; 10673 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21)) 10674 return false; 10675 10676 // if t2 == 15 || m == 15 then UNPREDICTABLE; 10677 if ((t2 == 15) || (m == 15)) 10678 return false; 10679 10680 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10681 if (wback && ((n == 15) || (n == t) || (n == t2))) 10682 return false; 10683 10684 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10685 if ((ArchVersion() < 6) && wback && (m == n)) 10686 return false; 10687 10688 break; 10689 10690 default: 10691 return false; 10692 } 10693 10694 RegisterInfo base_reg; 10695 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10696 RegisterInfo offset_reg; 10697 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10698 RegisterInfo data_reg; 10699 10700 uint32_t Rn = ReadCoreReg (n, &success); 10701 if (!success) 10702 return false; 10703 10704 uint32_t Rm = ReadCoreReg (m, &success); 10705 if (!success) 10706 return false; 10707 10708 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10709 addr_t offset_addr; 10710 if (add) 10711 offset_addr = Rn + Rm; 10712 else 10713 offset_addr = Rn - Rm; 10714 10715 // address = if index then offset_addr else R[n]; 10716 addr_t address; 10717 if (index) 10718 address = offset_addr; 10719 else 10720 address = Rn; 10721 // MemA[address,4] = R[t]; 10722 uint32_t Rt = ReadCoreReg (t, &success); 10723 if (!success) 10724 return false; 10725 10726 EmulateInstruction::Context context; 10727 if (t == 13) 10728 context.type = eContextPushRegisterOnStack; 10729 else 10730 context.type = eContextRegisterStore; 10731 10732 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10733 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10734 10735 const uint32_t addr_byte_size = GetAddressByteSize(); 10736 10737 if (!MemAWrite (context, address, Rt, addr_byte_size)) 10738 return false; 10739 10740 // MemA[address+4,4] = R[t2]; 10741 uint32_t Rt2 = ReadCoreReg (t2, &success); 10742 if (!success) 10743 return false; 10744 10745 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 10746 10747 context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg); 10748 10749 if (!MemAWrite (context, address + 4, Rt2, addr_byte_size)) 10750 return false; 10751 10752 // if wback then R[n] = offset_addr; 10753 if (wback) 10754 { 10755 context.type = eContextAdjustBaseRegister; 10756 context.SetAddress (offset_addr); 10757 10758 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr)) 10759 return false; 10760 10761 } 10762 } 10763 return true; 10764 } 10765 10766 // A8.6.319 VLDM 10767 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from 10768 // an ARM core register. 10769 bool 10770 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding) 10771 { 10772 #if 0 10773 if ConditionPassed() then 10774 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10775 address = if add then R[n] else R[n]-imm32; 10776 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10777 for r = 0 to regs-1 10778 if single_regs then 10779 S[d+r] = MemA[address,4]; address = address+4; 10780 else 10781 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10782 // Combine the word-aligned words in the correct order for current endianness. 10783 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10784 #endif 10785 10786 bool success = false; 10787 10788 if (ConditionPassed(opcode)) 10789 { 10790 bool single_regs; 10791 bool add; 10792 bool wback; 10793 uint32_t d; 10794 uint32_t n; 10795 uint32_t imm32; 10796 uint32_t regs; 10797 10798 switch (encoding) 10799 { 10800 case eEncodingT1: 10801 case eEncodingA1: 10802 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10803 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 10804 // if P == '1' && W == '0' then SEE VLDR; 10805 // if P == U && W == '1' then UNDEFINED; 10806 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10807 return false; 10808 10809 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10810 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 10811 single_regs = false; 10812 add = BitIsSet (opcode, 23); 10813 wback = BitIsSet (opcode, 21); 10814 10815 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 10816 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 10817 n = Bits32 (opcode, 19, 16); 10818 imm32 = Bits32 (opcode, 7, 0) << 2; 10819 10820 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 10821 regs = Bits32 (opcode, 7, 0) / 2; 10822 10823 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10824 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 10825 return false; 10826 10827 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 10828 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 10829 return false; 10830 10831 break; 10832 10833 case eEncodingT2: 10834 case eEncodingA2: 10835 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10836 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 10837 // if P == '1' && W == '0' then SEE VLDR; 10838 // if P == U && W == '1' then UNDEFINED; 10839 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10840 return false; 10841 10842 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 10843 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); 10844 single_regs = true; 10845 add = BitIsSet (opcode, 23); 10846 wback = BitIsSet (opcode, 21); 10847 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 10848 n = Bits32 (opcode, 19, 16); 10849 10850 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 10851 imm32 = Bits32 (opcode, 7, 0) << 2; 10852 regs = Bits32 (opcode, 7, 0); 10853 10854 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 10855 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 10856 return false; 10857 10858 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 10859 if ((regs == 0) || ((d + regs) > 32)) 10860 return false; 10861 break; 10862 10863 default: 10864 return false; 10865 } 10866 10867 RegisterInfo base_reg; 10868 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10869 10870 uint32_t Rn = ReadCoreReg (n, &success); 10871 if (!success) 10872 return false; 10873 10874 // address = if add then R[n] else R[n]-imm32; 10875 addr_t address; 10876 if (add) 10877 address = Rn; 10878 else 10879 address = Rn - imm32; 10880 10881 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10882 EmulateInstruction::Context context; 10883 10884 if (wback) 10885 { 10886 uint32_t value; 10887 if (add) 10888 value = Rn + imm32; 10889 else 10890 value = Rn - imm32; 10891 10892 context.type = eContextAdjustBaseRegister; 10893 context.SetImmediateSigned (value - Rn); 10894 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 10895 return false; 10896 10897 } 10898 10899 const uint32_t addr_byte_size = GetAddressByteSize(); 10900 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 10901 10902 context.type = eContextRegisterLoad; 10903 10904 // for r = 0 to regs-1 10905 for (uint32_t r = 0; r < regs; ++r) 10906 { 10907 if (single_regs) 10908 { 10909 // S[d+r] = MemA[address,4]; address = address+4; 10910 context.SetRegisterPlusOffset (base_reg, address - Rn); 10911 10912 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 10913 if (!success) 10914 return false; 10915 10916 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10917 return false; 10918 10919 address = address + 4; 10920 } 10921 else 10922 { 10923 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 10924 context.SetRegisterPlusOffset (base_reg, address - Rn); 10925 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 10926 if (!success) 10927 return false; 10928 10929 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn); 10930 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 10931 if (!success) 10932 return false; 10933 10934 address = address + 8; 10935 // // Combine the word-aligned words in the correct order for current endianness. 10936 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 10937 uint64_t data; 10938 if (GetByteOrder() == eByteOrderBig) 10939 { 10940 data = word1; 10941 data = (data << 32) | word2; 10942 } 10943 else 10944 { 10945 data = word2; 10946 data = (data << 32) | word1; 10947 } 10948 10949 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data)) 10950 return false; 10951 } 10952 } 10953 } 10954 return true; 10955 } 10956 10957 // A8.6.399 VSTM 10958 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an 10959 // ARM core register. 10960 bool 10961 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding) 10962 { 10963 #if 0 10964 if ConditionPassed() then 10965 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 10966 address = if add then R[n] else R[n]-imm32; 10967 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 10968 for r = 0 to regs-1 10969 if single_regs then 10970 MemA[address,4] = S[d+r]; address = address+4; 10971 else 10972 // Store as two word-aligned words in the correct order for current endianness. 10973 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 10974 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 10975 address = address+8; 10976 #endif 10977 10978 bool success = false; 10979 10980 if (ConditionPassed (opcode)) 10981 { 10982 bool single_regs; 10983 bool add; 10984 bool wback; 10985 uint32_t d; 10986 uint32_t n; 10987 uint32_t imm32; 10988 uint32_t regs; 10989 10990 switch (encoding) 10991 { 10992 case eEncodingT1: 10993 case eEncodingA1: 10994 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 10995 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 10996 // if P == '1' && W == '0' then SEE VSTR; 10997 // if P == U && W == '1' then UNDEFINED; 10998 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 10999 return false; 11000 11001 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 11002 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11003 single_regs = false; 11004 add = BitIsSet (opcode, 23); 11005 wback = BitIsSet (opcode, 21); 11006 11007 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11008 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11009 n = Bits32 (opcode, 19, 16); 11010 imm32 = Bits32 (opcode, 7, 0) << 2; 11011 11012 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11013 regs = Bits32 (opcode, 7, 0) / 2; 11014 11015 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 11016 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11017 return false; 11018 11019 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11020 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11021 return false; 11022 11023 break; 11024 11025 case eEncodingT2: 11026 case eEncodingA2: 11027 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11028 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11029 // if P == '1' && W == '0' then SEE VSTR; 11030 // if P == U && W == '1' then UNDEFINED; 11031 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21)) 11032 return false; 11033 11034 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !) 11035 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn); 11036 single_regs = true; 11037 add = BitIsSet (opcode, 23); 11038 wback = BitIsSet (opcode, 21); 11039 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11040 n = Bits32 (opcode, 19, 16); 11041 11042 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11043 imm32 = Bits32 (opcode, 7, 0) << 2; 11044 regs = Bits32 (opcode, 7, 0); 11045 11046 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE; 11047 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM))) 11048 return false; 11049 11050 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11051 if ((regs == 0) || ((d + regs) > 32)) 11052 return false; 11053 11054 break; 11055 11056 default: 11057 return false; 11058 } 11059 11060 RegisterInfo base_reg; 11061 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11062 11063 uint32_t Rn = ReadCoreReg (n, &success); 11064 if (!success) 11065 return false; 11066 11067 // address = if add then R[n] else R[n]-imm32; 11068 addr_t address; 11069 if (add) 11070 address = Rn; 11071 else 11072 address = Rn - imm32; 11073 11074 EmulateInstruction::Context context; 11075 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11076 if (wback) 11077 { 11078 uint32_t value; 11079 if (add) 11080 value = Rn + imm32; 11081 else 11082 value = Rn - imm32; 11083 11084 context.type = eContextAdjustBaseRegister; 11085 context.SetRegisterPlusOffset (base_reg, value - Rn); 11086 11087 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11088 return false; 11089 } 11090 11091 const uint32_t addr_byte_size = GetAddressByteSize(); 11092 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11093 11094 context.type = eContextRegisterStore; 11095 // for r = 0 to regs-1 11096 for (uint32_t r = 0; r < regs; ++r) 11097 { 11098 11099 if (single_regs) 11100 { 11101 // MemA[address,4] = S[d+r]; address = address+4; 11102 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 11103 if (!success) 11104 return false; 11105 11106 RegisterInfo data_reg; 11107 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11108 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11109 if (!MemAWrite (context, address, data, addr_byte_size)) 11110 return false; 11111 11112 address = address + 4; 11113 } 11114 else 11115 { 11116 // // Store as two word-aligned words in the correct order for current endianness. 11117 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11118 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11119 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success); 11120 if (!success) 11121 return false; 11122 11123 RegisterInfo data_reg; 11124 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg); 11125 11126 if (GetByteOrder() == eByteOrderBig) 11127 { 11128 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11129 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11130 return false; 11131 11132 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11133 if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size)) 11134 return false; 11135 } 11136 else 11137 { 11138 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11139 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11140 return false; 11141 11142 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11143 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11144 return false; 11145 } 11146 // address = address+8; 11147 address = address + 8; 11148 } 11149 } 11150 } 11151 return true; 11152 } 11153 11154 // A8.6.320 11155 // This instruction loads a single extension register from memory, using an address from an ARM core register, with 11156 // an optional offset. 11157 bool 11158 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding) 11159 { 11160 #if 0 11161 if ConditionPassed() then 11162 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11163 base = if n == 15 then Align(PC,4) else R[n]; 11164 address = if add then (base + imm32) else (base - imm32); 11165 if single_reg then 11166 S[d] = MemA[address,4]; 11167 else 11168 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11169 // Combine the word-aligned words in the correct order for current endianness. 11170 D[d] = if BigEndian() then word1:word2 else word2:word1; 11171 #endif 11172 11173 bool success = false; 11174 11175 if (ConditionPassed (opcode)) 11176 { 11177 bool single_reg; 11178 bool add; 11179 uint32_t imm32; 11180 uint32_t d; 11181 uint32_t n; 11182 11183 switch (encoding) 11184 { 11185 case eEncodingT1: 11186 case eEncodingA1: 11187 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11188 single_reg = false; 11189 add = BitIsSet (opcode, 23); 11190 imm32 = Bits32 (opcode, 7, 0) << 2; 11191 11192 // d = UInt(D:Vd); n = UInt(Rn); 11193 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11194 n = Bits32 (opcode, 19, 16); 11195 11196 break; 11197 11198 case eEncodingT2: 11199 case eEncodingA2: 11200 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11201 single_reg = true; 11202 add = BitIsSet (opcode, 23); 11203 imm32 = Bits32 (opcode, 7, 0) << 2; 11204 11205 // d = UInt(Vd:D); n = UInt(Rn); 11206 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11207 n = Bits32 (opcode, 19, 16); 11208 11209 break; 11210 11211 default: 11212 return false; 11213 } 11214 RegisterInfo base_reg; 11215 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11216 11217 uint32_t Rn = ReadCoreReg (n, &success); 11218 if (!success) 11219 return false; 11220 11221 // base = if n == 15 then Align(PC,4) else R[n]; 11222 uint32_t base; 11223 if (n == 15) 11224 base = AlignPC (Rn); 11225 else 11226 base = Rn; 11227 11228 // address = if add then (base + imm32) else (base - imm32); 11229 addr_t address; 11230 if (add) 11231 address = base + imm32; 11232 else 11233 address = base - imm32; 11234 11235 const uint32_t addr_byte_size = GetAddressByteSize(); 11236 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11237 11238 EmulateInstruction::Context context; 11239 context.type = eContextRegisterLoad; 11240 context.SetRegisterPlusOffset (base_reg, address - base); 11241 11242 if (single_reg) 11243 { 11244 // S[d] = MemA[address,4]; 11245 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success); 11246 if (!success) 11247 return false; 11248 11249 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data)) 11250 return false; 11251 } 11252 else 11253 { 11254 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11255 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success); 11256 if (!success) 11257 return false; 11258 11259 context.SetRegisterPlusOffset (base_reg, (address + 4) - base); 11260 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success); 11261 if (!success) 11262 return false; 11263 // // Combine the word-aligned words in the correct order for current endianness. 11264 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11265 uint64_t data64; 11266 if (GetByteOrder() == eByteOrderBig) 11267 { 11268 data64 = word1; 11269 data64 = (data64 << 32) | word2; 11270 } 11271 else 11272 { 11273 data64 = word2; 11274 data64 = (data64 << 32) | word1; 11275 } 11276 11277 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64)) 11278 return false; 11279 } 11280 } 11281 return true; 11282 } 11283 11284 // A8.6.400 VSTR 11285 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an 11286 // optional offset. 11287 bool 11288 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding) 11289 { 11290 #if 0 11291 if ConditionPassed() then 11292 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11293 address = if add then (R[n] + imm32) else (R[n] - imm32); 11294 if single_reg then 11295 MemA[address,4] = S[d]; 11296 else 11297 // Store as two word-aligned words in the correct order for current endianness. 11298 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11299 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11300 #endif 11301 11302 bool success = false; 11303 11304 if (ConditionPassed (opcode)) 11305 { 11306 bool single_reg; 11307 bool add; 11308 uint32_t imm32; 11309 uint32_t d; 11310 uint32_t n; 11311 11312 switch (encoding) 11313 { 11314 case eEncodingT1: 11315 case eEncodingA1: 11316 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11317 single_reg = false; 11318 add = BitIsSet (opcode, 23); 11319 imm32 = Bits32 (opcode, 7, 0) << 2; 11320 11321 // d = UInt(D:Vd); n = UInt(Rn); 11322 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11323 n = Bits32 (opcode, 19, 16); 11324 11325 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11326 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11327 return false; 11328 11329 break; 11330 11331 case eEncodingT2: 11332 case eEncodingA2: 11333 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11334 single_reg = true; 11335 add = BitIsSet (opcode, 23); 11336 imm32 = Bits32 (opcode, 7, 0) << 2; 11337 11338 // d = UInt(Vd:D); n = UInt(Rn); 11339 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22); 11340 n = Bits32 (opcode, 19, 16); 11341 11342 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11343 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11344 return false; 11345 11346 break; 11347 11348 default: 11349 return false; 11350 } 11351 11352 RegisterInfo base_reg; 11353 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11354 11355 uint32_t Rn = ReadCoreReg (n, &success); 11356 if (!success) 11357 return false; 11358 11359 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11360 addr_t address; 11361 if (add) 11362 address = Rn + imm32; 11363 else 11364 address = Rn - imm32; 11365 11366 const uint32_t addr_byte_size = GetAddressByteSize(); 11367 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11368 11369 RegisterInfo data_reg; 11370 GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg); 11371 EmulateInstruction::Context context; 11372 context.type = eContextRegisterStore; 11373 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11374 11375 if (single_reg) 11376 { 11377 // MemA[address,4] = S[d]; 11378 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11379 if (!success) 11380 return false; 11381 11382 if (!MemAWrite (context, address, data, addr_byte_size)) 11383 return false; 11384 } 11385 else 11386 { 11387 // // Store as two word-aligned words in the correct order for current endianness. 11388 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11389 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11390 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success); 11391 if (!success) 11392 return false; 11393 11394 if (GetByteOrder() == eByteOrderBig) 11395 { 11396 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size)) 11397 return false; 11398 11399 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11400 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size)) 11401 return false; 11402 } 11403 else 11404 { 11405 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size)) 11406 return false; 11407 11408 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn); 11409 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size)) 11410 return false; 11411 } 11412 } 11413 } 11414 return true; 11415 } 11416 11417 // A8.6.307 VLDI1 (multiple single elements) 11418 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving. Every 11419 // element of each register is loaded. 11420 bool 11421 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding) 11422 { 11423 #if 0 11424 if ConditionPassed() then 11425 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11426 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11427 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11428 for r = 0 to regs-1 11429 for e = 0 to elements-1 11430 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11431 address = address + ebytes; 11432 #endif 11433 11434 bool success = false; 11435 11436 if (ConditionPassed (opcode)) 11437 { 11438 uint32_t regs; 11439 uint32_t alignment; 11440 uint32_t ebytes; 11441 uint32_t esize; 11442 uint32_t elements; 11443 uint32_t d; 11444 uint32_t n; 11445 uint32_t m; 11446 bool wback; 11447 bool register_index; 11448 11449 switch (encoding) 11450 { 11451 case eEncodingT1: 11452 case eEncodingA1: 11453 { 11454 // case type of 11455 // when '0111' 11456 // regs = 1; if align<1> == '1' then UNDEFINED; 11457 // when '1010' 11458 // regs = 2; if align == '11' then UNDEFINED; 11459 // when '0110' 11460 // regs = 3; if align<1> == '1' then UNDEFINED; 11461 // when '0010' 11462 // regs = 4; 11463 // otherwise 11464 // SEE 'Related encodings'; 11465 uint32_t type = Bits32 (opcode, 11, 8); 11466 uint32_t align = Bits32 (opcode, 5, 4); 11467 if (type == 7) // '0111' 11468 { 11469 regs = 1; 11470 if (BitIsSet (align, 1)) 11471 return false; 11472 } 11473 else if (type == 10) // '1010' 11474 { 11475 regs = 2; 11476 if (align == 3) 11477 return false; 11478 11479 } 11480 else if (type == 6) // '0110' 11481 { 11482 regs = 3; 11483 if (BitIsSet (align, 1)) 11484 return false; 11485 } 11486 else if (type == 2) // '0010' 11487 { 11488 regs = 4; 11489 } 11490 else 11491 return false; 11492 11493 // alignment = if align == '00' then 1 else 4 << UInt(align); 11494 if (align == 0) 11495 alignment = 1; 11496 else 11497 alignment = 4 << align; 11498 11499 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11500 ebytes = 1 << Bits32 (opcode, 7, 6); 11501 esize = 8 * ebytes; 11502 elements = 8 / ebytes; 11503 11504 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11505 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11506 n = Bits32 (opcode, 19, 15); 11507 m = Bits32 (opcode, 3, 0); 11508 11509 // wback = (m != 15); register_index = (m != 15 && m != 13); 11510 wback = (m != 15); 11511 register_index = ((m != 15) && (m != 13)); 11512 11513 // if d+regs > 32 then UNPREDICTABLE; 11514 if ((d + regs) > 32) 11515 return false; 11516 } 11517 break; 11518 11519 default: 11520 return false; 11521 } 11522 11523 RegisterInfo base_reg; 11524 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11525 11526 uint32_t Rn = ReadCoreReg (n, &success); 11527 if (!success) 11528 return false; 11529 11530 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11531 addr_t address = Rn; 11532 if ((address % alignment) != 0) 11533 return false; 11534 11535 EmulateInstruction::Context context; 11536 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11537 if (wback) 11538 { 11539 uint32_t Rm = ReadCoreReg (m, &success); 11540 if (!success) 11541 return false; 11542 11543 uint32_t offset; 11544 if (register_index) 11545 offset = Rm; 11546 else 11547 offset = 8 * regs; 11548 11549 uint32_t value = Rn + offset; 11550 context.type = eContextAdjustBaseRegister; 11551 context.SetRegisterPlusOffset (base_reg, offset); 11552 11553 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11554 return false; 11555 11556 } 11557 11558 // for r = 0 to regs-1 11559 for (uint32_t r = 0; r < regs; ++r) 11560 { 11561 // for e = 0 to elements-1 11562 uint64_t assembled_data = 0; 11563 for (uint32_t e = 0; e < elements; ++e) 11564 { 11565 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11566 context.type = eContextRegisterLoad; 11567 context.SetRegisterPlusOffset (base_reg, address - Rn); 11568 uint64_t data = MemURead (context, address, ebytes, 0, &success); 11569 if (!success) 11570 return false; 11571 11572 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data 11573 11574 // address = address + ebytes; 11575 address = address + ebytes; 11576 } 11577 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data)) 11578 return false; 11579 } 11580 } 11581 return true; 11582 } 11583 11584 // A8.6.308 VLD1 (single element to one lane) 11585 // 11586 bool 11587 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding) 11588 { 11589 #if 0 11590 if ConditionPassed() then 11591 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11592 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11593 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11594 Elem[D[d],index,esize] = MemU[address,ebytes]; 11595 #endif 11596 11597 bool success = false; 11598 11599 if (ConditionPassed (opcode)) 11600 { 11601 uint32_t ebytes; 11602 uint32_t esize; 11603 uint32_t index; 11604 uint32_t alignment; 11605 uint32_t d; 11606 uint32_t n; 11607 uint32_t m; 11608 bool wback; 11609 bool register_index; 11610 11611 switch (encoding) 11612 { 11613 case eEncodingT1: 11614 case eEncodingA1: 11615 { 11616 uint32_t size = Bits32 (opcode, 11, 10); 11617 uint32_t index_align = Bits32 (opcode, 7, 4); 11618 // if size == '11' then SEE VLD1 (single element to all lanes); 11619 if (size == 3) 11620 return EmulateVLD1SingleAll (opcode, encoding); 11621 // case size of 11622 if (size == 0) // when '00' 11623 { 11624 // if index_align<0> != '0' then UNDEFINED; 11625 if (BitIsClear (index_align, 0)) 11626 return false; 11627 11628 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11629 ebytes = 1; 11630 esize = 8; 11631 index = Bits32 (index_align, 3, 1); 11632 alignment = 1; 11633 } 11634 else if (size == 1) // when '01' 11635 { 11636 // if index_align<1> != '0' then UNDEFINED; 11637 if (BitIsClear (index_align, 1)) 11638 return false; 11639 11640 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11641 ebytes = 2; 11642 esize = 16; 11643 index = Bits32 (index_align, 3, 2); 11644 11645 // alignment = if index_align<0> == '0' then 1 else 2; 11646 if (BitIsClear (index_align, 0)) 11647 alignment = 1; 11648 else 11649 alignment = 2; 11650 } 11651 else if (size == 2) // when '10' 11652 { 11653 // if index_align<2> != '0' then UNDEFINED; 11654 if (BitIsClear (index_align, 2)) 11655 return false; 11656 11657 // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED; 11658 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11659 return false; 11660 11661 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 11662 ebytes = 4; 11663 esize = 32; 11664 index = Bit32 (index_align, 3); 11665 11666 // alignment = if index_align<1:0> == '00' then 1 else 4; 11667 if (Bits32 (index_align, 1, 0) == 0) 11668 alignment = 1; 11669 else 11670 alignment = 4; 11671 } 11672 else 11673 { 11674 return false; 11675 } 11676 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11677 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11678 n = Bits32 (opcode, 19, 16); 11679 m = Bits32 (opcode, 3, 0); 11680 11681 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 11682 wback = (m != 15); 11683 register_index = ((m != 15) && (m != 13)); 11684 11685 if (n == 15) 11686 return false; 11687 11688 } 11689 break; 11690 11691 default: 11692 return false; 11693 } 11694 11695 RegisterInfo base_reg; 11696 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11697 11698 uint32_t Rn = ReadCoreReg (n, &success); 11699 if (!success) 11700 return false; 11701 11702 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11703 addr_t address = Rn; 11704 if ((address % alignment) != 0) 11705 return false; 11706 11707 EmulateInstruction::Context context; 11708 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11709 if (wback) 11710 { 11711 uint32_t Rm = ReadCoreReg (m, &success); 11712 if (!success) 11713 return false; 11714 11715 uint32_t offset; 11716 if (register_index) 11717 offset = Rm; 11718 else 11719 offset = ebytes; 11720 11721 uint32_t value = Rn + offset; 11722 11723 context.type = eContextAdjustBaseRegister; 11724 context.SetRegisterPlusOffset (base_reg, offset); 11725 11726 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value)) 11727 return false; 11728 } 11729 11730 // Elem[D[d],index,esize] = MemU[address,ebytes]; 11731 uint32_t element = MemURead (context, address, esize, 0, &success); 11732 if (!success) 11733 return false; 11734 11735 element = element << (index * esize); 11736 11737 uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 11738 if (!success) 11739 return false; 11740 11741 uint64_t all_ones = -1; 11742 uint64_t mask = all_ones << ((index+1) * esize); // mask is all 1's to left of where 'element' goes, & all 0's 11743 // at element & to the right of element. 11744 if (index > 0) 11745 mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes. 11746 // now mask should be 0's where element goes & 1's 11747 // everywhere else. 11748 11749 uint64_t masked_reg = reg_data & mask; // Take original reg value & zero out 'element' bits 11750 reg_data = masked_reg & element; // Put 'element' into those bits in reg_data. 11751 11752 context.type = eContextRegisterLoad; 11753 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data)) 11754 return false; 11755 } 11756 return true; 11757 } 11758 11759 // A8.6.391 VST1 (multiple single elements) 11760 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without 11761 // interleaving. Every element of each register is stored. 11762 bool 11763 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding) 11764 { 11765 #if 0 11766 if ConditionPassed() then 11767 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11768 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11769 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11770 for r = 0 to regs-1 11771 for e = 0 to elements-1 11772 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11773 address = address + ebytes; 11774 #endif 11775 11776 bool success = false; 11777 11778 if (ConditionPassed (opcode)) 11779 { 11780 uint32_t regs; 11781 uint32_t alignment; 11782 uint32_t ebytes; 11783 uint32_t esize; 11784 uint32_t elements; 11785 uint32_t d; 11786 uint32_t n; 11787 uint32_t m; 11788 bool wback; 11789 bool register_index; 11790 11791 switch (encoding) 11792 { 11793 case eEncodingT1: 11794 case eEncodingA1: 11795 { 11796 uint32_t type = Bits32 (opcode, 11, 8); 11797 uint32_t align = Bits32 (opcode, 5, 4); 11798 11799 // case type of 11800 if (type == 7) // when '0111' 11801 { 11802 // regs = 1; if align<1> == '1' then UNDEFINED; 11803 regs = 1; 11804 if (BitIsSet (align, 1)) 11805 return false; 11806 } 11807 else if (type == 10) // when '1010' 11808 { 11809 // regs = 2; if align == '11' then UNDEFINED; 11810 regs = 2; 11811 if (align == 3) 11812 return false; 11813 } 11814 else if (type == 6) // when '0110' 11815 { 11816 // regs = 3; if align<1> == '1' then UNDEFINED; 11817 regs = 3; 11818 if (BitIsSet (align, 1)) 11819 return false; 11820 } 11821 else if (type == 2) // when '0010' 11822 // regs = 4; 11823 regs = 4; 11824 else // otherwise 11825 // SEE 'Related encodings'; 11826 return false; 11827 11828 // alignment = if align == '00' then 1 else 4 << UInt(align); 11829 if (align == 0) 11830 alignment = 1; 11831 else 11832 alignment = 4 << align; 11833 11834 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11835 ebytes = 1 << Bits32 (opcode,7, 6); 11836 esize = 8 * ebytes; 11837 elements = 8 / ebytes; 11838 11839 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11840 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 11841 n = Bits32 (opcode, 19, 16); 11842 m = Bits32 (opcode, 3, 0); 11843 11844 // wback = (m != 15); register_index = (m != 15 && m != 13); 11845 wback = (m != 15); 11846 register_index = ((m != 15) && (m != 13)); 11847 11848 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 11849 if ((d + regs) > 32) 11850 return false; 11851 11852 if (n == 15) 11853 return false; 11854 11855 } 11856 break; 11857 11858 default: 11859 return false; 11860 } 11861 11862 RegisterInfo base_reg; 11863 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11864 11865 uint32_t Rn = ReadCoreReg (n, &success); 11866 if (!success) 11867 return false; 11868 11869 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11870 addr_t address = Rn; 11871 if ((address % alignment) != 0) 11872 return false; 11873 11874 EmulateInstruction::Context context; 11875 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11876 if (wback) 11877 { 11878 uint32_t Rm = ReadCoreReg (m, &success); 11879 if (!success) 11880 return false; 11881 11882 uint32_t offset; 11883 if (register_index) 11884 offset = Rm; 11885 else 11886 offset = 8 * regs; 11887 11888 context.type = eContextAdjustBaseRegister; 11889 context.SetRegisterPlusOffset (base_reg, offset); 11890 11891 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 11892 return false; 11893 } 11894 11895 RegisterInfo data_reg; 11896 context.type = eContextRegisterStore; 11897 // for r = 0 to regs-1 11898 for (uint32_t r = 0; r < regs; ++r) 11899 { 11900 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 11901 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 11902 if (!success) 11903 return false; 11904 11905 // for e = 0 to elements-1 11906 for (uint32_t e = 0; e < elements; ++e) 11907 { 11908 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 11909 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize); 11910 11911 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 11912 if (!MemUWrite (context, address, word, ebytes)) 11913 return false; 11914 11915 // address = address + ebytes; 11916 address = address + ebytes; 11917 } 11918 } 11919 } 11920 return true; 11921 } 11922 11923 // A8.6.392 VST1 (single element from one lane) 11924 // This instruction stores one element to memory from one element of a register. 11925 bool 11926 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding) 11927 { 11928 #if 0 11929 if ConditionPassed() then 11930 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11931 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11932 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 11933 MemU[address,ebytes] = Elem[D[d],index,esize]; 11934 #endif 11935 11936 bool success = false; 11937 11938 if (ConditionPassed (opcode)) 11939 { 11940 uint32_t ebytes; 11941 uint32_t esize; 11942 uint32_t index; 11943 uint32_t alignment; 11944 uint32_t d; 11945 uint32_t n; 11946 uint32_t m; 11947 bool wback; 11948 bool register_index; 11949 11950 switch (encoding) 11951 { 11952 case eEncodingT1: 11953 case eEncodingA1: 11954 { 11955 uint32_t size = Bits32 (opcode, 11, 10); 11956 uint32_t index_align = Bits32 (opcode, 7, 4); 11957 11958 // if size == '11' then UNDEFINED; 11959 if (size == 3) 11960 return false; 11961 11962 // case size of 11963 if (size == 0) // when '00' 11964 { 11965 // if index_align<0> != '0' then UNDEFINED; 11966 if (BitIsClear (index_align, 0)) 11967 return false; 11968 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 11969 ebytes = 1; 11970 esize = 8; 11971 index = Bits32 (index_align, 3, 1); 11972 alignment = 1; 11973 } 11974 else if (size == 1) // when '01' 11975 { 11976 // if index_align<1> != '0' then UNDEFINED; 11977 if (BitIsClear (index_align, 1)) 11978 return false; 11979 11980 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 11981 ebytes = 2; 11982 esize = 16; 11983 index = Bits32 (index_align, 3, 2); 11984 11985 // alignment = if index_align<0> == '0' then 1 else 2; 11986 if (BitIsClear (index_align, 0)) 11987 alignment = 1; 11988 else 11989 alignment = 2; 11990 } 11991 else if (size == 2) // when '10' 11992 { 11993 // if index_align<2> != '0' then UNDEFINED; 11994 if (BitIsClear (index_align, 2)) 11995 return false; 11996 11997 // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED; 11998 if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3)) 11999 return false; 12000 12001 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12002 ebytes = 4; 12003 esize = 32; 12004 index = Bit32 (index_align, 3); 12005 12006 // alignment = if index_align<1:0> == '00' then 1 else 4; 12007 if (Bits32 (index_align, 1, 0) == 0) 12008 alignment = 1; 12009 else 12010 alignment = 4; 12011 } 12012 else 12013 { 12014 return false; 12015 } 12016 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12017 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 12018 n = Bits32 (opcode, 19, 16); 12019 m = Bits32 (opcode, 3, 0); 12020 12021 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE; 12022 wback = (m != 15); 12023 register_index = ((m != 15) && (m != 13)); 12024 12025 if (n == 15) 12026 return false; 12027 } 12028 break; 12029 12030 default: 12031 return false; 12032 } 12033 12034 RegisterInfo base_reg; 12035 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12036 12037 uint32_t Rn = ReadCoreReg (n, &success); 12038 if (!success) 12039 return false; 12040 12041 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12042 addr_t address = Rn; 12043 if ((address % alignment) != 0) 12044 return false; 12045 12046 EmulateInstruction::Context context; 12047 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12048 if (wback) 12049 { 12050 uint32_t Rm = ReadCoreReg (m, &success); 12051 if (!success) 12052 return false; 12053 12054 uint32_t offset; 12055 if (register_index) 12056 offset = Rm; 12057 else 12058 offset = ebytes; 12059 12060 context.type = eContextAdjustBaseRegister; 12061 context.SetRegisterPlusOffset (base_reg, offset); 12062 12063 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12064 return false; 12065 } 12066 12067 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12068 uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12069 if (!success) 12070 return false; 12071 12072 uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1, index * esize); 12073 12074 RegisterInfo data_reg; 12075 GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12076 context.type = eContextRegisterStore; 12077 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn); 12078 12079 if (!MemUWrite (context, address, word, ebytes)) 12080 return false; 12081 } 12082 return true; 12083 } 12084 12085 // A8.6.309 VLD1 (single element to all lanes) 12086 // This instruction loads one element from memory into every element of one or two vectors. 12087 bool 12088 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding) 12089 { 12090 #if 0 12091 if ConditionPassed() then 12092 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12093 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12094 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12095 replicated_element = Replicate(MemU[address,ebytes], elements); 12096 for r = 0 to regs-1 12097 D[d+r] = replicated_element; 12098 #endif 12099 12100 bool success = false; 12101 12102 if (ConditionPassed (opcode)) 12103 { 12104 uint32_t ebytes; 12105 uint32_t elements; 12106 uint32_t regs; 12107 uint32_t alignment; 12108 uint32_t d; 12109 uint32_t n; 12110 uint32_t m; 12111 bool wback; 12112 bool register_index; 12113 12114 switch (encoding) 12115 { 12116 case eEncodingT1: 12117 case eEncodingA1: 12118 { 12119 //if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12120 uint32_t size = Bits32 (opcode, 7, 6); 12121 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4))) 12122 return false; 12123 12124 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' then 1 else 2; 12125 ebytes = 1 << size; 12126 elements = 8 / ebytes; 12127 if (BitIsClear (opcode, 5)) 12128 regs = 1; 12129 else 12130 regs = 2; 12131 12132 //alignment = if a == '0' then 1 else ebytes; 12133 if (BitIsClear (opcode, 4)) 12134 alignment = 1; 12135 else 12136 alignment = ebytes; 12137 12138 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12139 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12); 12140 n = Bits32 (opcode, 19, 16); 12141 m = Bits32 (opcode, 3, 0); 12142 12143 //wback = (m != 15); register_index = (m != 15 && m != 13); 12144 wback = (m != 15); 12145 register_index = ((m != 15) && (m != 13)); 12146 12147 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12148 if ((d + regs) > 32) 12149 return false; 12150 12151 if (n == 15) 12152 return false; 12153 } 12154 break; 12155 12156 default: 12157 return false; 12158 } 12159 12160 RegisterInfo base_reg; 12161 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12162 12163 uint32_t Rn = ReadCoreReg (n, &success); 12164 if (!success) 12165 return false; 12166 12167 // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12168 addr_t address = Rn; 12169 if ((address % alignment) != 0) 12170 return false; 12171 12172 EmulateInstruction::Context context; 12173 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12174 if (wback) 12175 { 12176 uint32_t Rm = ReadCoreReg (m, &success); 12177 if (!success) 12178 return false; 12179 12180 uint32_t offset; 12181 if (register_index) 12182 offset = Rm; 12183 else 12184 offset = ebytes; 12185 12186 context.type = eContextAdjustBaseRegister; 12187 context.SetRegisterPlusOffset (base_reg, offset); 12188 12189 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset)) 12190 return false; 12191 } 12192 12193 // replicated_element = Replicate(MemU[address,ebytes], elements); 12194 12195 context.type = eContextRegisterLoad; 12196 uint64_t word = MemURead (context, address, ebytes, 0, &success); 12197 if (!success) 12198 return false; 12199 12200 uint64_t replicated_element = 0; 12201 uint32_t esize = ebytes * 8; 12202 for (uint32_t e = 0; e < elements; ++e) 12203 replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0); 12204 12205 // for r = 0 to regs-1 12206 for (uint32_t r = 0; r < regs; ++r) 12207 { 12208 // D[d+r] = replicated_element; 12209 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element)) 12210 return false; 12211 } 12212 } 12213 return true; 12214 } 12215 12216 // B6.2.13 SUBS PC, LR and related instructions 12217 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack. It subtracts the 12218 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR. 12219 bool 12220 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding) 12221 { 12222 #if 0 12223 if ConditionPassed() then 12224 EncodingSpecificOperations(); 12225 if CurrentInstrSet() == InstrSet_ThumbEE then 12226 UNPREDICTABLE; 12227 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12228 case opcode of 12229 when '0000' result = R[n] AND operand2; // AND 12230 when '0001' result = R[n] EOR operand2; // EOR 12231 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12232 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12233 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12234 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12235 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12236 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12237 when '1100' result = R[n] OR operand2; // ORR 12238 when '1101' result = operand2; // MOV 12239 when '1110' result = R[n] AND NOT(operand2); // BIC 12240 when '1111' result = NOT(operand2); // MVN 12241 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12242 BranchWritePC(result); 12243 #endif 12244 12245 bool success = false; 12246 12247 if (ConditionPassed (opcode)) 12248 { 12249 uint32_t n; 12250 uint32_t m; 12251 uint32_t imm32; 12252 bool register_form; 12253 ARM_ShifterType shift_t; 12254 uint32_t shift_n; 12255 uint32_t code; 12256 12257 switch (encoding) 12258 { 12259 case eEncodingT1: 12260 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE 12261 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; // = SUB 12262 n = 14; 12263 imm32 = Bits32 (opcode, 7, 0); 12264 register_form = false; 12265 code = 2; 12266 12267 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12268 if (InITBlock() && !LastInITBlock()) 12269 return false; 12270 12271 break; 12272 12273 case eEncodingA1: 12274 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12275 n = Bits32 (opcode, 19, 16); 12276 imm32 = ARMExpandImm (opcode); 12277 register_form = false; 12278 code = Bits32 (opcode, 24, 21); 12279 12280 break; 12281 12282 case eEncodingA2: 12283 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12284 n = Bits32 (opcode, 19, 16); 12285 m = Bits32 (opcode, 3, 0); 12286 register_form = true; 12287 12288 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12289 shift_n = DecodeImmShiftARM (opcode, shift_t); 12290 12291 break; 12292 12293 default: 12294 return false; 12295 } 12296 12297 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12298 uint32_t operand2; 12299 if (register_form) 12300 { 12301 uint32_t Rm = ReadCoreReg (m, &success); 12302 if (!success) 12303 return false; 12304 12305 operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success); 12306 if (!success) 12307 return false; 12308 } 12309 else 12310 { 12311 operand2 = imm32; 12312 } 12313 12314 uint32_t Rn = ReadCoreReg (n, &success); 12315 if (!success) 12316 return false; 12317 12318 AddWithCarryResult result; 12319 12320 // case opcode of 12321 switch (code) 12322 { 12323 case 0: // when '0000' 12324 // result = R[n] AND operand2; // AND 12325 result.result = Rn & operand2; 12326 break; 12327 12328 case 1: // when '0001' 12329 // result = R[n] EOR operand2; // EOR 12330 result.result = Rn ^ operand2; 12331 break; 12332 12333 case 2: // when '0010' 12334 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12335 result = AddWithCarry (Rn, ~(operand2), 1); 12336 break; 12337 12338 case 3: // when '0011' 12339 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12340 result = AddWithCarry (~(Rn), operand2, 1); 12341 break; 12342 12343 case 4: // when '0100' 12344 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12345 result = AddWithCarry (Rn, operand2, 0); 12346 break; 12347 12348 case 5: // when '0101' 12349 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12350 result = AddWithCarry (Rn, operand2, APSR_C); 12351 break; 12352 12353 case 6: // when '0110' 12354 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12355 result = AddWithCarry (Rn, ~(operand2), APSR_C); 12356 break; 12357 12358 case 7: // when '0111' 12359 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12360 result = AddWithCarry (~(Rn), operand2, APSR_C); 12361 break; 12362 12363 case 10: // when '1100' 12364 // result = R[n] OR operand2; // ORR 12365 result.result = Rn | operand2; 12366 break; 12367 12368 case 11: // when '1101' 12369 // result = operand2; // MOV 12370 result.result = operand2; 12371 break; 12372 12373 case 12: // when '1110' 12374 // result = R[n] AND NOT(operand2); // BIC 12375 result.result = Rn & ~(operand2); 12376 break; 12377 12378 case 15: // when '1111' 12379 // result = NOT(operand2); // MVN 12380 result.result = ~(operand2); 12381 break; 12382 12383 default: 12384 return false; 12385 } 12386 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12387 12388 // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for 12389 // the best. 12390 uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12391 if (!success) 12392 return false; 12393 12394 CPSRWriteByInstr (spsr, 15, true); 12395 12396 // BranchWritePC(result); 12397 EmulateInstruction::Context context; 12398 context.type = eContextAdjustPC; 12399 context.SetImmediate (result.result); 12400 12401 BranchWritePC (context, result.result); 12402 } 12403 return true; 12404 } 12405 12406 EmulateInstructionARM::ARMOpcode* 12407 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12408 { 12409 static ARMOpcode 12410 g_arm_opcodes[] = 12411 { 12412 //---------------------------------------------------------------------- 12413 // Prologue instructions 12414 //---------------------------------------------------------------------- 12415 12416 // push register(s) 12417 { 0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12418 { 0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" }, 12419 12420 // set r7 to point to a stack offset 12421 { 0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" }, 12422 { 0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12423 // copy the stack pointer to ip 12424 { 0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" }, 12425 { 0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" }, 12426 { 0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12427 12428 // adjust the stack pointer 12429 { 0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12430 { 0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12431 12432 // push one register 12433 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12434 { 0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" }, 12435 12436 // vector push consecutive extension register(s) 12437 { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12438 { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12439 12440 //---------------------------------------------------------------------- 12441 // Epilogue instructions 12442 //---------------------------------------------------------------------- 12443 12444 { 0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12445 { 0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12446 { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12447 { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12448 12449 //---------------------------------------------------------------------- 12450 // Supervisor Call (previously Software Interrupt) 12451 //---------------------------------------------------------------------- 12452 { 0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12453 12454 //---------------------------------------------------------------------- 12455 // Branch instructions 12456 //---------------------------------------------------------------------- 12457 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>". 12458 { 0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12459 { 0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"}, 12460 { 0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12461 { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12462 // for example, "bx lr" 12463 { 0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12464 // bxj 12465 { 0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12466 12467 //---------------------------------------------------------------------- 12468 // Data-processing instructions 12469 //---------------------------------------------------------------------- 12470 // adc (immediate) 12471 { 0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12472 // adc (register) 12473 { 0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12474 // add (immediate) 12475 { 0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"}, 12476 // add (register) 12477 { 0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12478 // add (register-shifted register) 12479 { 0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12480 // adr 12481 { 0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12482 { 0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12483 // and (immediate) 12484 { 0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12485 // and (register) 12486 { 0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12487 // bic (immediate) 12488 { 0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12489 // bic (register) 12490 { 0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12491 // eor (immediate) 12492 { 0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12493 // eor (register) 12494 { 0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12495 // orr (immediate) 12496 { 0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12497 // orr (register) 12498 { 0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12499 // rsb (immediate) 12500 { 0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12501 // rsb (register) 12502 { 0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12503 // rsc (immediate) 12504 { 0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12505 // rsc (register) 12506 { 0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12507 // sbc (immediate) 12508 { 0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12509 // sbc (register) 12510 { 0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12511 // sub (immediate, ARM) 12512 { 0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"}, 12513 // sub (sp minus immediate) 12514 { 0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 12515 // sub (register) 12516 { 0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 12517 // teq (immediate) 12518 { 0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 12519 // teq (register) 12520 { 0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12521 // tst (immediate) 12522 { 0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 12523 // tst (register) 12524 { 0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 12525 12526 // mov (immediate) 12527 { 0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 12528 { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" }, 12529 // mov (register) 12530 { 0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 12531 // mvn (immediate) 12532 { 0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 12533 // mvn (register) 12534 { 0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 12535 // cmn (immediate) 12536 { 0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12537 // cmn (register) 12538 { 0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12539 // cmp (immediate) 12540 { 0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 12541 // cmp (register) 12542 { 0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 12543 // asr (immediate) 12544 { 0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 12545 // asr (register) 12546 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 12547 // lsl (immediate) 12548 { 0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 12549 // lsl (register) 12550 { 0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 12551 // lsr (immediate) 12552 { 0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 12553 // lsr (register) 12554 { 0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 12555 // rrx is a special case encoding of ror (immediate) 12556 { 0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 12557 // ror (immediate) 12558 { 0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 12559 // ror (register) 12560 { 0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 12561 // mul 12562 { 0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" }, 12563 12564 // subs pc, lr and related instructions 12565 { 0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" }, 12566 { 0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" }, 12567 12568 //---------------------------------------------------------------------- 12569 // Load instructions 12570 //---------------------------------------------------------------------- 12571 { 0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12572 { 0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" }, 12573 { 0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12574 { 0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" }, 12575 { 0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" }, 12576 { 0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" }, 12577 { 0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 12578 { 0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" }, 12579 { 0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12580 { 0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12581 { 0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" }, 12582 { 0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" }, 12583 { 0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12584 { 0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 12585 { 0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12586 { 0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" }, 12587 { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 12588 { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12589 { 0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12590 { 0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12591 { 0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12592 { 0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12593 { 0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12594 { 0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12595 { 0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12596 12597 //---------------------------------------------------------------------- 12598 // Store instructions 12599 //---------------------------------------------------------------------- 12600 { 0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12601 { 0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" }, 12602 { 0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12603 { 0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" }, 12604 { 0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" }, 12605 { 0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" }, 12606 { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 12607 { 0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12608 { 0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 12609 { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 12610 { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 12611 { 0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12612 { 0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 12613 { 0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 12614 { 0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 12615 { 0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12616 { 0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12617 12618 //---------------------------------------------------------------------- 12619 // Other instructions 12620 //---------------------------------------------------------------------- 12621 { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12622 { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" }, 12623 { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" }, 12624 { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" }, 12625 { 0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" } 12626 12627 }; 12628 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 12629 12630 for (size_t i=0; i<k_num_arm_opcodes; ++i) 12631 { 12632 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 12633 (g_arm_opcodes[i].variants & arm_isa) != 0) 12634 return &g_arm_opcodes[i]; 12635 } 12636 return NULL; 12637 } 12638 12639 12640 EmulateInstructionARM::ARMOpcode* 12641 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa) 12642 { 12643 12644 static ARMOpcode 12645 g_thumb_opcodes[] = 12646 { 12647 //---------------------------------------------------------------------- 12648 // Prologue instructions 12649 //---------------------------------------------------------------------- 12650 12651 // push register(s) 12652 { 0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" }, 12653 { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" }, 12654 { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" }, 12655 12656 // set r7 to point to a stack offset 12657 { 0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" }, 12658 // copy the stack pointer to r7 12659 { 0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" }, 12660 // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity) 12661 { 0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" }, 12662 12663 // PC-relative load into register (see also EmulateADDSPRm) 12664 { 0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 12665 12666 // adjust the stack pointer 12667 { 0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 12668 { 0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 12669 { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 12670 { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 12671 { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" }, 12672 12673 // vector push consecutive extension register(s) 12674 { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12675 { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12676 12677 //---------------------------------------------------------------------- 12678 // Epilogue instructions 12679 //---------------------------------------------------------------------- 12680 12681 { 0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 12682 { 0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 12683 { 0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12684 { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" }, 12685 { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" }, 12686 { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12687 { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12688 12689 //---------------------------------------------------------------------- 12690 // Supervisor Call (previously Software Interrupt) 12691 //---------------------------------------------------------------------- 12692 { 0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 12693 12694 //---------------------------------------------------------------------- 12695 // If Then makes up to four following instructions conditional. 12696 //---------------------------------------------------------------------- 12697 // The next 5 opcode _must_ come before the if then instruction 12698 { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"}, 12699 { 0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 12700 { 0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 12701 { 0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 12702 { 0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 12703 { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 12704 12705 //---------------------------------------------------------------------- 12706 // Branch instructions 12707 //---------------------------------------------------------------------- 12708 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 12709 { 0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 12710 { 0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 12711 { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 12712 { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"}, 12713 // J1 == J2 == 1 12714 { 0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12715 // J1 == J2 == 1 12716 { 0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12717 { 0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12718 // for example, "bx lr" 12719 { 0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12720 // bxj 12721 { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12722 // compare and branch 12723 { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 12724 // table branch byte 12725 { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 12726 // table branch halfword 12727 { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 12728 12729 //---------------------------------------------------------------------- 12730 // Data-processing instructions 12731 //---------------------------------------------------------------------- 12732 // adc (immediate) 12733 { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 12734 // adc (register) 12735 { 0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 12736 { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12737 // add (register) 12738 { 0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 12739 // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two. 12740 { 0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 12741 // adr 12742 { 0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12743 { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12744 { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12745 // and (immediate) 12746 { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 12747 // and (register) 12748 { 0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 12749 { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12750 // bic (immediate) 12751 { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 12752 // bic (register) 12753 { 0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 12754 { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12755 // eor (immediate) 12756 { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 12757 // eor (register) 12758 { 0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 12759 { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12760 // orr (immediate) 12761 { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 12762 // orr (register) 12763 { 0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 12764 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12765 // rsb (immediate) 12766 { 0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 12767 { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 12768 // rsb (register) 12769 { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12770 // sbc (immediate) 12771 { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12772 // sbc (register) 12773 { 0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 12774 { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 12775 // add (immediate, Thumb) 12776 { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" }, 12777 { 0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" }, 12778 { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" }, 12779 { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" }, 12780 // sub (immediate, Thumb) 12781 { 0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"}, 12782 { 0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 12783 { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 12784 { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"}, 12785 // sub (sp minus immediate) 12786 { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 12787 { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 12788 // sub (register) 12789 { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 12790 { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 12791 // teq (immediate) 12792 { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 12793 // teq (register) 12794 { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 12795 // tst (immediate) 12796 { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 12797 // tst (register) 12798 { 0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 12799 { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 12800 12801 12802 // move from high register to high register 12803 { 0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 12804 // move from low register to low register 12805 { 0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 12806 // mov{s}<c>.w <Rd>, <Rm> 12807 { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 12808 // move immediate 12809 { 0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 12810 { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 12811 { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 12812 // mvn (immediate) 12813 { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 12814 // mvn (register) 12815 { 0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 12816 { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 12817 // cmn (immediate) 12818 { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 12819 // cmn (register) 12820 { 0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 12821 { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 12822 // cmp (immediate) 12823 { 0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 12824 { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 12825 // cmp (register) (Rn and Rm both from r0-r7) 12826 { 0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12827 // cmp (register) (Rn and Rm not both from r0-r7) 12828 { 0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 12829 { 0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 12830 // asr (immediate) 12831 { 0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 12832 { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 12833 // asr (register) 12834 { 0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 12835 { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12836 // lsl (immediate) 12837 { 0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 12838 { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 12839 // lsl (register) 12840 { 0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 12841 { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12842 // lsr (immediate) 12843 { 0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 12844 { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 12845 // lsr (register) 12846 { 0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 12847 { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12848 // rrx is a special case encoding of ror (immediate) 12849 { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 12850 // ror (immediate) 12851 { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 12852 // ror (register) 12853 { 0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 12854 { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 12855 // mul 12856 { 0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" }, 12857 // mul 12858 { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" }, 12859 12860 // subs pc, lr and related instructions 12861 { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" }, 12862 12863 //---------------------------------------------------------------------- 12864 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table; 12865 // otherwise the wrong instructions will be selected. 12866 //---------------------------------------------------------------------- 12867 12868 { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" }, 12869 { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" }, 12870 12871 //---------------------------------------------------------------------- 12872 // Load instructions 12873 //---------------------------------------------------------------------- 12874 { 0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" }, 12875 { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" }, 12876 { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" }, 12877 { 0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 12878 { 0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 12879 { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 12880 { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 12881 // Thumb2 PC-relative load into register 12882 { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 12883 { 0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" }, 12884 { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" }, 12885 { 0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" }, 12886 { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12887 { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" }, 12888 { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" }, 12889 { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" }, 12890 { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12891 { 0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]" }, 12892 { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" }, 12893 { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}" }, 12894 { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" }, 12895 { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" }, 12896 { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12897 { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" }, 12898 { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12899 { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" }, 12900 { 0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" }, 12901 { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" }, 12902 { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" }, 12903 { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" }, 12904 { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" }, 12905 { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" }, 12906 { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12907 { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 12908 { 0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 12909 { 0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" }, 12910 { 0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12911 { 0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 12912 { 0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12913 { 0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 12914 { 0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12915 12916 //---------------------------------------------------------------------- 12917 // Store instructions 12918 //---------------------------------------------------------------------- 12919 { 0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" }, 12920 { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" }, 12921 { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" }, 12922 { 0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" }, 12923 { 0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" }, 12924 { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" }, 12925 { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" }, 12926 { 0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" }, 12927 { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" }, 12928 { 0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" }, 12929 { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" }, 12930 { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" }, 12931 { 0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" }, 12932 { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" }, 12933 { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" }, 12934 { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 12935 { 0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12936 { 0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 12937 { 0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 12938 { 0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 12939 { 0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12940 { 0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 12941 12942 //---------------------------------------------------------------------- 12943 // Other instructions 12944 //---------------------------------------------------------------------- 12945 { 0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" }, 12946 { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12947 { 0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" }, 12948 { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12949 { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" }, 12950 { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" }, 12951 { 0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" }, 12952 { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" }, 12953 }; 12954 12955 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 12956 for (size_t i=0; i<k_num_thumb_opcodes; ++i) 12957 { 12958 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 12959 (g_thumb_opcodes[i].variants & arm_isa) != 0) 12960 return &g_thumb_opcodes[i]; 12961 } 12962 return NULL; 12963 } 12964 12965 bool 12966 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch) 12967 { 12968 m_arch = arch; 12969 m_arm_isa = 0; 12970 const char *arch_cstr = arch.GetArchitectureName (); 12971 if (arch_cstr) 12972 { 12973 if (0 == ::strcasecmp(arch_cstr, "armv4t")) m_arm_isa = ARMv4T; 12974 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) m_arm_isa = ARMv5TEJ; 12975 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) m_arm_isa = ARMv5TE; 12976 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) m_arm_isa = ARMv5T; 12977 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) m_arm_isa = ARMv6K; 12978 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) m_arm_isa = ARMv6T2; 12979 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) m_arm_isa = ARMv7S; 12980 else if (0 == ::strcasecmp(arch_cstr, "arm")) m_arm_isa = ARMvAll; 12981 else if (0 == ::strcasecmp(arch_cstr, "thumb")) m_arm_isa = ARMvAll; 12982 else if (0 == ::strncasecmp(arch_cstr,"armv4", 5)) m_arm_isa = ARMv4; 12983 else if (0 == ::strncasecmp(arch_cstr,"armv6", 5)) m_arm_isa = ARMv6; 12984 else if (0 == ::strncasecmp(arch_cstr,"armv7", 5)) m_arm_isa = ARMv7; 12985 else if (0 == ::strncasecmp(arch_cstr,"armv8", 5)) m_arm_isa = ARMv8; 12986 } 12987 return m_arm_isa != 0; 12988 } 12989 12990 bool 12991 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) 12992 { 12993 if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) 12994 { 12995 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) 12996 m_opcode_mode = eModeThumb; 12997 else 12998 { 12999 AddressClass addr_class = inst_addr.GetAddressClass(); 13000 13001 if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown)) 13002 m_opcode_mode = eModeARM; 13003 else if (addr_class == eAddressClassCodeAlternateISA) 13004 m_opcode_mode = eModeThumb; 13005 else 13006 return false; 13007 } 13008 if (m_opcode_mode == eModeThumb) 13009 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13010 else 13011 m_opcode_cpsr = CPSR_MODE_USR; 13012 return true; 13013 } 13014 return false; 13015 } 13016 13017 bool 13018 EmulateInstructionARM::ReadInstruction () 13019 { 13020 bool success = false; 13021 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13022 if (success) 13023 { 13024 addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); 13025 if (success) 13026 { 13027 Context read_inst_context; 13028 read_inst_context.type = eContextReadOpcode; 13029 read_inst_context.SetNoArgs (); 13030 13031 if (m_opcode_cpsr & MASK_CPSR_T) 13032 { 13033 m_opcode_mode = eModeThumb; 13034 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13035 13036 if (success) 13037 { 13038 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0)) 13039 { 13040 m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder()); 13041 } 13042 else 13043 { 13044 m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder()); 13045 } 13046 } 13047 } 13048 else 13049 { 13050 m_opcode_mode = eModeARM; 13051 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder()); 13052 } 13053 } 13054 } 13055 if (!success) 13056 { 13057 m_opcode_mode = eModeInvalid; 13058 m_addr = LLDB_INVALID_ADDRESS; 13059 } 13060 return success; 13061 } 13062 13063 uint32_t 13064 EmulateInstructionARM::ArchVersion () 13065 { 13066 return m_arm_isa; 13067 } 13068 13069 bool 13070 EmulateInstructionARM::ConditionPassed (const uint32_t opcode) 13071 { 13072 // If we are ignoring conditions, then always return true. 13073 // this allows us to iterate over disassembly code and still 13074 // emulate an instruction even if we don't have all the right 13075 // bits set in the CPSR register... 13076 if (m_ignore_conditions) 13077 return true; 13078 13079 const uint32_t cond = CurrentCond (opcode); 13080 if (cond == UINT32_MAX) 13081 return false; 13082 13083 bool result = false; 13084 switch (UnsignedBits(cond, 3, 1)) 13085 { 13086 case 0: 13087 if (m_opcode_cpsr == 0) 13088 result = true; 13089 else 13090 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13091 break; 13092 case 1: 13093 if (m_opcode_cpsr == 0) 13094 result = true; 13095 else 13096 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13097 break; 13098 case 2: 13099 if (m_opcode_cpsr == 0) 13100 result = true; 13101 else 13102 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13103 break; 13104 case 3: 13105 if (m_opcode_cpsr == 0) 13106 result = true; 13107 else 13108 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13109 break; 13110 case 4: 13111 if (m_opcode_cpsr == 0) 13112 result = true; 13113 else 13114 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13115 break; 13116 case 5: 13117 if (m_opcode_cpsr == 0) 13118 result = true; 13119 else 13120 { 13121 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13122 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13123 result = n == v; 13124 } 13125 break; 13126 case 6: 13127 if (m_opcode_cpsr == 0) 13128 result = true; 13129 else 13130 { 13131 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13132 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13133 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13134 } 13135 break; 13136 case 7: 13137 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13138 // opcodes different meanings, but always means execution happens. 13139 return true; 13140 } 13141 13142 if (cond & 1) 13143 result = !result; 13144 return result; 13145 } 13146 13147 uint32_t 13148 EmulateInstructionARM::CurrentCond (const uint32_t opcode) 13149 { 13150 switch (m_opcode_mode) 13151 { 13152 case eModeInvalid: 13153 break; 13154 13155 case eModeARM: 13156 return UnsignedBits(opcode, 31, 28); 13157 13158 case eModeThumb: 13159 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13160 // 'cond' field of the encoding. 13161 { 13162 const uint32_t byte_size = m_opcode.GetByteSize(); 13163 if (byte_size == 2) 13164 { 13165 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 13166 return Bits32(opcode, 11, 8); 13167 } 13168 else if (byte_size == 4) 13169 { 13170 if (Bits32(opcode, 31, 27) == 0x1e && 13171 Bits32(opcode, 15, 14) == 0x02 && 13172 Bits32(opcode, 12, 12) == 0x00 && 13173 Bits32(opcode, 25, 22) <= 0x0d) 13174 { 13175 return Bits32(opcode, 25, 22); 13176 } 13177 } 13178 else 13179 // We have an invalid thumb instruction, let's bail out. 13180 break; 13181 13182 return m_it_session.GetCond(); 13183 } 13184 } 13185 return UINT32_MAX; // Return invalid value 13186 } 13187 13188 bool 13189 EmulateInstructionARM::InITBlock() 13190 { 13191 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13192 } 13193 13194 bool 13195 EmulateInstructionARM::LastInITBlock() 13196 { 13197 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13198 } 13199 13200 bool 13201 EmulateInstructionARM::BadMode (uint32_t mode) 13202 { 13203 13204 switch (mode) 13205 { 13206 case 16: return false; // '10000' 13207 case 17: return false; // '10001' 13208 case 18: return false; // '10010' 13209 case 19: return false; // '10011' 13210 case 22: return false; // '10110' 13211 case 23: return false; // '10111' 13212 case 27: return false; // '11011' 13213 case 31: return false; // '11111' 13214 default: return true; 13215 } 13216 return true; 13217 } 13218 13219 bool 13220 EmulateInstructionARM::CurrentModeIsPrivileged () 13221 { 13222 uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0); 13223 13224 if (BadMode (mode)) 13225 return false; 13226 13227 if (mode == 16) 13228 return false; 13229 13230 return true; 13231 } 13232 13233 void 13234 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate) 13235 { 13236 bool privileged = CurrentModeIsPrivileged(); 13237 13238 uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20; 13239 13240 if (BitIsSet (bytemask, 3)) 13241 { 13242 tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27); 13243 if (affect_execstate) 13244 tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24); 13245 } 13246 13247 if (BitIsSet (bytemask, 2)) 13248 { 13249 tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16); 13250 } 13251 13252 if (BitIsSet (bytemask, 1)) 13253 { 13254 if (affect_execstate) 13255 tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10); 13256 tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9); 13257 if (privileged) 13258 tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8); 13259 } 13260 13261 if (BitIsSet (bytemask, 0)) 13262 { 13263 if (privileged) 13264 tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6); 13265 if (affect_execstate) 13266 tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5); 13267 if (privileged) 13268 tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0); 13269 } 13270 13271 m_opcode_cpsr = tmp_cpsr; 13272 } 13273 13274 13275 bool 13276 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr) 13277 { 13278 addr_t target; 13279 13280 // Check the current instruction set. 13281 if (CurrentInstrSet() == eModeARM) 13282 target = addr & 0xfffffffc; 13283 else 13284 target = addr & 0xfffffffe; 13285 13286 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13287 return false; 13288 13289 return true; 13290 } 13291 13292 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr. 13293 bool 13294 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr) 13295 { 13296 addr_t target; 13297 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 13298 // we want to record it and issue a WriteRegister callback so the clients 13299 // can track the mode changes accordingly. 13300 bool cpsr_changed = false; 13301 13302 if (BitIsSet(addr, 0)) 13303 { 13304 if (CurrentInstrSet() != eModeThumb) 13305 { 13306 SelectInstrSet(eModeThumb); 13307 cpsr_changed = true; 13308 } 13309 target = addr & 0xfffffffe; 13310 context.SetISA (eModeThumb); 13311 } 13312 else if (BitIsClear(addr, 1)) 13313 { 13314 if (CurrentInstrSet() != eModeARM) 13315 { 13316 SelectInstrSet(eModeARM); 13317 cpsr_changed = true; 13318 } 13319 target = addr & 0xfffffffc; 13320 context.SetISA (eModeARM); 13321 } 13322 else 13323 return false; // address<1:0> == '10' => UNPREDICTABLE 13324 13325 if (cpsr_changed) 13326 { 13327 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13328 return false; 13329 } 13330 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target)) 13331 return false; 13332 13333 return true; 13334 } 13335 13336 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions. 13337 bool 13338 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr) 13339 { 13340 if (ArchVersion() >= ARMv5T) 13341 return BXWritePC(context, addr); 13342 else 13343 return BranchWritePC((const Context)context, addr); 13344 } 13345 13346 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set. 13347 bool 13348 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr) 13349 { 13350 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 13351 return BXWritePC(context, addr); 13352 else 13353 return BranchWritePC((const Context)context, addr); 13354 } 13355 13356 EmulateInstructionARM::Mode 13357 EmulateInstructionARM::CurrentInstrSet () 13358 { 13359 return m_opcode_mode; 13360 } 13361 13362 // Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 13363 // ReadInstruction() is performed. This function has a side effect of updating 13364 // the m_new_inst_cpsr member variable if necessary. 13365 bool 13366 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb) 13367 { 13368 m_new_inst_cpsr = m_opcode_cpsr; 13369 switch (arm_or_thumb) 13370 { 13371 default: 13372 return false; 13373 case eModeARM: 13374 // Clear the T bit. 13375 m_new_inst_cpsr &= ~MASK_CPSR_T; 13376 break; 13377 case eModeThumb: 13378 // Set the T bit. 13379 m_new_inst_cpsr |= MASK_CPSR_T; 13380 break; 13381 } 13382 return true; 13383 } 13384 13385 // This function returns TRUE if the processor currently provides support for 13386 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 13387 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 13388 bool 13389 EmulateInstructionARM::UnalignedSupport() 13390 { 13391 return (ArchVersion() >= ARMv7); 13392 } 13393 13394 // The main addition and subtraction instructions can produce status information 13395 // about both unsigned carry and signed overflow conditions. This status 13396 // information can be used to synthesize multi-word additions and subtractions. 13397 EmulateInstructionARM::AddWithCarryResult 13398 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in) 13399 { 13400 uint32_t result; 13401 uint8_t carry_out; 13402 uint8_t overflow; 13403 13404 uint64_t unsigned_sum = x + y + carry_in; 13405 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 13406 13407 result = UnsignedBits(unsigned_sum, 31, 0); 13408 // carry_out = (result == unsigned_sum ? 0 : 1); 13409 overflow = ((int32_t)result == signed_sum ? 0 : 1); 13410 13411 if (carry_in) 13412 carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0; 13413 else 13414 carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0; 13415 13416 AddWithCarryResult res = { result, carry_out, overflow }; 13417 return res; 13418 } 13419 13420 uint32_t 13421 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) 13422 { 13423 lldb::RegisterKind reg_kind; 13424 uint32_t reg_num; 13425 switch (num) 13426 { 13427 case SP_REG: 13428 reg_kind = eRegisterKindGeneric; 13429 reg_num = LLDB_REGNUM_GENERIC_SP; 13430 break; 13431 case LR_REG: 13432 reg_kind = eRegisterKindGeneric; 13433 reg_num = LLDB_REGNUM_GENERIC_RA; 13434 break; 13435 case PC_REG: 13436 reg_kind = eRegisterKindGeneric; 13437 reg_num = LLDB_REGNUM_GENERIC_PC; 13438 break; 13439 default: 13440 if (num < SP_REG) 13441 { 13442 reg_kind = eRegisterKindDWARF; 13443 reg_num = dwarf_r0 + num; 13444 } 13445 else 13446 { 13447 //assert(0 && "Invalid register number"); 13448 *success = false; 13449 return UINT32_MAX; 13450 } 13451 break; 13452 } 13453 13454 // Read our register. 13455 uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success); 13456 13457 // When executing an ARM instruction , PC reads as the address of the current 13458 // instruction plus 8. 13459 // When executing a Thumb instruction , PC reads as the address of the current 13460 // instruction plus 4. 13461 if (num == 15) 13462 { 13463 if (CurrentInstrSet() == eModeARM) 13464 val += 8; 13465 else 13466 val += 4; 13467 } 13468 13469 return val; 13470 } 13471 13472 // Write the result to the ARM core register Rd, and optionally update the 13473 // condition flags based on the result. 13474 // 13475 // This helper method tries to encapsulate the following pseudocode from the 13476 // ARM Architecture Reference Manual: 13477 // 13478 // if d == 15 then // Can only occur for encoding A1 13479 // ALUWritePC(result); // setflags is always FALSE here 13480 // else 13481 // R[d] = result; 13482 // if setflags then 13483 // APSR.N = result<31>; 13484 // APSR.Z = IsZeroBit(result); 13485 // APSR.C = carry; 13486 // // APSR.V unchanged 13487 // 13488 // In the above case, the API client does not pass in the overflow arg, which 13489 // defaults to ~0u. 13490 bool 13491 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context, 13492 const uint32_t result, 13493 const uint32_t Rd, 13494 bool setflags, 13495 const uint32_t carry, 13496 const uint32_t overflow) 13497 { 13498 if (Rd == 15) 13499 { 13500 if (!ALUWritePC (context, result)) 13501 return false; 13502 } 13503 else 13504 { 13505 lldb::RegisterKind reg_kind; 13506 uint32_t reg_num; 13507 switch (Rd) 13508 { 13509 case SP_REG: 13510 reg_kind = eRegisterKindGeneric; 13511 reg_num = LLDB_REGNUM_GENERIC_SP; 13512 break; 13513 case LR_REG: 13514 reg_kind = eRegisterKindGeneric; 13515 reg_num = LLDB_REGNUM_GENERIC_RA; 13516 break; 13517 default: 13518 reg_kind = eRegisterKindDWARF; 13519 reg_num = dwarf_r0 + Rd; 13520 } 13521 if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result)) 13522 return false; 13523 if (setflags) 13524 return WriteFlags (context, result, carry, overflow); 13525 } 13526 return true; 13527 } 13528 13529 // This helper method tries to encapsulate the following pseudocode from the 13530 // ARM Architecture Reference Manual: 13531 // 13532 // APSR.N = result<31>; 13533 // APSR.Z = IsZeroBit(result); 13534 // APSR.C = carry; 13535 // APSR.V = overflow 13536 // 13537 // Default arguments can be specified for carry and overflow parameters, which means 13538 // not to update the respective flags. 13539 bool 13540 EmulateInstructionARM::WriteFlags (Context &context, 13541 const uint32_t result, 13542 const uint32_t carry, 13543 const uint32_t overflow) 13544 { 13545 m_new_inst_cpsr = m_opcode_cpsr; 13546 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 13547 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 13548 if (carry != ~0u) 13549 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 13550 if (overflow != ~0u) 13551 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 13552 if (m_new_inst_cpsr != m_opcode_cpsr) 13553 { 13554 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 13555 return false; 13556 } 13557 return true; 13558 } 13559 13560 bool 13561 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options) 13562 { 13563 // Advance the ITSTATE bits to their values for the next instruction. 13564 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock()) 13565 m_it_session.ITAdvance(); 13566 13567 ARMOpcode *opcode_data = NULL; 13568 13569 if (m_opcode_mode == eModeThumb) 13570 opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13571 else if (m_opcode_mode == eModeARM) 13572 opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa); 13573 13574 if (opcode_data == NULL) 13575 return false; 13576 13577 const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 13578 m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions; 13579 13580 bool success = false; 13581 if (m_opcode_cpsr == 0 || m_ignore_conditions == false) 13582 { 13583 m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF, 13584 dwarf_cpsr, 13585 0, 13586 &success); 13587 } 13588 13589 // Only return false if we are unable to read the CPSR if we care about conditions 13590 if (success == false && m_ignore_conditions == false) 13591 return false; 13592 13593 uint32_t orig_pc_value = 0; 13594 if (auto_advance_pc) 13595 { 13596 orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13597 if (!success) 13598 return false; 13599 } 13600 13601 // Call the Emulate... function. 13602 success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); 13603 if (!success) 13604 return false; 13605 13606 if (auto_advance_pc) 13607 { 13608 uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success); 13609 if (!success) 13610 return false; 13611 13612 if (auto_advance_pc && (after_pc_value == orig_pc_value)) 13613 { 13614 if (opcode_data->size == eSize32) 13615 after_pc_value += 4; 13616 else if (opcode_data->size == eSize16) 13617 after_pc_value += 2; 13618 13619 EmulateInstruction::Context context; 13620 context.type = eContextAdvancePC; 13621 context.SetNoArgs(); 13622 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value)) 13623 return false; 13624 13625 } 13626 } 13627 return true; 13628 } 13629 13630 bool 13631 EmulateInstructionARM::IsInstructionConditional() 13632 { 13633 const uint32_t cond = CurrentCond (m_opcode.GetOpcode32()); 13634 return cond != 0xe && cond != 0xf && cond != UINT32_MAX; 13635 } 13636 13637 bool 13638 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) 13639 { 13640 if (!test_data) 13641 { 13642 out_stream->Printf ("TestEmulation: Missing test data.\n"); 13643 return false; 13644 } 13645 13646 static ConstString opcode_key ("opcode"); 13647 static ConstString before_key ("before_state"); 13648 static ConstString after_key ("after_state"); 13649 13650 OptionValueSP value_sp = test_data->GetValueForKey (opcode_key); 13651 13652 uint32_t test_opcode; 13653 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64)) 13654 { 13655 out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n"); 13656 return false; 13657 } 13658 test_opcode = value_sp->GetUInt64Value (); 13659 13660 if (arch.GetTriple().getArch() == llvm::Triple::arm) 13661 { 13662 m_opcode_mode = eModeARM; 13663 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13664 } 13665 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 13666 { 13667 m_opcode_mode = eModeThumb; 13668 if (test_opcode < 0x10000) 13669 m_opcode.SetOpcode16 (test_opcode, GetByteOrder()); 13670 else 13671 m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); 13672 13673 } 13674 else 13675 { 13676 out_stream->Printf ("TestEmulation: Invalid arch.\n"); 13677 return false; 13678 } 13679 13680 EmulationStateARM before_state; 13681 EmulationStateARM after_state; 13682 13683 value_sp = test_data->GetValueForKey (before_key); 13684 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13685 { 13686 out_stream->Printf ("TestEmulation: Failed to find 'before' state.\n"); 13687 return false; 13688 } 13689 13690 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary (); 13691 if (!before_state.LoadStateFromDictionary (state_dictionary)) 13692 { 13693 out_stream->Printf ("TestEmulation: Failed loading 'before' state.\n"); 13694 return false; 13695 } 13696 13697 value_sp = test_data->GetValueForKey (after_key); 13698 if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary)) 13699 { 13700 out_stream->Printf ("TestEmulation: Failed to find 'after' state.\n"); 13701 return false; 13702 } 13703 13704 state_dictionary = value_sp->GetAsDictionary (); 13705 if (!after_state.LoadStateFromDictionary (state_dictionary)) 13706 { 13707 out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n"); 13708 return false; 13709 } 13710 13711 SetBaton ((void *) &before_state); 13712 SetCallbacks (&EmulationStateARM::ReadPseudoMemory, 13713 &EmulationStateARM::WritePseudoMemory, 13714 &EmulationStateARM::ReadPseudoRegister, 13715 &EmulationStateARM::WritePseudoRegister); 13716 13717 bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC); 13718 if (!success) 13719 { 13720 out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n"); 13721 return false; 13722 } 13723 13724 success = before_state.CompareState (after_state); 13725 if (!success) 13726 out_stream->Printf ("TestEmulation: 'before' and 'after' states do not match.\n"); 13727 13728 return success; 13729 } 13730 // 13731 // 13732 //const char * 13733 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 13734 //{ 13735 // if (reg_kind == eRegisterKindGeneric) 13736 // { 13737 // switch (reg_num) 13738 // { 13739 // case LLDB_REGNUM_GENERIC_PC: return "pc"; 13740 // case LLDB_REGNUM_GENERIC_SP: return "sp"; 13741 // case LLDB_REGNUM_GENERIC_FP: return "fp"; 13742 // case LLDB_REGNUM_GENERIC_RA: return "lr"; 13743 // case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 13744 // default: return NULL; 13745 // } 13746 // } 13747 // else if (reg_kind == eRegisterKindDWARF) 13748 // { 13749 // return GetARMDWARFRegisterName (reg_num); 13750 // } 13751 // return NULL; 13752 //} 13753 // 13754 bool 13755 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 13756 { 13757 unwind_plan.Clear(); 13758 unwind_plan.SetRegisterKind (eRegisterKindDWARF); 13759 13760 UnwindPlan::RowSP row(new UnwindPlan::Row); 13761 13762 // Our previous Call Frame Address is the stack pointer 13763 row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0); 13764 13765 unwind_plan.AppendRow (row); 13766 unwind_plan.SetSourceName ("EmulateInstructionARM"); 13767 unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); 13768 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); 13769 unwind_plan.SetReturnAddressRegister (dwarf_lr); 13770 return true; 13771 } 13772